Skip to content
This repository has been archived by the owner on Mar 27, 2022. It is now read-only.

support for parameter vectors in Model #4

Open
dafred94 opened this issue Mar 18, 2021 · 5 comments
Open

support for parameter vectors in Model #4

dafred94 opened this issue Mar 18, 2021 · 5 comments

Comments

@dafred94
Copy link

dafred94 commented Mar 18, 2021

I created a Model that starts like this:

SingleTrackModel = Model(
    inputs   = :[delta,T_F,T_R],
    m = 1450,
    I_z = 1.0,
    l_F = 1.1,
    l_R = 1.59,
    h = 0.4,
    I_w = [1.8, 1.8],
    ...

Now in the equations section, I cannot access elements of parameters I_w using I_w[ind...]. A tested workaround I found is to use getindex(I_w, ind...) instead. However, neither does I_w show up in field parametersAndConstantVariables of the instantiated model, nor can I spot its contents in the field p.

However I would like to alter p after model instantiation (machine learning purposes).

Is there any supported and intended way to use and alter parameters in arrays?

@HildingElmqvist
Copy link
Contributor

It would have been better if you would have provided a complete example illustrating the problem. I successfully tested the following model in my development version:

using TinyModia
using ModiaPlot

SingleTrackModel = Model(
#    inputs   = :[delta,T_F,T_R],
    m = 1450,
    I_z = 1.0,
    l_F = 1.1,
    l_R = 1.59,
    h = 0.4,
    I_w = [1.8, 2.8],
    equations = :[
        I_w_2 = I_w[2...]
    ]
)

model = @instantiateModel(SingleTrackModel, log=true, logCode=true)
simulate!(model)
plot(model, "I_w_2")

So I might have misunderstood you. BTW, why do you want to use: I_w[ind...]

It should be possible to use parameter arrays and also change them in the simulate! call without redoing the symbolic transformation (under development, coming to main soon).

@dafred94
Copy link
Author

dafred94 commented Mar 19, 2021

So I created a minimal but complete demonstration:

using TinyModia


function simandprint!(model)
	simulate!(model)

	println("
	m = $(model.p[1])
		x starts at $(get_result(model, "x")[1]) and ends at $(get_result(model, "x")[end])
	")
end


MinimalModel = Model(
	m = 2.0,
	pv = [3.0, 5.0],

	init = Map(x=2.0),

	equations = :[
		#der(x) = m*p[1]*p[2] # THIS LINE does not work
		der(x) = m*getindex(pv, 1)*getindex(pv, 2) # I have to use getindex() instead
	]
)


model = @instantiateModel(MinimalModel)

println("model.p: $(model.p)")
println("model.paramatersAndConstantVariables: $(model.parametersAndConstantVariables)")

simandprint!(model)

# manual altering of a scalar parameter works BUT there is no way to change pv from here!
model.p[1] = 4.0

simandprint!(model)

I marked the relevant bits I was talking about using comments.
If I execute this, I cannot see pv in the model parameters (which I am printing).
(I should mention that I am on [0169e107] TinyModia v0.7.1-dev `dev/TinyModia` )

@HildingElmqvist
Copy link
Contributor

I suppose yo meant:
der(x) = m*pv[1]*pv[2] instead of
der(x) = m*p[1]*p[2]
and
model.p[1].pv[1] = 4.0
instead of
model.p[1] = 4.0

model.p is the root of the parameters. We are supporting changing (merging) parameters in the simulate! call .

@dafred94
Copy link
Author

You are right about your first remark (where I mixed up p and pv), this was a remainder of an earlier refactoring.
However, if I try to uncomment
#der(x) = m*pv[1]*pv[2] # THIS LINE does not work,
I am getting the error:

AssertionError: Equation not solved for der(x): der(x) = m * pv[1] * pv[2]
(::TinyModia.var"#getSolvedEquationAST#65"{Bool,Array{Any,1},Array{Any,1}})(::Int64, ::Int64) at TinyModia.jl:460
addSolvedEquations!(::ModiaBase.EquationGraph, ::Array{Int64,1}, ::Array{Int64,1}) at StateSelection.jl:858
getSortedAndSolvedAST(::Array{Array{Int64,1},1}, ::Array{Array{Int64,1},1}, ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Int64,1}, ::ModiaBase.StateSelectionFunctions; log::Bool, logDetails::Bool, logStates::Bool, modelName::String, unitless::Bool, defaultParameterAndStartValues::Nothing) at StateSelection.jl:1247
getSortedAndSolvedAST at StateSelection.jl:1197 [inlined]
stateSelectionAndCodeGeneration(::Tuple{Array{Any,1},Array{Any,1},Array{Array{Int64,1},1},Array{Int64,1},Array{Int64,1},Array{Int64,1},Array{Array{Int64,1},1},OrderedCollections.OrderedDict{Any,Any}}, ::String, ::Module, ::Type{T} where T, ::OrderedCollections.OrderedDict{Any,Any}, ::OrderedCollections.OrderedDict{Any,Any}, ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Union{Expr, Symbol},1}; unitless::Bool, logStateSelection::Bool, logCode::Bool, logExecution::Bool, logTiming::Bool) at TinyModia.jl:588
(::TinyModia.var"#stateSelectionAndCodeGeneration##kw")(::NamedTuple{(:unitless, :logStateSelection, :logCode, :logExecution, :logTiming),NTuple{5,Bool}}, ::typeof(TinyModia.stateSelectionAndCodeGeneration), ::Tuple{Array{Any,1},Array{Any,1},Array{Array{Int64,1},1},Array{Int64,1},Array{Int64,1},Array{Int64,1},Array{Array{Int64,1},1},OrderedCollections.OrderedDict{Any,Any}}, ::String, ::Module, ::Type{T} where T, ::OrderedCollections.OrderedDict{Any,Any}, ::OrderedCollections.OrderedDict{Any,Any}, ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Union{Expr, Symbol},1}) at TinyModia.jl:455
instantiateModel(::NamedTuple{(:m, :pv, :init, :equations),Tuple{Float64,Array{Float64,1},NamedTuple{(:x,),Tuple{Float64}},Expr}}; modelName::String, modelModule::Module, FloatType::Type{T} where T, aliasReduction::Bool, unitless::Bool, log::Bool, logModel::Bool, logDetails::Bool, logStateSelection::Bool, logCode::Bool, logExecution::Bool, logTiming::Bool) at TinyModia.jl:791
(::TinyModia.var"#instantiateModel##kw")(::NamedTuple{(:modelName, :modelModule),Tuple{String,Module}}, ::typeof(instantiateModel), ::NamedTuple{(:m, :pv, :init, :equations),Tuple{Float64,Array{Float64,1},NamedTuple{(:x,),Tuple{Float64}},Expr}}) at TinyModia.jl:711
top-level scope at demo.jl:33

