Examples¶
The examples can be downloaded from COLNA’s github repository.
Feedforward Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Creates a simple feedforward network with constant input.
This example is part of the :ref:`User Manual`.
The network topology is as follows:
A > B > D
v
C
"""
from colna.analyticnetwork import Network, Edge
# Create a network
net = Network()
# Add nodes
net.add_node(name='a')
net.add_node(name='b')
net.add_node(name='c')
net.add_node(name='d')
# Add edges
net.add_edge(Edge(start='a',end='b',phase=1,attenuation=0.8,delay=1))
net.add_edge(Edge(start='b',end='c',phase=2,attenuation=0.6,delay=2))
net.add_edge(Edge(start='b',end='d',phase=3,attenuation=0.4,delay=3))
# Add input
net.add_input(name='a',amplitude=1.0, phase=0)
# Visualize the network
net.visualize(path='./visualizations/feedforward', format='svg')
# Evaluate the network
net.evaluate(amplitude_cutoff=1e-3)
# Compute output and show results
print('paths leading to c:', net.get_paths('c'))
print('paths leading to d:', net.get_paths('d'))
print('waves arriving at c:', net.get_result('c'))
print('waves arriving at d:', net.get_result('d'))
print('latex string for waves arriving at c:', net.get_latex_result('c'))
# render output in a html file
net.get_html_result(['c','d'], precision=2, path='./visualizations/feedforward.html')
|
Output of the Network.get_html_result()
:
Waves at node c
\(\begin{equation}\begin{split}&0.48\cdot\exp(j (3))\cdot a_{in}(t-3)\\\end{split}\end{equation}\)
Waves at node d
\(\begin{equation}\begin{split}&0.32\cdot\exp(j (4))\cdot a_{in}(t-4)\\\end{split}\end{equation}\)
Feedforward Network with Testbench¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Creates a simple feedforward network with a testbench.
This is the example used in the basic usage guide.
The network topology is as follows:
A -> B > D
v
C
A testbench is used to inject time varying signals at node A and B.
"""
from colna.analyticnetwork import Network, Edge, Testbench
import numpy as np
import matplotlib.pyplot as plt
### Create the Network and add the nodes
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=1,attenuation=0.8,delay=1))
net.add_edge(Edge(start='b',end='c',phase=2,attenuation=0.6,delay=2))
net.add_edge(Edge(start='b',end='d',phase=3,attenuation=0.4,delay=3))
# Visualize the network
net.visualize(path='./visualizations/feedforward_with_testbench', format='svg')
# Create a testbench
tb = Testbench(network=net, timestep=0.1) # Timestep should be factor of all delays
# add an input signal to the testbench
x_in_a = np.sin(np.linspace(0,15,500))+1.5 # create the input signal (Dimensino N)
t_in = np.linspace(0, 10, num=501) # create the input time vector (Dimension N+1)
tb.add_input_sequence(node_name='a',x=x_in_a,t=t_in)
# add output nodes to testbench (nodes at which output signal should be recorded)
tb.add_output_node('c')
tb.add_output_node('d')
# evaluate the network (through the testbench)
tb.evaluate_network()
# Calculate the output signal at the output nodes
tb.calculate_output(n_threads=8) # uses multithreading with at most 8 threads
t, x = tb.t_out.transpose(), tb.x_out.transpose()
### Plot the signals
plt.plot(tb.input_t[0][:-1], np.abs(tb.input_x[0][:-1]), 'o') # Input signal
plt.plot(t, np.abs(x), 'x') # Output signal
plt.xlabel('Time')
plt.ylabel('|x|')
plt.legend(['Input', 'Output C', 'Output D'], loc='lower left')
plt.grid()
# plt.savefig('./visualizations/feedforward_with_testbench_output.svg')
plt.show()
|
Physical Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
"""
Creates a physical network.
This demonstrates how devices and devicelinks can be used to create a PhysicalNetwork.
"""
from colna.analyticnetwork import PhysicalNetwork, Device, DeviceLink
import numpy as np
# define a physical network
physnet = PhysicalNetwork()
# create a splitter and a combiner Device based on their scattering matrix
splitter = Device(name='0', devicetype='Splitter', scattering_matrix=np.array([[1 / np.sqrt(2), 1 / np.sqrt(2)]]),
delay=1)
combiner = Device(name='0', devicetype='Combiner', scattering_matrix=np.array([[1 / np.sqrt(2)], [1 / np.sqrt(2)]]),
delay=1)
# add input and output nodes to the devices
splitter.add_input('i0', amplitude=1)
combiner.add_output('o0')
# add the devices to the physical network
physnet.add_device(splitter)
physnet.add_device(combiner)
# connect the devices using two DeviceLinks
physnet.add_devicelink(
DeviceLink(startdevice='0', startdevicetype='Splitter', startnode='o0', enddevicetype='Combiner', enddevice='0',
endnode='i0', phase=5 * np.pi, attenuation=0.5, delay=2))
physnet.add_devicelink(
DeviceLink(startdevice='0', startdevicetype='Splitter', startnode='o1', enddevicetype='Combiner', enddevice='0',
endnode='i1', phase=6 * np.pi, attenuation=0.7, delay=3)
)
# visualize the full and simplified
physnet.visualize(full_graph=True, path='./visualizations/Physical_Network_Full', format='svg')
physnet.visualize(full_graph=False, path='./visualizations/Physical_Network_Simplified', format='svg')
# evaluate network
physnet.evaluate()
out = physnet.get_outputs()
print(out)
|
Small Recurrent Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Example of a basic recurrent network.
Network topology:
A -> B
^ v
D <- C
"""
from colna.analyticnetwork import Network, Edge
###Define Network
nodes = ['a', 'b', 'c', 'd']
edges = [Edge('a', 'b', phase=0.5, attenuation=1.1, delay=1.0), # some edges can have gain, but the overall gain of loops must be <1
Edge('b', 'c', phase=1, attenuation=0.9, delay=2.0),
Edge('c', 'd', phase=0.2, attenuation=0.98, delay=0.5),
Edge('d', 'a', phase=-0.5, attenuation=0.8, delay=1.5)]
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/recurrent', format='svg')
####
#Evaluate Network
####
net.evaluate(amplitude_cutoff=1e-1, max_endpoints=1e6)
####
#Print data
####
print('paths leading to a:', net.get_paths('a'))
print('waves arriving at a:', net.get_result('a'))
net.print_stats()
|
Recurrent Network with Testbench¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Creates a very simple recurrent network with a testbench.
This is the example used in the basic usage guide.
The network topology is as follows:
A -> B
^ v
D <- C
A testbench is used to inject time varying signals at node A and B.
"""
from colna.analyticnetwork import Network, Edge, Testbench
import numpy as np
import matplotlib.pyplot as plt
### Create the Network and add the nodes
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=1,attenuation=0.8,delay=1))
net.add_edge(Edge(start='b',end='c',phase=2,attenuation=0.7,delay=2))
net.add_edge(Edge(start='c',end='d',phase=3,attenuation=0.8,delay=1))
net.add_edge(Edge(start='d',end='a',phase=-1,attenuation=0.9,delay=0.5))
net.visualize(path='./visualizations/recurrent_with_testbench')
### Create a testbench
tb = Testbench(network=net, timestep=0.1) # Timestep should be factor of all delays
x_in_a = np.sin(np.linspace(0,15,500))+1.5 # create the input signal (Dimensino N)
t_in = np.linspace(0, 10, num=501) # create the input time vector (Dimension N+1)
tb.add_input_sequence(node_name='a',x=x_in_a,t=t_in)
# add output nodes to testbench (nodes at which output signal should be recorded)
tb.add_output_node('c')
tb.add_output_node('d')
# evaluate the network (through the testbench)
tb.evaluate_network(amplitude_cutoff=1e-6)
# Calculate the output signal at the output nodes
tb.calculate_output(n_threads=8) # uses multithreading with at most 8 threads
t, x = tb.t_out.transpose(), tb.x_out.transpose()
### Plot the signals
plt.plot(tb.input_t[0][:-1], np.abs(tb.input_x[0][:-1]), 'o') # Input signal
plt.plot(t, np.abs(x), 'x') # Output signal
plt.xlabel('Time')
plt.ylabel('|x|')
plt.legend(['Input', 'Output C', 'Output D'], loc='lower left')
plt.grid()
# plt.savefig('basic_feedforward_tb_output.svg')
plt.show()
|
Symbolic Feedforward Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" 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))
net.add_input(name='a',amplitude=1.0, phase=0)
net.visualize(path='./visualizations/symbolicfeedforward', format='svg')
net.evaluate(use_shared_default=False, feed_dict=None)
# print('paths leading to c:', net.get_paths('c'))
# print('paths leading to d:', net.get_paths('d'))
print('waves arriving at c:', net.get_result('c'))
print('waves arriving at d:', net.get_result('d'))
net.get_html_result(['c','d'],path='./visualizations/symbolicfeedforward.html')
# Evaluation without feed dictionary, using the default value of each SymNum
waves = [tuple([w.eval(feed_dict=None, use_shared_default=False) if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('c')]
print('Waves arriving at c:', waves, '\n')
print(net.get_eval_result(name='c',feed_dict=None,use_shared_default=False))
# Evaluation without feed dictionary, with global defaults
waves = [tuple([w.eval(feed_dict=None, use_shared_default=True) if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('c')]
print('Waves arriving at c:', waves, '\n')
print(net.get_eval_result(name='c',feed_dict=None,use_shared_default=True))
# Evaluation with a feed dictionary
feed = {'a1': 1, 'a2': 2, 'phi1': 2, 'phi2': 4}
waves = [tuple([w.eval(feed_dict=feed, use_shared_default=True) if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('c')]
print('Waves arriving at c:', waves, '\n')
print(net.get_eval_result(name='c',feed_dict=feed,use_shared_default=True))
# Evaluation with a partial feed dictionary
feed = {'a1': 0.5, 'phi2': 4}
waves = [tuple([w.eval(feed_dict=feed, use_shared_default=True) if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('c')]
print('Waves arriving at c:', waves, '\n')
print(net.get_eval_result(name='c',feed_dict=feed,use_shared_default=True))
|
Symbolic Feedforward Network with Testbench¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Creates a very simple recurrent network with some symbolic edge properties and a testbench.
The network topology is as follows:
A -> B > D
v
C
"""
from colna.analyticnetwork import Network, Edge, SymNum
from colna.analyticnetwork import Testbench
import numpy as np
import matplotlib.pyplot as plt
amp1 = SymNum(name='a1', default=1.5, product=True)
amp2 = SymNum(name='a2', default=2, product=True)
phi1 = SymNum(name='phi1', default=2, product=False)
phi2 = SymNum(name='phi2', default=3, 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))
### Create a testbench with a feed dictionary
tb = Testbench(network=net, timestep=0.1, feed_dict={'a1':0.2,'a2':1.5,'phi1':2,'phi2':3})
x_in_a = np.sin(np.linspace(0,15,500))+1.5 # create the input signal (Dimensino N)
t_in = np.linspace(0, 10, num=501) # create the input time vector (Dimension N+1)
tb.add_input_sequence(node_name='a',x=x_in_a,t=t_in)
tb.add_output_node(node_name='c')
tb.add_output_node(node_name='d')
# evaluate the network (through the testbench)
tb.evaluate_network(amplitude_cutoff=1e-3,use_shared_default=False)
# Calculate the output signal at the output nodes
tb.calculate_output(n_threads=8, use_shared_default=False) # uses multithreading with at most 8 threads
t, x = tb.t_out.transpose(), tb.x_out.transpose()
### Plot the signals
plt.plot(tb.input_t[0][:-1], np.abs(tb.input_x[0][:-1]), 'o') # Input signal
plt.plot(t, np.abs(x), 'x') # Output signal
# Set a different feed dict and recompute the
tb.set_feed_dict({'a1':1.2,'a2':1.5,'phi1':2,'phi2':3})
tb.calculate_output(n_threads=8, use_shared_default=False) # uses multithreading with at most 8 threads
t, x = tb.t_out.transpose(), tb.x_out.transpose()
### Plot the signals
plt.plot(t, np.abs(x), 'x') # Output signal
### Format the plot
plt.xlabel('Time')
plt.ylabel('|x|')
plt.legend(['Input', 'Output C', 'Output D', 'Output C (Feed Dict 2)', 'Output D (Feed Dict 2)'], loc='lower left')
plt.grid()
# plt.savefig('./visualizations/symnum_feedforward_tb_output.svg')
plt.show()
|
Symbolic Recurrent Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
""" Example of a basic recurrent network with symbolic variables.
Network topology:
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')
####
# Evaluate Network
####
net.evaluate(amplitude_cutoff=1e-2, max_endpoints=1e6, use_shared_default=False)
print('paths leading to a:', net.get_paths('a'))
waves = [tuple([w.eval() if hasattr(w, 'eval') else w for w in inner]) for inner in net.get_result('a')]
print('waves arriving at a:', waves, '\n')
net.print_stats()
####
# Inserting variable values
###
waves = [tuple([w.eval(feed_dict={'amp1': .5, 'ph1': .2}) if hasattr(w, 'eval') else w for w in inner])
for inner in net.get_result('a')]
print('waves arriving at a (different variable values):', waves, '\n')
####
# Showing symbolic values
####
print('symbolic values', net.get_result('a'), '\n')
|
Large Symbolic Recurrent Network¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | # +-----------------------------------------------------------------------------+
# | Copyright 2019-2020 IBM Corp. All Rights Reserved. |
# | |
# | Licensed under the Apache License, Version 2.0 (the "License"); |
# | you may not use this file except in compliance with the License. |
# | 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 |
# +-----------------------------------------------------------------------------+
"""
Network topology:
P <- N <- L <- J
v v v ^
O <- M <- K <- I
v v ^ ^
A -> C -> E -> G
v v ^ ^
B -> D -> F -> H
"""
from colna.analyticnetwork import Network, Edge, SymNum
import numpy as np
import matplotlib.pyplot as plt
# 4x4 network
class SymbolicEdge(Edge):
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)
####
# Define Network
####
nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p']
edges = [SymbolicEdge('a', 'b'), SymbolicEdge('a', 'c'), SymbolicEdge('b', 'd'), SymbolicEdge('c', 'd'),
SymbolicEdge('c', 'e'), SymbolicEdge('d', 'f'), SymbolicEdge('f', 'e'), SymbolicEdge('e', 'g'),
SymbolicEdge('f', 'h'), SymbolicEdge('h', 'g'), SymbolicEdge('g', 'i'), SymbolicEdge('e', 'k'),
SymbolicEdge('i', 'j'), SymbolicEdge('i', 'k'), SymbolicEdge('j', 'l'), SymbolicEdge('l', 'k'),
SymbolicEdge('l', 'n'), SymbolicEdge('k', 'm'), SymbolicEdge('n', 'm'), SymbolicEdge('n', 'p'),
SymbolicEdge('p', 'o'), SymbolicEdge('m', 'o'), SymbolicEdge('o', 'a'), SymbolicEdge('m', 'c')]
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)
for i, edge in enumerate(net.edges):
edge.phase = np.random.uniform(0, 2 * np.pi)
####
# Evaluate Network
####
net.evaluate(amplitude_cutoff=5e-3, max_endpoints=1e6,use_shared_default=True)
waves = [tuple([w.eval() if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('a')]
####
# Print and plot
####
for node in net.nodes:
print('number of paths to ' + node + ':', len(net.get_paths(node)))
print('final path to a added:', net.get_paths('a')[-1])
print('10 first waves arriving at a:', waves[:10])
net.print_stats()
#####
# Reset variable
#####
feed = {"Edge_ab": 0.8}
waves = [tuple([w.eval(feed_dict=feed) if hasattr(w,'eval') else w for w in inner]) for inner in net.get_result('a')]
print('10 first waves arriving at a:', waves[:10], '\n')
####
# Print Symbolic values
####
print('3 last waves at a (symbolic)', net.get_result('a')[-3:], '\n')
#####
# Plot
#####
phases = np.asarray([val[1].eval() if hasattr(val[1], 'eval') else val[1] for val in net.get_result('a')])
phases = phases % 2 * np.pi
amplitudes = np.asarray([val[0].eval() if hasattr(val[0], 'eval') else val[0] for val in net.get_result('a')])
plt.hist(phases, weights=amplitudes, bins=30)
plt.title("amplitude weighted, binned phase contributions to a")
plt.ylabel('amplitude')
plt.xlabel('phase')
plt.show()
|