#show_doc(BaseFunction.summary)
Functions
Overview
Each function outputs the result of applying the function logic and may be a scalar or array, depending on the input. The inputs are supplied as links to another function, from where the values are read. Unless the function is a simple case, such as a ‘Constant’.
Parameters are supplied as arguments to the constructor of the class.
All functions include the methods defined by the BaseFunction class.
HPCTFUNCTION
HPCTFUNCTION (value, names=None, module=None, qualname=None, type=None, start=1)
Types of control functions in a node.
Functions
BaseFunction
BaseFunction
BaseFunction (name=None, value=None, links=None, new_name=True, namespace=None)
Base class of a PCT function. This class is not used directly by developers, but defines the functionality common to all.
FunctionFactory
FunctionFactory ()
Initialize self. See help(type(self)) for accurate signature.
#show_doc(BaseFunction.get_config)
Subtract
Subtract
Subtract (value=0, name='subtract', links=None, new_name=True, namespace=None, **cargs)
A function that subtracts one value from another. Parameter: None. Links: Two links required to each the values to be subtracted.
Proportional
Proportional (gain=1, value=0, name='proportional', links=None, new_name=True, namespace=None, **cargs)
A proportion of the input value as defined by the gain parameter. Parameters: The gain value. Links: One.
Variable
Variable (value=0, name='variable', links=None, new_name=True, namespace=None, **cargs)
A function that returns a variable value. Parameter: The variable value. Links: None
PassOn
PassOn (value=0, name='variable', links=None, new_name=True, namespace=None, **cargs)
A function that passes on a variable value from a linked function. Parameter: None. Links: One
GreaterThan
GreaterThan (threshold=0, upper=1, lower=0, value=0, name='greaterthan', links=None, new_name=True, namespace=None, **cargs)
One of two supplied values is returned if the input is greater than supplied threshold.
Parameters: The threshold and upper and lower value. Links: One
Constant
Constant (value=0, name='constant', new_name=True, namespace=None, **cargs)
A function that returns a constant value. Parameter: The constant value. Links: None
Step
Step (upper=None, lower=None, delay=None, period=None, value=0, name='step', new_name=True, namespace=None, **cargs)
A function that returns an alternating signal. Parameter: The upper and lower values, and a delay value. Links: None
Integration
Integration (gain=1, slow=2, value=0, name='integration', links=None, new_name=True, namespace=None, **cargs)
A leaky integrating function. Equivalent of a exponential smoothing function, of the amplified input. Parameters: The gain and slow values. Links: One.
IntegrationDual
IntegrationDual (gain=1, slow=2, value=0, name='integration', links=None, new_name=True, namespace=None, **cargs)
A leaky integrating function, applying one signal to another. Equivalent of a exponential smoothing function, of the amplified input. Parameters: The gain and slow values. Links: Two.
Sigmoid
Sigmoid (range=2, slope=10, value=0, name='sigmoid', links=None, new_name=True, namespace=None, **cargs)
A sigmoid function. Similar to a proportional function, but kept within a limit (+/- half the range). Parameters: The range and slope values. Links: One.
WeightedSum
WeightedSum (weights=[0], value=0, name='weighted_sum', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that combines a set of inputs by multiplying each by a weight and then adding them up. Parameter: The weights array. Links: Links to all the input functions.
SmoothWeightedSum
SmoothWeightedSum (weights=[0], smooth_factor=0.0, value=0, name='smooth_weighted_sum', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that combines a set of inputs by multiplying each by a weight and then adding them up. And then smooths the result. Parameter: The weights array. Links: Links to all the input functions.
IndexedParameter
IndexedParameter (index=None, value=0, name='indexed_parameter', links=None, new_name=True, namespace=None, **cargs)
A function that returns a parameter from a linked function, indexed by number. Parameter: The index. Links: One.
SigmoidWeightedSum
SigmoidWeightedSum
SigmoidWeightedSum (weights=[0], range=2.0, slope=10.0, value=0, name='sigmoid_weighted_sum', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that combines a set of inputs by multiplying each by a weight and then adding them up. And then limits the output by squashing with a sigmoid function. Parameter: The weights array. Links: Links to all the input functions.
SigmoidSmoothWeightedSum
SigmoidSmoothWeightedSum
SigmoidSmoothWeightedSum (weights=[0], smooth_factor=0.0, range=2.0, slope=10.0, value=0, name='sigmoid_smooth_weighted_sum', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that combines a set of inputs by multiplying each by a weight and then adding them up. It then smooths the result and then limits the output by squashing with a sigmoid function. Parameter: The weights array. Links: Links to all the input functions.
Derivative
Derivative (history_length=1, value=0, name='derivative', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that provides the difference to previous values of the input signal. Parameter: The weights array. Links: Links to all the input functions.
DerivativeWeightedSum
DerivativeWeightedSum (weights=[0], history_length=1, value=0, name='derivative_weighted_sum', links=None, new_name=True, usenumpy=False, namespace=None, **cargs)
A function that combines a set of inputs by multiplying each by a weight and then adding them up. And then takes the difference of with a past value. Parameter: The weights array. Links: Links to all the input functions.
Usage
Creating Functions
Standard class constructor. Different ways to create a function with the standard constructor.
= Proportional()
prop print(prop.get_config())
= Proportional("myprop", 10)
prop print(prop.get_config())
= Proportional(gain=10)
prop print(prop.get_config())
{'type': 'Proportional', 'name': 'proportional', 'value': 0, 'links': {}, 'gain': 1}
{'type': 'Proportional', 'name': 'proportional', 'value': 10, 'links': {}, 'gain': 'myprop'}
{'type': 'Proportional', 'name': 'proportional', 'value': 0, 'links': {}, 'gain': 10}
Configuration class constructor. Create the function by passing a configuration structure to the constructor.
= Proportional(**{'name': 'myprop', 'value': 5, 'gain': 20})
prop print(prop.get_config())
{'type': 'Proportional', 'name': 'myprop', 'value': 5, 'links': {}, 'gain': 20}
Configuration class method. Create the function by passing a configuration structure to a class method.
= {'name': 'myprop', 'value': -0.5, 'gain': 21}
config = Proportional.from_config(config)
prop print(prop.get_config())
{'type': 'Proportional', 'name': 'myprop', 'value': -0.5, 'links': {}, 'gain': 21}
= Proportional()
prop print(prop.get_config())
= Proportional.from_config(prop.get_config())
prop1 print(prop1.get_config())
assert prop.get_config() == prop1.get_config()
{'type': 'Proportional', 'name': 'proportional', 'value': 0, 'links': {}, 'gain': 1}
{'type': 'Proportional', 'name': 'proportional', 'value': 0, 'links': {}, 'gain': 1}
An example showing creating a WeightedSum function.
=[1,1,1]
wts= WeightedSum(weights=wts)
ws = ws.namespace
ns 10, namespace=ns))
ws.add_link(Constant(5, namespace=ns))
ws.add_link(Constant(20, namespace=ns))
ws.add_link(Constant(assert ws() == 35
= ws.get_config() config
#ws1 = WeightedSum.from_config(config, namespace=ns)
= WeightedSum.from_config(config, new_name= 'weighted_sum1', namespace=ns)
ws1 ws1.get_config()
{'type': 'WeightedSum',
'name': 'weighted_sum1',
'value': 35,
'links': {0: 'constant', 1: 'constant1', 2: 'constant2'},
'weights': [1, 1, 1]}
= Constant(2, name='scons')
scons = Sigmoid()
sig
sig.add_link(scons) sig()
0.9999092042625952
= Constant([2,2], name='cons')
cons print(cons.output_string()+ "")
[2, 2]
Viewing Functions
View the details of the function with the “summary”, which prints the name, type, parameters, value and links (if any).
prop.summary()
proportional Proportional | gain 1 | 0
As already seen the function details can be seen by retrieving the configuration.
print(prop.get_config())
{'type': 'Proportional', 'name': 'proportional', 'value': 0, 'links': {}, 'gain': 1}
Or you can print the function.
print(prop)
{'namespace': UUID('6d28b227-62e7-11ef-87fe-5c879c15de65'), 'value': 0, 'links': [], 'checklinks': True, 'name': 'proportional', 'decimal_places': 3, 'gain': 1}
Set the decimal places for output display.
print(prop.output_string())
2)
prop.set_decimal_places(print(prop.output_string())
0.000
0.00
You can also view a function graphically as a network of connected nodes.
= Subtract(links=[Constant(1, name='cons'), Proportional(10, name='prop')], name='sub')
sub print(sub.value)
= sub.graph()
g print(g)
=2000) sub.draw(node_size
0
DiGraph with 3 nodes and 2 edges
Save and Load
Save a function to file.
import json
print(ws.get_config())
"ws.json") ws.save(
{'type': 'WeightedSum', 'name': 'weighted_sum', 'value': 35, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [1, 1, 1]}
Create a function from file.
= WeightedSum.load("ws.json", new_name='weighted_sum1', namespace=ns)
wss print(ws.get_config())
print(wss.get_config())
assert wss.get_config() == {'type': 'WeightedSum', 'name': 'weighted_sum2', 'value': 35, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [1, 1, 1]}
{'type': 'WeightedSum', 'name': 'weighted_sum', 'value': 35, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [1, 1, 1]}
{'type': 'WeightedSum', 'name': 'weighted_sum2', 'value': 35, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [1, 1, 1]}
Setting Links
The next cell shows how a link is added to one function from another. In this case from an Integration function to a Constant function. So, whenever “integrator” runs it will get its input from “cons”.
= Integration(3, 10)
integrator = Constant(5)
cons
integrator.add_link(cons)
integrator.summary()
= integrator()
output print(output)
assert output == 1.5
integration Integration | gain 3 slow 10 | 0 | links constant
1.5
# initialises the list of function names
UniqueNamer.getInstance().clear() = Integration(**{'name': 'myinteg', 'value': 1, 'gain': 20, 'slow': 100})
integ = Proportional(5, name="myprop")
prop
integ.add_link(prop)print(integ.get_config())
assert integ.get_config() == {'type': 'Integration', 'name': 'myinteg', 'value': 1, 'links': {0: 'myprop'}, 'gain': 20, 'slow': 100}
{'type': 'Integration', 'name': 'myinteg', 'value': 1, 'links': {0: 'myprop'}, 'gain': 20, 'slow': 100}
You can also define the link when you create the function, as in this example with “Proportional”.
= Constant(1, name='const')
const = const.namespace
ns print(const())
= Proportional(name='pr1', links=const, namespace=ns)
pr1
pr1.summary()assert pr1() == 1
1
pr1 Proportional | gain 1 | 0 | links const
It can be the name of the linked function.
= Proportional(gain=10, name='pr', links='const', namespace=ns)
pr
pr.summary()assert pr() == 10
print(pr())
pr Proportional | gain 10 | 0 | links const
10
Or it can be a list of names.
= Subtract(links=[ 'pr', 'const'], namespace=ns)
sub print(sub.get_config())
print(const())
print(pr())
print(pr())
sub.summary()print(sub())
assert sub()==9
{'type': 'Subtract', 'name': 'subtract', 'value': 0, 'links': {0: 'pr', 1: 'const'}}
1
10
10
subtract Subtract | 0 | links pr const
9
Running a Fucntion
A function can simply be run by calling it, without any parameters. It will use whatever input was set by the links. It returns the result of the function. In this example it will be 5 * 3 / 10, that is, input * gain / slow.
= sub()
out print(out)
9
A function can be also run in a loop with the run() method and provided the loop count.
= Integration(gain=3, slow=10)
integrator
integrator.add_link(sub)= integrator.run(steps=10, verbose=True) o
2.700 5.130 7.317 9.285 11.057 12.651 14.086 15.377 16.540 17.586
=True) integrator(verbose
18.527
18.527113905569998
= integrator()
output print(output)
#assert output == 1.5
19.374402515013) npt.assert_almost_equal(output,
19.374402515013
print(integrator.get_config())
{'type': 'Integration', 'name': 'integration', 'value': 19.374402515013, 'links': {0: 'subtract'}, 'gain': 3, 'slow': 10}
An example showing creating and running a sigmoid WeightedSum function.
=[0.01,0.01,0.01]
wts= SigmoidWeightedSum(weights=wts, range=1.0, slope=5.0)
sgws = sgws.namespace
ns 10, namespace=ns))
sgws.add_link(Constant(5, namespace=ns))
sgws.add_link(Constant(20, namespace=ns))
sgws.add_link(Constant(
sgws.summary()print(sgws.get_parameters_list())
= sgws()
out print(out)
assert out == 0.3519528019683106
sigmoid_weighted_sum SigmoidWeightedSum | weights [0.01, 0.01, 0.01] range 1.00 slope 5.00 | 0 | links constant constant1 constant2
[[0.01, 0.01, 0.01], 1.0, 5.0]
0.3519528019683106
An example showing creating and running a sigmoid smooth WeightedSum function.
=[0.01,0.01,0.01]
wts= SigmoidSmoothWeightedSum(weights=wts, smooth_factor=0.9)
sgsmws = sgsmws.namespace
ns 10, namespace=ns))
sgsmws.add_link(Constant(5, namespace=ns))
sgsmws.add_link(Constant(20, namespace=ns))
sgsmws.add_link(Constant(
sgsmws.summary()print(sgsmws.get_parameters_list())
print(sgsmws.get_graph_name())
= {}
labels
sgsmws.get_weights_labels_funcdata(labels)print('wts labels',labels)
for _ in range(5):
# print(sgsmsm())
= sgsmws()
out print(out)
0.34373448930708195) npt.assert_almost_equal(out,
sigmoid_smooth_weighted_sum SigmoidSmoothWeightedSum | weights [0.01, 0.01, 0.01] smooth 0.90 range 2.00 slope 10.00 | 0 | links constant constant1 constant2
[[0.01, 0.01, 0.01], 0.9, 2.0, 10.0]
sigmoid_smooth_weighted_sum
0.90:2.00|10.00
wts labels {('sigmoid_smooth_weighted_sum\n0.90:2.00|10.00', 'constant\n10.00'): '0.01', ('sigmoid_smooth_weighted_sum\n0.90:2.00|10.00', 'constant1\n5.00'): '0.01', ('sigmoid_smooth_weighted_sum\n0.90:2.00|10.00', 'constant2\n20.00'): '0.01'}
0.08727737447415773
0.16473508145615878
0.23277835967904958
0.2921474527779875
0.34373448930708195
An example showing creating and running a smoothed WeightedSum function.
=[1.0,1.0,1.0]
wts=[0.01,0.01,0.01]
wts= SmoothWeightedSum(weights=wts, smooth_factor=0.9)
smws = smws.namespace
ns 10, namespace=ns))
smws.add_link(Constant(5, namespace=ns))
smws.add_link(Constant(20, namespace=ns))
smws.add_link(Constant(
smws.summary()print(smws.get_parameters_list())
print(smws.get_graph_name())
for _ in range(5):
= smws()
out print(out)
0.1433285) npt.assert_almost_equal(out,
smooth_weighted_sum SmoothWeightedSum | weights [0.01, 0.01, 0.01] smooth 0.90 | 0 | links constant constant1 constant2
[[0.01, 0.01, 0.01], 0.9]
smooth_weighted_sum
0.90
0.034999999999999996
0.0665
0.09485
0.120365
0.1433285
An example showing creating and running a derivative function.
= Derivative(history_length=5)
dv = dv.namespace
ns = Constant(10, namespace=ns)
cons
dv.add_link(cons)
dv.summary()print(dv.get_config())
print(dv.get_parameters_list())
print(dv.get_graph_name())
= {}
labels
dv.get_weights_labels(labels)print(labels)
for i in range(20):
*i)
cons.set_value(i= dv()
out print(out, end=" ")
print()
assert out == -136
print(dv.history)
assert dv.history == [225, 256, 289, 324, 361]
derivative Derivative | history_length 5 | 0 | links constant
{'type': 'Derivative', 'name': 'derivative', 'value': 0, 'links': {0: 'constant'}, 'history_length': 5}
[5]
derivative
5.00
{}
0 -1 -4 -9 -16 -24 -32 -40 -48 -56 -64 -72 -80 -88 -96 -104 -112 -120 -128 -136
[225, 256, 289, 324, 361]
An example showing creating a derivative WeightedSum function.
=[0.01,0.01,0.01]
wts= DerivativeWeightedSum(weights=wts, history_length=5)
dvws = dvws.namespace
ns = Constant(10, namespace=ns)
cons
dvws.add_link(cons)
#dvws.add_link(Constant(10, namespace=ns))
5, namespace=ns))
dvws.add_link(Constant(20, namespace=ns))
dvws.add_link(Constant(
dvws.summary()print(dvws.get_config())
print(dvws.get_parameters_list())
print(dvws.get_graph_name())
= {}
labels
dvws.get_weights_labels(labels)print(labels)
for i in range(20):
*i)
cons.set_value(i= dvws()
out print(out, end=" ")
print()
-1.3599999999999999)
npt.assert_almost_equal(out, print(dvws.history)
assert dvws.history == [2.5, 2.81, 3.14, 3.49, 3.86]
derivative_weighted_sum DerivativeWeightedSum | weights [0.01, 0.01, 0.01] history_length 5 | 0 | links constant constant1 constant2
{'type': 'DerivativeWeightedSum', 'name': 'derivative_weighted_sum', 'value': 0, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [0.01, 0.01, 0.01], 'history_length': 5}
[[0.01, 0.01, 0.01], 5]
derivative_weighted_sum
5
{('derivative_weighted_sum', 'constant'): '0.01', ('derivative_weighted_sum', 'constant1'): '0.01', ('derivative_weighted_sum', 'constant2'): '0.01'}
0.0 -0.010000000000000009 -0.040000000000000036 -0.09000000000000002 -0.16000000000000003 -0.24 -0.31999999999999995 -0.39999999999999997 -0.4800000000000001 -0.56 -0.64 -0.72 -0.7999999999999998 -0.8799999999999999 -0.96 -1.04 -1.12 -1.2000000000000002 -1.2800000000000002 -1.3599999999999999
[2.5, 2.81, 3.14, 3.49, 3.86]
=[0.01,0.01,0.01]
wts= DerivativeWeightedSum(weights=wts, history_length=0)
dvws = dvws.namespace
ns = Constant(10, namespace=ns)
cons
dvws.add_link(cons)5, namespace=ns))
dvws.add_link(Constant(20, namespace=ns))
dvws.add_link(Constant(
dvws.summary()print(dvws.get_config())
print(dvws.get_parameters_list())
print(dvws.get_graph_name())
= {}
labels
dvws.get_weights_labels(labels)print(labels)
for i in range(20):
*i)
cons.set_value(i= dvws()
out print(out, end=" ")
print()
3.86) npt.assert_almost_equal(out,
derivative_weighted_sum DerivativeWeightedSum | weights [0.01, 0.01, 0.01] history_length 0 | 0 | links constant constant1 constant2
{'type': 'DerivativeWeightedSum', 'name': 'derivative_weighted_sum', 'value': 0, 'links': {0: 'constant', 1: 'constant1', 2: 'constant2'}, 'weights': [0.01, 0.01, 0.01], 'history_length': 0}
[[0.01, 0.01, 0.01], 0]
derivative_weighted_sum
0
{('derivative_weighted_sum', 'constant'): '0.01', ('derivative_weighted_sum', 'constant1'): '0.01', ('derivative_weighted_sum', 'constant2'): '0.01'}
0.25 0.26 0.29000000000000004 0.34 0.41000000000000003 0.5 0.61 0.74 0.8900000000000001 1.06 1.25 1.46 1.69 1.94 2.21 2.5 2.81 3.14 3.49 3.86
Examples
Configuration
Create a function from the configuration of another.
= Integration(3, 10)
integrator =integrator.namespace
ns= Constant(5, namespace=ns)
cons
integrator.add_link(cons)= integrator.get_config()
config = Integration.from_config(config, new_name='integration1', namespace=ns)
inte print(inte())
= {'type': 'Integration', 'name': 'integration1', 'value': 1.5, 'links': {0: 'constant'}, 'gain': 3, 'slow': 10}
target print(target)
assert inte.get_config() == target
1.5
{'type': 'Integration', 'name': 'integration1', 'value': 1.5, 'links': {0: 'constant'}, 'gain': 3, 'slow': 10}