def test_not_equal(self): self.assertEqual(self.add_0 == self.add_1, False) add_0_2 = SymNum('add_0', default=0.1, product=False) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_01', default=0, product=False) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_0', default=0, product=True) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_0', default=0, product=False, numerical=3) self.assertEqual(self.add_0 == add_0_2, False)
def test_get_eval_result(self): """ creates and evaluates a feed forward combiner """ edge_1 = Edge('b', 'a', phase=SymNum('phi1',default=0.5,product=False), attenuation=0.5, delay=2) edge_2 = Edge('c', 'a', phase=SymNum('phi2',default=0.0,product=False), attenuation=SymNum('amp2',default=1.5,product=True), delay=-1) split_net = Network() split_net.add_node('a') split_net.add_node('b') split_net.add_node('c') split_net.add_edge(edge_1) split_net.add_edge(edge_2) split_net.add_input('b', amplitude=1) split_net.add_input('c', amplitude=1) split_net.evaluate() self.assertEqual(split_net.get_eval_result('a'), [(0.5, 0.5, 2.0), (1.5, 0.0, -1.0)]) self.assertEqual(split_net.get_eval_result('a',feed_dict=None, use_shared_default=True), [(0.5, 0.5, 2.0), (1.5, 0.0, -1.0)]) self.assertEqual(split_net.get_eval_result('a',feed_dict={'phi1':0.6,'phi2':3,'amp2':6}, use_shared_default=True), [(0.5, 0.6, 2.0), (6.0, 3.0, -1.0)])
def __init__(self, start, end, name=None, phase=.4, attenuation=.75, delay=1.0): super().__init__(start, end, phase, attenuation, delay) if name is None: name = "Edge_" + start + end self.attenuation = SymNum(name, default=0.75)
# | limitations under the License. | # +-----------------------------------------------------------------------------+ # | Authors: Lorenz K. Mueller, Pascal Stark | # +-----------------------------------------------------------------------------+ """ Creates a very simple feedforward network with constant input and some symbolic edge properties. The network topology is as follows: A -> B > D v C """ from colna.analyticnetwork import Network, Edge, SymNum, Testbench amp1 = SymNum(name='a1', default=1.5, product=True) amp2 = SymNum(name='a2', default=2.0, product=True) phi1 = SymNum(name='phi1', default=2.0, product=False) phi2 = SymNum(name='phi2', default=3.0, product=False) net = Network() net.add_node(name='a') net.add_node(name='b') net.add_node(name='c') net.add_node(name='d') net.add_edge(Edge(start='a', end='b', phase=phi1, attenuation=amp1, delay=1)) net.add_edge(Edge(start='b', end='c', phase=phi2, attenuation=amp2, delay=2)) net.add_edge(Edge(start='b', end='d', phase=3, attenuation=0.4, delay=3))
from colna.analyticnetwork import Network, Edge, SymNum from colna.analyticnetwork import Testbench import numpy as np import matplotlib.pyplot as plt import matplotlib font = {'family': 'normal', 'weight': 'bold', 'size': 15} matplotlib.rc('text', usetex=False) matplotlib.rc('axes', linewidth=2) matplotlib.rc('lines', linewidth=2) matplotlib.rc('font', **font) net = Network() amp1 = SymNum(name='v_1', product=True) amp2 = SymNum(name='v_2', product=True) amp3 = SymNum(name='v_3', product=True) phi3 = SymNum(name='v_4', product=False) net.add_node(name='a') net.add_node(name='b') net.add_node(name='c') net.add_edge(Edge(start='a', end='b', phase=2, attenuation=amp1, delay=1)) net.add_edge(Edge(start='b', end='c', phase=1, attenuation=amp2, delay=2)) net.add_edge( Edge(start='c', end='a', phase=phi3, attenuation=0.5 * amp3, delay=3)) net.add_input('a') net.add_input('b')
from colna.analyticnetwork import Network, Edge, SymNum from colna.analyticnetwork import Testbench from colna.analyticnetwork import PhysicalNetwork, Device, DeviceLink from colna.lossconversion import dBcm_to_attenuation import numpy as np import matplotlib.pyplot as plt # Global defaults wavelength = 1.55e-6 neff = 2.6 # Splitter configuration splitter_length = 10e-6 splitter_phase_default = 2 * np.pi / wavelength * neff * splitter_length splitter_efficiency00 = SymNum(name='split_{00}', default=1 / np.sqrt(2), product=True) splitter_efficiency01 = SymNum(name='split_{01}', default=1 / np.sqrt(2), product=True) splitter_phase00 = SymNum(name='split_{\phi00}', default=splitter_phase_default, product=False) splitter_phase01 = SymNum(name='split_{\phi01}', default=splitter_phase_default, product=False) splitter = Device('splitter') splitter.init_from_phase_and_attenuation_matrix(np.array([[splitter_efficiency00, splitter_efficiency01]]), np.array([[splitter_phase00, splitter_phase01]]), delay=0) splitter.add_input('i0') # Combiner configuration combiner_length = 10e-6 combiner_phase_default = 2 * np.pi / wavelength * neff * combiner_length combiner_efficiency00 = SymNum(name='comb_{00}', default=1 / np.sqrt(2), product=True) combiner_efficiency01 = SymNum(name='comb_{10}', default=1 / np.sqrt(2), product=True) combiner_phase00 = SymNum(name='comb_{\phi00}', default=combiner_phase_default, product=False)
# | You may obtain a copy of the License at | # | | # | http://www.apache.org/licenses/LICENSE-2.0 | # | | # | Unless required by applicable law or agreed to in writing, software | # | distributed under the License is distributed on an "AS IS" BASIS, | # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | # | See the License for the specific language governing permissions and | # | limitations under the License. | # +-----------------------------------------------------------------------------+ # | Authors: Lorenz K. Mueller, Pascal Stark | # +-----------------------------------------------------------------------------+ from colna.analyticnetwork import SymNum amp1 = SymNum(name='a1', default=0.5, product=True) amp2 = SymNum(name='a2', default=0.8, product=True) amp3 = amp1 * amp2 print(amp1) print(amp2) print(amp3) # Evaluate without feed dictionary and use individual defaults print(amp3.eval(feed_dict=None, use_shared_default=False)) # Evaluate without feed dictionary, but use shared defaults print('amp3 shared default:', amp3.shared_default) print(amp3.eval(feed_dict=None, use_shared_default=True))
def test_equal(self): add_0_2 = SymNum('add_0', default=0, product=False) self.assertEqual(self.add_0 == add_0_2, True) add_0_2b = self.add_0 self.assertEqual(self.add_0 == add_0_2b, True)
def setUp(self): self.mult_0 = SymNum('mult_0', default=0, product=True) self.mult_1 = SymNum('mult_1', default=1, product=True) self.mult_5 = SymNum('mult_5', default=5, product=True) self.mult_6 = SymNum('mult_6', default=6, product=True) self.add_0 = SymNum('add_0', default=0, product=False) self.add_1 = SymNum('add_1', default=1, product=False) self.add_5 = SymNum('add_5', default=5, product=False) self.add_6 = SymNum('add_6', default=6, product=False)
class TestSymNum(unittest.TestCase): def setUp(self): self.mult_0 = SymNum('mult_0', default=0, product=True) self.mult_1 = SymNum('mult_1', default=1, product=True) self.mult_5 = SymNum('mult_5', default=5, product=True) self.mult_6 = SymNum('mult_6', default=6, product=True) self.add_0 = SymNum('add_0', default=0, product=False) self.add_1 = SymNum('add_1', default=1, product=False) self.add_5 = SymNum('add_5', default=5, product=False) self.add_6 = SymNum('add_6', default=6, product=False) def test_equal(self): add_0_2 = SymNum('add_0', default=0, product=False) self.assertEqual(self.add_0 == add_0_2, True) add_0_2b = self.add_0 self.assertEqual(self.add_0 == add_0_2b, True) def test_not_equal(self): self.assertEqual(self.add_0 == self.add_1, False) add_0_2 = SymNum('add_0', default=0.1, product=False) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_01', default=0, product=False) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_0', default=0, product=True) self.assertEqual(self.add_0 == add_0_2, False) add_0_2 = SymNum('add_0', default=0, product=False, numerical=3) self.assertEqual(self.add_0 == add_0_2, False) def test_copy(self): """ we expect deepcopy of defaults and symbolic dictionary""" copy_0 = self.mult_0.__copy__() self.assertEqual( copy_0.symbolic == self.mult_0.symbolic and copy_0.defaults == self.mult_0.defaults and copy_0.product == self.mult_0.product and copy_0.numerical == self.mult_0.numerical and id( copy_0.symbolic) != id(self.mult_0.symbolic) and id(copy_0.defaults) != id(self.mult_0.symbolic), True) copy_1 = self.add_1.__copy__() self.assertEqual( copy_1.symbolic == self.add_1.symbolic and copy_1.defaults == self.add_1.defaults and copy_1.product == self.add_1.product and copy_1.numerical == self.add_1.numerical and id( copy_1.symbolic) != id(self.add_1.symbolic) and id(copy_1.defaults) != id(self.add_1.symbolic), True) def test_add_mult(self): """ Tests if adding multiplicative numbers does raise a Value error""" with self.assertRaises(ValueError): self.mult_0 + self.mult_1 with self.assertRaises(ValueError): self.add_0 + self.mult_1 with self.assertRaises(ValueError): self.mult_1 + self.add_0 def test_add(self): """ Tests if adding two symnums returns the expected new symnum""" add_0 = self.add_1 add_1 = self.add_5 sum = add_0 + add_1 self.assertEqual(sum.product, False) self.assertEqual(sum.shared_default, max(add_0.shared_default, add_1.shared_default)) self.assertEqual(sum.numerical, 0.0) self.assertEqual(sum.symbolic, {'add_5': 1, 'add_1': 1}) self.assertEqual(sum.defaults, {'add_5': 5, 'add_1': 1}) def test_mult_add(self): """ Tests if multypling additive numbers does raise a Value error""" with self.assertRaises(ValueError): self.add_0 * self.add_1 with self.assertRaises(ValueError): self.add_0 * self.mult_1 with self.assertRaises(ValueError): self.mult_1 * self.add_0 def test_mult(self): mult_0 = self.mult_1 mult_1 = self.mult_5 mult = mult_0 * mult_1 self.assertEqual(mult.product, True) self.assertEqual(mult.shared_default, max(mult_0.shared_default, mult_1.shared_default)) self.assertEqual(mult.numerical, 1.0) self.assertEqual(mult.symbolic, {'mult_1': 1, 'mult_5': 1}) self.assertEqual(mult.defaults, {'mult_5': 5, 'mult_1': 1}) mult_2 = mult_1 * 2 self.assertEqual(mult_2.product, True) self.assertEqual(mult_2.shared_default, mult_1.shared_default) self.assertEqual(mult_2.numerical, 2.0) self.assertEqual(mult_2.symbolic, {'mult_5': 1}) self.assertEqual(mult_2.defaults, {'mult_5': 5}) def test_div_add(self): """ Tests if multypling additive numbers does raise a Value error""" with self.assertRaises(ValueError): self.add_0 / self.add_1 with self.assertRaises(ValueError): self.add_0 / self.mult_1 with self.assertRaises(ValueError): self.mult_1 / self.add_0 def test_div(self): mult_0 = self.mult_1 mult_1 = self.mult_5 mult = mult_0 / mult_1 self.assertEqual(mult.product, True) self.assertEqual(mult.shared_default, max(mult_0.shared_default, mult_1.shared_default)) self.assertEqual(mult.numerical, 1.0) self.assertEqual(mult.symbolic, {'mult_1': 1, 'mult_5': -1}) self.assertEqual(mult.defaults, {'mult_5': 5, 'mult_1': 1}) def test_eval(self): ## using default values self.assertEqual(self.mult_1.eval(use_shared_default=False, feed_dict=None), 1) self.assertEqual(self.add_5.eval(use_shared_default=False, feed_dict=None), 5) ## using shared defaults self.assertEqual(self.mult_1.eval(use_shared_default=True, feed_dict=None), 1) self.assertEqual(self.add_5.eval(use_shared_default=True, feed_dict=None), 5) ## using feed dictionary self.assertEqual(self.mult_1.eval(use_shared_default=False, feed_dict={'mult_1': 2}), 2) self.assertEqual(self.add_5.eval(use_shared_default=False, feed_dict={'add_5': 7}), 7) ## the following lines are not strictly speaking a unit test and could be classified as integration test # Test addition addition = self.add_5 + self.add_6 self.assertEqual(addition.eval(use_shared_default=False), 11) self.assertEqual(addition.eval(use_shared_default=True), 12) self.assertEqual(addition.eval(use_shared_default=False, feed_dict={'add_5': 4}), 10) self.assertEqual(addition.eval(use_shared_default=False, feed_dict={'add_5': 4, 'add_6': 5}), 9) # Test addition addition = self.add_5 + 6 self.assertEqual(addition.eval(use_shared_default=False), 11) self.assertEqual(addition.eval(use_shared_default=True), 11) self.assertEqual(addition.eval(use_shared_default=False, feed_dict={'add_5': 4}), 10) # Test addition addition = 6 + self.add_5 self.assertEqual(addition.eval(use_shared_default=False), 11) self.assertEqual(addition.eval(use_shared_default=True), 11) self.assertEqual(addition.eval(use_shared_default=False, feed_dict={'add_5': 4}), 10) # Test Multiplication symnum * symnum mult = self.mult_6 * self.mult_5 self.assertEqual(mult.eval(use_shared_default=False), 30) self.assertEqual(mult.eval(use_shared_default=True), 36) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4}), 24) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4, 'mult_6': 5}), 20) # Test Multiplication constant * symnum mult = 3 * self.mult_5 self.assertEqual(mult.eval(use_shared_default=False), 15) self.assertEqual(mult.eval(use_shared_default=True), 15) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4}), 12) # Test Multiplication symnum * constant mult = self.mult_5 * 3 self.assertEqual(mult.eval(use_shared_default=False), 15) self.assertEqual(mult.eval(use_shared_default=True), 15) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4}), 12) # Test division symnum/symnum mult = self.mult_1 / self.mult_5 self.assertEqual(mult.eval(use_shared_default=False), 0.2) self.assertEqual(mult.eval(use_shared_default=True), 1.0) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4}), 0.25) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_5': 4, 'mult_1': 2}), 0.5) # Test division symnum/constant mult = self.mult_1 / 5 self.assertEqual(mult.eval(use_shared_default=False), 0.2) self.assertEqual(mult.eval(use_shared_default=True), 0.2) self.assertEqual(mult.eval(use_shared_default=False, feed_dict={'mult_1': 2}), 0.4) def test_str(self): """ Tests the conversion of SymNum to string.""" self.assertEqual(self.mult_0.__str__(), '1.0 * mult_0**1') self.assertEqual(self.add_0.__str__(), '0.0 + add_0*1') self.assertEqual(str(self.mult_1 / self.mult_5), '1.0 * mult_1**1 * mult_5**-1') self.assertEqual(str(self.mult_1 / self.mult_5 / 2), '0.5 * mult_1**1 * mult_5**-1') self.assertEqual(str(self.mult_1 * self.mult_5), '1.0 * mult_1**1 * mult_5**1') self.assertEqual(str(3 * self.mult_1 * self.mult_5), '3.0 * mult_1**1 * mult_5**1') self.assertEqual(str(self.add_5 + self.add_6), '0.0 + add_5*1 + add_6*1') self.assertEqual(str(2 + self.add_5 + self.add_6), '2.0 + add_5*1 + add_6*1') def test_latex(self): """ Tests the conversion of SymNum to latex strings.""" self.assertEqual(self.mult_0.to_latex(), '1.0 mult_0^1') self.assertEqual(self.add_0.to_latex(), '0.0 + add_0 \cdot 1')
A -> B ^ v D <- C """ from colna.analyticnetwork import Network, Edge, SymNum #### # Define Network #### nodes = ['a', 'b', 'c', 'd'] edges = [ Edge('a', 'b', phase=SymNum('ph1', default=0.4, product=False), attenuation=0.95, delay=1.0), Edge('b', 'c', .5, SymNum('amp1', default=0.95), 1.), Edge('c', 'd', .5, 0.95, SymNum('del1', default=1.2, product=False)), Edge('d', 'a', .5, 0.95, 1.) ] net = Network() for node in nodes: net.add_node(node) for edge in edges: net.add_edge(edge) net.add_input('a', amplitude=1.0) net.visualize(path='./visualizations/symbolicrecurrent')
import matplotlib.pyplot as plt # Define Network net = Network() # Add three nodes net.add_node(name='a') net.add_node(name='b') net.add_node(name='c') # Add three edges (with mixed symbolic and numeric values) net.add_edge(Edge(start='c', end='a', phase=0.5, attenuation=0.6, delay=0.1)) net.add_edge( Edge(start='a', end='b', phase=SymNum('ph_{ab}', default=5, product=False), attenuation=0.95, delay=0.2)) net.add_edge( Edge(start='b', end='c', phase=SymNum('ph_{bc}', default=3, product=False), attenuation=SymNum('amp_{bc}', default=0.8, product=True), delay=0.1)) # Visualize the network (if graphviz is installed) net.visualize(path='./visualizations/quickstart2', format='svg') # Create a testbench tb = Testbench(network=net, timestep=0.1)