Message Boards Message Boards

0
|
10034 Views
|
9 Replies
|
4 Total Likes
View groups...
Share
Share this post:

Problems addressing Vectors in Mathematica / WSMLink

Posted 11 years ago
Hi,

I've got some issues regarding Mathematica and System Modeler Link but I think it's mainly a Mathematica regarded question, so that there might be people who can help me even though they don't work with Wolfram System Modeler.

What I try to do:
I run a simulation in WSM (but controlled from Mathematica), at the end I want to take some values and start another Simulation with them.

So here's an example:
N1 = WSMSimulate["TestMathematica", {0, 10}]        (*at the beginning I run the simulation for the period 0..10 seconds*)

The simulation "TestMathematica" has three parameters that form a vector together. In WSM they are defined this way:
Real[3] gStart;    
In WSM the vector elements are addressed like this: gStart = {gStart[1], gStart[2], gStart[3]}
In contrary in Mathematica it's like this: ....gStart[[1]]
So I think that Mathematica doesn't know that the Parameters gStart[1 to 3] belong together and form a vector but rather that they are three independent parameters. But still all parameters together (and in this case there are only these 3 elements) form a vector:
MatrixForm[N1["ParameterNames"]]
leads to a column vector:
{"gStart[1]", "gStart[2]", "gStart[3]"}


At the end of the simulation I want to save 3 Values into a vector named init2:
For[i = 1, i <= 3, ++i, init2[[i]] = ToExpression[StringJoin["N1[{\"g[", ToString[i], "]\"},{10}]"]]]
so for each element this should do this:
init2[[1]] = N1[{"g[1]"}, {10}]

I would prefer something like this: init2 = N1["gStart"] but it doesn't seem to work since Mathematica doesn't seem to know that the 3 gStart elements belong to one vector.
Of course the for loop doesn't make sense for these 3 elements but this is only an example for a much more complicated simulation.
init2                             (*returns this...:*)
{{{10.}}, {{20.}}, {{15.}}}
MatrixForm shows a column  vector again but with brackets around each element.

Now I want to start a new simulation with init2 as parameter values:
N2 = WSMSimulate["TestMathematica", {0, 10}, WSMParameterValues -> {For[i = 1, i <= 3, i++,
       ToExpression[StringJoin["\"gStart[", ToString[i], "]\""]] -> init2[[i]]  ] }]
leads to this error
WSMSimulate::par: "Value of option WSMParameterValues -> {Null} should be on the form {\"par1\" -> v1, ...}."
I already tried a lot of things: I thought the vectors are different forms, but both are column vectors. Transpose[...] didn't change anything. One problem might be the curly brackets at init2, but I also tried Flatten[...] or set this manual in different forms. I didn't work. The only thing that works is to put every parameter element by itself in the equation without the for loop. But as I said, this is just an example for something more complex.

Does anybody have an idea?

Thanks in adavance! Stefan
POSTED BY: skdaufer
9 Replies
Posted 11 years ago
Ok, I got it working now. for anybody who's interested:
DMS = S1[{"var1"},t]
note the "t" at the end
Plot[DMS, {t, 0, 1000}]
Seems like I have to give Mathematica the variable for the x-Axis in order to plot. Also the piecewise-joint function now works with plot.
POSTED BY: skdaufer
Posted 11 years ago
Happy new year to everybody!
Thanks so far!
I would rather like to add both simulation results to a function DMT so that it is a discontionuous function. I allready found out, that this is possible by using the Piecewise[ ]-command as well.
DMT = Piecewise[{{S1[{"var1"}, t],
    t <= EndTime}, {S2[{"var1"}, t], t > Endtime}}]
(EndTime is defined as the end of simulation S1 (1321.87s))

this leads to an output simular to this:

(by the way: how can I add this to the forum so that it is displayed as in mathematica?)

If I try to plot the function DMT it only displays an empty plot. There's no error message neither when defining the function nor when trying to plot it.



edit:
Ok, I just realized that I can't even plot simulation results as they are with Plot[...]:
In: DMS = S1[{"var1"}]

Out: {InterpolatingFunction[{{0.,1321.87}},<>]}
Plotting just leads to an empty plot:
Plot[DMS, {t, 0, 1000}]

Does anybody know what I am missing out?
POSTED BY: skdaufer
For two simulations with different time spans:
sim1 = WSMSimulate["IntroductoryExamples.HelloWorld", {0, 1}];
sim2 = WSMSimulate["IntroductoryExamples.HelloWorld", {1, 5}];

Combine two plots:
Show[WSMPlot[sim1, {"x"}, PlotStyle -> Blue],
WSMPlot[sim2, {"x"}, PlotStyle -> Purple],
PlotRange -> {{0, 5}, Automatic}]



A Piecewise will work too, but not give different colors:
Plot[Piecewise[{{sim1[{"x"}, t][[1]], t < 1}, {sim2[{"x"}, t][[1]], t > 1}}], {t, 0, 5}]
POSTED BY: Malte Lenz
Posted 11 years ago
Ok, next question.:
Now I have two simulation results S1 and S2. S1 is for time 0 to about 1300, S2 for 1300 to 2000.
If I want to plot these I can do it like this:
WSMPlot[{S1, S2}, {"g"}]
Now it plots the variable g from S1 and S2 in different colors and for the whole time period:

