rparedis 4 лет назад
Родитель
Сommit
050029f26d

+ 33 - 4
src/CBD/converters/eq2CBD.py

@@ -109,9 +109,16 @@ class eq2CBD:
 			contents = file.read()
 		self.parser = Lark(contents, parser="earley")
 
-	def parse(self, text):
+	def parse(self, text, model=None):
+		"""
+		Parses the text and constructs a CBD model thereof.
+
+		Args:
+			text (str): The text to parse.
+			model:      An optional CBD model to use for the construction.
+		"""
 		tree = self.parser.parse(text)
-		transformer = EqTransformer()
+		transformer = EqTransformer(model)
 		return transformer.transform(tree)
 
 
@@ -120,10 +127,25 @@ from CBD.lib.std import *
 import math
 
 class EqFunctions:
+	"""
+	Collection class for all the functions that can be called in the
+	textual mode. They are given as member functions of this class.
+	Each of these functions should return a tuple of
+	:code:`block, n[, mapping]`, where :code:`block` indicates the block
+	to link in the transformer, :code:`n` identifies the amount of arguments
+	and the optional :code:`mapping` is a dictionary used when the ports are
+	not named w.r.t. :code:`IN\\d+`.
+
+	Args:
+		model:  The model to add the blocks to.
+	"""
 	def __init__(self, model):
 		self.model = model
 
 	def _has_func(self, fname):
+		"""
+		Checks if a function exists.
+		"""
 		return fname in [x for x in dir(self) if callable(getattr(self, x)) and not x.startswith("_")]
 
 	def int(self):
@@ -178,11 +200,18 @@ class EqFunctions:
 
 
 class EqTransformer(Transformer):
+	"""
+	Transforms the AST into a CBD model.
+
+	Args:
+		model:  The CBD model to start from. When :code:`None`, a
+				new model will be created. Defaults to :code:`None`.
+	"""
 	# TODO: multiple output ports?
 	# TODO: constant folding
-	def __init__(self):
+	def __init__(self, model=None):
 		super().__init__()
-		self.model = CBD("")
+		self.model = CBD("") if model is None else model
 		self.functions = EqFunctions(self.model)
 		self.vars = {}
 		self.var_results = {}

+ 2 - 3
src/CBD/lib/std.py

@@ -59,7 +59,7 @@ class InverterBlock(BaseBlock):
 		# TO IMPLEMENT
 		input = self.getInputSignal(curIteration, "IN1").value
 		if abs(input) < self._tolerance:
-			raise ZeroDivisionError("InverterBlock received input less than {}.".format(self._tolerance))
+			raise ZeroDivisionError("InverterBlock '{}' received input less than {}.".format(self.getPath(), self._tolerance))
 		self.appendToSignal(1.0 / input)
 
 
