Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Cutoff protocol, related synchronization communication tags, and general Improvements to protocol stability #120

Merged
merged 103 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 90 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
ad650ed
initial changes to the way tags are stored
ba2tro Apr 15, 2024
242024e
Revert "initial changes to the way tags are stored"
ba2tro Apr 17, 2024
dcbedeb
make the internals compatible with dictionary for query and tagging
ba2tro May 1, 2024
dedfb55
Merge branch 'QuantumSavory:master' into tag_time
ba2tro May 1, 2024
7266af1
Merge branch 'tag_time' of https://github.com/Abhishek-1Bhatt/Quantum…
ba2tro May 1, 2024
42342a3
fix typo
ba2tro May 1, 2024
1935828
Complete missing `querydelete!` tests
ba2tro May 2, 2024
c1aa85d
simplify tests
ba2tro May 2, 2024
1c49cd8
Fixes to doctests
ba2tro May 3, 2024
f847609
fix
ba2tro May 3, 2024
f82afbe
apply suggestions from code review
ba2tro May 4, 2024
b702261
update test_tags_and_queries.jl
ba2tro May 4, 2024
13c7a05
use `_querydelete` for both registers and refs
ba2tro May 8, 2024
b9481d6
Version bump for breaking release
ba2tro May 8, 2024
691911f
some more refinement on query interface
ba2tro May 8, 2024
6827364
update queries.jl
ba2tro May 8, 2024
0900da9
Update queries.jl
ba2tro May 8, 2024
f606f1b
Merge branch 'QuantumSavory:master' into tag_time
ba2tro May 15, 2024
0540e90
Apply suggestions from code review
ba2tro May 16, 2024
a897ede
added repeater grid example and started how-to tutorial with animation
ba2tro Feb 21, 2024
4f90800
use only horizontal and vertical paths
ba2tro Mar 11, 2024
664d54a
complete the how to section
ba2tro Mar 31, 2024
8d9aeb2
Update repeatergrid.md
ba2tro Mar 31, 2024
f57edc5
fixes
ba2tro Apr 3, 2024
4f0e2ee
a bit more inline comments and set number of rounds to infinite
Krastanov Apr 16, 2024
cacaeb6
add entanglement consumer to the grid example
Krastanov Apr 16, 2024
6cdef72
edits for clarity and style in repeatergrid.md
Krastanov Apr 16, 2024
a220671
Add changes from code review
ba2tro May 3, 2024
67b0fd4
Update repeatergrid.jl
ba2tro May 3, 2024
e9103f2
Update Project.toml
ba2tro May 8, 2024
fd9fe4f
make the internals compatible with dictionary for query and tagging
ba2tro May 1, 2024
2ca4871
make the protcols aware of decoherence and continue the documentation…
ba2tro May 19, 2024
0d279e2
Set default retention time to so that we don't break the existing tests
ba2tro May 20, 2024
fae8306
Use retention time in tests
ba2tro May 20, 2024
b6ef8aa
findfreeslot returns true when slot guid is -1(default) which only ha…
ba2tro May 20, 2024
3f176af
revert change made for debugging
ba2tro May 20, 2024
b45d731
Merge branch 'master' into deadlocks
ba2tro May 21, 2024
f622124
Add decoherence protocol with asynchronous messaging
ba2tro Jun 1, 2024
7ef0172
Some leftover cleanup from previous style of code
ba2tro Jun 1, 2024
eb2f96d
synchronous mode for decoherence protocol
ba2tro Jun 1, 2024
6653db5
Separate Swappers based on the use of DecoherenceProt, and fix naming…
ba2tro Jun 3, 2024
e3682cf
typo
ba2tro Jun 3, 2024
7d67e76
Completely rename SwapperProt to SwapperKeeper
ba2tro Jun 3, 2024
7f7ee20
Fix merge conflicts
ba2tro Jun 3, 2024
d31c72a
Fix a little mess from yesterday's merge
ba2tro Jun 4, 2024
98cded5
more fixes and cleanup
ba2tro Jun 4, 2024
7961189
fix
ba2tro Jun 4, 2024
afc200c
Apply changes from code review
ba2tro Jun 11, 2024
fbdeb5c
Merge branch 'QuantumSavory:master' into deadlocks
ba2tro Jun 11, 2024
39dbbfd
renamed example files
ba2tro Jun 11, 2024
7eda00e
fix
ba2tro Jun 12, 2024
fa64154
More logic for delete-swap-swap case
ba2tro Jun 17, 2024
8c52609
typo in file name
ba2tro Jun 17, 2024
c591f64
More work on requested changes
ba2tro Jun 18, 2024
35736de
more fixes
ba2tro Jun 18, 2024
948ec3c
fix
ba2tro Jun 18, 2024
df969cf
fix for docs
ba2tro Jun 18, 2024
3c6f201
docs fix?
ba2tro Jun 18, 2024
5a951e7
Merge branch 'master' into deadlocks
ba2tro Jun 20, 2024
be46b21
fix
ba2tro Jun 20, 2024
6a1a66e
change in naming convention
ba2tro Jun 20, 2024
49bbfa8
Merge branch 'master' into deadlocks
Krastanov Jul 2, 2024
aa8ded3
a bit more inline comments for protocolzoo.jl
Krastanov Jul 3, 2024
9cda39c
simplify SwapperProt
Krastanov Jul 3, 2024
2f205b7
undo spurious whitespace changes to make the git history easier to skim
Krastanov Jul 3, 2024
63b5bff
undo deleted plot (for now, to delete again if tests still fail)
Krastanov Jul 3, 2024
de5cf6e
cutoff protocol comment updates and type parameterization
Krastanov Jul 3, 2024
ebb3cbd
minor cleanup of examples
Krastanov Jul 3, 2024
d6d487b
some notes for the new queries isassigned error
Krastanov Jul 3, 2024
62ca174
update CHANGELOG
Krastanov Jul 3, 2024
5d26084
Apply noise to qubtis
ba2tro Jul 2, 2024
958bd05
fix1 for race condition
ba2tro Jul 4, 2024
46eb0a4
Why does this work?
ba2tro Jul 4, 2024
8d0f1e4
Add new visualizations and edit readme
ba2tro Jul 11, 2024
ac0c27d
typos
ba2tro Jul 11, 2024
6fee642
typo
ba2tro Jul 11, 2024
86e7176
move timeout before unlock
ba2tro Jul 17, 2024
eb92e47
Rerun CI?
ba2tro Jul 18, 2024
f04c2fe
fix
ba2tro Jul 23, 2024
fdfc868
Some touches to the visualization code, correction in avg fidelity ex…
ba2tro Jul 26, 2024
04ae501
comment out offending code in docs, add type annotation in isolderthan
ba2tro Jul 30, 2024
b85870d
bump jet lower bound
ba2tro Jul 31, 2024
870ccd1
docs fix
ba2tro Aug 10, 2024
31b7d71
fix commenting in visualizations.md
ba2tro Aug 10, 2024
48ba2cd
remove nsubsystems(Nothing)
ba2tro Aug 10, 2024
55062c2
undo previous experimental commit
ba2tro Aug 10, 2024
8f25b9e
Merge branch 'master' into deadlocks
ba2tro Aug 12, 2024
43d42b2
add new tests, bump jet count again after merging master
ba2tro Aug 19, 2024
bb0d81a
add cutoffprot tests to runtests
ba2tro Aug 20, 2024
02aa5d1
use record instead of a for loop in congestionchain example
ba2tro Aug 21, 2024
9384485
docs and changelog and version bump
Krastanov Sep 5, 2024
e30e385
Merge branch 'master' into deadlocks
Krastanov Sep 5, 2024
8945686
fix the documentation example
Krastanov Sep 5, 2024
367442a
undo SProjector removal now that it is public again
Krastanov Sep 5, 2024
f603dfa
misc cleanup, adding TODOs, and renaming
Krastanov Sep 5, 2024
5d8d0dd
cleanup of the example files
Krastanov Sep 6, 2024
edebdbe
minor subjective stylistic changes to doc file
Krastanov Sep 6, 2024
1ab540b
doc fix
Krastanov Sep 6, 2024
892651e
shorten the repeatergrid demos, they take much too long during tests
Krastanov Sep 6, 2024
b56c53e
env variable name fixup for repeatergrid example
Krastanov Sep 6, 2024
fabc5eb
shorten repeatergrid demos even more
Krastanov Sep 6, 2024
3b273d8
fix the freakin doc building failure... gosh this was staring us in t…
Krastanov Sep 6, 2024
a56e783
make autolims in examples/congestionchain more resilient
Krastanov Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# News

