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

Fre*_*ple 5 wolfram-mathematica

相关Mathematica 8中的函数声明问题

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;
Run Code Online (Sandbox Code Playgroud)

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

functionB1[Sqrt[0.2]] // Trace
functionB2[Sqrt[0.2]] // Trace 
Run Code Online (Sandbox Code Playgroud)

我对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的清晰绘图过程.有人可以展示吗?

谢谢〜:)

Sjo*_*ies 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 *)
Run Code Online (Sandbox Code Playgroud)

那么,你能做的是两件事之一:

  • 用途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]]

    出[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)
Run Code Online (Sandbox Code Playgroud)

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

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

Out[95]= 2.13607
Run Code Online (Sandbox Code Playgroud)

嗯,这基本上Plot也是如此.这就是为什么你仍然得到一个情节.


WRe*_*ach 5

定义:

functionB2[x_] := model /. fit
Run Code Online (Sandbox Code Playgroud)

是Mathematica的指令以替换,看起来像一个表达式的所有将来重复functionB2[x_]与的每次出现替换参数的值的结果x中的表达model /. fit.但是,没有出现xmodel /. fit:在表达式中唯一的符号modelfit(和,在技术上,ReplaceAll).因此,model /. fit无论参数如何,定义都会返回固定的结果.实际上,定义可能只是:

functionB2a[] := model /. fit
Run Code Online (Sandbox Code Playgroud)

如果您绘制functionB2a[],您将获得与绘制时相同的结果functionB2[anything].为什么?因为Plotx在绘图范围内改变符号时评估该表达式.它恰好model /. fit评估了涉及该符号的表达式,因此您可以获得展示的图表.

现在考虑functionB1:

functionB1[x_] = model /. fit
Run Code Online (Sandbox Code Playgroud)

它也说要替换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)
Run Code Online (Sandbox Code Playgroud)

所以,如果你绘图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])
Run Code Online (Sandbox Code Playgroud)

正式符号

使用时建立定义时SetDelayed,形式参数的名称(x在本例中)与定义之外的同一符号的出现无关.此类定义可以使用任何其他符号,并仍然生成相同的结果.另一方面,使用Set(例如functionB1)建立的定义依赖于评估包含与形式参数相同的符号的右侧的结果.这可能是微妙错误的根源,因为必须注意不要使用意外具有预先存在的降值的符号.对参数名称使用形式符号(在字母和字母形式中描述)可以帮助管理这个问题.


Dr.*_*ius 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}
*)
Run Code Online (Sandbox Code Playgroud)

被替换的是xfunctionB2 的定义内部,而不是形式参数。

编辑

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

在此输入图像描述