@@ -586,7 +586,6 @@ class Clock(CBD):
 	"""
 	def __init__(self, block_name, start_time=0.0):
 		# TODO: simplify if start_time is 0
-		# TODO: rel_time must not depend on delay + h !!
 		CBD.__init__(self, block_name, ["h"], ["time", "rel_time"])
 		self.__start_time = start_time
 
@@ -604,7 +603,7 @@ class Clock(CBD):
 		self.addConnection("IC", "delay", input_port_name='IC')
 
 		self.addConnection("IC", "STNeg")
-		self.addConnection("TSum", "STSum")
+		self.addConnection("delay", "STSum")
 		self.addConnection("STNeg", "STSum")
 		self.addConnection("STSum", "rel_time")
 

+ 80 - 0
src/CBD/preprocessing/rk-notes/RKF.m

@@ -0,0 +1,80 @@
+function [w,t,flg] = RKF(FunFcnIn, Intv, alpha, tol, stepsize)
+% On input: 
+%   FunFcnIn is the name of function to be integrated
+%   interv is the interval to be integrated over
+% 
+%   The problem: y' = f(t,y), y(a) = alpha, a<= t <= b
+%   where Intv = [a b], and a call to FunFcnIn with 
+%   argument (t, y) returns f(t,y).
+%
+%   RKF uses the Runge-Kutta-Fehlberg method to solve
+%   the above problem, to a given tolerance. 
+%   hmin and hmax are the minimum and maximum step sizes.
+%
+% On output
+%   t contains the (unequi-spaced) mesh points, w the
+%   function values at these points. 
+%   flg is success flag. If flg == 0 method succeeded,
+%   and if flg ~=0 method failed.
+%
+% Written by Ming Gu for Math 128A, Fall 2008
+% 
+[FunFcn,msg] = fcnchk(FunFcnIn,0);
+if ~isempty(msg)
+    error('InvalidFUN',msg);
+end
+flg  = 0;
+a    = Intv(1);
+b    = Intv(2);
+hmin = stepsize(1);
+hmax = stepsize(2);
+h    = min(hmax,b-a);
+if (h<=0)
+    msg = ['Illegal hmax or interval'];
+    error('InvalidFUN',msg);
+end
+w    = alpha;
+t    = a;
+c    = [0;      1/4; 3/8;       12/13;      1;  1/2];
+d    = [25/216  0    1408/2565  2197/4104 -1/5  0   ];
+r    = [1/360   0   -128/4275  -2197/75240 1/50 2/55];
+KC   = [zeros(1,5); 
+        1/4,       zeros(1,4); 
+        3/32       9/32       zeros(1,3);
+        1932/2197 -7200/2197, 7296/2197, 0,         0;
+        439/216   -8          3680/513  -845/4104,  0;
+          -8/27    2         -3544/2565  1859/4104 -11/40];
+K    = zeros(6,1);
+%
+% main loop
+%
+while (flg == 0)
+    ti   = t(end);
+    wi   = w(end);
+    for j = 1:6
+        K(j) = h*FunFcn(ti+c(j)*h,wi+KC(j,:)*K(1:5));
+    end
+%
+% accept approximation
+%
+    R = max(eps,abs(r*K)/h);
+    if (R <= tol)
+        t = [t; ti+h];
+        w = [w; wi+d*K];
+    end
+%
+% reset stepsize.
+%
+    delta = 0.84*(tol/R)^(1/4);
+    delta = min(4,max(0.1,delta));
+    h     = min(hmax, delta * h);
+    h     = min(h, b-t(end));
+    if (abs(h)<eps)
+        return;
+    end
+    if (h < hmin)
+        flg = 1;
+        return;
+    end
+end
+

+ 13 - 7
src/CBD/preprocessing/rk-notes/rkf.py

@@ -77,11 +77,10 @@ class rkf():
             r = r / (self.atol + self.rtol*(abs(x)+abs(k1)))
             if len( np.shape( r ) ) > 0:
                 r = max( r )
-            if r <= 1:
-                t = t + h
-                x = x + c1 * k1 + c3 * k3 + c4 * k4 + c5 * k5
-                T = np.append( T, t )
-                X = np.append( X, [x], 0 )
+            t = t + h
+            x = x + c1 * k1 + c3 * k3 + c4 * k4 + c5 * k5
+            T = np.append( T, t )
+            X = np.append( X, [x], 0 )
             h = h * min( max( self.safety * (1 / r)**0.25, 0.1 ), 4.0 )
             if h > self.hmax:
                 h = self.hmax
@@ -128,13 +127,20 @@ if __name__ == '__main__':
     x0 = 0
     # x0=[2,2,2]
 
-    # t,u  = rkf( f=lorenz, a=0, b=1e+1, x0=x0, atol=1e-8, rtol=1e-6 , hmax=1e-1, hmin=1e-40,plot_stepsize=True).solve()
-    t, u  = rkf( f=test, a=0, b=1.4, x0=x0, atol=2e-5, rtol=0, hmax=0.1, safety=.84, plot_stepsize=False).solve()
+    # t,u  = rkf(f=lorenz, a=0, b=1e+1, x0=x0, atol=1e-8, rtol=1e-6 , hmax=1e-1, hmin=1e-40,plot_stepsize=True).solve()
+    t, u  = rkf(f=test, a=0, b=1.4, x0=x0, atol=2e-5, rtol=0, hmax=0.1, safety=.84, plot_stepsize=False).solve()
+    # t, u  = rkf(f=test, a=0, b=2.0, x0=x0, atol=1e-5, rtol=0, hmax=0.25, safety=.84, plot_stepsize=False).solve()
 
     # x, y = u.T
 
     df = pd.DataFrame({"t": t, "u": u})
     print(df)
+    fig, ax = plt.subplots()
+    # ax.plot(np.arange(0, 2.01, 0.01), [((1 + x)**2 - 0.5 * np.exp(x)) for x in np.arange(0, 2.01, 0.01)], label="actual")
+    ax.plot(np.arange(0, 1.41, 0.01), [np.tan(x) for x in np.arange(0, 1.41, 0.01)], label="actual")
+    ax.plot(t, u, label="RKF45", alpha=0.7)
+    ax.legend()
+    plt.show()
 
     # plt.style.use('dark_background')
     # fig = plt.figure()

+ 45 - 52
src/CBD/preprocessing/rungekutta.py

@@ -22,13 +22,17 @@ class RKPreprocessor:
 		atol (float):       The absolute tolerance for precision in approximating, given that the
 							tableau is an extended tableau. Defaults to 1e-8.
 		hmin (float):       Minimal value for the delta, given that the tableau is an extended
-							tableau. Defaults to 1e-40.
+							tableau. When non-extended, this will identify the clock delta.
+							Defaults to 1e-40.
 		hmax (float):       Maximal value for the delta, given that the tableau is an extended
-							tableau. Defaults to 1e-1.
+							tableau. This value will also be used as the initial delta.
+							Defaults to 1e-1.
 		safety (float):     Safety factor for the error computation. Must be in (0, 1], preferrably
-							on the high end of the range. Defaults to 0.9.
+							on the high end of the range. For RKF45, commonly :math:`2^{-1/4} \approx 0.84`
+							is used. Defaults to 0.9.
 	"""
 	def __init__(self, tableau, atol=1e-8, hmin=1e-40, hmax=1e-1, safety=0.9):
