Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I was just evaluating a couple of expressions and started to get errors like this:

General::ivar: -1.49994 is not a valid variable. >>
General::ivar: -1.43871 is not a valid variable. >>
General::ivar: -1.37749 is not a valid variable. >>
General::stop: Further output of General::ivar will be 
               suppressed during this calculation. >>

I'm doing nothing complicated - currently, I simply did this:

f[x_]:=x^2 + 2x + 1
Plot[f[x], {x, -4, 4}]
Solve[f[x] == 4]
g[x_]:=D[f[x], x]
Plot[g[x], {x, -2, 2}]
// ^ errors caused by this

Actually, this isn't the exact quadratic I am investigating, but it is a quadratic and I expected this to work. I googled, as you'd expect, and found this Stack Overflow question which suggested:

Plot[Evaluate[g[x]], {x, -2, 2}]

As a workaround.

It works - my question is, why doesn't that set of instructions generate that error (I can see it is something to do with replacing, but why is one plot different from the other?) and how can I avoid it? Is there something I should specifically have done in forming g?

share|improve this question
    
Or you could do g[x_] = D[f[x], x] (note that I changed SetDelayed to Set) before plotting... –  J. M. Feb 4 '12 at 14:01
    
@J.M. that works - got an explanation as to why? Would make a nice answer :) –  Ninefingers Feb 4 '12 at 14:07
2  
Related question: stackoverflow.com/questions/5320330/… –  Leonid Shifrin Feb 4 '12 at 15:02

3 Answers 3

up vote 18 down vote accepted

The problem lies in g[x_] := D[f[x], x]; remember that what SetDelayed (that is, :=) does is to replace stuff on the right corresponding to patterns on the left before evaluating. Thus, when one does something like g[2] (and something like this happens within Plot[]), you are in fact evaluating D[f[2], 2], and since one cannot differentiate with respect to a constant ;), you get the General::ivar error message.

If you use Set instead (that is, g[x_] = D[f[x], x]), f[x] is differentiated first before the result of D[] is assigned to g[x_]. Since what's on the right of g[x_] is now an actual function, Plot[] no longer has a reason to complain.

share|improve this answer

J. M. has already given you a good answer to your question on the General::ivar error and how to avoid it. I wanted to demonstrate another example in the same spirit, where the difference between Set and SetDelayed is important, but you don't have the luxury of getting an error message like you did in this case, because it isn't semantically/syntactically incorrect. This is a common pitfall to watch out for, and is often the cause of "slow" plotting.

Consider a function that's the result of an expensive (however slight) calculation defined using Set and SetDelayed, as:

f[x_] := (Pause[0.05]; Integrate[y^2, {y, 0, 1}] x)
g[x_] = (Pause[0.05]; Integrate[y^2, {y, 0, 1}] x);

Now let's monitor the time taken in plotting the two functions and the points plotted in each case with:

Module[{i = 0, t},
  t = (Plot[f[x], {x, 0, 1}, EvaluationMonitor :> i++]; // AbsoluteTiming // First);
  Print["Timing = ", t, ", Points = ", i, ", Time/Point = ",  t/i]
]

and replace f[x] with g[x] for the latter. I get the following for f[x] and g[x] respectively:

(*
f[x] — Timing = 4.289333, Points = 77, Time/Point = 0.05570562
g[x] — Timing = 0.001735, Points = 77, Time/Point = 0.00002253
*)

What's happening here is that Plot is evaluating f[x] for each plot point (time/point ≈ 0.05), which can result in a tremendous slow down in cases where the evaluation takes considerable time. On the other hand, if you use Set as in g[x], the expensive calculation is computed only once and only the result is stored as the definition for g[x], and hence Plot doesn't have to re-evaluate it. The alternative is to force evaluation of f[x] and pass the result to Plot and this can also be done by wrapping an Evaluate around f[x].

share|improve this answer
2  
I like this example. :) –  J. M. Feb 4 '12 at 15:21

As has already been explained by J. M., you need to evaluate the derivative.

When using the format g[x_] = D[f[x], x] I highly recommend either localizing x or using \[FormalX] (enter with Esc $x Esc) in its place:

Module[{x},
  g[x_] = D[f[x], x]
]

Or:

Mathematica graphics

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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