Ported objects
PortedObject(name, input_ports=[], output_ports=[], variable_ports=[], parsing_locals={}, **kwargs)
Bases: ABC
Base class implementing ported objects. Cannot be instantiated directly.
PARAMETER | DESCRIPTION |
---|---|
name
|
a string which must be unique for each
TYPE:
|
input_ports
|
list of input ports to expose. See add_input_ports.
TYPE:
|
output_ports
|
list of output ports to expose. See add_output_ports.
TYPE:
|
variable_ports
|
list of variable ports to expose. See add_variable_ports.
TYPE:
|
parsing_locals
|
a dictionary mapping strings to
TYPE:
|
**kwargs
|
arguments passed to super().init(). No user arguments should be supplied.
DEFAULT:
|
Source code in psymple/build/abstract.py
add_input_ports(*ports)
Add input ports to self.
PARAMETER | DESCRIPTION |
---|---|
*ports
|
data specifying an input port, in the form of:
Arguments can contain a mixture of the above data formats.
TYPE:
|
Examples:
Using an InputPort instance:
>>> from psymple.ported_objects import VariablePortedObject, InputPort
>>> X = VariablePortedObject(name="X")
>>> X.add_input_ports(InputPort("A", default_value=6))
>>> X._dump_input_ports()
[{'name': 'A', 'description': '', 'default_value': 6}]
Using a dictionary:
>>> X = VariablePortedObject(name="X")
>>> X.add_input_ports(dict(name = "A", description = "input port A", default_value=6))
>>> X._dump_input_ports()
[{'name': 'A', 'description': 'input port A', 'default_value': 6}]
Using a tuple:
>>> X = VariablePortedObject(name="X")
>>> X.add_input_ports(("A", 6, "input port A"))
>>> X._dump_input_ports()
[{'name': 'A', 'description': 'input port A', 'default_value': 6}]
Using a string (note that a description or default value cannot be specified):
>>> X = VariablePortedObject(name="X")
>>> X.add_input_ports("A")
>>> X._dump_input_ports()
[{'name': 'A', 'description': '', 'default_value': None}]
Source code in psymple/build/abstract.py
add_output_ports(*ports)
Add input ports to self.
PARAMETER | DESCRIPTION |
---|---|
*ports
|
data specifying an output port, in the form of:
Arguments can contain a mixture of the above data formats.
TYPE:
|
Examples:
Using an OutputPort instance:
>>> from psymple.ported_objects import FunctionalPortedObject, OutputPort
>>> X = FunctionalPortedObject(name="X")
>>> X.add_output_ports(OutputPort("A", description="output port A"))
>>> X._dump_output_ports()
[{'name': 'A', 'description': 'output port A'}]
Using a dictionary:
>>> X = FunctionalPortedObject(name="X")
>>> X.add_output_ports(dict(name = "A", description = "output port A"))
>>> X._dump_output_ports()
[{'name': 'A', 'description': 'output port A'}]
Using a string (note that a description or default value cannot be specified):
>>> X = FunctionalPortedObject(name="X")
>>> X.add_output_ports("A")
>>> X._dump_output_ports()
[{'name': 'A', 'description': ''}]
Source code in psymple/build/abstract.py
add_variable_ports(*ports)
Add input ports to self.
PARAMETER | DESCRIPTION |
---|---|
*ports
|
data specifying a variable port, in the form of:
Arguments can contain a mixture of the above data formats.
TYPE:
|
Examples:
Using an VariablePort instance:
>>> from psymple.ported_objects import VariablePortedObject, VariablePort
>>> X = VariablePortedObject(name="X")
>>> X.add_variable_ports(VariablePort("A", description="variable port A"))
>>> X._dump_variable_ports()
[{'name': 'A', 'description': 'variable port A'}]
Using a dictionary:
>>> X = VariablePortedObject(name="X")
>>> X.add_variable_ports(dict(name = "A", description = "variable port A"))
>>> X._dump_variable_ports()
[{'name': 'A', 'description': 'variable port A'}]
Using a string (note that a description or default value cannot be specified):
>>> X = VariablePortedObject(name="X")
>>> X.add_variable_ports("A")
>>> X._dump_variable_ports()
[{'name': 'A', 'description': ''}]
Source code in psymple/build/abstract.py
PortedObjectWithAssignments(**kwargs)
Bases: PortedObject
Abstract class to hold common functionality of VariablePortedObject and FunctionalPortedObject. Cannot be instantiated directly.
Source code in psymple/build/abstract.py
VariablePortedObject(name, input_ports=[], variable_ports=[], assignments=[], create_output_ports=True, create_input_ports=True, parsing_locals={}, **kwargs)
Bases: PortedObjectWithAssignments
A ported object containing a collection of ODEs
(DifferentialAssignment
instances).
Each ODE is associated to a variable, which may or may not be exposed as a variable port. Symbols on the RHS of the ODE should be either:
- Variables defined in this ported object
- parameters that have corresponding input ports
- globally defined symbols
PARAMETER | DESCRIPTION |
---|---|
name
|
a string which must be unique for each
TYPE:
|
input_ports
|
list of input ports to expose. See add_input_ports.
TYPE:
|
variable_ports
|
list of variable ports to expose. See add_variable_ports.
TYPE:
|
assignments
|
list of differential assignments (ODEs). See add_variable_assignments
TYPE:
|
create_output_ports
|
if
TYPE:
|
create_input_ports
|
if
TYPE:
|
parsing_locals
|
a dictionary mapping strings to
TYPE:
|
**kwargs
|
arguments passed to super().init(). No user arguments should be supplied.
DEFAULT:
|
Notes
-
By default, each variable (dependent variable of each ODE) is automatically exposed as a variable port. Alternatively, chosen variables can be exposed by specifying them in the list variable_ports.
-
By default, each exposed variable will be mirrored in the creation of an output port with the same name. This output port reads the value of the variable.
-
Parameters listed in input_ports are exposed and can be used in ODE expressions.
-
If
create_input_ports=True
(default), then each symbol appearing in an ODE which is not a variable or parameter defined in input_ports is also exposed as a parameter input port. The created parameter will have no default value, and must be otherwise specified or linked by a wire in a parentCompositePortedObject
.
Source code in psymple/build/ported_objects.py
add_variable_assignments(*assignments, create_variable_ports=True, create_output_ports=True, create_input_ports=True)
Add variable assignments to self.
PARAMETER | DESCRIPTION |
---|---|
*assignments
|
data specifying a
TYPE:
|
create_variable_ports
|
if
TYPE:
|
create_output_ports
|
if
TYPE:
|
create_input_ports
|
if
TYPE:
|
RAISES | DESCRIPTION |
---|---|
ValueError
|
if an assignment with the same variable name is already defined in self |
Source code in psymple/build/ported_objects.py
compile(prefix_names=False, global_symbols=set())
Generate a CompiledPortedObject
with:
- input ports generated from the input ports of self
- variable ports exposing the variable and assignment of each assignment instance of self which have a corresponding variable port of self
- internal variable assignments for each assignment instance of self which do not have a corresponding variable port of self
- identity functional assignments at output ports corresponding to each exposed variable
PARAMETER | DESCRIPTION |
---|---|
prefix_names
|
if
TYPE:
|
global_symbols
|
symbols to pass to
TYPE:
|
Source code in psymple/build/ported_objects.py
to_data()
A dismantler method such that every instance X of VariablePortedObject
can be recreated by calling X.to_data().to_ported_object()
RETURNS | DESCRIPTION |
---|---|
data
|
a data object capturing the data of self
TYPE:
|
Source code in psymple/build/ported_objects.py
FunctionalPortedObject(name, input_ports=[], assignments=[], create_input_ports=True, parsing_locals={}, **kwargs)
Bases: PortedObjectWithAssignments
A PortedObject containing a multivariate function.
The function is defined by a set of
ParameterAssignment
instances.
The function arguments are the free symbols on the RHS of the assignments, and should be exposed as input ports. The function values are the LHS of the assignments, and are automatically exposed as output ports.
Function assignments whose expression references a parameter defined as the function value of another expression are not allowed.
PARAMETER | DESCRIPTION |
---|---|
name
|
a string which must be unique for each
TYPE:
|
input_ports
|
list of input ports to expose. See add_input_ports.
TYPE:
|
assignments
|
list of functional assignments. See add_parameter_assignments.
TYPE:
|
create_input_ports
|
if
TYPE:
|
parsing_locals
|
a dictionary mapping strings to
TYPE:
|
**kwargs
|
arguments passed to super().init(). No user arguments should be supplied.
DEFAULT:
|
Notes
-
The parameter of every created assignment is automatically exposed as an output port.
-
If
create_input_ports=True
(default), then each symbol appearing in a function which is not a parameter defined in input_ports is also exposed as a parameter input port. The created parameter will have no default value, and must be otherwise specified or linked by a wire in a parentCompositePortedObject
.
Source code in psymple/build/ported_objects.py
add_parameter_assignments(*assignments, create_input_ports=True)
Add parameter assignments to self.
PARAMETER | DESCRIPTION |
---|---|
*assignments
|
data specifying a
TYPE:
|
create_input_ports
|
if
TYPE:
|
RAISES | DESCRIPTION |
---|---|
ValueError
|
if an assignment with the same variable name is already defined in self |
ValueError
|
if an expression contains a symbol with no corresponding input port |
Source code in psymple/build/ported_objects.py
compile(prefix_names=False)
Generate a CompiledPortedObject
with:
- input ports generated from input ports of self
- output ports exposing the parameter and assignment of each assignment instance of self
PARAMETER | DESCRIPTION |
---|---|
prefix_names
|
if
TYPE:
|
Source code in psymple/build/ported_objects.py
to_data()
A dismantler method such that every instance X of VariablePortedObject
can be recreated by calling X.to_data().to_ported_object()
RETURNS | DESCRIPTION |
---|---|
data
|
a data object capturing the data of self
TYPE:
|
Source code in psymple/build/ported_objects.py
CompositePortedObject(name, children=[], input_ports=[], output_ports=[], variable_ports=[], variable_wires=[], directed_wires=[], parsing_locals={}, **kwargs)
Bases: PortedObject
A ported object containing other ported object instances whose ports are connected by directed wires and variable wires.
Directed wires
Directed wires connect:
- an input port of self to input ports of children, or,
- an output port of a child to input ports of children and/or upto one output port of self, or,
- a variable port of a child to input ports of children.
These wires capture functional composition. In the following example, a CompositePortedObject
instance
X
contains FunctionalPortedObject
instances A
and B
.
Object A
specifies the assignment \( x = f(y) \) and B
specifies the assignment \( r = g(u,v) \).
Connecting output port x
of A
(accessed by "A.x"
) to input port u
of B
(accessed by "B.u"
)
with a directed wire represents the composite assignment \( r = g(f(y), v) \).
Examples:
>>> from psymple.build import FunctionalPortedObject, CompositePortedObject
>>> A = FunctionalPortedObject(name="A", assignments=[("x", "f(y)")])
>>> B = FunctionalPortedObject(name="B", assignments=[("y", "g(u,v)")])
>>> X = CompositePortedObject(name="X", children=[A,B], directed_wires=[("A.x", "B.u")])
See add_wires
for the syntax to specify
directed wires.
Variable wires
Variable wires connect variable ports of children to upto one variable port of self.
These wires capture ODE aggregation:
ODE aggregation
The aggregation of the ODEs \( dx/dt = f(x,t,a) \) and \( dy/dt = g(y,t,b) \), identifying \( (x,y) \longrightarrow z \), is the ODE \( dz/dt = f(z,t,a) + g(z,t,b) \).
In the following example, a CompositePortedObject
instance X
contains
VariablePortedObject
instances A
and B
. Object
A
specifies the ODE \( dx/dt = f(x,t,a) \) and B
specifies the ODE \( dy/dt = g(y,t,b) \). Aggregating
variable port x
of A
(accessed by "A.x"
) and variable port y
of B
(accessed by "B.y"
) and
exposing at variable port z
of X
(identifying \( (x,y) \longrightarrow z \)) represents the
ODE \( dz/dt = f(z,t,a) + g(z,t,b) \).
Examples:
>>> from psymple.build import FunctionalPortedObject, CompositePortedObject
>>> A = FunctionalPortedObject(name="A", assignments=[("x", "f(x,t,a)")])
>>> B = FunctionalPortedObject(name="B", assignments=[("y", "g(y,t,b)")])
>>> X = CompositePortedObject(name="X", children=[A,B], variable_ports = ["z"], variable_wires=[(["A.x", "B.u"], "z")])
See add_wires
for the syntax to specify
directed wires.
Requirements
-
Every input port of self should be the source of at least one directed wire
-
Every output port of self must be the destination of exactly one directed wire
-
Every variable port of self must be the destination of at most one variable wire
-
Every input port of a child must either have a default value or a directed wire connected to it
-
Every output port of a child should have a directed wire going out of it
-
Every variable port of a child should have a variable wire connected to it
-
The directed wires should have no cycles (when contracting child ported objects into nodes of a graph)
PARAMETER | DESCRIPTION |
---|---|
name
|
a string which must be unique for each
TYPE:
|
children
|
list of children to add. See add_children.
TYPE:
|
input_ports
|
list of input ports to expose. See add_input_ports.
TYPE:
|
output_ports
|
list of output ports to expose. See add_output_ports.
TYPE:
|
variable_ports
|
list of variable ports to expose. See add_variable_ports.
TYPE:
|
variable_wires
|
list of variable wires to create. See add_wires.
TYPE:
|
directed_wires
|
list of directed wires to create. See add_wires.
TYPE:
|
parsing_locals
|
a dictionary mapping strings to
TYPE:
|
**kwargs
|
arguments passed to super().init(). No user arguments should be supplied.
DEFAULT:
|
Note
There is no automatic creation of ports in a CompositePortedObject
Source code in psymple/build/ported_objects.py
add_children(*children)
Add children to self
. A child is a PortedObject
instance whose ports and assignments
become available to self
.
PARAMETER | DESCRIPTION |
---|---|
*children
|
instance of
TYPE:
|
Source code in psymple/build/ported_objects.py
add_directed_wire(source_name, destination_names)
Add a directed wire to self.
PARAMETER | DESCRIPTION |
---|---|
source_name
|
a string identifying the source port
TYPE:
|
destination_names
|
a string or a list of strings identifying destination port(s)
TYPE:
|
RAISES | DESCRIPTION |
---|---|
WiringError
|
if the provided ports cannot be found or are of incorrect type. |
Note
It is recommended to use the add_wires method for additional entry options and to add multiple wires at the same time.
Source code in psymple/build/ported_objects.py
add_variable_wire(child_ports, parent_port=None, output_name=None)
Add a variable wire to self.
PARAMETER | DESCRIPTION |
---|---|
child_ports
|
a list of strings identifying variable ports to aggregate
TYPE:
|
parent_port
|
a string identifying the parent variable port of self to identify with
TYPE:
|
output_name
|
a string identifying the aggregation internally if a parent port is not specified.
TYPE:
|
RAISES | DESCRIPTION |
---|---|
WiringError
|
if the provided ports cannot be found or are of incorrect type. |
Note
It is recommended to use the add_wires method for additional entry options and to add multiple wires at the same time.
Source code in psymple/build/ported_objects.py
add_wires(variable_wires=[], directed_wires=[])
Add wires to self.
Variable wires aggregate a set of child variable ports, and either
- expose the result as a variable port of self, or,
- store the result internally.
Either a parent port or internal name must be provided. Specifying a parent port will override the internal name.
Directed wires connect
- an input port of self to input ports of children, or,
- an output port of a child to input ports of children and/or upto one output port of self, or,
- a variable port of a child to input ports of children.
PARAMETER | DESCRIPTION |
---|---|
variable_wires
|
a list of either:
TYPE:
|
directed_wires
|
a list of either:
TYPE:
|
RAISES | DESCRIPTION |
---|---|
ValidationError
|
if the provided data cannot be parsed correctly. |
Source code in psymple/build/ported_objects.py
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
|
compile(prefix_names=False)
Generate a CompiledPortedObject
with:
- input ports generated from input ports of self
- output ports generated from output ports of self, with assignments exposed by directed wires
- variable ports generated from variable ports of self, with assignments exposed by variable wires
- internal variable assignments generated from variable assignments of children not exposed to variable ports
- internal parameter assignments generated from parameter assignments of children not exposed to output ports
PARAMETER | DESCRIPTION |
---|---|
prefix_names
|
if
TYPE:
|
Source code in psymple/build/ported_objects.py
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 |
|
to_data()
A dismantler method such that every instance X of CompositePortedObject
can be recreated by calling X.to_data().to_ported_object()
RETURNS | DESCRIPTION |
---|---|
data
|
a data object capturing the data of self
TYPE:
|