关于绘图过程 - 关于“Mathematica 8中的函数声明问题”的另一个问题

时间:2011-05-19 11:59:18

标签: wolfram-mathematica

相关A problem in Mathematica 8 with function declaration

Clear["Global`*"]

model = 4/Sqrt[3] - a1/(x + b1) - a2/(x + b2)^2 - a3/(x + b3)^4;
fit = {a1 -> 0.27, a2 -> 0.335, a3 -> -0.347, b1 -> 4.29, b2 -> 0.435,
b3 -> 0.712};

functionB1[x_] = model /. fit;
functionB2[x_] := model /. fit;

functionM1和functionB2之间的评估差异可以通过mma中的Trace命令显示,如下所示:

functionB1[Sqrt[0.2]] // Trace
functionB2[Sqrt[0.2]] // Trace 

我对functionB1毫无疑问。 让我感到困惑的是,因为functionB2[Sqrt[0.2]]甚至不提供数字结果但是给出了x 4/Sqrt[3] - 0.335/(0.435 + x)^2 + 0.347/(0.712 + x)^4 - 0.27/( 4.29 + x)的函数,然后它的情节Plot[functionB2[Sqrt[x]], {x, 0, 1}]是如何可能的?

我的意思是当你运行Plot[functionB2[Sqrt[x]], {x, 0, 1}]时,mma内部会发生什么:

x取一个数字,比方说0.2,然后0.2最终传递给functionB2,但是functionB2给出一个函数,而不是一个数字。那么如何生成下图?

enter image description here

其跟踪结果(Plot[functionB2[Sqrt[x]], {x, 0, 1}] // Trace)似乎非常难以理解。我想知道functionB2的清晰绘图过程。任何人都可以展示它吗?

谢谢〜:)

3 个答案:

答案 0 :(得分:5)

SetDelayed充当范围构建。如有必要,参数将进行本地化。 显式匹配参数的任何变量都绑定在此范围内,其他变量不是。

In[78]:= a[x_] := x^2 + b
         b = x^4;

(* the first x^2 is explicitly present and bound to the argument. 
   The x in x^4 present via b is not bound *)

In[80]:= a[x]

Out[80]= x^2 + x^4 (* this is what you would expect *)

In[81]:= a[y]

Out[81]= x^4 + y^2 (* surprise *)

In[82]:= a[1]

Out[82]= 1 + x^4 (* surprise *)

所以,你可以做的是两件事之一:

  • 使用EvaluatefunctionB2[x_] := Evaluate[model /. fit];
  • model依赖于x explicit:

    在[68]中:= model2 [x_] =   4 / Sqrt [3] - a1 /(x + b1) - a2 /(x + b2)^ 2 - a3 /(x + b3)^ 4;

    在[69]中:= functionB3 [x_]:= model2 [x] /。适合;

    在[85]中:= functionB3 [Sqrt [0.2]]

    Out [85] = 2.01415

由于问题更新,

修改 由于你定义了functionB2,任何参数值都会产生相同的结果,如上所述:

In[93]:= functionB2[1]

Out[93]= 4/Sqrt[3] - 0.335/(0.435 + x)^2 + 0.347/(0.712 + 
   x)^4 - 0.27/(4.29 + x)

In[94]:= functionB2["Even a string yields the same ouput"]

Out[94]= 4/Sqrt[3] - 0.335/(0.435 + x)^2 + 0.347/(0.712 + 
   x)^4 - 0.27/(4.29 + x)

但是,这个表达式包含x,因此如果我们为x提供数值,它可以得到一个数值:

In[95]:= functionB2["Even a string yields the same ouput"] /. x -> 1

Out[95]= 2.13607

嗯,这基本上也是Plot所做的。这就是为什么你仍然得到一个情节。

答案 1 :(得分:5)

定义:

functionB2[x_] := model /. fit

是Mathematica的一条指令,用于替换表达式functionB2[x_]的所有未来出现的结果,其结果是在表达式x中每次出现model /. fit时替换参数的值}。但 x中没有出现model /. fit:该表达式中唯一的符号是modelfit(从技术上讲,{{ 1}})。因此,无论参数如何,定义都会返回固定的结果ReplaceAll。实际上,定义可能只是:

model /. fit

如果您绘制functionB2a[] := model /. fit ,则会得到与绘制functionB2a[]时相同的结果。为什么?因为functionB2[anything]会在绘图范围内改变符号Plot时评估该表达式。恰好x评估了涉及该符号的表达式,因此您获得了展示的情节。

现在考虑model /. fit

functionB1

它也表示要替换右侧的所有functionB1[x_] = model /. fit - 但这次在定义建立之前评估右侧。评估x的结果是 包含符号model /. fit的表达式,因此现在定义对传递的参数值敏感。最终结果就好像这样定义了函数:

x

因此,如果您绘制functionB1a[x_] := 4/Sqrt[3]-0.335/(0.435+x)^2+0.347/(0.712+x)^4-0.27/(4.29+x) functionB1[Sqrt[x]]命令将看到表达式:

Plot

正式符号

使用4/Sqrt[3]-0.335/(0.435 +Sqrt[x])^2+0.347/(0.712 +Sqrt[x])^4-0.27/(4.29 +Sqrt[x]) 建立定义时,形式参数的名称(在本例中为SetDelayed)与定义之外的同一符号的出现无关。此类定义可以使用任何其他符号,并仍然生成相同的结果。另一方面,使用x(例如Set建立的定义依赖于评估包含与形式参数相同的符号的右侧的结果。这可能是微妙错误的根源,因为必须注意不要使用意外具有预先存在的降值的符号。在参数名称中使用形式符号(在Letters and Letter-like Forms中描述)可以帮助解决这个问题。

答案 2 :(得分:2)

您可以通过尝试来了解正在发生的事情:

Table[functionB2[Sqrt[y]],{y,0.5,.5,.5}]
Table[functionB2[Sqrt[x]],{x,0.5,.5,.5}]
(*
{4/Sqrt[3] - 0.335/(0.435+ x)^2 + 0.347/(0.712+ x)^4 - 0.27/(4.29+ x)}
{2.03065}
*)

被替换的是functionB2定义中的x,而不是正式的参数。

修改

你得到的情节不是你想要的。 Sqrt[x]functionB2[...]被忽略,隐含的x被替换,您可以在此处看到:

enter image description here