Furthermore, model.p is reported to be an Array{Float64,1} which does not have a field named pv so I do not understand that second remark of yours.

Also, line model.p[1] = 4.0 does exactly what I want: alter the behaviour of model.getDerivatives!.
I am interested in getting model.getDerivatives! to behave differently so that I can

  1. instantiate a model
  2. set a model parameter (possibly located in an array) to a desired value
  3. solve the model using an arbitrary code (in my case solve from DifferentialEquations.jl)
  4. repeat 2. and 3. until the model does what I want it to

I'm appending a more relevant demonstration below:

using TinyModia


function simandprint!(model)
	simulate!(model)

	println("
	m = $(model.p[1])
		x starts at $(get_result(model, "x")[1]) and ends at $(get_result(model, "x")[end])
	")
end


function print_derivatives!(derx, x0, model)
	model.getDerivatives!(derx, x0, model, t0)
	println("m = $(model.p[1]) => dx = $(derx)")
end


MinimalModel = Model(
	m = 2.0,
	pv = [3.0, 5.0],

	init = Map(x=2.0),

	equations = :[
		#der(x) = m*pv[1]*pv[2] # THIS LINE does not work
		der(x) = m*getindex(pv, 1)*getindex(pv, 2) # I have to use getindex() instead
	]
)


model = @instantiateModel(MinimalModel)

println("model.p: $(model.p)")
println("model.paramatersAndConstantVariables: $(model.parametersAndConstantVariables)")

derx = zeros(1)
x0 = similar(derx)
t0 = 0.0

print_derivatives!(derx, x0, model)

#simandprint!(model)

# manual altering of a scalar parameter works BUT there is no way to change pv from here!
model.p[1] = 4.0

print_derivatives!(derx, x0, model)

#simandprint!(model)

@HildingElmqvist
Copy link
Contributor

You are right. I recently changed how parameters are passed. I tested in the branch "development". We want to make some more updates before merging to main. You might want to use development branch in the mean time.

Support for indexing was added in ModiaBase 11 days ago, so you might want to update.

Note that all TinyModia models can not be simulated directly with DifferentialEquations. The simulate! function of TinyModia is needed. Note that the workflow you indicated is now supported by an additional parameter merge in simulate!. It takes a nested Map modification for changing parameters.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants