|
| 1 | +using Distributed |
| 2 | +using Plots |
| 3 | +addprocs(8) |
| 4 | + |
| 5 | + |
| 6 | +@everywhere using DifferentialEquations |
| 7 | +@everywhere using DiffEqParamEstim |
| 8 | +@everywhere using BlackBoxOptim |
| 9 | + |
| 10 | +# Define function to fix parameters |
| 11 | + |
| 12 | +function fixvalues(vs, fixspec, dims) |
| 13 | + newvs = zeros(Float64, dims) |
| 14 | + vsidx = fixidx = 1 |
| 15 | + for i in 1:dims |
| 16 | + if (fixidx <= length(fixspec) && i == fixspec[fixidx][1]) |
| 17 | + newvs[i] = fixspec[fixidx][2] |
| 18 | + fixidx += 1 |
| 19 | + else |
| 20 | + newvs[i] = vs[vsidx] |
| 21 | + vsidx += 1 |
| 22 | + end |
| 23 | + end |
| 24 | + newvs |
| 25 | +end |
| 26 | + |
| 27 | +# Define DAE System: Lorenz Attractor + Extra Variable to illustarte DAE syntax |
| 28 | +function g(du,u,p,t) |
| 29 | + σ,ρ,β = p |
| 30 | + x,y,z,w = u |
| 31 | + du[1] = σ*(y-x) |
| 32 | + du[2] = x*(ρ-z) - y |
| 33 | + du[3] = x*y - β*z |
| 34 | + du[4] = w - (x + y + z) |
| 35 | +end |
| 36 | + |
| 37 | +# Define Limits |
| 38 | +lower=Float64.([0, 0, 0]) |
| 39 | +upper=Float64.([20, 30, 10]) |
| 40 | + |
| 41 | +# Define Initial Conditions as well as time span |
| 42 | +u0 = [1.0;0.0;0.0;1.0] |
| 43 | +t = 0.0:0.05:1 |
| 44 | +tspan = (0.0,1.0) |
| 45 | + |
| 46 | +# Generate Mass Matrox MM to transfrom ODE into DAE |
| 47 | +MM=zeros(4,4) |
| 48 | +MM[1,1]=MM[2,2]=MM[3,3]=1 |
| 49 | + |
| 50 | +# Generate Equation system |
| 51 | +ODESystem = ODEFunction(g;mass_matrix=MM) |
| 52 | + |
| 53 | +# Generate Function that creates ODE problem as function of parameters (optmization argument) |
| 54 | +model_ode(p_) = ODEProblem(ODESystem, u0, tspan,p_) |
| 55 | + |
| 56 | +# Generate Function that solves system as function of parameters, saves every s interval and save only vars we want. |
| 57 | +solve_model(mp_,s, i) = DifferentialEquations.solve(model_ode(mp_), Rodas5(),saveat=s, save_idxs=i) |
| 58 | + |
| 59 | +# Generate Clean mock data / will add nisy mock data later |
| 60 | +mock_data = Array(solve_model([10.0,28.0,8/3],0.05,[1,2,3,4]))#,4 |
| 61 | + |
| 62 | + |
| 63 | +# Create Loss function |
| 64 | +function L(t,dat,w=nothing) |
| 65 | + return L2Loss(t,dat;data_weight=w) |
| 66 | +end |
| 67 | + |
| 68 | +# Create objective function |
| 69 | +loss_objective(mp_, dat)=build_loss_objective(model_ode(mp_), Rodas5(), L(t,dat)) |
| 70 | + |
| 71 | +# Simplify fitness/objective function to depend only on parameter we want to vary |
| 72 | +function origfitness(args) |
| 73 | + return loss_objective(args, mock_data)(args) |
| 74 | +end |
| 75 | + |
| 76 | +dims = 3 |
| 77 | + |
| 78 | +# In specific opt problem A there is one var (at position 1) with fixed value of 10. |
| 79 | + |
| 80 | +problemfixed = [(1, 10.0)] |
| 81 | + |
| 82 | +# Create objective function with fix value =10 at position 1 |
| 83 | +fitnessFix(vs) = origfitness(fixvalues(vs, problemfixed, dims)) |
| 84 | + |
| 85 | +# Generate options for optimization for problem with free parameters |
| 86 | +opt_free = bbsetup(origfitness; Method=:separable_nes, SearchRange = (collect(zip(lower,upper))), |
| 87 | + NumDimensions = 3, MaxFuncEvals = 100000, workers=workers(), TargetFitness=100.0 ) |
| 88 | + |
| 89 | +# Generate options for optimization for problem with fix parameters (note dimensions are 2 instead of 3) |
| 90 | +opt_fix = bbsetup(fitnessFix; Method=:separable_nes, SearchRange = (collect(zip(lower[2:3],upper[2:3]))), |
| 91 | + NumDimensions = 2, MaxFuncEvals = 100000, workers=workers()) |
| 92 | + |
| 93 | +# Call bboptim as usual and optimizing for fitnessFix and origfitness. |
| 94 | +bbfix=bboptimize(opt_fix); |
| 95 | +bbfree=bboptimize(opt_free); |
| 96 | +bsfix=fixvalues(best_candidate(bbfix), problemfixed,dims) # then is our best solution to the general DAE problem with a fixed param. |
| 97 | +bsfree=best_candidate(bbfree) # then is our best solution to the general DAE problem with full freedom. |
| 98 | + |
| 99 | +Note that within error bsfix and bs free are equal |
| 100 | + |
| 101 | +(bsfree, origfitness(bsfree)), (bsfix, origfitness(bsfix)) |
| 102 | + |
| 103 | + |
| 104 | +# Plot results |
| 105 | +pyplot() |
| 106 | +# Shot Times to see Fitness to Data |
| 107 | +Sol1=solve(ODEProblem(ODESystem, u0, (0,1.0), bsfix),Rodas5()) |
| 108 | +plot(Sol1, layout=(2,2), xlabel="Time", ylabel=[:x :y :z :w], label=["" "" "" "w=x+y+z"]) |
| 109 | +scatter!(t,[mock_data[i,:] for i in 1:4],layout=(2,2), label="") |
| 110 | + |
| 111 | +# Long times to see attractor behavior |
| 112 | +Sol2=solve(ODEProblem(ODESystem, u0, (0,100.0), bsfix),Rodas5()) |
| 113 | +#plot(Sol,layout=(2,2), labels=[:w :x :y "z=w+x+y"]) |
| 114 | +P1=plot(Sol2.t, [Sol2[i,:] for i in 1:4], layout=(2,2), xlabel="Time", ylabel=[:x :y :z :w], labels=["" "" "" "w=x+y+z"]) |
| 115 | +P2=plot(Sol2,vars=(1,2,3),xlabel="x", ylabel="y", zlabel="z", labels="") |
| 116 | +l = @layout([a;b{0.5h}]) |
| 117 | +PF=plot(P1,P2, layout=l, size=(900,600)) |
| 118 | + |
0 commit comments