Solve函數計算的結果為什麼不能分步轉換成函數?

使用Solve求解方程,求得的解可以保存成函數使用,但我試了兩種方法,只有第一種起作用,從語義上說完全一樣,只是第二種是分兩步做的,為什麼會這樣?

第一種:

第二種:


方法一中由於 SetDelayed (:=)有 HoldAll 這個屬性,會阻止右手邊的定義表達式中 sol[[1]] 被進一步取值為 y -&> 3-x。你可以把方法一修改為 f[x_] = y /. sol[[1]] 來解決這個問題。Set (=) 和 SetDelayed (:=) 的區別可以看看文檔「立即定義和延時定義」。可以根據適用性選擇用 SetDelayed(:=)定義函數 f[x_] := ... 或用 Set(=)定義函數 f[x] := ... 。

遇到這類貌似迷惑的問題,經常可以用 DownValues 和 TracePrint 來「解謎」。比如你可以用 DownValues[f] 和 TracePrint[f[5]] 觀察一下兩種方法下 f 函數的定義究竟如何不同,以及 f[5] 的求值步驟又具體是怎樣的(若不熟悉這兩個函數,可以看他們的文檔和示例):

方法一:

In[98]:= sol = Solve[x + y == 3, y]

Out[98]= {{y -&> 3 - x}}

In[99]:= f[x_] := y /. sol[[1]]

In[100]:= f[5]
f[6]

Out[100]= 3 - x

Out[101]= 3 - x

In[102]:= DownValues[f]

Out[102]= {HoldPattern[f[x_]] :&> (y /. sol[[1]])}

(* 注意這裡函數定義的右手邊 x 沒有顯式出現。*)

In[64]:= Attributes[SetDelayed]

Out[64]= {HoldAll, Protected, SequenceHold}

In[104]:= TracePrint[f[5]]

During evaluation of In[104]:= f[5]

During evaluation of In[104]:= f

During evaluation of In[104]:= 5

During evaluation of In[104]:= y/. sol[[1]]

During evaluation of In[104]:= ReplaceAll

During evaluation of In[104]:= y

During evaluation of In[104]:= sol[[1]]

During evaluation of In[104]:= Part

During evaluation of In[104]:= sol

During evaluation of In[104]:= {{y-&>3-x}}

During evaluation of In[104]:= 1

During evaluation of In[104]:= {{y-&>3-x}}[[1]]

During evaluation of In[104]:= {y-&>3-x}

During evaluation of In[104]:= y/. {y-&>3-x}

During evaluation of In[104]:= 3-x

Out[104]= 3 - x

方法二:

...

In[94]:= DownValues[f]

Out[94]= {HoldPattern[f[x_]] :&> (y /. Solve[x + y == 3, y][[1]])}

(* 注意 x 在函數定義中顯示出現了 *)

In[95]:= TracePrint[f[5]]

During evaluation of In[95]:= f[5]

During evaluation of In[95]:= f

During evaluation of In[95]:= 5

During evaluation of In[95]:= y/. Solve[5+y==3,y][[1]]

(* f[5] 求值的第一步即把在函數定義中顯式出現的 x 取值為 x=5;方法一中 x 在定義里沒有顯式出現,所以也沒有被取值為 x=5。 *)

During evaluation of In[95]:= ReplaceAll

During evaluation of In[95]:= y

During evaluation of In[95]:= Solve[5+y==3,y][[1]]

During evaluation of In[95]:= Part

During evaluation of In[95]:= Solve[5+y==3,y]

During evaluation of In[95]:= Solve

During evaluation of In[95]:= 5+y==3

During evaluation of In[95]:= Equal

During evaluation of In[95]:= 5+y

During evaluation of In[95]:= Plus

During evaluation of In[95]:= 5

During evaluation of In[95]:= y

During evaluation of In[95]:= 3

During evaluation of In[95]:= y

During evaluation of In[95]:= 5+y==3

During evaluation of In[95]:= 5+y==3

During evaluation of In[95]:= 5+y==3

During evaluation of In[95]:= {{y-&>-2}}

During evaluation of In[95]:= List

During evaluation of In[95]:= {y-&>-2}

During evaluation of In[95]:= List

During evaluation of In[95]:= y-&>-2

During evaluation of In[95]:= Rule

During evaluation of In[95]:= y

During evaluation of In[95]:= -2

During evaluation of In[95]:= y-&>-2

During evaluation of In[95]:= Rule

During evaluation of In[95]:= y

During evaluation of In[95]:= -2

During evaluation of In[95]:= {y-&>-2}

During evaluation of In[95]:= {{y-&>-2}}

During evaluation of In[95]:= 1

During evaluation of In[95]:= {{y-&>-2}}[[1]]

During evaluation of In[95]:= {y-&>-2}

During evaluation of In[95]:= y/. {y-&>-2}

During evaluation of In[95]:= -2

Out[95]= -2


推薦閱讀:

這張圖中能數出多少個三角形?
如何系統的學習Mathematica?
Mathematica 里如何查看函數內部代碼?
為什麼在 Mathematica 中使用循環是低效的?

TAG:WolframMathematica |