0
$\begingroup$

EDIT: I believe this is not a duplicate question, because the answers to questions pointed to as similar DO NOT give practical solutions to the problems, at least not for normal Mathematica users like me (not computer science experts) who are endlessly confused by the arcane details of Set, SetDelayed, Evaluate, etc.

I thank Karsten 7 here who produced a practical, usable answer

EDIT: in view of the questions below, in particular Bill's one, here is the puzzling code. Manipulate and the first Plot do not work, the last Plot does. Why???:

f[x_] = a + c x^2 + d x^3;

sol = Solve[{f[0] == f0, f[1] == f1, f'[1] == ff1, f'[0] == 0}, {a, c, d}, Reals];

g[t_, f0_, f1_, ff1_] := f[t] /. sol[[1]];

Manipulate[
 Plot[g[t, f0, f1, ff1], {t, 0, 1}], {{f0, 0}, 0, 1}, {{f1, 1/2}, 0, 1}, {{ff1, 0}, -1, 0}]

Plot[g[t, 0.8, 0.9, -1/2], {t, 0, 1}]

Plot[g[t, f0, f1, ff1] /. {f0 -> 0.8, f1 -> 0.9, ff1 -> -1/2}, {t, 0, 1}]
$\endgroup$
14
  • $\begingroup$ Control variables will are localized within Manipulate. Have a look at Manipulate[{a, Hold[a]}, {a, 0, 1}]. $\endgroup$
    – Yves Klett
    Commented Dec 4, 2014 at 13:05
  • 2
    $\begingroup$ Better duplicate: 10604 (dup. 31322). Related: (18820) $\endgroup$
    – Michael E2
    Commented Dec 5, 2014 at 15:00
  • 1
    $\begingroup$ @Alberto, For people who find variable scoping an unnecessary nightmare visited upon users by CS demons, the solution Manipulate[..., LocalizeVariables -> False] is easier to understand and use than just about anything else. (Those to whom all variables being global is an abomination will shudder.) HTH. :) $\endgroup$
    – Michael E2
    Commented Dec 5, 2014 at 15:08
  • 1
    $\begingroup$ Leonid mentioned lexical scoping, which is the issue in your case, too. The explanation is that the symbols f0 etc. do not appear in the literal (lexical), unevaluated RHS f[t] /. sol[[1]]. This is related to SetDelayed in that the substitution of the parameters is done before the RHS is evaluated. Since t is the only parameter appearing in the RHS, it is the only one substituted. Then the RHS is evaluated and global symbols f0 etc. remain. Manipulate by default localizes symbols, so that the f0 in it is different than the global f0 in g[t]. $\endgroup$
    – Michael E2
    Commented Dec 5, 2014 at 20:02
  • 1
    $\begingroup$ @Alberto, btw, I would approach this particular problem with InterpolatingPolynomial: Manipulate[Plot[InterpolatingPolynomial[{{{0}, f0, 0}, {{1}, f1, ff1}}, t], {t, 0, 1}], {{f0, 0}, 0, 1}, {{f1, 1/2}, 0, 1}, {{ff1, 0}, -1, 0}]. I would have answered your related question, but the value of the interpolating polynomial sometimes exceeds 1, violating a condition of that question. $\endgroup$
    – Michael E2
    Commented Dec 5, 2014 at 20:03

1 Answer 1

2
$\begingroup$

The Problem

The Manipulate and the first Plot of your code don't work because you use a combination of SetDelayed (:=) and ReplaceAll (/.) that doesn't behave like you expected.

When you define

g[t_, f0_, f1_, ff1_] := f[t] /. sol[[1]]

and now evaluate

g[2, 1, 1, 1]

you get

f0 + 4 (-3 f0 + 3 f1 - ff1) + 8 (2 f0 - 2 f1 + ff1)

instead of the expacted

5

This happens because (due to the use of :=) f[t] on the rhs is first evaluated as f[2] (giving a + 4 c + 8 d) and then the replacement (/. sol[[1]]) is done.

Using Set instead of SetDelayed

If you replace := with =

g2[t_, f0_, f1_, ff1_] = f[t] /. sol[[1]]

then /. will be performed only once, when you define g2 and whenever you use g2 it is replaced by its rhs with the ReplacedAll already performed.

g2[2, 1, 1, 1]
5

Using Evaluate

You can also force the evaluation of the right-hand side by using Evaluate:

g3[t_, f0_, f1_, ff1_] := Evaluate[f[t] /. sol[[1]]]

This way the rhs is evaluated before it is SetDelayed as the definition of g3.

Definition@g3
g3[t_, f0_, f1_, ff1_] := f0 + (-3 f0 + 3 f1 - ff1) t^2 + (2 f0 - 2 f1 + ff1) t^3

Using an additional ReplaceAll

You can also use an additional /. to replace the parameters f0, f1, and ff1 with some values

g4[t_, pf0_, pf1_, pff1_] := f[t] /. sol[[1]] /. {f0 -> pf0, f1 -> pf1, ff1 -> pff1}

now

g4[2, 1, 1, 1]
5

This is similar to the last Plot in your code.

$\endgroup$
1
  • $\begingroup$ thank you - much appreciated. I do wish Mathematica found a way to remove these kind og problems, and get closer to human/mathematical normal conventions... it keeps it from being more widely used by professionals who would like to use it, but do not have months to spend to learn the intricacies (I use it intermittently, and when I get back to it after a few weeks I loose days in solving this trivial issues.) $\endgroup$
    – ac1965
    Commented Dec 5, 2014 at 14:39

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