0
$\begingroup$

I'm trying to iterate some expression through for loop:

 a = 0; b = 0.1; ϵ = 0.01; Ns = 100;
 lhr[t_] := Normal[Series[-k7 x[t] y[t] /. Nsol /. initConst, {t, 0, Ns}]][[1]]; lhr[t]
 rhr1[t_] := Normal[Series[-k7 x[t] y[t] /. Nsol /. initConst, {t, 0, Ns}]][[1]]; rhr1[t]
 h = 0.01
 For[t = a, t < b, t += h; 
   If[Abs[lhr[t]] < ϵ*Max[Abs[rhr1[t]]], Print[t]]]

I'm getting following errors:

General::ivar: 0.01` is not a valid variable. >>
General::ivar: 0.01` is not a valid variable. >>
General::ivar: 0.01` is not a valid variable. >>
General::stop: Further output of General::ivar will be suppressed during this calculation. >>

Can you help with this problem?

$\endgroup$
  • 1
    $\begingroup$ Please include complete code (what areNsol,initConst?). In any case, the ; in the For is incorrect. $\endgroup$ – ciao May 17 '14 at 9:45
  • $\begingroup$ Hi wizar and welcome to Mathematica.SE. Don't set h outside the For loop. It's causing a clash. $\endgroup$ – Verbeia May 17 '14 at 10:49
  • 2
    $\begingroup$ the ivar error is not in the For loop, but in Series. You need to use some other variable for the series expansion, then substitute the numeric value of t: Normal[Series[ f[x] ,{x,0,Ns}]] /. x->t $\endgroup$ – george2079 May 17 '14 at 11:57
  • $\begingroup$ For[t = a, t < b, t += h; If[Abs[lhr[t]] < ϵ Max[Abs[rhr1[t]]], Print[t]]] should be For[t = a, t < b, t += h, If[Abs[lhr[t]] < ϵ Max[Abs[rhr1[t]]], Print[t]]]; that is, comma not semicolon after h. $\endgroup$ – m_goldberg May 17 '14 at 21:15
1
$\begingroup$

Others have mentioned two important points:

  • you really should provide a working example
  • your problem is actually not really with For but with the evaluation of your series expansion.

the latter you can solve relatively easy by using Set (=) instead of SetDelayed (:=) in your definitions, e.g.:

lhr[t_] = Normal[Series[-k7 x[t] y[t] /. Nsol /. initConst, {t, 0, Ns}]][[1]];

That has also the advantage that the series expansion is only done once, not for every new numeric value of t again.

You almost certainly will run into problems when you work with this, though: As For does not localize its variables it will leave t set to the last value in the loop. If you then change your definitions and reevaluate them, they won't work because they expect t to be a symbol without a numeric value. To prevent that, you probably want to localize t at definition time, like so:

Module[{t},
lhr[t_] = Normal[Series[-k7 x[t] y[t] /. Nsol /. initConst, {t, 0, Ns}]][[1]];
]

This is also a good example why For loops in Mathematica always are (at most) the second best choice, as I have explained in this answer. Here Do[...,{t,a,b,h}] (or Do[...,{t,a,b-h/2,h}] if you insist on the < vs. <=) would be shorter and -- at least in my opinion -- much clearer. It would do the same thing but additionally localize t and thus not leave t behind with a value defined. Note that I have added a section about the differences how the two will handle numeric errors potentially accumulating in the loop variable in the answer mentioned which might be of interest for your use case.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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