AnabridREDAC
Documentation for AnabridREDAC.
Introduction
AnabridREDAC uses REDACProtocol to communicate with a network connected REDAC and is able to send a configuration for the analog components which when executed solve a differential equation and get a sampled solution back from the analog. AnabridREDAC also defines the compontents of the analog computer.
Usage
host = "lucidac-147476.ulm.anabrid.net"
port = 5732
using AnabridREDAC, Plots
RR = RemoteREDAC2(host,port)
RC = REDACConfig(
AnabridREDAC.MIntBlock([AnabridREDAC.Integration(i*0.1,10000) for i in 1:8]),
AnabridREDAC.MMulBlock(),
AnabridREDAC.UBlock(nothing, [(i%8)+8 for i in 0:31]),
AnabridREDAC.CBlock([ifelse(i<1,0.,-0.5) for i in 1:32]),
AnabridREDAC.IBlock([ifelse(i<9, missing, [i]) for i in 0:15])
)
data, time = run_remotely(RR,RC)
plot(time, data)Analog calculation components
An analog computer is a network of calculating elements. Our network has a particular topology. Summed signals are processed by Integration or Multiplication. The results are then cloned, scaled and summed up again thus fed back into Integration or Multiplication.
Integration
The REDAC analog computer can integrate the summed signals 8 through 15. This enables us to solve to differential equations by feeding back the integrated signal into the input.
function integration(sum8,sum9,sum10,sum11,sum12,sum13,sum14,sum15)
return integrate(sum8/MINTBlock.outputs[1].k; ic=MINTBlock.outputs[1].ic), ... , integrate(sum15/MINTBlock.outputs[8].k; ic=MINTBlock.outputs[8].ic)
endAnabridREDAC.Integration — Typestruct Integrationic::Float64k::Int64
Representation of one Integrator on the REDAC solving
$x(t) = ic + \int_{t_0}^t \frac{\dot x (\tau)}{k} d\tau$ Integrators are restricted to take values between -1 and +1. This is called a machine unit.
The REDAC has a MINTBlock which contains all 8 Integrators
AnabridREDAC.MIntBlock — TypeThe MMIntBlock can either be build using an Array of 8 Integrator objects or an IntegratorConfig object.
AnabridREDAC.IntegratorConfig — TypeRepresent the state of MInt Block which contains 8 Integrators indexed. This allows for sparsely changing some.
struct IntegratorConfig1::Union{Missing, AnabridREDAC.Integration}2::Union{Missing, AnabridREDAC.Integration}3::Union{Missing, AnabridREDAC.Integration}4::Union{Missing, AnabridREDAC.Integration}5::Union{Missing, AnabridREDAC.Integration}6::Union{Missing, AnabridREDAC.Integration}7::Union{Missing, AnabridREDAC.Integration}8::Union{Missing, AnabridREDAC.Integration}
Lets assume we want to solve a Lotka-Volterra model where the second integrator is used for the prey population with an initial population of 0.1 and the seventh integrator is used for the preditor population with an initial population of 0.05. We choose 1/10000 to make the ODE run slower.
AnabridREDAC.MIntBlock(
[
AnabridREDAC.Integration(0.,10000),
AnabridREDAC.Integration(0.2,10000),
AnabridREDAC.Integration(0.,10000),
AnabridREDAC.Integration(0.,10000),
AnabridREDAC.Integration(0.,10000),
AnabridREDAC.Integration(0.,10000),
AnabridREDAC.Integration(0.05,10000),
AnabridREDAC.Integration(0.,10000),
])Multiplication
The Multiplication block has no configuration it operates on the the summed signals 0 through 7. Consider this pseudocode.
function multiplication(sum0,sum1,sum2,sum3,sum4,sum5,sum6,sum7)
return sum0*sum1, sum2*sum3, sum4*sum5, sum6*sum7,1,1,1,1
endIt returns 4 products and a constant 4 times. The result of a network of self contained multipliers is undefined.
Linear operations
The output of the multiplication (0, ..., 7) and integration (8, ..., 15) can be copied into one of 32 signals for scalin, scaled and then summed up.
Duplicating signals
To clone or duplicate signals we use the UBlock.
AnabridREDAC.UBlock — TypeThe UBlock represents how signals are cloned. It can map any single of the 8 signals from the multiplier (available as 0, ..., 7) and any single of the 8 signals from the integrator (available as 8, ..., 15) to any of the 32 cloned signals. Should you want a cloned signal to not be used use missing. The alt signals are not implemented and subject to change in future designs.
In addition the cloned signals 8, ..., 15 can be recorded using and ADC returned to us as measurements. Only the cloned signals 8, ... , 15 can be recorded. The number of recorded channels must be a power of 2 and always starts at channel 8.
If we want to record the output of the first and last multiplier and the second and seventh integrator into the first 4 channels our configuration would look like:
AnabridREDAC.UBlock(nothing,
[
nothing,nothing,nothing,nothing, nothing,nothing,nothing,nothing,
0, 3, 9, 14, nothing,nothing,nothing,nothing,
nothing,nothing,nothing,nothing, nothing,nothing,nothing,nothing,
nothing,nothing,nothing,nothing, nothing,nothing,nothing,nothing
]
)The integrators have 1 input each while the multiplier have two inputs each. Thus we need 6 summed signals for that we need more atleast 6 things to sum over. Thus this configuration is not sensible.
AnabridREDAC.UBlock(nothing,
[
nothing,nothing,nothing,nothing, 6, 6,nothing,nothing,
0, 3, 9, 14, nothing,nothing,nothing,nothing,
0,nothing, 9, 14, nothing,nothing,nothing,nothing,
nothing,nothing, 9, 14, nothing,nothing,nothing,nothing
]
)The 5th output of a multiplier is a constant, thus cloned signals 4 and 5 can be set to be any constant even while they are fed by the same constant (6). We also created a second copy of a multiplier and 2 additional copies of the integrators.
Scaling signals
Only cloned signals can be scaled.
AnabridREDAC.CBlock — TypeRepresent the configuration of the scaling "coefficient" CBlock. There are 32 coefficients either passed as an Array of Missings and Floats or as CBlockElements struct.
struct CBlockelements::Union{AnabridREDAC.CBlockElements, Vector{Float64}}
AnabridREDAC.ScalarMultiplicationElement — TypeCan multiply a cloned signal by some value between -20 and 20 the results is available as scaled signal of the same number. Values between -2 and 2 and increased better precision.
struct ScalarMultiplicationElementfactor::Float64
Let's scale our example like this.
AnabridREDAC.CBlock(
[
0. , 0. , 0. , 0. , 0.5,-1. , 0. , 0. ,
0.3, 0. , 0.4,-0.2, 0. , 0. , 0. , 0. ,
-0.3, 0. , 1. , 1. , 0. , 0. , 0. , 0. ,
0. , 0. , 1. , 1. , 0. , 0. , 0. , 0. ,
]
)We masked of one multiplier and the second multiplier is scaled with -0.3 and 0.3. We have the constants 0.3 and -1 available. The integrators are available unchanged 2 times each and the cloned signal of the output of the second integrator is scaled by 0.4 while the seventh integrator is scaled by -0.2.
Summing signals
Only scaled signals can be summed. Scaled signal can only appear in one sum.
AnabridREDAC.IBlock — Typestruct IBlockoutputs::Union{AnabridREDAC.IBlockElements, Vector{Union{Missing, Vector{Int64}}}}
To see how to configure the IBlock for a Lotka-Volterra equation lets study the equation structure. Let y be the prey population and r the preditor population.
\[\dot y(t) = +\alpha y(t) -\beta y(t) r(t) \\ \dot r(t) = -\delta r(t) +\varepsilon y(t) r(t)\]
We will use the other mulitplier to calculate this non-sense
\[(y(t)+0.5) (r(t)-1.)\]
Since we have two copies of the first multiplier with different sign this is our product $y(t) r(t)$. Thus we need to feed our states $y(t), r(t)$ in to the multiplier block by making them the 0th and 1st summed signal respectively. The two middle multipliers go unused.
AnabridREDAC.IBlock(
[
[18],[19],
missing,missing,
missing,missing,
....
]
)The other multiplier should calculate the non-sense term. We only use the second multiplier for prey and the seventh multiplier for the preditor population.
AnabridREDAC.IBlock(
[ #Multipliers
[18],[19], ## y(t), r(t)
missing,missing,
missing,missing,
[4,18+8], [5,19+8], ## (0.5 +y(t)), (-1+r(t))
# Integrators
missing,
[10,16], ## 0.4*y(t) + -0.3*y(t)*r(t)
missing,
missing,
nothing,
nothing,
[11,8], ## -0.2*r(t) + 0.3*y(t)*r(t)
nothing
]
)Scaling differential equations
We should measure the outputs: [y(t)*r(t), (y(t)+0.5)*(r(t)-1.), y(t), r(t)] however we did not consider scaling our differential equations so that it remains between -1 and 1. The output will look very different.
All docs
AnabridREDAC.AbstractResourcesAnabridREDAC.CBlockAnabridREDAC.CBlockElementsAnabridREDAC.IBlockAnabridREDAC.IBlockElementsAnabridREDAC.IntegrationAnabridREDAC.IntegratorConfigAnabridREDAC.MIntBlockAnabridREDAC.MMulBlockAnabridREDAC.MatchTypeClientREDACAnabridREDAC.MatchTypeHcREDACAnabridREDAC.REDACConfigAnabridREDAC.ScalarMultiplicationElementAnabridREDAC.UBlockAnabridREDAC.processAnabridREDAC.process
AnabridREDAC.AbstractResources — TypeAbstractResourcesAn abstract type to collect different types of resources. Examples of resources are entities. Resources might be reserved. Whether resources can be paritially reserved in unclear. Resources are indentified by some kind of identifier. Acutally i can't think of any reason to have non reserved resources or setting of configuation should be an option which requires authenitcation. "A tree-like dictionary structure" is really vague but that is the most specificity we have in the python docs.
AnabridREDAC.CBlockElements — TypeRepresent the configuration of Scalar Multiplication Block which contains 32 ScalarMultiplicationElements. This allows for sparsely changing some.
struct CBlockElements1::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}2::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}3::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}4::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}5::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}6::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}7::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}8::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}9::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}10::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}11::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}12::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}13::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}14::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}15::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}16::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}17::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}18::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}19::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}20::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}21::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}22::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}23::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}24::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}25::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}26::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}27::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}28::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}29::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}30::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}31::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}32::Union{Missing, AnabridREDAC.ScalarMultiplicationElement}
AnabridREDAC.IBlockElements — TypeRepresent the configuration of Summing IBlock which defines a how the scaled outputs are summed up. At the moment each scaled output can only appear in one sum. [[0,1],[2,4]] means the first signal is the sum the output of the 0th and 1st scaled signal and the second signal is the sum of the 2nd and 4th scaled output.
struct IBlockElements1::Union{Missing, Vector{Int64}}2::Union{Missing, Vector{Int64}}3::Union{Missing, Vector{Int64}}4::Union{Missing, Vector{Int64}}5::Union{Missing, Vector{Int64}}6::Union{Missing, Vector{Int64}}7::Union{Missing, Vector{Int64}}8::Union{Missing, Vector{Int64}}9::Union{Missing, Vector{Int64}}10::Union{Missing, Vector{Int64}}11::Union{Missing, Vector{Int64}}12::Union{Missing, Vector{Int64}}13::Union{Missing, Vector{Int64}}14::Union{Missing, Vector{Int64}}15::Union{Missing, Vector{Int64}}16::Union{Missing, Vector{Int64}}
AnabridREDAC.MMulBlock — TypeThe MMulBlock has no parameters.
AnabridREDAC.MatchTypeClientREDAC — TypeUsing this constant as matchtype enables to parse the JSON arriving at the Client to the correct Julia types for teh REDAC harware.
AnabridREDAC.MatchTypeHcREDAC — TypeUsing this constant as matchtype enables to parse the JSON arriving at the Hybridcontroller to the correct Julia types for teh REDAC harware.
AnabridREDAC.REDACConfig — TypeREDAC configuration object defining both initial condition via MIntBlock and the differential equation to be solved. REDACConfig(MIntBlock, MMulBlock, UBlock, CBlock, IBlock)
AnabridREDAC.process — Methodprocess(RR::RemoteREDAC2, env::MatchType)Unpacks the envelope and process that into the channel waiting for that reply. Then all references to the conversation with _id are deleted. The channel is closed. This behaviour can be changed for particular Envelope{MsgType}, in case we want to add messages which can recieve multiple replies later.
AnabridREDAC.process — Methodprocess(RR::RemoteREDAC2, c::Channel, msg)msg is put in Channel c. However specialising the function signature on msg allows changing the what computations will be performed before the msg is done. This is useful for some real time processing required for Pong