+		assert atol > 0, "Tolerance must be a positive value"
 		self._tableau = tableau
 		self._tolerance = atol
 		self._h_range = hmin, hmax
@@ -50,7 +54,7 @@ class RKPreprocessor:
 		Args:
 			original (CBD.CBD.CBD): A CBD model to get the RK approximating model for.
 
-		Note:
+		Warning:
 			Currently, this fuction will yield undefined behaviour if the original model
 			has input ports with a name that matches :code:`(IN\\d+|((rel_)?time))`,
 			output ports that match :code:`OUT\\d+` and non-clock steering blocks with
@@ -79,7 +83,7 @@ class RKPreprocessor:
 		new_model.addConnection("clock", RK, 'rel_time', 'rel_time')
 		if RK.hasBlock("h_new"):
 			# TODO: take delta from original
-			new_model.addBlock(ConstantBlock("HIC", 0.1))
+			new_model.addBlock(ConstantBlock("HIC", self._h_range[1]))
 			new_model.addBlock(DelayBlock("HDelay"))
 			new_model.addConnection(RK, "HDelay", output_port_name="h_new")
 			new_model.addConnection("HIC", "HDelay", input_port_name="IC")
@@ -87,7 +91,7 @@ class RKPreprocessor:
 			new_model.addConnection("HDelay", RK, input_port_name="h")
 		else:
 			# TODO: take delta from original
-			new_model.addBlock(ConstantBlock("clock-delta", 0.1))
+			new_model.addBlock(ConstantBlock("clock-delta", self._h_range[0]))
 			new_model.addConnection("clock-delta", "clock", "h")
 			new_model.addConnection("clock-delta", RK, "h")
 		for y in outputs:
