12

この議論は前の質問で出てきました.2つの違いを知りたいです. 例のイラストがいいでしょう。

4

3 に答える 3

16

基本的な例

Leonid Shifrin の著書Mathematica プログラミングからの例を次に示します。

この種の質問には優れたリソースです。参照: (1) (2)

ClearAll[a, b]

a = RandomInteger[{1, 10}];

b := RandomInteger[{1, 10}]
テーブル[a, {5}]
  {4、4、4、4、4}
Table[b, {5}]
  {10、5、2、1、3}

複雑な例

上記の例は、シンボルの定義が を使用して作成されるSetと、その値は固定され、変更されないという印象を与える可能性があります。そうではありません。

f = ...代入時にf評価される式に代入します。シンボルがその評価された式に残り、後でそれらの値が変更された場合、 の見かけの値も変更されます。f

ClearAll[f, x]

f = 2 x;
f
x = 7;
f
  14
x = 3;
f
  6

ルールが内部でどのように保存されているかを覚えておくと便利です。として値が割り当てられたシンボルの場合symbol = expression、ルールは に保存されOwnValuesます。通常 (常にではありませんが)、OwnValues1 つのルールのみが含まれます。この特定のケースでは、

In[84]:= OwnValues[f]

Out[84]= {HoldPattern[f] :> 2 x}

x現在、私たちにとって重要な部分は、シンボルとして含まれている rhsです。評価にとって本当に重要なのは、この形式、つまりルールが内部に保存される方法です。x割り当ての時点で が値を持っていない限り、 と の両方がグローバル ルール ベースで上記の同じルールSetSetDelayed生成 (作成) し、それがすべてです。したがって、これらはこのコンテキストでは同等です。

f計算された値は の現在の値に依存するため、最終結果は関数のような動作を持つシンボルになりますx。ただし、これはパラメーターを持たず、シンボルの変更のみをトリガーするため、真の関数ではありませんx。一般に、グローバルシンボル(変数)への暗黙の依存関係は、他の言語と同様に Mathematica でも悪いため、このような構造の使用はお勧めできません.コードを理解しにくくし、バグをより微妙で見落としやすくします. 多少関連する議論はここで見つけることができます。


関数に使用されるセット

Set関数に使用できますが、必要な場合もあります。例を挙げましょう。ここでMathematica はSumをシンボリックに解き,それをaF(x)に代入し,プロットに使用します.

ClearAll[aF, x]

aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]

ここに画像の説明を入力

一方、使用しようとする場合は、SetDelayedプロットする各値をSum関数に渡します。これは非常に遅くなるだけでなく、少なくとも Mathematica 7 では完全に失敗します。

ClearAll[aF, x]

aF[x_] := Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]

x新しい関数を定義するプロセスで、仮パラメーター (ここ) の可能なグローバル値が干渉せず、無視されることを確認したい場合Clearは、代わりに定義をラップBlockします。

ClearAll[aF, x];
x = 1;
Block[{x}, aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}]];

関数の定義を見ると、必要なものが得られていることが確認できます。

?aF
Global`aF
aF[x_]=-(x/(-1+x+x^2))
于 2011-03-16T02:22:20.677 に答える
9
In[1]:= Attributes[Set]

Out[1]= {HoldFirst, Protected, SequenceHold}

In[2]:= Attributes[SetDelayed]

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

属性からわかるように、どちらの関数も最初の引数 (割り当て先のシンボル) を保持しますが、SetDelayed は 2 番目の引数も保持し、Set は保持しないという点で異なります。これは=、代入が行われた時点で Set が式を右に評価することを意味します。:=SetDelayed は、変数が実際に使用されるまで、式の右側を評価しません。

代入の右側に副作用がある場合 (例: Print[])、何が起こっているのかがより明確になります。

In[3]:= x = (Print["right hand side of Set"]; 3)
x
x
x

During evaluation of In[3]:= right hand side of Set

Out[3]= 3

Out[4]= 3

Out[5]= 3

Out[6]= 3

In[7]:= x := (Print["right hand side of SetDelayed"]; 3)
x
x
x

During evaluation of In[7]:= right hand side of SetDelayed

Out[8]= 3

During evaluation of In[7]:= right hand side of SetDelayed

Out[9]= 3

During evaluation of In[7]:= right hand side of SetDelayed

Out[10]= 3
于 2011-03-16T03:27:51.317 に答える
3

:=基本的に、関数を定義するためのもの=であり、値を設定するためのものです。

つまり:=、読み取り時に=評価され、設定時に評価されます。

について考える:

x = 2
y = x
z := x
x = 4

ここで、y がまだ 2 であるときに評価すると、z は 4 です。

于 2011-03-16T02:20:58.680 に答える