rparedis %!s(int64=3) %!d(string=hai) anos
pai
achega
aeed224d9b

+ 3 - 2
README.md

@@ -27,8 +27,9 @@ pip install .
 python -m pip install .
 python -m pip install .
 ```
 ```
 
 
-Note that these commands assume `python` and `pip` refer to either Python 2 or
-Python 3, depending on your system.
+Note that these commands assume `python` and `pip` refer to Python 3.
+
+**As of version 1.5, Python 2 is no longer supported.**
 
 
 _**Note:** Some editors allow you to "mark" a directory as a source root. Use
 _**Note:** Some editors allow you to "mark" a directory as a source root. Use
 this option in your favorite IDE to use the library in a project without the
 this option in your favorite IDE to use the library in a project without the

+ 2 - 4
doc/CBD.converters.CBD2C.rst

@@ -1,7 +1,5 @@
 Generate C code from CBDs
 Generate C code from CBDs
 =========================
 =========================
 
 
-.. automodule:: CBD.converters.CBD2C
-    :members:
-    :undoc-members:
-    :show-inheritance:
+This module has been extracted to the CBD2FMU generator project in order to minimize
+code duplication and dependency overhead.

+ 16 - 0
doc/changelog.rst

@@ -3,6 +3,22 @@ Changelog
 
 
 .. code-block:: text
 .. code-block:: text
 
 
+    Version 1.5
+        * Changed how ports work. Instead of using PortBlocks, a custom Port
+          (and Connection) class has been introduced.
+            - InputPortBlock, WireBlock and OutputPortBlock were removed.
+            * Flattening now ignores empty CBD blocks and in-between ports.
+        * Some functions have been renamed to have a more descriptive name.
+            * linkInput was changed to linkToInput
+            * getSignals was split to getOutputPortNames and getSignalHistory
+        * naivelog now uses the standard Python logging module.
+        * Changed realtime simulation to be used more efficiently.
+            * Pubsub structure now runs asynchronously.
+            * Tracing now happens asynchronously.
+        - Removed the CBD2C module to reduce code duplication w.r.t. the
+          CBD2FMU project.
+        + Plotting framework now works with Bokeh.
+
     Version 1.4
     Version 1.4
         + Added DeltaTBlock
         + Added DeltaTBlock
         - Removed "delta_t" input port of IntegratorBlock and DerivatorBlock
         - Removed "delta_t" input port of IntegratorBlock and DerivatorBlock

+ 1 - 1
doc/conf.py

@@ -25,7 +25,7 @@ copyright = '2020, Randy Paredis'
 author = 'Randy Paredis'
 author = 'Randy Paredis'
 
 
 # The short X.Y version
 # The short X.Y version
-version = ''
+version = '1.5'
 # The full version, including alpha/beta/rc tags
 # The full version, including alpha/beta/rc tags
 release = ''
 release = ''
 
 

+ 2 - 0
doc/index.rst

@@ -21,6 +21,8 @@ to model complex systems of equations.
 
 
 :Python Version: :code:`>= 3.4`
 :Python Version: :code:`>= 3.4`
 
 
+.. versionchanged:: 1.5
+    Python 2 is no longer supported.
 
 
 .. note::
 .. note::
     This documentation is a mere description of the CBD modelling framework
     This documentation is a mere description of the CBD modelling framework

+ 0 - 2
doc/install.rst

@@ -31,8 +31,6 @@ Next, there are some additional **optional** requirements:
     allow the creation of CBDs directly from a textual language.
     allow the creation of CBDs directly from a textual language.
   * `PythonPDEVS <http://msdl.cs.mcgill.ca/projects/DEVS/PythonPDEVS>`_ for the :mod:`CBD.converters.hybrid`
   * `PythonPDEVS <http://msdl.cs.mcgill.ca/projects/DEVS/PythonPDEVS>`_ for the :mod:`CBD.converters.hybrid`
     module. This allows CBDs to be run inside of DEVS simulations.
     module. This allows CBDs to be run inside of DEVS simulations.
-  * `Jinja2 <https://jinja.palletsprojects.com/en/3.0.x/>`_ for the :mod:`CBD.converters.CBD2C` module, allowing
-    conversion to C code.
 
 
 * **Documentation:**
 * **Documentation:**
 
 

+ 1 - 1
src/CBD/Core.py

@@ -533,7 +533,7 @@ class CBD(BaseBlock):
                             no blocks are ignored. Defaults to :code:`None`.
                             no blocks are ignored. Defaults to :code:`None`.
             psep (str):     The path separator to use. Defaults to :code:`"."`.
             psep (str):     The path separator to use. Defaults to :code:`"."`.
 
 
-        Note:
+        .. versionchanged:: 1.5
             When an empty CBD block is encountered during flattening, this block will be removed from
             When an empty CBD block is encountered during flattening, this block will be removed from
             the resulting flattened model. Add it to the :attr:`ignore` iterable to prevent such a
             the resulting flattened model. Add it to the :attr:`ignore` iterable to prevent such a
             removal.
             removal.

+ 0 - 233
src/CBD/converters/CBD2C/__init__.py

@@ -1,233 +0,0 @@
-"""
-A module that allows the creation of a C file, in which the block's computations are inlined.
-Additional library files will be created to allow for linking:
-
-- lsolve.c
-- lsolve.h
-
-
-Requires `Jinja2 <https://jinja.palletsprojects.com/en/3.0.x/>`_.
-The :code:`template.c` file is the jinja template file.
-
-Note:
-	To compile the generated code, execute :code:`gcc <filename>.c lsolve.c -lm`.
-"""
-from CBD.scheduling import TopologicalScheduler
-from CBD.loopsolvers.linearsolver import LinearSolver
-from CBD.depGraph import createDepGraph
-from CBD.converters.latexify import CBD2Latex, Time
-import CBD.naivelog as naivelog
-from CBD.simulator import Simulator
-
-from jinja2 import Template
-from shutil import copyfile
-import os, re
-
-
-class CBD2C:
-	"""
-	Main conversion class. Generates the new C file.
-	The C model will be executed in fixed-time steps of size
-	:code:`delta`, for a total of :code:`itcnt` iterations.
-	In total, the simulation will thus execute until timestep
-	:code:`itcnt * delta`.
-
-	Note:
-		This class does **not** change the original model.
-
-	Warning:
-		This class only works if the dependency graph is fixed
-		after the first iteration. I.e., iteration 0 can be
-		different, but all others must be the same.
-
-	Args:
-		model (CBD):    CBD model that will be converted to C.
-		itcnt (int):    The amount of iterations to execute the
-						c model for.
-		delta (float):  The stepsize of the C code.
-	"""
-	def __init__(self, model, itcnt, delta=1.0):
-		self.itcnt = itcnt
-		self.delta = delta
-		self.model = model.clone()
-		self.model.flatten(psep='_')
-		for block in self.model.getBlocks():
-			block.setBlockName(block.getBlockName().replace("-", "_"))
-		self.scheduler = TopologicalScheduler()
-		self.solver = LinearSolver(naivelog.getLogger("CBD"))
-
-	def get_blocks(self):
-		"""
-		Gets all the blocks from the flattened model.
-		"""
-		return self.model.getBlocks()
-
-	def get_order(self, curIt):
-		"""
-		Gets the topological order of the blocks at a specific iteration.
-
-		Args:
-			curIt (int):
-		"""
-		depGraph = createDepGraph(self.model, curIt)
-		return self.scheduler.schedule(depGraph, curIt, 0.0)
-
-	def obtain_eqs_from_order(self, order, curIt):
-		"""
-		Given the order in which the blocks must be executed,
-		this function will use the :class:`CBD2Latex` class to
-		construct the C-representation for the functions.
-
-		Args:
-			order:          List of components, topologically ordered.
-			curIt (int):    The current iteration.
-
-		Returns:
-			A list of tuples like :code:`[([LHS, ...], RHS), ...]`;
-			where the :code:`LHS` identifies an ordered list of
-			left-hand sides (when there are multiple, it means an
-			algebraic loop); and :code:`RHS` the string-representation
-			of the results.
-		"""
-		conf = {
-			"path_sep": '_',
-			"ignore_path": False,
-			"escape_nonlatex": False,
-			"time_variable": "i",
-			"time_format": "[{time}]"
-		}
-		ltx = CBD2Latex(self.model, **conf)
-		eqs = [re.sub(r"-(?!\s*\d)", "_", x) for x in ltx.eq(Time(0, curIt == "i")).split("\n")]
-		if eqs[-1] == '':
-			eqs.pop()
-		res_order = []
-		# reverse the order to allow scheduling at end as well
-		for c in reversed(order):
-			c_order = []
-			if len(c) == 1:  # NO ALGEBRAIC LOOP
-				block = c[0]
-
-				# Assumes no special blocks that change the deps exist
-				deps = block.getDependencies(1 if curIt == "i" else curIt)
-				path = block.getPath("_")
-				for out in block.getSignals().keys():
-					p = path + "_" + out + "[%s]" % curIt
-					for e in eqs:
-						if e.startswith(p):
-							c_order.insert(0, e)
-							break
-				for inp in block.getInputPortNames():
-					p = path + "_" + inp + "[%s]" % curIt
-					in_deps = block.getBlockConnectedToInput(inp).block in deps
-					for e in eqs:
-						if e.startswith(p):
-							if in_deps:
-								c_order.insert(0, e)
-							else:
-								c_order.append(e)
-							break
-				if block.getBlockType() == "WireBlock":
-					for e in eqs:
-						if e.startswith(path + "[%s]" % curIt):
-							c_order.append(e)
-							break
-			else:  # ALGEBRAIC LOOP!
-				self.solver.checkValidity(self.model.getPath("."), c)
-				other = []
-				known = {}
-				for block in c:
-					path = block.getPath("_")
-					for inp, b in block.getLinksIn().items():
-						var = path + "_" + inp
-						p = var + "[%s]" % curIt
-						prev = block.getBlockConnectedToInput(inp).block
-						for e in eqs:
-							if e.startswith(p):
-								if prev not in c:
-									c_order.insert(0, e)
-									known[var] = p
-
-					for inp in block.getInputPortNames():
-						var = path + "_" + inp
-						if var in known: continue
-						p = var + "[%s]" % curIt
-						for e in eqs:
-							if e.startswith(p):
-								other.insert(0, e)
-								break
-
-				# Get matrix representation
-				m1, m2 = self.solver.get_matrix(c, '_', known)
-				mat = m1.concat(m2)
-
-				deps = {}
-				for b in c:
-					D = [b.getBlockConnectedToInput(x) for x in b.getInputPortNames()]
-					deps[b] = [b.block.getPath('_') + '_' + b.output_port for b in D if b.block in c]
-
-				if mat.rows == 1:
-					# TODO: fix this?
-					raise NotImplementedError("Suspected singular matrix. However, currently cannot find an example "
-					                          "that enters this branch. Please contact the repository owner with this "
-					                          "error and all associated files.")
-					# nc = ([deps[c[mat[0].index(1)]]], mat[0][-1])
-					# print("NC:", nc)
-				else:
-					dlist = []
-					for b in c:
-						for d in deps[b]:
-							if d not in dlist:
-								dlist.append(d)
-					sm = "{" + mat.format(', ', '{}', "%f", ', ').replace("{,", "{").replace(", }", " }") + "}"
-					nc = (dlist, sm)
-
-				c_order.append(nc)
-				c_order += other
-			res_order = c_order + res_order
-		return res_order
-
-	def generate(self, fname):
-		"""
-		Generates the C file and copies the sources for the
-		lsolve library in the same folder.
-
-		To compile the generated code, execute :code:`gcc <filename>.c lsolve.c -lm`.
-
-		Args:
-			fname (str):    The filename of the C-code.
-		"""
-		path = os.path.dirname(os.path.realpath(__file__))
-		tpath = os.path.dirname(os.path.realpath(fname))
-		filename = os.path.join(path, "template.c")
-		with open(filename, 'r') as file:
-			template = Template(file.read(), trim_blocks=True, lstrip_blocks=True)
-		if not os.path.exists(os.path.join(tpath, "lsolve.c")):
-			copyfile(os.path.join(path, "lsolve.c"), os.path.join(tpath, "lsolve.c"))
-		if not os.path.exists(os.path.join(tpath, "lsolve.h")):
-			copyfile(os.path.join(path, "lsolve.h"), os.path.join(tpath, "lsolve.h"))
-		variables = []
-		for block in self.get_blocks():
-			if block.getBlockType() == "WireBlock":
-				variables.append(block.getPath('_'))
-			for port in block.getSignals().keys():
-				variables.append(block.getPath('_') + '_' + port)
-			for port in block.getInputPortNames():
-				variables.append(block.getPath('_') + '_' + port)
-		variables = [v.replace("-", "_") for v in variables]
-
-		# Obtain the data
-		comp0 = self.get_order(0)
-		comp = self.get_order(1)
-
-		eqs0 = self.obtain_eqs_from_order(comp0, 0)
-		eqs = self.obtain_eqs_from_order(comp, "i")
-
-		contents = template.render(itcnt = self.itcnt,
-		                           filename = fname,
-		                           delta = self.delta,
-		                           variables = variables,
-		                           components0 = eqs0,
-		                           components = eqs )
-		with open(fname, 'w') as file:
-			file.write(contents)
-

