My problem is essentially to do with manipulating and storing Sow data in a nested loop structure.
I have a set of differential equations describing time-evolution of a bunch of variables. Eventually I want the initial conditions i0, j0, k0
to be parameters. I have a range for each of these that I want to scan over. Eventually, I want to find out the t
value at which point i[t]==1
.
So far I can set up an NDSolveValue taking parameteres, and Reap for a specific set of parameters.
test[i0_, j0_, k0_] := NDSolveValue[{coupled nonlinear first order ODEs,
i[0] == i0, j[0] == j0, k[0] == k0, WhenEvent[i[t] == 1, Sow@{i0, j0, k0};
Sow[t]]}, {i, j, k}, {t, 0, 15}];
test[0.4, 0.001, 0.03]; // Reap
The output makes sense, giving the t-value as 11.2293 for this case which seems correct:
{Null, {{{0.4, 0.001, 0.03}, 11.2293}}}
I have been struggling with scanning across a specified i0, j0, k0
range. Here is something that kind of works (StopIntegration is to avoid a pole that happens at some late t):
Table[Table[Table[
NDSolveValue[{the ODEs, i[0] == i0, j[0] == j0, k[0] == k0,
WhenEvent[i[t] == 1, Print[t,i0,j0,k0];
Sow[t, {i0,j0,k0}]; "StopIntegration"]}, {i, j, k}, {t, 0, 25}],
{i0,0.3, 0.4, 0.1}], {j0, 0.0001, 0.005, 0.001}], {k0, 0.1, 0.5, 0.1}]
And this gives me:
22.1212....0.3....0.0001....0.1
11.2014....0.4....0.0001....0.1
6.79366....0.5....0.0001....0.1
22.1209....0.3....0.0021....0.1
etc. (ellipses added by me)
for each combination of values, which also seem correct. However, I am struggling with saving these results in a proper data (.dat) file. I want to ultimately make a table with columns i0, j0, j0, t
which can be exported as a .dat file. Ideally, I would also like to append to this table the columns f(i0,j0,k0), g(i0,j0,k0)
, which are certain functions of the values. How do I create a professional data table out of this data (I've been using 'Print' because I don't know how to use Sow/Reap data properly)?
Edit: If I add Reap@ to the start of the expression it gives me a list of t-values for i0=i1 then for i0=i2 then i0=i3, that is, for each constant i from the i range, with the others varying; followed by a list of t-values for j0=j1,....
At this stage my query is mainly to do with formatting the data, i.e. generating a neat exportable table. How do I convert the Reap output into a data table?
Any help would be appreciated!
ijk={{.4,.001,.03},{.6,.002,.06},{.8,.004,.1}}
Now run my code once for each of those three triples? Or run my code for every possible subset of those 9 values? Can you show precisely how you want the result to be a matrix of values from the 3 runs? Maybe skip getting confused with writing the code and just clearly tell someone exactly what calculations you want them to do and exactly how you want them to save the results. $\endgroup${ {tlist(i1)}, {tlist(j1), {tlist(k1)}, {tlist(i2)}, {tlist (j2)}...}
where by tlist(i1) I mean the t-value for all the permutations with i0=i1 (first element in i-list). This has all the data I need, except I would ultimately like a table with columns t,i0, j0, k0
. $\endgroup$Reap[Table[Table[Table[stuff;Sow[{t,{i,j,k}}],{i,..}],{j,..}],{k,..}]]
tonBy4Matrix=Reap[Do[stuff;Sow[{t,i,j,k}],{i,...},{j,...},{k,...}]][[2,1]]
and see if you get a nice n by 4 matrix for all your i,j,k values. Then you can doMatrixForm[nBy4Matrix]
and see if that gives you your formatting. $\endgroup$