From d0570642af3961b534ea3450d4b85765f1acb21b Mon Sep 17 00:00:00 2001
From: Rodrigo CORTES PORTO <Rodrigo.Cortes-porto@lip6.fr>
Date: Thu, 16 Aug 2018 12:20:59 +0200
Subject: [PATCH] Added schedule generation for TDF cluster diagrams in TTool.
 Initial sync validation in TTool.

---
 .../SysCAMSSpecification.java                 |  14 +-
 .../syscamstranslator/SysCAMSTBlockTDF.java   | 117 ++++++++-
 .../SysCAMSValidateException.java             |  61 +++++
 .../toSysCAMSCluster/ClusterCode.java         |  13 +-
 .../toSysCAMSCluster/Header.java              |   7 +-
 .../TopCellGeneratorCluster.java              |   2 +
 ...DialogSysCAMSExecutableCodeGeneration.java | 242 +++++++++++++++---
 7 files changed, 409 insertions(+), 47 deletions(-)
 create mode 100644 src/main/java/syscamstranslator/SysCAMSValidateException.java

diff --git a/src/main/java/syscamstranslator/SysCAMSSpecification.java b/src/main/java/syscamstranslator/SysCAMSSpecification.java
index 7349f34aea..4c4f1e7471 100644
--- a/src/main/java/syscamstranslator/SysCAMSSpecification.java
+++ b/src/main/java/syscamstranslator/SysCAMSSpecification.java
@@ -170,6 +170,18 @@ public class SysCAMSSpecification{
 		}
 		return cons;
 	}