BIN=BIN
src/CBD/converters/CBD2C/a.out


+ 0 - 100
src/CBD/converters/CBD2C/example.c

@@ -1,100 +0,0 @@
-/**
- *  Generated from the Python CBD Simulator
- *  In order to compile:
- *      gcc example.c lsolve.c -lm
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <time.h>
-#include "lsolve.h"
-
-#define M 14    /* No of Blocks */
-#define N 100    /* No of Iterations */
-
-/* BLOCK VARIABLE NAMES */
-#define test_sum_OUT1 RESULT[0]
-#define test_sum_IN1 RESULT[1]
-#define test_sum_IN2 RESULT[2]
-#define test_three_OUT1 RESULT[3]
-#define test_seven_OUT1 RESULT[4]
-#define test_mult_OUT1 RESULT[5]
-#define test_mult_IN1 RESULT[6]
-#define test_mult_IN2 RESULT[7]
-#define test_x RESULT[8]
-#define test_x_OUT1 RESULT[9]
-#define test_x_IN1 RESULT[10]
-#define test_y RESULT[11]
-#define test_y_OUT1 RESULT[12]
-#define test_y_IN1 RESULT[13]
-
-double RESULT[M][N];
-
-/* EQUATIONS */
-void _eq_init(const double time, const double delta) {
-    test_three_OUT1[0] = 3.0;
-    test_seven_OUT1[0] = 7;
-    test_sum_IN1[0] = test_three_OUT1[0];
-    test_mult_IN1[0] = test_seven_OUT1[0];
-
-    /* Algebraic Loop */
-    double _C4[2][3] = {{ -1.000000, 1 * test_mult_IN1[0] + 0, 0.000000 }, { 1.000000, -1.000000, 0 - test_sum_IN1[0] }};
-    agloop(&_C4, 2, &test_sum_OUT1[0], &test_mult_OUT1[0]);
-
-    test_sum_IN2[0] = test_mult_OUT1[0];
-    test_mult_IN2[0] = test_sum_OUT1[0];
-    test_x_IN1[0] = test_sum_OUT1[0];
-    test_x_OUT1[0] = test_x_IN1[0];
-    test_x[0] = test_x_OUT1[0];
-    test_y_IN1[0] = test_mult_OUT1[0];
-    test_y_OUT1[0] = test_y_IN1[0];
-    test_y[0] = test_y_OUT1[0];
-}
-
-void _eq_iter(const unsigned int i, const double time, const double delta) {
-    test_three_OUT1[i] = 3.0;
-    test_seven_OUT1[i] = 7;
-    test_sum_IN1[i] = test_three_OUT1[i];
-    test_mult_IN1[i] = test_seven_OUT1[i];
-
-    /* Algebraic Loop */
-    double _C4[2][3] = {{ -1.000000, 1 * test_mult_IN1[i] + 0, 0.000000 }, { 1.000000, -1.000000, 0 - test_sum_IN1[i] }};
-    agloop(&_C4, 2, &test_sum_OUT1[i], &test_mult_OUT1[i]);
-
-    test_sum_IN2[i] = test_mult_OUT1[i];
-    test_mult_IN2[i] = test_sum_OUT1[i];
-    test_x_IN1[i] = test_sum_OUT1[i];
-    test_x_OUT1[i] = test_x_IN1[i];
-    test_x[i] = test_x_OUT1[i];
-    test_y_IN1[i] = test_mult_OUT1[i];
-    test_y_OUT1[i] = test_y_IN1[i];
-    test_y[i] = test_y_OUT1[i];
-}
-
-/* SIMULATOR */
-int main(int argc, char *args[]) {
-    double delta = 1.0;
-    double time = 0.0;
-
-    _eq_init(0.0, delta);
-    for(int i = 1; i < N; ++i) {
-        time += delta;
-        _eq_iter(i, time, delta);
-    }
-
-    printf("\t%-20s = %12.4f\n", "TIME", time);
-    printf("\t%-20s = %12.4f\n", "test_sum_OUT1", test_sum_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_sum_IN1", test_sum_IN1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_sum_IN2", test_sum_IN2[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_three_OUT1", test_three_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_seven_OUT1", test_seven_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_mult_OUT1", test_mult_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_mult_IN1", test_mult_IN1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_mult_IN2", test_mult_IN2[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_x", test_x[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_x_OUT1", test_x_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_x_IN1", test_x_IN1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_y", test_y[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_y_OUT1", test_y_OUT1[N - 1]);
-    printf("\t%-20s = %12.4f\n", "test_y_IN1", test_y_IN1[N - 1]);
-}

+ 0 - 146
src/CBD/converters/CBD2C/lsolve.c

@@ -1,146 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include "lsolve.h"
-
-double getelm(double* matrix, const unsigned int i, const unsigned int j, const unsigned int m) {
-    const unsigned n = m + 1;
-    return *((matrix + i * n) + j);
-}
-
-void setelm(double* matrix, const unsigned i, const unsigned int j, const unsigned int m, double val) {
-    const unsigned n = m + 1;
-    *((matrix + i * n) + j) = val;
-}
-
-unsigned int argmax_abs(const unsigned int low, const unsigned int high, const unsigned int column, double* A) {
-    unsigned int i_max = 0;
-    double max_value = -1.0;  // computes the abs argmax, so always larger than -1
-    for(unsigned int i = low; i < high; ++i) {
-        double a = fabs(getelm(A, i, column, high));
-        if(a > max_value) {
-            max_value = a;
-            i_max = i;
-        }
-    }
-    return i_max;
-}
-
-void swrows(double* matrix, const unsigned int r1, const unsigned int r2, const unsigned int cols) {
-    if(r1 == r2) { return; }
-    double tmp;
-    for(unsigned int i = 0; i < cols; ++i) {
-        tmp = getelm(matrix, r2, i, cols - 1);
-        setelm(matrix, r2, i, cols - 1, getelm(matrix, r1, i, cols - 1));
-        setelm(matrix, r1, i, cols - 1, tmp);
-    }
-}
-
-void lsolve(double* matrix, const unsigned int size) {
-    const double eps = 1e-4;
-    const unsigned int m = size;        // rows
-    const unsigned int n = size + 1;    // columns
-    unsigned int h = 0;                 // pivot row
-    unsigned int k = 0;                 // pivot column
-
-    unsigned int* swaps = malloc(2 * sizeof(unsigned int));
-    int swaps_done = 0;
-
-    while(h < m && k < n) {
-        unsigned int i_max = argmax_abs(h, m, k, matrix);
-        double elm = getelm(matrix, i_max, k, m);
-        if(fabs(elm) <= eps) {
-            // Go to the next column
-            k += 1;
-        } else {
-            swrows(matrix, h, i_max, n);
-            for(unsigned int i = k; i < n; ++i) {
-                setelm(matrix, h, i, m, getelm(matrix, h, i, m) / elm);
-            }
-
-            for(unsigned int i = 0; i < m; ++i) {
-                if(i == h) { continue; }
-                double f = getelm(matrix, i, k, m) / getelm(matrix, h, k, m);
-                setelm(matrix, i, k, m, 0.0);
-                for(unsigned int j = k + 1; j < n; ++j) {
-                    setelm(matrix, i, j, m, getelm(matrix, i, j, m) - getelm(matrix, h, j, m) * f);
-                }
-            }
-
-            ++swaps_done;
-            swaps = realloc(swaps, (2 * swaps_done) * sizeof(unsigned int));
-            swaps[2 * (swaps_done - 1)] = h;
-            swaps[2 * (swaps_done - 1) + 1] = i_max;
-
-            h += 1;
-            k += 1;
-        }
-    }
-
-    for(int i = swaps_done - 1; i >= 0; --i) {
-        swrows(matrix, swaps[i * 2], swaps[i * 2 + 1], n);
-    }
-}
-
-double det(double* matrix, const unsigned int size) {
-    unsigned int height = size - 1;
-
-    if(size == 2) {
-        double a00 = getelm(matrix, 0, 0, size);
-        double a01 = getelm(matrix, 0, 1, size);
-        double a10 = getelm(matrix, 1, 0, size);
-        double a11 = getelm(matrix, 1, 1, size);
-        return (a00 * a11) - (a01 * a10);
-    }
-
-    double total = 0.0;
-    for(unsigned int fc = 0; fc < size; ++fc) {
-        double As[height][height];
-        for(unsigned int r = 0; r < height; ++r) {
-            for(unsigned int c = 0; c < fc; ++c) {
-                As[r][c] = getelm(matrix, r + 1, c, height);
-            }
-            for(unsigned int c = fc; c < height; ++c) {
-                As[r][c] = getelm(matrix, r + 1, c + 1, height);
-            }
-        }
-        double sign = -1.0;
-        if(fc % 2 == 1) {
-            sign = 1.0;
-        }
-        double sub_det = det(&As, height);
-        total += sign * getelm(matrix, 0, fc, height) * sub_det;
-    }
-    return total;
-}
-
-void agloop(double* A, const unsigned int size, ...) {
-    double D = det(A, size);
-    if(fabs(D) < 1e-5) {
-        printf("ERROR: SINGULAR MATRIX!\n");
-        exit(1);
-    }
-    lsolve(A, size);
-
-    // Read the arguments
-    va_list list;
-    va_start(list, size);
-    for(unsigned int j = 0; j < size; ++j) {
-        *va_arg(list, double*) = getelm(A, j, size, size);
-    }
-    va_end(list);
-}
-
-//int main(int argc, char *args[]) {
-//    double A[2][3] = {{-1.0, 7.0, 0.0}, {1.0, -1.0, -3.0}};
-//    lsolve(&A, 2);
-//
-//    printf("END\n");
-//    for(unsigned int i = 0; i < 2; ++i) {
-//        for(unsigned int j = 0; j < 3; ++j) {
-//            printf("\t%7f", A[i][j]);
-//        }
-//        printf("\n");
-//    }
-//}

+ 0 - 76
src/CBD/converters/CBD2C/lsolve.h

@@ -1,76 +0,0 @@
-#ifndef LSOLVE
-#define LSOLVE
-
-/**
- *  Obtains an element from a 2D array matrix, using pointers.
- *  This is mainly a helper function.
- *
- *  @param  matrix  An address to an (NxN+1) matrix, which is
- *                  to be constructed as a 2D array.
- *  @param  i       The row index of the element to obtain.
- *  @param  j       The column index of the element to obtain.
- *  @param  m       The amount of rows for the input matrix.
- **/
-double getelm(double* matrix, const unsigned int i, const unsigned int j, const unsigned int m);
-
-/**
- *  Sets an element in a 2D array matrix, using pointers.
- *  This is mainly a helper function.
- *
- *  @param  matrix  An address to an (NxN+1) matrix, which is
- *                  to be constructed as a 2D array.
- *  @param  i       The row index of the element to set.
- *  @param  j       The column index of the element to set.
- *  @param  m       The amount of rows for the input matrix.
- *  @param  val     The new value for the element.
- **/
-void setelm(double* matrix, const unsigned int i, const unsigned int j, const unsigned int m, double val);
-
-/**
- *  Computes the row index that yields the highest absolute value.
- *  This is mainly a helper function.
- *
- *  @param  low     The minimal row index to return.
- *  @param  high    The maximal row index to return.
- *  @param  A       An address to an (NxN+1) matrix, which is
- *                  to be constructed as a 2D array.
- **/
-unsigned int argmax_abs(const unsigned int low, const unsigned int high, const unsigned int column, double* A);
-
-/**
- *  Solves a system of equations linearly, by using matrices
- *  and Gauss-Jordan Elimination. Only works for N equations
- *  and N unknowns.
- *
- *  @param  matrix  An address to an (NxN+1) matrix, which is
- *                  to be constructed as a 2D array.
- *  @param  size    The amount of rows for the input matrix N.
- **/
-void lsolve(double* matrix, const unsigned int size);
-
-/**
- *  Computes the determinant of the matrix.
- *
- *  @param  matrix  An address to an (NxN) matrix, which is
- *                  to be constructed as a 2D array.
- *  @param  size    The amount of rows for the input matrix N.
- **/
-double det(double* matrix, const unsigned int size);
-
-/**
- *  Helper function to linearly solve algebraic loops.
- *  This first checks if the block matrix is not singular,
- *  after which it solves the equations w.r.t. Gauss-Jordan.
- *  Finally, the resulting matrix is automatically stored in
- *  the corresponding variables.
- *
- *  @param  A       An address to an (NxN+1) matrix, which is
- *                  to be constructed as a 2D array.
- *  @param  size    The amount of rows for the input matrix N.
- *  @param  ...     An undefined amount of arguments that refer
- *                  to the variables in which the data must be
- *                  stored in the end.
- **/
-void agloop(double* A, const unsigned int size, ...);
-
-#endif

+ 0 - 66
src/CBD/converters/CBD2C/template.c

@@ -1,66 +0,0 @@
-/**
- *  Generated from the Python CBD Simulator
- *  In order to compile:
- *      gcc {{ filename }} lsolve.c -lm
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <time.h>
-#include "lsolve.h"
-
-#define M {{ variables|length }}    /* No of Blocks */
-#define N {{ itcnt }}    /* No of Iterations */
-
-/* BLOCK VARIABLE NAMES */
-{% for var in variables %}
-#define {{ var }} RESULT[{{ loop.index0 }}]
-{% endfor %}
-
-double RESULT[M][N];
-
-/* EQUATIONS */
-void _eq_init(const double time, const double delta) {
-    {% for comp in components0 %}
-        {% if comp is string %}
-    {{comp}};
-        {% else %}
-
-    /* Algebraic Loop */
-    double _C{{ loop.index0 }}[{{comp[0]|length}}][{{comp[0]|length + 1}}] = {{ comp[1] }};
-    agloop(&_C{{ loop.index0 }}, {{comp|length}}{% for block in comp[0] %}, &{{ block }}[0]{% endfor %});
-
-        {% endif %}
-    {% endfor %}
-}
-
-void _eq_iter(const unsigned int i, const double time, const double delta) {
-    {% for comp in components %}
-        {% if comp is string %}
-    {{comp}};
-        {% else %}
-
-    /* Algebraic Loop */
-    double _C{{ loop.index0 }}[{{comp[0]|length}}][{{comp[0]|length + 1}}] = {{ comp[1] }};
-    agloop(&_C{{ loop.index0 }}, {{comp|length}}{% for block in comp[0] %}, &{{ block }}[i]{% endfor %});
-
-        {% endif %}
-    {% endfor %}
-}
-
-/* SIMULATOR */
-int main(int argc, char *args[]) {
-    double delta = {{ delta }};
-    double time = 0.0;
-
-    _eq_init(0.0, delta);
-    for(int i = 1; i < N; ++i) {
-        time += delta;
-        _eq_iter(i, time, delta);
-    }
-
-    printf("\t%-20s = %12.4f\n", "TIME", time);
-    {% for var in variables %}
-    printf("\t%-20s = %12.4f\n", "{{ var }}", {{ var }}[N - 1]);
-    {% endfor %}
-}

+ 0 - 60
src/CBD/converters/CBD2C/template_old.c

@@ -1,60 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <time.h>
-#include "lsolve.h"
-
-#define M {{ variables|length }}    /* No of Blocks */
-#define N {{ itcnt }}    /* No of Iterations */
-
-/* BLOCK VARIABLE NAMES */
-{% for var in variables %}
-#define {{ var }} RESULT[{{ loop.index0 }}]
-{% endfor %}
-
-double RESULT[M][N];
-
-/* EQUATIONS */
-void _eq_init(const double time, const double delta) {
-    {% for comp in components0 %}
-        {% if comp[0]|length == 1 %}
-    {{ comp[0][0] }}[0] = {{ comp[1] }};
-        {% else %}
-
-    /* Algebraic Loop */
-    double _C{{ loop.index0 }}[{{comp[0]|length}}][{{comp[0]|length + 1}}] = {{ comp[1] }};
-    agloop(&_C{{ loop.index0 }}, {{comp|length}}{% for block in comp[0] %}, &{{ block }}[0]{% endfor %});
-
-        {% endif %}
-    {% endfor %}
-}
-
-void _eq_iter(const unsigned int i, const double time, const double delta) {
-    {% for comp in components %}
-        {% if comp[0]|length == 1 %}
-    {{ comp[0][0] }}[i] = {{ comp[1] }};
-        {% else %}
-
-    /* Algebraic Loop */
-    double _C{{ loop.index0 }}[{{comp[0]|length}}][{{comp[0]|length + 1}}] = {{ comp[1] }};
-    agloop(&_C{{ loop.index0 }}, {{comp|length}}{% for block in comp[0] %}, &{{ block }}[i]{% endfor %});
-
-        {% endif %}
-    {% endfor %}
-}
-
-/* SIMULATOR */
-int main(int argc, char *args[]) {
-    double delta = {{ delta }};
-    double time = 0.0;
-
-    _eq_init(0.0, delta);
-    for(int i = 1; i < N; ++i) {
-        time += delta;
-        _eq_iter(i, time, delta);
-    }
-
-    printf("\t%-20s = %12.4f\n", "TIME", time);
-    {% for var in variables %}
-    printf("\t%-20s = %12.4f\n", "{{ var }}", {{ var }}[N - 1]);
-    {% endfor %}
-}

+ 3 - 3
src/CBD/simulator.py

@@ -787,9 +787,9 @@ class Simulator:
 		Sets the verbose tracer.
 		Sets the verbose tracer.
 
 
 		Args:
 		Args:
-			filename (str): The file to which the trace must be written.
-							When :code:`None`, the trace will be written to
-							the console.
+			filename (Union[str, None]):    The file to which the trace must be written.
+											When :code:`None`, the trace will be written to
+											the console.
 
 
 		Note:
 		Note:
 			Calling this function multiple times will continuously add new tracers. Thus output
 			Calling this function multiple times will continuously add new tracers. Thus output