But I would like to plot value "g" for t = 0 ~1300 from S1 (blue), and for t > 1300 from S2 (violet). How can I define a discontinuous function like this using a WSMSimulationData-object as S1 and S2?

It could somehow work using Plot[Piecewise[...]...].
Plot[Piecewise[{S1[{"filter1.DirtMassTotal"}],
   Time < EndTime}, {S2[{"filter1.DirtMassTotal"}],
   Time > EndTime}], {0, 4000}]
But this one isn't working. Also I don't know how I need to call the time-variable?
POSTED BY: skdaufer
Posted 11 years ago
Thanks for the quick response! I found a solution to do it. You were right, there was a comma missing between the two partial lists, which I didn't notice before.  Now I fixed it by wrapping a curly bracket around the two tables and using the flatten command after that to get 1 vector out of everything.
Print[WSMParameterValues ->
  Flatten[{Table[
     ToExpression[StringJoin["\"gStart1[", ToString[i], "]\""]] ->
      init[[i, 1]], {i, 1, 3}],
    Table[ToExpression[
       StringJoin["\"gStart2[", ToString[i], "]\""]] ->
      initTotal[[i, 1]], {i, 1, 3}]}]]
leads to:
WSMParameterValues->{gStart1[1]->{7.64462*10^10},gStart1[2]->{4.05628*10^10},gStart1[3]->{1.68837*10^10},gStart2[1]->{3.32122*10^11},gStart2[2]->{2.11542*10^11},gStart2[3]->{9.03956*10^10}}
So this is working fine now.
POSTED BY: skdaufer
The code you have in your post seems to be missing some brackets in a few places, as it stands the syntax is invalid.
I think you might be able to solve your problem by wrapping a Join around your tables, something like this:
WSMParameterValues ->
Join[Table[
   ToExpression[StringJoin["\"gStart1[", ToString[i], "]\""]] ->
    init[[i, 1]], {i, 1, 3}],
  Table[ToExpression[StringJoin["\"gStart2[", ToString[i], "]\""]] ->
    initTotal[[i, 1]], {i, 1, 3}]]
I would really wish that there were simpler ways to read in parameters with WSM, especially Vectors and Matrices, so that it would be possibly to run a simulation, stop it, change single end values and restart the simulation from the time you stopped it.

I agree that this would be a nice feature, and it is something we are hoping to provide in future versions.
POSTED BY: Malte Lenz
Posted 11 years ago
Thank you so far! The table-command was a big help. But I'm still having trouble. For example if I have to vectors with the same amount of elements as parameters.
example:
gStart1  <- vector with 3 elements
gStart2 <- vector with another 3 elements

So what I want is a form like this:
WSMParameterValues -> {"gStart1[1]" -> init1[[1]], "gStart2[1]" -> init2[[1]], "gStart1[2]" -> init1[[2]], .... }


What I tried is:
WSMParameterValues ->
  Table[ToExpression[
     StringJoin["\"gStart1[",
      ToString[i], "]\""]] -> init[[i, 1]], {i, 1, 3}],
Table[ToExpression[
    StringJoin["\"gStart2[", ToString[i], "]\""]] ->
   initTotal[[i, 1]], {i, 1, 3}]]
this leads to this output:
WSMParameterValues->{gStart1[1]->{1.33798*10^8},gStart1[2]->{4.03577*10^8},gStart1[3]->{2.82601*10^8}}{gStart2[1]->{1.33798*10^8},gStart2[2]->{4.03577*10^8},gStart2[3]->{2.82601*10^8}}
note the curly brackets around gStart1 and gStart2! This seems to lead to the problem that WSMLink can't give the parameters to WSM. Is there any way to avoid these brackets? So that it's a 6 x 1 Matrix, rather than a 3 x 2 Matrix?


I would really wish that there were simpler ways to read in parameters with WSM, especially Vectors and Matrices, so that it would be possibly to run a simulation, stop it, change single end values and restart the simulation from the time you stopped it.
POSTED BY: skdaufer
You are correct that WSMLink currently does not detect vectors very well. It always handles each element separately, as you discovered.

We are working on better Mathematica integration for vectors, and hopefully there will be some progress on this in the next version of SystemModeler.
POSTED BY: Malte Lenz
The problem is in the For loop over the parameter values. If you evaluate
 WSMParameterValues -> {For[i = 1, i <= 3, i++,
       ToExpression[StringJoin["\"gStart[", ToString[i], "]\""]] -> init2[[i]]  ] }
In a separate cell you'll see that it comes out as
WSMParameterValues -> {Null}

Instead change to:
Table[ToExpression[StringJoin["\"gStart[", ToString[i], "]\""]] ->
  init2[[i, 1, 1]], {i, 3}]
Which evaluates to:
{"gStart[1]" -> 10., "gStart[2]" -> 20., "gStart[3]" -> 15.}

I hope this helps.
POSTED BY: Peter Aronsson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract