项目作者: jonniedie

项目描述 :
Signal logging and scoping for DifferentialEquations.jl simulations.
高级语言: Julia
项目地址: git://github.com/jonniedie/SimulationLogs.jl.git
创建时间: 2021-04-02T23:05:53Z
项目社区:https://github.com/jonniedie/SimulationLogs.jl

开源协议:MIT License

下载


SimulationLogs.jl

Documentation Build Status

SimulationLogs lets you log variables from within a DifferentialEquations.jl ODE simulation.

The Basics

To log a variable, use the @log macro before an existing variable declaration in the simulation. The syntax for this looks like:

  1. @log x = u[1]+u[3]

To log an expression to an output variable without creating that variable in the simulation use the following syntax:

  1. @log x u[1]+u[3]

To extract logged values from a simulation, either use the logged_solve function to obtain a Logged solution or call the get_log function on an existing solution object.

Example

  1. using DifferentialEquations
  2. using SimulationLogs
  3. function lorenz!(du, u, p, t)
  4. @log a = u[2]-u[1]
  5. @log b u[3]+a
  6. du[1] = p[1]*a
  7. du[2] = u[1]*(p[2]-u[3]) - u[2]
  8. du[3] = u[1]*u[2] - p[3]*u[3]
  9. end
  10. p = [10.0, 28.0, 8/3]
  11. u0 = [1.0, 0.0, 0.0]
  12. tspan = (0.0, 100.0)
  13. prob = ODEProblem(lorenz!, u0, tspan, p)
  14. sol = solve(prob)

Now we can extract the simulation log with get_log.

  1. julia> out = get_log(sol)
  2. SimulationLog with signals:
  3. a :: Float64
  4. b :: Float64
  5. julia> out.a
  6. 1278-element Vector{Float64}:
  7. -1.0
  8. -0.9986446507807255
  9. -0.9851391500213387
  10. -0.8795890363074045
  11. 5.072093963230147
  12. 5.402915814211024
  13. 2.8508213179241197
  14. 1.1035303908083802
  15. julia> out.b
  16. 1278-element Vector{Float64}:
  17. -1.0
  18. -0.9986446329663776
  19. -0.9851370030659728
  20. -0.8794452356321748
  21. 40.76318830048574
  22. 37.12952959918623
  23. 29.24474520341088
  24. 23.899870630658324

We can also use scope to visually inspect signals from the simulation. This requires using the Plots.jl library. For an interactive scope (pan, zoom, etc.), use the PlotlyJS backend of Plots by calling plotlyjs().

  1. using Plots; plotlyjs()
  2. scope(sol, [:a, :b])

News

As of version 0.3.0, we can now handle cases where parameters change in DiscreteCallbacks. The callback or callback set must be passed into the get_log function through the keyword callback. Alternatively, just replace your solve with logged_solve and everything will be handled automatically. The logged variables from a logged_solve can be accessed in a solution object sol as sol.log.

FAQs

How does this work with time stepping and variable caches and all that?

Despite the name, @log doesn’t actually log anything while the simulation is running. The “logging” actually happens by calculating values from the stored solutions when get_log is called.

Wait, how does that work?

There is a global SimulationLog that is turned off by default. When it is off, the @log macro basically doesn’t do anything. The get_log function turns on the global log and then calls your simulation function (derivative function, vector field… whatever you want to call it) for each time point (these can be supplied, but will default to the saved time points). A copy of the global simulation log is passed as an output to the user, after which the global log then gets erased and turned back off.

Will logging variables slow my simulation down?

Nope. There is no runtime overhead because no logging is actually happening during the simulation.

How does this work when the same @log gets called multiple times in the same time step (e.g. in a subfunction that gets called more than once)?

The logged solution will then be a n x m Matrix where n is the number of time steps and m is the number of times the @log macro was called in a single time step.

What if my parameters are changed during the simulation?

If you do this, you must include the callback you used to change the parameters in the get_log function as a keyword argument callback. If you changed the parameters without using a callback, the results will be incorrect (but in general you shouldn’t be changing parameters without a callback anyway).

What if my simulation depends on some changing global state?

Solutions that changed global state cannot be handled (or, rather, @log will most likely give you incorrect results).

Attributions

Icons made by Freepik from www.flaticon.com