@@ -253,13 +257,6 @@ class RKPreprocessor:
 		.. math::
 			y_{n+1} = y_n + \sum_{i=1}^s b_i k_i
 
-		The full CBD model (for a standard, non-extended butcher tableau) looks
-		like this (where the :math:`K`-blocks are constructed with the :func:`create_K`
-		function):
-
-		.. image:: _figures/rungekutta.png
-	         :width: 600
-
 		Args:
 			f (CBD.CBD.CBD):    The CBD representing the actual IVP for which the
 								RK approximation must be done.
@@ -317,7 +314,7 @@ class RKPreprocessor:
 				for q in range(len(weights)):
 					RK.addConnection("YSum_1_%d" % y, "error", "y_%d" % y)
 					RK.addConnection("YSum_2_%d" % y, "error", "z_%d" % y)
-			RK.addConnection("h", "error", "h")
+			RK.addConnection("h", "error", input_port_name="h")
 			RK.addConnection("error", "h_new", output_port_name='h_new')
 
 		return RK
@@ -328,12 +325,7 @@ class RKPreprocessor:
 		approximation computation. The generic formula is:
 
 		.. math::
-			k_s = h\cdot f(t_n + c_s\cdot h, y_n + \sum_{i=1}^{s-1}a_{s, i} k_i)
-
-		Which gives the following CBD model:
-
-		.. image:: _figures/rungekutta.png
-	         :width: 600
+			k_s = h\cdot f\left(t_n + c_s\cdot h, y_n + \sum_{i=1}^{s-1}a_{s, i} k_i\right)
 
 		Args:
 			s (int):            The :math:`s`-value of the :math:`k_s` to compute.
@@ -393,7 +385,8 @@ class RKPreprocessor:
 		Creates the error computation block, which computes:
 
 		.. math::
-			h_{new} = S\cdot h_{old}\cdot\left(\dfrac{\epsilon\cdot h_{old}}{\vert z_{n+1} - y_{n+1}\vert}\right)^{\dfrac{1}{q}}
+			h_{new} = h_{old}\cdot clamp\left(S\cdot\left(\dfrac{\epsilon\cdot h_{old}}
+			{\vert z_{n+1} - y_{n+1}\vert}\right)^{\dfrac{1}{q}}, 0.1, 4.0\right)
 
 		Where :math:`\epsilon` is the provided error tolerance, :math:`q` the lowest order of the computation,
 		:math:`z_{n+1}` the higher-order (more precise) value and :math:`y_{n+1}` the lower-order computation
@@ -408,7 +401,11 @@ class RKPreprocessor:
 		Err = CBD("error", ["h"] + ["y_%d" % (i+1) for i in range(vlen)] + ["z_%d" % (i+1) for i in range(vlen)],
 		          ["h_new", "error"])
 
-		Err.addBlock(MaxBlock("Max", vlen))
+		Err.addBlock(ConstantBlock("Tol", self._tolerance))
+		Err.addBlock(ConstantBlock("Eps", 1e-20))
+		Err.addBlock(MaxBlock("Max", vlen+1))
+		Err.addConnection("Eps", "Max")
+		Err.addConnection("Max", "error")
 		for i in range(vlen):
 			j = i + 1
 			Err.addBlock(NegatorBlock("Neg_%i" % j))
@@ -420,36 +417,32 @@ class RKPreprocessor:
 			Err.addConnection("Sum_%d" % j, "Abs_%d" % j)
 			Err.addConnection("Abs_%d" % j, "Max")
 
