Operations on output from solve()

I am running a simple jump_process. Here is some code (which is not runnable, but works). The details are not important.

        prob = DiscreteProblem(u0,tspan,params)
	prob_jump = JumpProblem(prob, Direct(), infection_jump, recovery_jump)
	sol_jump = solve(prob_jump, FunctionMap());
	out_jump = sol_jump(t);

out_jump has type of

DiffEqArray{Int64,2,Array{Array{Int64,1},1},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}

What is interesting is that I compute 100 different solutions and wish to average them. So I added up out_jump and divided by the number of runs. And it worked! Examining further, I found that the following operation:

s = out_jump + out_jump

result in s having type Array{Int64,2} and the time component is not affected. This is what I wanted, but it seems strange to me. This change of type was unexpected. Is this a feature?

Finally, what is the best way to compute the average of many runs performed within the DifferentialEquations.jl package?

Thanks. Gordon.

Yes, the DESolution <: DiffEqArray <: AbstractVectorOfArray <: AbstractArray, so it inherits the capabilities of acting like an array. That’s very tersely described here: https://diffeq.sciml.ai/latest/basics/solution/ .

So you can compute a mean like mean(sol,dims=2) to average over time, since it just behave like an array so “things that want arrays” will work on the solution type. It also behaves as a table, so DataFrame(sol) and things like statistical operations will work.

If you want to do a bunch of analyses over many trajectories though, you might want to look at the ensemble interface:

https://diffeq.sciml.ai/latest/features/ensemble/

1 Like

Great! I will look into these possibilities.

What is the best way to find out the type hierarchy of a particular type?

Chris,

Quick question. Looking through the source code of various package, I notice that Julia style is radically different than most other languages, mostly because of the dispatch algorithms. Also, various functions are defined where the function name is a structure type listed in parentheses.

Where can I find a tutorial (or anything) that explains how to construct package in the “correct” style? Of course, I can write my own module, but that does note mean it will be done the Julia way. Surely the thought process is explained somewhere?

Thanks, as usual.

Chris,

I loaded DifferentialEquations.jl ,and then listed all the subtypes of AbstractArray.
DiffEqArray was not listed (I am in REPL within Atom). However, when I type:
supertype(DiffEqArray), the result is
AbstractDiffEqArray{T,N,A} where A where N where T
which is also not listed when using the subtypes command.

It would seem that what subtypes lists is dependent on the modules loaded. Is that the case? If so, then it is hard to see how operations on the subtype would work if the chain up to AbstractArray depends on the modules loaded. Obviously, dealing with types is rather complex.

Gordon

supertype(typeof(x)), and keep hopping.

There’s a few styles around. I usually point to my video to first show the workflow:

and it demonstrates a few standard things you’ll see, like exports and include all at the top level file, the standard way to name variables, modules, functions, etc. But if you want more directly into the exact styles, there are three style guides that I know of:

They are more similar than different.

Yes, new packages can add subtypes to inherit their dispatch behaviors.