Ответ 1
Основной пример
Вот пример из книги Леонида Шифрина Математическое программирование: расширенное введение
Это отличный ресурс для такого рода вопросов. Смотрите: (1) (2)
ClearAll[a, b]
a = RandomInteger[{1, 10}];
b := RandomInteger[{1, 10}]
Table[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
2 x
x = 7;
f
14
x = 3;
f
6
Полезно иметь в виду, как правила хранятся внутри страны. Для символов, которым присвоено значение symbol = expression
, правила сохраняются в OwnValues
. Обычно (но не всегда), OwnValues
содержит только одно правило. В этом конкретном случае
In[84]:= OwnValues[f]
Out[84]= {HoldPattern[f] :> 2 x}
Важной для нас сейчас является r.h.s., которая содержит x
как символ. Что действительно важно для оценки, эта форма - способ сохранения правил внутри страны. Пока x
не имеет значения в момент назначения, оба Set
и SetDelayed
производят (создают) то же правило выше в глобальной базе правил, и это все, что имеет значение. Таким образом, они эквивалентны в этом контексте.
Конечным результатом является символ 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))