-		Err.addBlock(ProductBlock("Mult"))
-		Err.addBlock(ProductBlock("Frac", 3))
-		Err.addBlock(ConstantBlock("S", self._safety))
-		Err.addBlock(ConstantBlock("q", self._tableau.getOrder()))
-		Err.addBlock(InverterBlock("Inv"))
-		Err.addBlock(ConstantBlock("Eps", self._tolerance))
+		Err.addBlock(InverterBlock("hinv"))
+		Err.addConnection("h", "hinv")
+		Err.addBlock(ProductBlock("R"))
+		Err.addConnection("Max", "R")
+		Err.addConnection("hinv", "R")
+		Err.addBlock(InverterBlock("Rinv"))
+		Err.addConnection("R", "Rinv")
+		Err.addBlock(ProductBlock("RinvMult"))
+		Err.addConnection("Rinv", "RinvMult")
+		Err.addConnection("Tol", "RinvMult")
 		Err.addBlock(RootBlock("Root"))
-		Err.addBlock(ProductBlock("MultH"))
+		Err.addBlock(ConstantBlock("q", self._tableau.getOrder()))
+		Err.addConnection("RinvMult", "Root", input_port_name='IN1')
+		Err.addConnection("q", "Root", input_port_name='IN2')
+		Err.addBlock(ConstantBlock("S", self._safety))
+		Err.addBlock(ProductBlock("SMult"))
+		Err.addConnection("S", "SMult")
+		Err.addConnection("Root", "SMult")
 		Err.addBlock(ClampBlock("Clamp", 0.1, 4.0))
-		Err.addBlock(ClampBlock("ClampH", self._h_range[0], self._h_range[1]))
-
-		Err.addConnection("h", "MultH")
-		Err.addConnection("S", "Mult")
-
-		Err.addConnection("Max", "Inv")
-		Err.addConnection("Eps", "Frac")
-		Err.addConnection("Inv", "Frac")
-		Err.addConnection("h", "Frac")
-		Err.addConnection("Frac", "Root", input_port_name="IN1")
-		Err.addConnection("q", "Root", input_port_name="IN2")
-		Err.addConnection("Root", "Mult")
-		Err.addConnection("MultH", "ClampH")
-		Err.addConnection("ClampH", "h_new")
-		Err.addConnection("Clamp", "MultH")
-		Err.addConnection("Mult", "Clamp")
-
-		Err.addConnection("Max", "error")
-
-		# TODO: enforce positive tolerance
-		# TODO: if Max <= Eps * h: don't progress time
+		Err.addConnection("SMult", "Clamp")
+		Err.addBlock(ProductBlock("HMult"))
+		Err.addConnection("h", "HMult")
+		Err.addConnection("Clamp", "HMult")
+		Err.addBlock(ClampBlock("HClamp", self._h_range[0], self._h_range[1]))
+		Err.addConnection("HMult", "HClamp")
+		Err.addConnection("HClamp", "h_new")
 
 		return Err
 
@@ -492,7 +485,7 @@ if __name__ == '__main__':
 
 	test = Test("Test")
 	test.addFixedRateClock("clock", 0.1)
-	prep = RKPreprocessor(BT.RKF45(), atol=2e-5, safety=.84)
+	prep = RKPreprocessor(BT.RKF45(), atol=2e-5, hmin=1e-8, safety=.84)
 	model = prep.preprocess(test)
 	draw(model.findBlock("RK.error")[0], "test.dot")
 	# model = Test("Test")
@@ -508,7 +501,7 @@ if __name__ == '__main__':
 	hs = model.findBlock("RK.error")[0].getSignal("h_new")
 	# errs = hs = s
 
-	# print([x for _, x in errs])
+	# print([x for _, x in model.findBlock("RK.myDelay")[0].getSignal("OUT1")])
 
 	import numpy as np
 	print("+------------+------------+------------+------------+------------+------------+")

+ 84 - 72
src/CBD/preprocessing/test.dot