## v0.5.0 - 2024-08-11

## v0.5.0 - 2024-08-11
- Develop `CutoffProt` to deal with deadlocks in a simulation
- Expand `SwapperProt` with `agelimit` to permit cutoff policies (with `CutoffProt`)
- Tutorial and interactive examples for entanglement distribution on a grid with local-only knowledge
- `observable` now takes a default value as a kwarg, i.e., you need to make the substitution `observable(regs, obs, 0.0; time)` ↦ `observable(regs, obs; something=0.0, time)`
- Bump QuantumSymbolics and QuantumOpticsBase compat bound and bump julia compat to 1.10.

Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ push!(LOAD_PATH,"../src/")
using Documenter
using DocumenterCitations
using QuantumSavory
using QuantumSavory.ProtocolZoo
Krastanov marked this conversation as resolved.
Show resolved Hide resolved

DocMeta.setdocmeta!(QuantumSavory, :DocTestSetup, :(using QuantumSavory); recursive=true)

Expand Down
167 changes: 167 additions & 0 deletions docs/src/howto/repeatergrid/repeatergrid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# [Entanglement Generation On A Repeater Grid](@id Entanglement-Generation-On-A-Repeater-Grid)

```@meta
DocTestSetup = quote
using QuantumSavory
end
```

This section provides a detailed walkthrough of how QuantumSavory.jl can be used to simulate entanglement generation on a network of repeaters where each repeater relies only on local knowledge of the network.