+    
+    public LinkedList<SysCAMSTConnector> getAllConnectorsCluster4Matrix(){
+        LinkedList<SysCAMSTConnector> cons = new LinkedList<SysCAMSTConnector>();
+        for (SysCAMSTConnector con : connectors) {
+            if (con instanceof SysCAMSTConnector) {
+                if (con.get_p1().getComponent() instanceof SysCAMSTPortTDF && con.get_p2().getComponent() instanceof SysCAMSTPortTDF) {
+                    cons.add(con);
+                }
+            }
+        }
+        return cons;
+    }
 
 	public int getNbBlockTDF(){
 		return (getAllBlockTDF()).size();
@@ -198,4 +210,4 @@ public class SysCAMSSpecification{
 	public int getNbConnectorCluster(){
 		return (getAllConnectorCluster()).size();
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java b/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java
index 65cff7cbf0..f773138e5e 100644
--- a/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java
+++ b/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java
@@ -64,6 +64,8 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent {
 	
 	private LinkedList<SysCAMSTPortTDF> portTDF;
 	private LinkedList<SysCAMSTPortConverter> portConverter;
+    private SysCAMSTPortConverter localPortConverter;
+    private int n;
 	
 	public SysCAMSTBlockTDF(String _name, int _period, String _time, String _processCode, DefaultListModel<String> _listStruct, String _nameTemplate, String _typeTemplate, DefaultListModel<String> _listTypedef, SysCAMSTCluster _cluster) {
 		name = _name;
@@ -77,6 +79,7 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent {
 		cluster = _cluster;
 		portTDF = new LinkedList<SysCAMSTPortTDF>();
 		portConverter = new LinkedList<SysCAMSTPortConverter>();
+        n = 0;
 	}
 
 	public String getName() {
@@ -130,4 +133,116 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent {
 	public void addPortConverter(SysCAMSTPortConverter converter){
 		portConverter.add(converter);
 	}
-}
\ No newline at end of file
+
+    public void syncTDFBlockDEBlock(double[] time_prev) throws SysCAMSValidateException {
+        double tp;
+        try{
+            for(int i = 0; i < portConverter.size(); i++) {
+                localPortConverter = portConverter.get(i);
+                if(localPortConverter.getOrigin() == 0) { //Input
+                    check_causality_in(time_prev);
+                } else if (localPortConverter.getOrigin() == 1) { //Output
+                    check_causality_out(time_prev);
+                }
+            }
+        } catch (SysCAMSValidateException se){
+             throw new SysCAMSValidateException(se.getMessage());
+        }
+    }
+    
+    private void check_causality_in(double[] time_prev_max) throws SysCAMSValidateException {
+        double time_now_min_tdf, time_now_max_tdf, time_tmp_tdf, time_tmp_de,
+                time_now_min_de, time_now_max_de;
+        double tm = 0.0;
+        double tp = 0.0;
+        int r = 0;
+        int d = 0;
+        int k = 1;
+        if(period > 0)
+            tm = period;
+        if(localPortConverter.getPeriod() > 0)
+            tp = localPortConverter.getPeriod();
+        if(localPortConverter.getRate() > 0)
+            r = localPortConverter.getRate();
+        if(localPortConverter.getDelay() > 0)
+            d = localPortConverter.getDelay();
+
+        time_now_min_tdf = (n*tm)+((k-1)*tp);
+        time_now_max_tdf = (n*tm)+((k-1)*tp);
+        time_now_min_de = (n*tm)+((k-1)*tp)-(d*tp);
+        time_now_max_de = (n*tm)+((k-1)*tp)-(d*tp);
+        
+        for (k = 1; k <= r; k++) {
+            time_tmp_tdf = (n*tm)+((k-1)*tp);
+            time_tmp_de = (n*tm)+((k-1)*tp)-(d*tp);
+            System.out.println("tmstmp_in_tdf: " + time_tmp_tdf);
+            System.out.println("tmstmp_in_de: " + time_tmp_de);
+            time_now_min_tdf = Math.min(time_tmp_tdf, time_now_min_tdf);
+            time_now_max_tdf = Math.max(time_tmp_tdf, time_now_max_tdf);
+            time_now_min_de = Math.min(time_tmp_de, time_now_min_de);
+            time_now_max_de = Math.max(time_tmp_de, time_now_max_de);
+            System.out.println("time_now_min_de: " + time_now_min_de);
+            System.out.println("time_now_max_de: " + time_now_max_de);
+            System.out.println("time_now_min_tdf: " + time_now_min_tdf);
+            System.out.println("time_now_max_tdf: " + time_now_max_tdf);
+        }
+        //Increase number of times block has been executed
+        n++;
+        
+        System.out.println("time_prev_max_out: " + time_prev_max[1]);
+        if(time_now_min_de < time_prev_max[1]) {
+            throw new SysCAMSValidateException("Timestamp of previous write port executed module is: " + time_prev_max[1]
+                 + " and current timestamp is: " + time_now_min_de);
+        }
+        time_prev_max[0] = Double.valueOf(Math.max(time_prev_max[0],time_now_max_de));
+        System.out.println("New time_prev_max_in: " + time_prev_max[0]);
+    }
+    
+    private void check_causality_out(double[] time_prev_max) throws SysCAMSValidateException {
+        double time_now_min_tdf, time_now_max_tdf, time_tmp_tdf, time_tmp_de,
+                time_now_min_de, time_now_max_de;
+        double tm = 0.0;
+        double tp = 0.0;
+        int r = 0;
+        int d = 0;
+        int k = 1;
+        if(period > 0)
+            tm = period;
+        if(localPortConverter.getPeriod() > 0)
+            tp = localPortConverter.getPeriod();
+        if(localPortConverter.getRate() > 0)
+            r = localPortConverter.getRate();
+        if(localPortConverter.getDelay() > 0)
+            d = localPortConverter.getDelay();
+
+        time_now_min_tdf = (n*tm)+((k-1)*tp);
+        time_now_max_tdf = (n*tm)+((k-1)*tp);
+        time_now_min_de = (n*tm)+((k-1)*tp)+(d*tp);
+        time_now_max_de = (n*tm)+((k-1)*tp)+(d*tp);
+        
+        for (k = 1; k <= r; k++) {
+            time_tmp_tdf = (n*tm)+((k-1)*tp);
+            time_tmp_de = (n*tm)+((k-1)*tp)+(d*tp);;
+            System.out.println("tmstmp_in_tdf: " + time_tmp_tdf);
+            System.out.println("tmstmp_in_de: " + time_tmp_de);
+            time_now_min_tdf = Math.min(time_tmp_tdf, time_now_min_tdf);
+            time_now_max_tdf = Math.max(time_tmp_tdf, time_now_max_tdf);
+            time_now_min_de = Math.min(time_tmp_de, time_now_min_de);
+            time_now_max_de = Math.max(time_tmp_de, time_now_max_de);
+            System.out.println("time_now_min_de: " + time_now_min_de);
+            System.out.println("time_now_max_de: " + time_now_max_de);
+            System.out.println("time_now_min_tdf: " + time_now_min_tdf);
+            System.out.println("time_now_max_tdf: " + time_now_max_tdf);
+        }
+        //Increase number of times block has been executed
+        n++;
+        
+        System.out.println("time_prev_max_in: " + time_prev_max[0]);
+        if(time_now_min_de < time_prev_max[0]) {
+            throw new SysCAMSValidateException("Timestamp of previous read port executed module is: " + time_prev_max[0]
+                 + " and current timestamp is: " + time_now_min_de);
+        }
+        time_prev_max[1] = Double.valueOf(Math.max(time_prev_max[1],time_now_max_tdf));
+        System.out.println("New time_prev_max_out: " + time_prev_max[1]);
+    }
+}
diff --git a/src/main/java/syscamstranslator/SysCAMSValidateException.java b/src/main/java/syscamstranslator/SysCAMSValidateException.java
new file mode 100644
index 0000000000..5784ed7956
--- /dev/null
+++ b/src/main/java/syscamstranslator/SysCAMSValidateException.java
@@ -0,0 +1,61 @@
+/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+ * 
+ * ludovic.apvrille AT enst.fr
+ * 
+ * This software is a computer program whose purpose is to allow the
+ * edition of TURTLE analysis, design and deployment diagrams, to
+ * allow the generation of RT-LOTOS or Java code from this diagram,
+ * and at last to allow the analysis of formal validation traces
+ * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+ * from INRIA Rhone-Alpes.
+ * 
+ * This software is governed by the CeCILL  license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+
+
+package syscamstranslator;
+
+
+/**
+ * Class SysCAMSValidateException
+ * Creation: 14/08/2018
+ * version 1.0 14/08/2018
+ * @author Rodrigo CORTES PORTO
+ */
+public class SysCAMSValidateException extends Exception {
+    
+    public SysCAMSValidateException() {
+        super("SysC-AMS diagram validation exception");
+    }
+    
+    public SysCAMSValidateException(String msg) {
+        super(msg);
+    }
+    
+} // Class
diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java b/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java
index fecbe00e61..d76cc5ddce 100644
--- a/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java
+++ b/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java
@@ -38,11 +38,6 @@
  * knowledge of the CeCILL license and that you accept its terms.
  */
 
-/* this class produces the lines containing essentially the initial #includes; we include all potential components event if they are not used in the deployment diagram*/
-
-/* authors: v1.0 Raja GATGOUT 2014
-            v2.0 Daniela GENIUS, Julien HENON 2015 */
-
 package syscamstranslator.toSysCAMSCluster;
 
 import java.util.LinkedList;
@@ -51,10 +46,10 @@ import syscamstranslator.*;
 
 /**
  * Class ClusterCode
- * Principal code of a cluster component
- * Creation: 14/05/2018
- * @version 1.0 14/05/2018
- * @author Irina Kit Yan LEE
+ * Principal code of a cluster component that wraps all AMS components.
+ * Creation: 30/07/2018
+ * @version 1.0 30/07/2018
+ * @author Rodrigo CORTES PORTO
 */
 
 public class ClusterCode {
diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java b/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java
index e20067c572..ba78e5bef3 100644
--- a/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java
+++ b/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java
@@ -38,11 +38,6 @@
  * knowledge of the CeCILL license and that you accept its terms.
  */
 
-/* this class produces the lines containing essentially the initial #includes; we include all potential components event if they are not used in the deployment diagram*/
-
-/* authors: v1.0 Raja GATGOUT 2014
-            v2.0 Daniela GENIUS, Julien HENON 2015 */
-
 package syscamstranslator.toSysCAMSCluster;
 
 import java.util.LinkedList;
@@ -55,6 +50,8 @@ import syscamstranslator.*;
  * Creation: 14/05/2018
  * @version 1.0 14/05/2018
  * @author Irina Kit Yan LEE
+ * @version 1.1 30/07/2018
+ * @author Rodrigo CORTES PORTO
 */
 
 public class Header {
diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java b/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java
index fb6dfac0f6..7d469baeba 100644
--- a/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java
+++ b/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java
@@ -56,6 +56,8 @@ import java.util.LinkedList;
  * Creation: 14/05/2018
  * @version 1.0 14/05/2018
  * @author Irina Kit Yan LEE
+ * @version 1.1 30/07/2018
+ * @author Rodrigo CORTES PORTO
 */
 
 public class TopCellGeneratorCluster {
diff --git a/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java b/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java
index f207d6f395..2782a23bfb 100644
--- a/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java
+++ b/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java
@@ -44,12 +44,14 @@ import syscamstranslator.toSysCAMSCluster.TopCellGeneratorCluster;
 import launcher.LauncherException;
 import launcher.RshClient;
 import myutil.*;
-import syscamstranslator.SysCAMSSpecification;
-import syscamstranslator.SysCAMSTCluster;
+import syscamstranslator.*;
 import ui.util.IconManager;
 import ui.MainGUI;
 import ui.SysCAMSPanelTranslator;
 import ui.syscams.SysCAMSComponentTaskDiagramPanel;
+import org.apache.commons.math3.linear.*;
+import org.apache.commons.math3.util.*;
+import org.apache.commons.math3.fraction.*;
 
 import javax.swing.*;
 import java.awt.*;
@@ -60,6 +62,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.util.LinkedList;
 import java.util.Vector;
+import java.util.Arrays;
 
 /**
  * Class JDialogSysCAMSExecutableCodeGeneration
@@ -130,7 +133,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
 
     private Thread t;
     private boolean go = false;
-//    private boolean hasError = false;
+    private boolean hasError = false;
     protected boolean startProcess = false;
 
 //    private String hostExecute;
@@ -178,31 +181,33 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
 
         // Issue #41 Ordering of tabbed panes 
         jp1 = GraphicLib.createTabbedPane();//new JTabbedPane();
-
+        
+        JPanel jp00 = new JPanel();
+        GridBagLayout gridbag00 = new GridBagLayout();
+        GridBagConstraints c00 = new GridBagConstraints();
+        jp00.setLayout(gridbag00);
+        jp00.setBorder(new javax.swing.border.TitledBorder("Validation"));
+       
         JPanel jp01 = new JPanel();
         GridBagLayout gridbag01 = new GridBagLayout();
         GridBagConstraints c01 = new GridBagConstraints();
         jp01.setLayout(gridbag01);
         jp01.setBorder(new javax.swing.border.TitledBorder("Code generation"));
+        
+         // Panel 00 -> Validation
+        c00.gridheight = 1;
+        c00.weighty = 1.0;
+        c00.weightx = 1.0;
+        c00.gridwidth = GridBagConstraints.REMAINDER; //end row
+        c00.fill = GridBagConstraints.BOTH;
+        c00.gridheight = 1;
 
-//        JPanel jp02 = new JPanel();
-//        GridBagLayout gridbag02 = new GridBagLayout();
-//        GridBagConstraints c02 = new GridBagConstraints();
-//        jp02.setLayout(gridbag02);
-//        jp02.setBorder(new javax.swing.border.TitledBorder("Compilation"));
-//
-//        JPanel jp03 = new JPanel();
-//        GridBagLayout gridbag03 = new GridBagLayout();
-//        GridBagConstraints c03 = new GridBagConstraints();
-//        jp03.setLayout(gridbag03);
-//        jp03.setBorder(new javax.swing.border.TitledBorder("Execution"));
-//
-//        JPanel jp04 = new JPanel();
-//        GridBagLayout gridbag04 = new GridBagLayout();
-//        GridBagConstraints c04 = new GridBagConstraints();
-//        jp04.setLayout(gridbag04);
-//        jp04.setBorder(new javax.swing.border.TitledBorder("Simulation trace"));
+        jp00.add(new JLabel(" "), c00);
+        c00.gridwidth = GridBagConstraints.REMAINDER; //end row
 
+        jp1.add("Validation", jp00);
+
+        // Panel 01 -> Code Generation
         c01.gridheight = 1;
         c01.weighty = 1.0;
         c01.weightx = 1.0;
@@ -229,7 +234,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
         jp01.add(code3, c01);
 
         jp01.add(new JLabel(" "), c01);
-        c01.gridwidth = GridBagConstraints.REMAINDER; //end row
+        //c01.gridwidth = GridBagConstraints.REMAINDER; //end row
 
 //        removeCFiles = new JCheckBox("Remove .c / .h files");
 //        removeCFiles.setSelected(removeCFilesValue);
@@ -371,7 +376,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
         jta.setEditable(false);
         jta.setMargin(new Insets(10, 10, 10, 10));
         jta.setTabSize(3);
-        jta.append("Select options and then, click on 'start' to launch code generation\n"); // / compilation / execution
+        jta.append("Select options and then, click on 'start' to launch validation / code generation\n"); // / compilation / execution
         Font f = new Font("Courrier", Font.BOLD, 12);
         jta.setFont(f);
         jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
@@ -500,10 +505,55 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
     public void run() {
 //        String cmd;
 //        String list;//, data;
-//        hasError = false;
+        hasError = false;
 
         try {
             if (jp1.getSelectedIndex() == 0) {
+                Vector<SysCAMSComponentTaskDiagramPanel> syscamsDiagramPanels = mgui.getListSysCAMSPanel();
+                for (SysCAMSComponentTaskDiagramPanel syscamsDiagramPanel : syscamsDiagramPanels) {
+                    SysCAMSPanelTranslator syscamspaneltranslator = new SysCAMSPanelTranslator(syscamsDiagramPanel);
+                    SysCAMSSpecification syscalsspec = syscamspaneltranslator.getSysCAMSSpecification();
+                    if (syscalsspec == null) {
+                        jta.append("Error: No SYSCAMS specification\n");
+                    } else {
+                        jta.append("Performing Validation for \""+(syscalsspec.getCluster()).getClusterName()+"\".\n");
+                        LinkedList<SysCAMSTConnector> connectors = syscalsspec.getAllConnectorsCluster4Matrix();
+                        System.out.printf("Connectors for 1 cluster = %d.\n", connectors.size());
+                        LinkedList<SysCAMSTBlockTDF> tdfBlocks = syscalsspec.getAllBlockTDF();
+                        System.out.printf("Blocks for 1 cluster = %d.\n", tdfBlocks.size());
+                        //TODO: verify trivial case when only 1 block and no connectors. 
+                        if(connectors.size() > 0) {
+                            RealVector buffer = new ArrayRealVector(connectors.size());
+                            RealVectorFormat printFormat = new RealVectorFormat();
+                            RealMatrix topologyMatrix = buildTopologyMatrix(connectors, tdfBlocks, buffer);
+                            System.out.println("Buffer after topMatrix is: " + printFormat.format(buffer) );
+                            try {
+                                RealVector execRate = solveTopologyMatrix(topologyMatrix, tdfBlocks);
+                                //TODO: to recompute, put a while loop here with a flag. Check after compute if no error. If error, modify buffer with the suggested delay, and loop.
+                                computeSchedule(execRate, topologyMatrix, buffer, tdfBlocks, connectors);
+                                jta.append("Validation for \""+(syscalsspec.getCluster()).getClusterName()+"\" completed.\n");
+                            } catch (InterruptedException ie) {
+                                System.err.println("Interrupted");
+                                jta.append("Interrupted\n");
+                                mode = STOPPED;
+                                setButtons();
+                                hasError = true;
+                                //return;
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                                mode = STOPPED;
+                                setButtons();
+                                hasError = true;
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+            
+            testGo();
+            
+            if (jp1.getSelectedIndex() == 1) {
                 jta.append("Generating executable code (SystemC-AMS version)\n");
 
                 Vector<SysCAMSComponentTaskDiagramPanel> syscamsDiagramPanels = mgui.getListSysCAMSPanel();
@@ -675,17 +725,18 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
 //                    return;
 //                }
 //            }
-//            if ((hasError == false) && (jp1.getSelectedIndex() < 2)) {
-//                jp1.setSelectedIndex(jp1.getSelectedIndex() + 1);
-//            }
+            if ((hasError == false) && (jp1.getSelectedIndex() < 2)) {
+                jp1.setSelectedIndex(jp1.getSelectedIndex() + 1);
+            }
         } catch (InterruptedException ie) {
             jta.append("Interrupted\n");
         }
+        if (!hasError) {
+            jta.append("\n\nReady to process next command\n");
 
-        jta.append("\n\nReady to process next command\n");
-
-        checkMode();
-        setButtons();
+            checkMode();
+            setButtons();
+        }
     }
 
     protected void processCmd(String cmd, JTextArea _jta) throws LauncherException {
@@ -739,6 +790,135 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i
 //        hasError = true;
     }
 
+    public RealMatrix buildTopologyMatrix(LinkedList<SysCAMSTConnector> connectors, LinkedList<SysCAMSTBlockTDF> blocks, RealVector buffer) {
+        double [][] tArray = new double[connectors.size()][blocks.size()];
+        for(int i = 0; i < connectors.size(); i++) {
+            for(int j = 0; j < blocks.size(); j++) {
+                if( ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getBlockTDF().getName().equals(blocks.get(j).getName()) ) {
+                    System.out.println("Inserting in : "+ i + " " + j + " From port: "+ ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getName() +" Rate: " + ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getRate() );
+                    tArray[i][j] = ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getRate();
+                    if(((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getDelay() > 0) {
+                        buffer.addToEntry(i, ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getDelay() ); 
+                    }
+                } else if( ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getBlockTDF().getName().equals(blocks.get(j).getName()) ) {
+                    System.out.println("Inserting in : "+ i + " " + j + " From port: "+ ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getName() +" Rate: " + -((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getRate() );
+                    tArray[i][j] = -((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getRate();
+                    if(((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getDelay() > 0) {
+                        buffer.addToEntry(i, ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getDelay() );
+                    }
+                }
+            }
+        }
+        
+        //double[][] tArray = { { 2, -1, 0 }, { 0, 2, -4 }, { -1, 0, 1 } };
+        //double[][] tArray = { { 2, 3, 5 }, { -4, 2, 3} };
+        //double[][] tArray = { { 3, -2, 0, 0 }, { 0, 4, 0, -3 }, { 0, 1, -3, 0 }, { -1, 0, 2, 0 }, { -2, 0, 0, 1 } };
+        //double[][] tArray = { { 3, -2 } };
+        RealMatrix tMatrix = new Array2DRowRealMatrix(tArray);
+        return tMatrix;
+    }
+
+    public RealVector solveTopologyMatrix(RealMatrix matrixA, LinkedList<SysCAMSTBlockTDF> blocks) throws InterruptedException {
+        double dropThreshold = 1e-7;
+        //Using QR decomposition, A^TP=QR. Since rank MUST be rank = s-1 
+        //(where s is number of blocks), then the last column of Q provides a basis for the kernel of A.
+        RRQRDecomposition qr = new RRQRDecomposition(matrixA.transpose());
+        RealMatrix qMatrix = qr.getQ();
+        int rank = qr.getRank(dropThreshold);
+        if(rank != blocks.size()-1){
+            jta.append("Error: Port sample rates are inconsistent. Topology matrix can not be solved.\n");
+            System.err.println("Port sample rates are inconsistent. Topology matrix can not be solved. Rank: " +rank+" != #blocks-1");
+            throw new InterruptedException(); 
+        }
+        System.out.println("Checking kernel columns ...");
+        RealMatrix zMatrix = matrixA.multiply(qMatrix);
+        for (int c = rank; c < matrixA.getColumnDimension(); c++) {
+            System.out.printf("The product of A with column %d of Q has sup "
+                            + "norm %f.\n",
+                            c, zMatrix.getColumnMatrix(c).getNorm());
+            //TODO: verify if norm is not zero, throw error that kernel could not be found.              
+        }
+        
+        RealMatrix kernelMatrix = qMatrix.getSubMatrix( 0, qMatrix.getRowDimension()-1, rank, qMatrix.getColumnDimension()-1 );
+        double[] resultArray = new double[kernelMatrix.getRowDimension()];
+        double result_tmp = 0.0;
+        int v_lcm = 1;
+        Fraction[] resultFractionArray = new Fraction[kernelMatrix.getRowDimension()];
+        for (int i = 0; i < kernelMatrix.getRowDimension(); i++) {
+            System.out.printf("The kernelMatrix is %f .\n", kernelMatrix.getEntry(i, 0) );
+            resultArray[i] = kernelMatrix.getEntry(i, 0) / kernelMatrix.getEntry(kernelMatrix.getRowDimension()-1, 0);
+            result_tmp = kernelMatrix.getEntry(i, 0) / kernelMatrix.getEntry(kernelMatrix.getRowDimension()-1, 0);
+            resultFractionArray[i] = new Fraction(result_tmp);
+            System.out.println("The resultArray is: "+ resultArray[i] );
+            System.out.println("The resultFractionArray is: "+ resultFractionArray[i].toString() );
+            v_lcm = ArithmeticUtils.lcm(resultFractionArray[i].getDenominator() , v_lcm);
+            System.out.println("The lcm is: "+ v_lcm );
+        }
+        int[] tmpResult = new int[kernelMatrix.getRowDimension()];
+        double[] finalResult = new double[kernelMatrix.getRowDimension()];
+        for (int i = 0; i < kernelMatrix.getRowDimension(); i++) {
+            tmpResult[i] = (resultFractionArray[i].multiply(v_lcm)).intValue();
+            finalResult[i] = (double)tmpResult[i];
+            System.out.println("The finalResult is: "+ finalResult[i] + " - " + blocks.get(i).getName() );
+        }
+            RealVector xVector = new ArrayRealVector(finalResult);
+            return xVector;
+    }
+    
+    public void computeSchedule(RealVector q, RealMatrix gamma, RealVector buffer, LinkedList<SysCAMSTBlockTDF> tdfBlocks, LinkedList<SysCAMSTConnector> connectors) throws InterruptedException {
+        RealVector q1 = new ArrayRealVector(q.getDimension());
+        RealVector nu = new ArrayRealVector(q.getDimension());
+        RealVector tmpBuffer = new ArrayRealVector(gamma.getRowDimension());;
+        RealVectorFormat printFormat = new RealVectorFormat();
+        boolean deadlock = false;
+        SysCAMSTBlockTDF tdfBlock;
+        double[] time_prev = {0.0, 0.0}; //array to store in[0] and out[1] previous times
+        try {
+            while (!(q1.equals(q)) && !deadlock){
+                deadlock = true;
+                for(int i = 0; i < tdfBlocks.size(); i++) {
+                    tdfBlock = tdfBlocks.get(i);
+                    //check if block is runnable: If it has not run q times 
+                    //and it won't cause a buffer size to go negative.
+                    System.out.println("q1 is: " + printFormat.format(q1) );
+                    System.out.println("q is: " + printFormat.format(q) );
+                    if(q1.getEntry(i) != q.getEntry(i)) {
+                        nu.setEntry(i, 1);
+                        tmpBuffer = buffer.add(gamma.operate(nu));
+                        System.out.println("tmpBuffer is: " + printFormat.format(tmpBuffer) );
+                        if(tmpBuffer.getMinValue() >= 0) {
+                            deadlock = false;
+                            q1 = q1.add(nu);
+                            buffer = tmpBuffer.copy();
+                            System.out.println("Schedule " + tdfBlock.getName() );
+                            System.out.println("Buffer is: " + printFormat.format(buffer) );
+                            //Validate sync bewtween TDF/DE 
+                            tdfBlock.syncTDFBlockDEBlock(time_prev);
+                        }
+                        nu.setEntry(i, 0);
+                    }
+                }
+            }
+        } catch (SysCAMSValidateException se) {
+            System.out.println("Causality exception: " + se.getMessage());
+        }
+        if (deadlock){
+            System.out.println("Static schedule can not be computed due to missing delays in loops" );
+            jta.append("Error: Static schedule can not be computed due to missing delays in loops\n" );
+            int minIndex = tmpBuffer.getMinIndex();
+            //TODO: for the suggested delay, I need to first detect loops within the graph(DFS?), then recompute recursively with the suggested delay until it can be solved.
+            /*jta.append("Following delay is suggested:\n" );
+            int currentDelay = ((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getDelay();
+            jta.append(currentDelay-(int)tmpBuffer.getMinValue() +" in port \""
+            +((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getName()
+            +"\" from block \""+ ((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getBlockTDF().getName()+"\"\n");
+            */
+            throw new InterruptedException(); 
+        } else {
+            System.out.println("Schedule complete-STOP" );
+        }
+    }
+    
 //    public void showSimulationTrace() {
 //        JFrameSimulationSDPanel jfssdp = new JFrameSimulationSDPanel(f, mgui, "Simulation trace of " + simulationTraceFile.getText());
 //        jfssdp.setIconImage(IconManager.img8);
-- 
GitLab