@@ -5,77 +5,89 @@ digraph model {
  label=<<B>Test.RK.error (CBD)</B>>;
  labelloc="t";
  fontsize=20;
- node_139845894015200 [label="h", shape=none];
- inter_139845894015200_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015200 -> inter_139845894015200_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015344 [label="y_1", shape=none];
- inter_139845894015344_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015344 -> inter_139845894015344_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015440 [label="z_1", shape=none];
- inter_139845894015440_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015440 -> inter_139845894015440_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015536 [label="h_new", shape=none];
- inter_139845894016400_OUT1 -> node_139845894015536 [headlabel="", arrowhead="normal", arrowtail="none", dir=both];
- node_139845894015632 [label="error", shape=none];
- inter_139845894015248_OUT1 -> node_139845894015632 [headlabel="", arrowhead="normal", arrowtail="none", dir=both];
- node_139845894015248 [label="MaxBlock\n(Max)", shape=box];
- inter_139845894015968_OUT1 -> node_139845894015248 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015248_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015248 -> inter_139845894015248_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015776 [label="NegatorBlock\n(Neg_1)", shape=box];
- inter_139845894015344_OUT1 -> node_139845894015776 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015776_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015776 -> inter_139845894015776_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015872 [label="AdderBlock\n(Sum_1)", shape=box];
- inter_139845894015776_OUT1 -> node_139845894015872 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015440_OUT1 -> node_139845894015872 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015872_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015872 -> inter_139845894015872_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015968 [label="AbsBlock\n(Abs_1)", shape=box];
- inter_139845894015872_OUT1 -> node_139845894015968 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015968_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015968 -> inter_139845894015968_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894015728 [label="ProductBlock\n(Mult)", shape=box];
- inter_139845894016112_OUT1 -> node_139845894015728 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016256_OUT1 -> node_139845894015728 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015728_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894015728 -> inter_139845894015728_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016064 [label="ProductBlock\n(Frac)", shape=box];
- inter_139845894016208_OUT1 -> node_139845894016064 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016160_OUT1 -> node_139845894016064 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894015200_OUT1 -> node_139845894016064 [headlabel="IN3", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016064_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016064 -> inter_139845894016064_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016112 [label=" ConstantBlock\n(S)\n0.84", shape=ellipse];
- inter_139845894016112_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016112 -> inter_139845894016112_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016016 [label=" ConstantBlock\n(q)\n4", shape=ellipse];
- inter_139845894016016_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016016 -> inter_139845894016016_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016160 [label="InverterBlock\n(Inv)", shape=box];
- inter_139845894015248_OUT1 -> node_139845894016160 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016160_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016160 -> inter_139845894016160_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016208 [label=" ConstantBlock\n(Eps)\n2e-05", shape=ellipse];
- inter_139845894016208_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016208 -> inter_139845894016208_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016256 [label="RootBlock\n(Root)", shape=box];
- inter_139845894016064_OUT1 -> node_139845894016256 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016016_OUT1 -> node_139845894016256 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016256_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016256 -> inter_139845894016256_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016352 [label="ProductBlock\n(MultH)", shape=box];
- inter_139845894015200_OUT1 -> node_139845894016352 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016448_OUT1 -> node_139845894016352 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016352_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016352 -> inter_139845894016352_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016448 [label=" ClampBlock\n(Clamp)\n[0.1, 4.0]", shape=box];
- inter_139845894015728_OUT1 -> node_139845894016448 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016448_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016448 -> inter_139845894016448_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
- node_139845894016400 [label=" ClampBlock\n(ClampH)\n[1e-40, 0.1]", shape=box];
- inter_139845894016352_OUT1 -> node_139845894016400 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
- inter_139845894016400_OUT1 [shape=point, width=0.01, height=0.01];
- node_139845894016400 -> inter_139845894016400_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280436912 [label="h", shape=none];
+ inter_139764280436912_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280436912 -> inter_139764280436912_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437056 [label="y_1", shape=none];
+ inter_139764280437056_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437056 -> inter_139764280437056_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437152 [label="z_1", shape=none];
+ inter_139764280437152_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437152 -> inter_139764280437152_OUT1 [taillabel="", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437248 [label="h_new", shape=none];
+ inter_139764280418112_OUT1 -> node_139764280437248 [headlabel="", arrowhead="normal", arrowtail="none", dir=both];
+ node_139764280437344 [label="error", shape=none];
+ inter_139764280437488_OUT1 -> node_139764280437344 [headlabel="", arrowhead="normal", arrowtail="none", dir=both];
+ node_139764280436960 [label=" ConstantBlock\n(Tol)\n2e-05", shape=ellipse];
+ inter_139764280436960_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280436960 -> inter_139764280436960_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437440 [label=" ConstantBlock\n(Eps)\n1e-20", shape=ellipse];
+ inter_139764280437440_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437440 -> inter_139764280437440_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437488 [label="MaxBlock\n(Max)", shape=box];
+ inter_139764280437440_OUT1 -> node_139764280437488 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437776_OUT1 -> node_139764280437488 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437488_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437488 -> inter_139764280437488_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437584 [label="NegatorBlock\n(Neg_1)", shape=box];
+ inter_139764280437056_OUT1 -> node_139764280437584 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437584_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437584 -> inter_139764280437584_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437680 [label="AdderBlock\n(Sum_1)", shape=box];
+ inter_139764280437584_OUT1 -> node_139764280437680 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437152_OUT1 -> node_139764280437680 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437680_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437680 -> inter_139764280437680_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437776 [label="AbsBlock\n(Abs_1)", shape=box];
+ inter_139764280437680_OUT1 -> node_139764280437776 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437776_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437776 -> inter_139764280437776_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437536 [label="InverterBlock\n(hinv)", shape=box];
+ inter_139764280436912_OUT1 -> node_139764280437536 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437536_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437536 -> inter_139764280437536_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437824 [label="ProductBlock\n(R)", shape=box];
+ inter_139764280437488_OUT1 -> node_139764280437824 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437536_OUT1 -> node_139764280437824 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437824_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437824 -> inter_139764280437824_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437920 [label="InverterBlock\n(Rinv)", shape=box];
+ inter_139764280437824_OUT1 -> node_139764280437920 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437920_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437920 -> inter_139764280437920_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280437872 [label="ProductBlock\n(RinvMult)", shape=box];
+ inter_139764280437920_OUT1 -> node_139764280437872 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280436960_OUT1 -> node_139764280437872 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280437872_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280437872 -> inter_139764280437872_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280438016 [label="RootBlock\n(Root)", shape=box];
+ inter_139764280437872_OUT1 -> node_139764280438016 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438064_OUT1 -> node_139764280438016 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438016_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280438016 -> inter_139764280438016_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280438064 [label=" ConstantBlock\n(q)\n4", shape=ellipse];
+ inter_139764280438064_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280438064 -> inter_139764280438064_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280438112 [label=" ConstantBlock\n(S)\n0.84", shape=ellipse];
+ inter_139764280438112_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280438112 -> inter_139764280438112_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280438160 [label="ProductBlock\n(SMult)", shape=box];
+ inter_139764280438112_OUT1 -> node_139764280438160 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438016_OUT1 -> node_139764280438160 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438160_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280438160 -> inter_139764280438160_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280438256 [label=" ClampBlock\n(Clamp)\n[0.1, 4.0]", shape=box];
+ inter_139764280438160_OUT1 -> node_139764280438256 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438256_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280438256 -> inter_139764280438256_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280416720 [label="ProductBlock\n(HMult)", shape=box];
+ inter_139764280436912_OUT1 -> node_139764280416720 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280438256_OUT1 -> node_139764280416720 [headlabel="IN2", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280416720_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280416720 -> inter_139764280416720_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
+ node_139764280418112 [label=" ClampBlock\n(HClamp)\n[1e-08, 0.1]", shape=box];
+ inter_139764280416720_OUT1 -> node_139764280418112 [headlabel="IN1", arrowhead="normal", arrowtail="none", dir=both];
+ inter_139764280418112_OUT1 [shape=point, width=0.01, height=0.01];
+ node_139764280418112 -> inter_139764280418112_OUT1 [taillabel="OUT1", arrowtail="invempty", arrowhead="none", dir=both];
 
 }