For this example, we consider a square grid topology in which each node is connected to its nearest neighbors.
The registers act as repeater nodes. The nodes on the diagonal corners are Alice and Bob, the two special nodes that the network is trying to entangle through generating link-level entanglement at each edge and performing appropriate swaps at each node.

The goal is to establish entanglement between Alice and Bob by routing entanglement through any of the possible paths (horizontal or vertical) formed by local entanglement links and then swapping those links by performing entanglement swaps.

This employs functionality from the `ProtocolZoo` module of QuantumSavory to run the following Quantum Networking protocols:

- [`EntanglerProt`](@ref): Entangler protocol to produce link level entanglement at each edge in the network

- [`SwapperProt`](@ref): Swapper protocol runs at each node except at the Alice and Bob nodes, to perform swaps. The swaps are performed only if a query deems them useful for propagating entanglement closer and closer to Alice and Bob.

- [`EntanglementTracker`](@ref): Entanglement Tracker protocol to keep track of/and update the local link state-classical knowledge by querying for "entanglement update" messages generated by the other protocols (`SwapperProt` & `CutoffProt` specifically).

- [`CutoffProt`](@ref): As the simulation progresses, the unused entangled pairs generated by `EntanglerProt` need to be discarded due to the loss of fidelity under noise as they might not be suitable for networking applications beyond a certain cutoff interval of time from their instantiation. The `CutoffProt` is instantiated with a `retention_time` parameter that discards such qubits in each node.

- [`EntanglementConsumer`](@ref): This protocol runs between the end nodes and consumes the final entanglement generated as a result of all of the above protocols, which is supposed to represent the qubits being consumed in a networking application.

All of the above protocols rely on the query and tagging functionality as described in the [Tagging and Querying](@ref tagging-and-querying) section.

Other than that, `ConcurrentSim` and `ResumableFunctions` are used in the backend to run the discrete event simulation. `Graphs` helps with some functionality needed for `RegisterNet` datastructure that forms the grid. `GLMakie` and `NetworkLayout` are used for visualization along with the visualization functionality implemented in `QuantumSavory` itself.

# Custom Predicate And Choosing function

