Mathematica 还处于早期,所以请原谅可能是一个非常明显的问题。我正在尝试生成一些参数图。我有:

ParametricPlot[{
    (a + b) Cos[t] - h Cos[(a + b)/b t],
    (a + b) Sin[t] - h Sin[(a + b)/b t]},
    {t, 0, 2 \[Pi]}, PlotRange -> All] /. {a -> 2, b -> 1, h -> 1}

不高兴:没有应用替换规则, abh 保持未定义。

如果我改为:
Hold@ParametricPlot[{
    (a + b) Cos[t] - h Cos[(a + b)/b t],
    (a + b) Sin[t] - h Sin[(a + b)/b t]},
    {t, 0, 2 \[Pi]}, PlotRange -> All] /. {a -> 2, b -> 1, h -> 1}

正如输出所证实的那样,看起来规则正在起作用:
Hold[ParametricPlot[{(2 + 1) Cos[t] -
1 Cos[(2 + 1) t], (2 + 1) Sin[t] - 1 Sin[(2 + 1) t]}, {t, 0,
2 \[Pi]}, PlotRange -> All]]

这是我所期望的。但是,去掉 HoldParametricPlot 不起作用。不过,方程或 ParametricPlot 本身没有任何问题,因为我尝试在单独的表达式 ( a=2; b=1; h=1 ) 中设置 a、b 和 h 的值,并且我按预期得到了漂亮的双心形。

那么,我在使用 ReplaceAll 时做错了什么,为什么转换规则不起作用?这是 MMA 的另一个基本重要方面,我被 OOP 毁了的大脑不理解。

我尝试阅读 ReplaceAllParametricPlot ,我发现的最接近的线索是“ParametricPlot 具有属性 HoldAll 并且仅在将特定数值分配给变量后评估 f”,这没有多大帮助,否则我不会在这里。

谢谢。

最佳答案

Mathematica 通过首先计算每个子表达式的 head 来计算每个 head 而不保存属性。由于 ReplaceAll 没有保持属性,因此 ParametricPlot 在替换前变为 Graphics
要查看表达式树,请执行

ParametricPlot[{(a + b) Cos[t] - h Cos[(a + b)/b t], (a + b) Sin[t] -
      h Sin[(a + b)/b t]}, {t, 0, 2 \[Pi]},
    PlotRange -> All] /. {a -> 2, b -> 1, h -> 1} // Hold // TreeForm

从那棵树你可以看到你的命令和做的一样
temp1=ParametricPlot[{(a + b) Cos[t] - h Cos[(a + b)/b t], (a + b) Sin[t] -
          h Sin[(a + b)/b t]}, {t, 0, 2 \[Pi]},
        PlotRange -> All]
temp2={a -> 2, b -> 1, h -> 1}
temp1/.temp2

查看 FullForm[temp1] 以确认该表达式中没有 ab

如果您将 ReplaceAll 设置为 HoldFirst ,这会阻止 ParametricPlot 在 ReplaceAll 之前被评估,结果就是您所期望的。在这种情况下, ReplaceAll 计算为带有 h​​ead ParametricPlot 的表达式,并且仅在该点计算 ParametricPlot 。确保重新设置属性,因为更改内置命令的行为可能会产生意想不到的副作用。
SetAttributes[ReplaceAll, HoldFirst];
ParametricPlot[{(a + b) Cos[t] - h Cos[(a + b)/b t], (a + b) Sin[t] -
    h Sin[(a + b)/b t]}, {t, 0, 2 \[Pi]},
  PlotRange -> All] /. {a -> 2, b -> 1, h -> 1}
ClearAttributes[ReplaceAll, HoldFirst]

例如,当需要使用 HoldAll 评估传递给函数的参数时,一个有用的技巧是使用 List 头对表达式进行操作,并在最后替换 ParametricPlot
ParametricPlot @@ ({{(a + b) Cos[t] -
      h Cos[(a + b)/b t], (a + b) Sin[t] - h Sin[(a + b)/b t]}, {t, 0,
      2 \[Pi]}, PlotRange -> All} /. {a -> 2, b -> 1, h -> 1})

关于wolfram-mathematica - ReplaceAll 没有按预期工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4520658/

10-13 06:04