相关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给出一个函数,而不是一个数字。那么如何生成下图?
其跟踪结果(Plot[functionB2[Sqrt[x]], {x, 0, 1}] // Trace
)似乎非常难以理解。我想知道functionB2的清晰绘图过程。任何人都可以展示它吗?
谢谢〜:)
答案 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 *)
所以,你可以做的是两件事之一:
Evaluate
:functionB2[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
:该表达式中唯一的符号是model
和fit
(从技术上讲,{{ 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被替换,您可以在此处看到: