1
$\begingroup$

I would like to define a variable that equals the solution of a numerical equation. Usually something like smax=zmax/.FindRoot[Exp[-zmax/2]==2,{zmax,0}] would work. The value of smax would be numerical. In the following, smax gets assigned the non-numerical string zmax instead of the numerical solution.

How to assign the numerical solution to a variable instead of assigning the label of the solution?

smin = -1;
h[z_] := Exp[-z/2]
smax=zmax/.Last @ Reap[
    NDSolveValue[
        {
        int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
        WhenEvent[int[z]==0, {"StopIntegration", Sow[z, "zmax"]}]
        },
        int,
        {z, smin, Infinity}
    ],
    _,
    #1 -> First@#2&
]

It seems I need to somehow delay the assignment until after the evaluation. I also tried

sol = Last@
  Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
     WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, 
int, {z, smin, Infinity}], _, #1 -> First@#2 &]
smax = zmax /. First@sol

and

sol = Last@
  Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
     WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, 
int, {z, smin, Infinity}], _, #1 -> First@#2 &]
smax = zmax /.sol

and

smax = Hold[
  zmax /. Last@
Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
   WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, 
  int, {z, smin, Infinity}], _, #1 -> First@#2 &]
]

The input forms of the output are

{InterpolatingFunction[
  {{-1., 
    0.9999999503483246}}, 
  {5, 7, 1, {29}, {4}, 0, 0, 
   0, 0, Automatic, {}, {}, 
   False}, {{-1., 
   -0.9999015069919955, 
   -0.9998030139839911, 
   -0.9941899410658487, 
   -0.9885768681477063, 
   -0.9829637952295639, 
   -0.9656960118691706, 
   -0.9484282285087774, 
   -0.9311604451483841, 
   -0.9138926617879909, 
   -0.8793570950672045, 
   -0.844821528346418, 
   -0.8102859616256315, 
   -0.775750394904845, 
   -0.7412148281840585, 
   -0.6364160981321162, 
   -0.5316173680801739, 
   -0.42681863802823167, 
   -0.3220199079762894, 
   -0.2172211779243471, 
   -0.11242244787240478, 
   0.09310080516319964, 
   0.25133693191093665, 
   0.38002571750014225, 
   0.5087145030893478, 
   0.6374032886785534, 
   0.7660920742677592, 
   0.8947808598569648, 
   0.9999999503483246}}, 
  {Developer`PackedArrayForm, 
   {0, 2, 4, 6, 8, 10, 12, 
   14, 16, 18, 20, 22, 24, 
   26, 28, 30, 32, 34, 36, 
   38, 40, 42, 44, 46, 48, 
   50, 52, 54, 56, 58}, {0., 
   -1.0421906109874948, 
   -0.00010263754935876063, 
   -1.0420795489780026, 
   -0.00020526416013504978, 
   -1.0419684894957806, 
   -0.006036157749020502, 
   -1.0356434260875778, 
   -0.011831571189832578, 
   -1.0293265200823063, 
   -0.017591550131026527, 
   -1.0230177217238963, 
   -0.03508953803441338, 
   -1.0036599518365754, 
   -0.05225392606613451, 
   -0.9843769993273269, 
   -0.06908597587427147, 
   -0.9651674267571602, 
   -0.08558694219637947, 
   -0.9460298021571588, 
   -0.11760052213606785, 
   -0.9079646957022863, 
   -0.1483042124375252, 
   -0.870170329566471, 
   -0.17770716293874222, 
   -0.8326354340838389, 
   -0.20581814386923664, 
   -0.7953488169584483, 
   -0.2326455374667564, 
   -0.7582993599269294, 
   -0.3062765350826772, 
   -0.6472108015918777, 
   -0.3683613617451538, 
   -0.5378996923572129, 
   -0.41907053594729565, 
   -0.43006582874627264, 
   -0.4585433186321676, 
   -0.32341306427417876, 
   -0.48688811403985527, 
   -0.21764849613430565, 
   -0.5041827660984485, 
   -0.11248166079293165, 
   -0.5061691280086447, 
   0.09313443278259884, 
   -0.47887710321230265, 
   0.2519989968825433, 
   -0.43807650845487345, 
   0.3823166468446675, 
   -0.3804094520455811, 
   0.5142177107173006, 
   -0.30563706497632676, 
   0.6482484738402796, 
   -0.21344968009960505, 
   0.7849640419787253, 
   -0.10346548870948925, 
   0.9249306403654647, 
   -3.0461744238152733*^-15, 
   1.0421905549989765}}, 
  {Automatic}], 
 {{0.9999999503483246}}}
$\endgroup$
6
$\begingroup$

Since your Last @Reap[...] returns {"zmax" -> 1.} you should use "zmax" in ReplaceAll:

rule = Last@Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
         WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, 
     int, {z, smin, Infinity}], _, #1 -> First@#2 &];
smax = "zmax" /. rule

1.

Alternatively, you can use one-argument form of Reap and simply get Part (2,1,1) of Reap[...] output:

out = Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, 
         WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, int,
     {z, smin, Infinity}]];
smax = out[[2, 1, 1]]

1.

$\endgroup$
  • $\begingroup$ Both solutions still assign the label zmax to smax for me, not the numerical value 1.. I copy-pasted your solutions, so it is interesting that the results differ. $\endgroup$ – Sander Heinsalu Jun 18 at 14:21
  • $\begingroup$ @Sander, try starting with fresh kernel, or use ClearAll[smax, zmax] before you execute the relevant code. If you still have the same issue it is probably version/os issue. Both methods work without issue in version 9 /windows10 and version 12 /wolfram cloud. $\endgroup$ – kglr Jun 18 at 14:34
  • $\begingroup$ Quitting and restarting the kernel, quitting and restarting Mathematica and ClearAll did not change anything: the label zmax is still assigned, not 1.. Using Ubuntu 18.04, Mathematica 11.3. $\endgroup$ – Sander Heinsalu Jun 18 at 14:39
  • $\begingroup$ @Sander, interesting. Can you post the input forms of the outputs from Last@Reap[ NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, int, {z, smin, Infinity}], _, #1 -> First@#2 &] and from Reap[NDSolveValue[{int'[z] == (Exp[z] - 1) h[z], int[smin] == 0, WhenEvent[int[z] == 0, {"StopIntegration", Sow[z, "zmax"]}]}, int, {z, smin, Infinity}]]? $\endgroup$ – kglr Jun 18 at 14:48
  • $\begingroup$ Not sure what the input forms of the outputs are (Googling didn't help), but the outputs are {"zmax" -> 1.} and {InterpolatingFunction[*small picture*],{{1.}}} where the small picture says Domain: {{-1.,1.}} Output:scalar $\endgroup$ – Sander Heinsalu Jun 18 at 15:00
1
$\begingroup$

The posted code uses "zmax" (with quotes) to Sow the value, but uses zmax (without quotes) for the call to ReplaceAll. Removing the quotes returns the expected numerical value. (At least it does that in Mathemematica 12.0 under Windows 10.)

BTW: Both solutions from kgrl work for me (with Mathematica 12.0)

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.