```julia
function check_nodes(net, c_node, node; low=true)
n = Int(sqrt(size(net.graph)[1])) # grid size
c_x = c_node%n == 0 ? c_node ÷ n : (c_node ÷ n) + 1
c_y = c_node - n*(c_x-1)
x = node%n == 0 ? node ÷ n : (node ÷ n) + 1
y = node - n*(x-1)
return low ? (c_x - x) >= 0 && (c_y - y) >= 0 : (c_x - x) <= 0 && (c_y - y) <= 0
end
```

The Swapper Protocol is initialized with a custom predicate function which is then placed in a call to `queryall` inside the Swapper to pick the nodes that are suitable to perform a swap with. The criteria for "suitability" is described below.

This predicate function encodes most of the "logic" a local node will be performing.

The custom predicate function shown above is parametrized with `net` and `c_node` along with the keyword argument `low`, when initializing the Swapper Protocol. This predicate function `Int->Bool` selects the target remote nodes for which a swap is appropriate. The arguments are:

- `net`: The network of register nodes representing the graph structure, an instance of `RegisterNet`.

- `c_node`: The node in which the Swapper protocol would be running.

- `node`: As the [`queryall`](@ref) function goes through all the nodes linked with the current node, the custom predicate filters them depending on whether the node is suitable for a swap or not.

- `low`: The nodes in the grid are numbered as consecutive integers starting from 1. If the Swapper is running at some node n, we want a link closest to Alice and another closest to Bob to perform a swap. We communicate whether we are looking for nodes of the first kind or the latter with the `low` keyword.

Out of all the links at some node, the suitable ones are picked by computing the difference between the coordinates of the current node with the coordinates of the candidate node. A `low` node should have both of the `x` and `y` coordinate difference positive and vice versa for a non-`low` node.

As the Swapper gets a list of suitable candidates for a swap in each direction, the one with the furthest distance from the current node is chosen by summing the x distance and y-distance.

```julia
function choose_node(net, node, arr; low=true)
grid_size = Int(sqrt(size(net.graph)[1]))
return low ? argmax((distance.(grid_size, node, arr))) : argmin((distance.(grid_size, node, arr)))
end

function distance(n, a, b)
x1 = a%n == 0 ? a ÷ n : (a ÷ n) + 1
x2 = b%n == 0 ? b ÷ n : (b ÷ n) + 1
y1 = a - n*(x1-1)
y2 = b - n*(x2-1)

return x1 - x2 + y1 - y2
end
```

# Simulation and Visualization

```julia
n = 6 # the size of the square grid network (n × n)
regsize = 8 # the size of the quantum registers at each node

graph = grid([n,n])

net = RegisterNet(graph, [Register(regsize, fill(5.0, regsize)) for i in 1:n^2])

sim = get_time_tracker(net)

# each edge is capable of generating raw link-level entanglement
for (;src, dst) in edges(net)
eprot = EntanglerProt(sim, net, src, dst; rounds=-1, randomize=true)
@process eprot()
end

# each node except the corners on one of the diagonals is capable of swapping entanglement
for i in 2:(n^2 - 1)
l(x) = check_nodes(net, i, x)
h(x) = check_nodes(net, i, x; low=false)
cL(arr) = choose_node(net, i, arr)
cH(arr) = choose_node(net, i, arr; low=false)
swapper = SwapperProt(sim, net, i; nodeL = l, nodeH = h, chooseL = cL, chooseH = cH, rounds=-1)
@process swapper()
end

for v in vertices(net)
tracker = EntanglementTracker(sim, net, v)
@process tracker()
end

# Entanglement usage/consumption by the network end nodes

consumer = EntanglementConsumer(sim, net, 1, n^2)
@process consumer()

# decoherence protocol runs at each node to free up slots that haven't been used past the retention time
for v in vertices(net)
decprot = DecoherenceProt(sim, net, v)
@process decprot()
end
```

We set up the simulation to run with a 6x6 grid of nodes above. Here, each node has 8 qubit slots.
Each vertical and horizontal edge runs an entanglement generation protocol. Each node in the network runs an entanglement tracker protocol and all of the nodes except the nodes that we're trying to connect, i.e., Alice' and Bob's nodes which are at the diagonal ends of the grid run the swapper protocol. The code that runs and visualizes this simulation is shown below

```julia
fig = Figure(;size=(600, 600))

# the network part of the visualization
layout = SquareGrid(cols=:auto, dx=10.0, dy=-10.0)(graph) # provided by NetworkLayout, meant to simplify plotting of graphs in 2D
_, ax, _, obs = registernetplot_axis(fig[1:2,1], net;registercoords=layout)

# the performance log part of the visualization
entlog = Observable(consumer.log) # Observables are used by Makie to update the visualization in real-time in an automated reactive way
ts = @lift [e[1] for e in $entlog] # TODO this needs a better interface, something less cluncky, maybe also a whole Makie recipe
tzzs = @lift [Point2f(e[1],e[2]) for e in $entlog]
txxs = @lift [Point2f(e[1],e[3]) for e in $entlog]
Δts = @lift length($ts)>1 ? $ts[2:end] .- $ts[1:end-1] : [0.0]
entlogaxis = Axis(fig[1,2], xlabel="Time", ylabel="Entanglement", title="Entanglement Successes")
ylims!(entlogaxis, (-1.04,1.04))
stem!(entlogaxis, tzzs)
histaxis = Axis(fig[2,2], xlabel="ΔTime", title="Histogram of Time to Successes")
hist!(histaxis, Δts)

display(fig)

step_ts = range(0, 200, step=0.1)
record(fig, "grid_sim6x6hv.mp4", step_ts; framerate=10, visible=true) do t
run(sim, t)
notify.((obs,entlog))
ylims!(entlogaxis, (-1.04,1.04))
xlims!(entlogaxis, max(0,t-50), 1+t)
autolimits!(histaxis)
end

```

# Result

```@repl
include("../../../../examples/repeatergrid/1a_async_interactive_visualization.jl") # hide
```

```@raw html
<video src="../grid_sim6x6hv.mp4" autoplay loop muted></video>
```
3 changes: 1 addition & 2 deletions docs/src/symbolics.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,4 @@ express(MixedState(X1)/2+SProjector(Z1)/2, CliffordRepr())
```

!!! warning "Stabilizer state expressions"

The state written as $\frac{|Z₁⟩⊗|Z₁⟩+|Z₂⟩⊗|Z₂⟩}{√2}$ is a well known stabilizer state, namely a Bell state. However, automatically expressing it as a stabilizer is a prohibitively expensive computational operation in general. We do not perform that computation automatically. If you want to ensure that states you define can be automatically converted to tableaux for Clifford simulations, avoid using summation of kets. On the other hand, in all of our Clifford Monte-Carlo simulations, `⊗` is fully supported, as well as [`SProjector`](@ref), [`MixedState`](@ref), [`StabilizerState`](@ref), and summation of density matrices.
The state written as $\frac{|Z₁⟩⊗|Z₁⟩+|Z₂⟩⊗|Z₂⟩}{√2}$ is a well known stabilizer state, namely a Bell state. However, automatically expressing it as a stabilizer is a prohibitively expensive computational operation in general. We do not perform that computation automatically. If you want to ensure that states you define can be automatically converted to tableaux for Clifford simulations, avoid using summation of kets. On the other hand, in all of our Clifford Monte-Carlo simulations, `⊗` is fully supported, as well as `SProjector`, [`MixedState`](@ref), [`StabilizerState`](@ref), and summation of density matrices.
2 changes: 1 addition & 1 deletion docs/src/visualizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fig

And here with some extra tag metadata.

```@example vis
```
tag!(net[2,3], :specialplace, 1, 2)
tag!(net[2,3], :otherdata, 3, 4)
QuantumSavory.showmetadata(fig,ax,plt,2,3)
Expand Down
3 changes: 2 additions & 1 deletion examples/congestionchain/1_visualization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ scatter!(ax_fidZZ,ts,fidZZ,label="ZZ",color=(c2,0.1))
display(fig)

step_ts = range(0, 1000, step=0.1)
for t in step_ts

record(fig, "congestionchain.mp4", step_ts; framerate=50, visible=true) do t
run(sim, t)
ax.title = "t=$(t)"
notify(obs)
Expand Down
79 changes: 79 additions & 0 deletions examples/repeatergrid/1a_async_interactive_visualization.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using GLMakie
# TODO significant code duplication with the other examples

include("setup.jl")

sim, net, graph, consumer, params... = prepare_simulation()

fig = Figure(;size=(1200, 1100))

# the network part of the visualization
layout = SquareGrid(cols=:auto, dx=30.0, dy=-30.0)(graph) # provided by NetworkLayout, meant to simplify plotting of graphs in 2D
_, ax, _, obs = registernetplot_axis(fig[1:2,1], net;registercoords=layout)

# the performance log part of the visualization
entlog = Observable(consumer.log) # Observables are used by Makie to update the visualization in real-time in an automated reactive way
ts = @lift [e[1] for e in $entlog] # TODO this needs a better interface, something less cluncky, maybe also a whole Makie recipe
tzzs = @lift [Point2f(e[1],e[2]) for e in $entlog]
txxs = @lift [Point2f(e[1],e[3]) for e in $entlog]
Δts = @lift length($ts)>1 ? $ts[2:end] .- $ts[1:end-1] : [0.0]
entlogaxis = Axis(fig[1,2], xlabel="Time", ylabel="Entanglement", title="Entanglement Successes")
ylims!(entlogaxis, (-1.04,1.04))
stem!(entlogaxis, txxs)
histaxis = Axis(fig[2,2], xlabel="ΔTime", title="Histogram of Time to Successes")
hist!(histaxis, Δts)

avg_fids = @lift cumsum([e[3] for e in $entlog])./cumsum(ones(length($entlog))) #avg fidelity per unit time
fid_info = @lift [Point2f(t,f) for (t,f) in zip($ts, $avg_fids)]
fid_axis = Axis(fig[3,1], xlabel="Time", ylabel="Avg. Fidelity", title="Time evolution of Average Fidelity")
lines!(fid_axis, fid_info)

num_epr = @lift cumsum(ones(length($entlog)))./($ts) #avg number of pairs per unit time
num_epr_info = @lift [Point2f(t,n) for (t,n) in zip($ts, $num_epr)]
num_epr_axis = Axis(fig[3,2], xlabel="Time", title="Avg. Number of Entangled Pairs between Alice and Bob")
lines!(num_epr_axis, num_epr_info)


# sliders
sg = SliderGrid( # TODO significant code duplication with the other examples
fig[4,1],
(label="Probability of success of Entanglement generation at each attempt",
range=0.001:0.05:1.0, format="{:.3f}", startvalue=0.001),
(label="Local busy time for swapper",
range=0.001:0.5:10.0, format="{:.3f}", startvalue=0.001),
(label="Wait time after failure to lock qubits for a swap",
range=0.1:0.05:1.0, format="{:.2f}", startvalue=0.1),
(label="Retention time for an unused qubit",
range=0.1:0.1:10.0, format="{:.2f}", startvalue=5.0),
(label="Time before a qubit's retention time runs out (for `agelimit`)",
range=0.1:0.5:10.0, format="{:.2f}", startvalue=0.5),
(label="Period of time between subsequent queries at the consumer",
range=0.001:0.05:1.0, format="{:.3f}", startvalue=0.001),
(label="Period of time between subsequent queries at the DecoherenceProtocol",
range=0.001:0.05:1.0, format="{:.3f}", startvalue=0.001),

width = 600,
tellheight = false)

for (param, slider) in zip(params, sg.sliders)
on(slider.value) do val
param[] = val
end
end


display(fig)

step_ts = range(0, 1000, step=0.1)
record(fig, "grid_sim6x6hv.mp4", step_ts; framerate=10, visible=true) do t
run(sim, t)
notify.((obs,entlog))
notify.(params)
ylims!(entlogaxis, (-1.04,1.04))
xlims!(entlogaxis, max(0,t-50), 1+t)
ylims!(fid_axis, (0, 1.04))
xlims!(fid_axis, max(0, t-50), 1+t)
autolimits!(histaxis)
ylims!(num_epr_axis, (0, 4))
xlims!(num_epr_axis, max(0, t-50), 1+t)
end
Loading
Loading