о процессе построения графика - еще один вопрос о «проблеме в Mathematica 8 с объявлением функции» - PullRequest
5 голосов
/ 19 мая 2011

Связано Проблема в 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;

Разница оценки между functionB1 и functionB2 может быть обнаружена командой Trace в mma, как показано ниже:

functionB1[Sqrt[0.2]] // Trace
functionB2[Sqrt[0.2]] // Trace 

У меня нет вопросов о функции B1. что меня озадачивает, это то, что , потому что 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 передается функции B2, но функция B2 дает функцию, а не число. Тогда как генерируется следующий рисунок?

enter image description here

И результат его трассировки (Plot[functionB2[Sqrt[x]], {x, 0, 1}] // Trace) кажется очень нечитаемым. Интересно, чёткий процесс прорисовки функции B2. Кто-нибудь может показать это?

спасибо ~:)

Ответы [ 3 ]

5 голосов
/ 19 мая 2011

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 явной:

    В [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 тоже делает. Вот почему вы все еще получаете сюжет.

5 голосов
/ 19 мая 2011

Определение:

functionB2[x_] := model /. fit

- это инструкция для Mathematica заменить все будущие вхождения выражения, которое выглядит как functionB2[x_], результатом замены значения аргумента для каждого вхождения x в выражении model /. fit. Но отсутствуют x в model /. fit: единственными символами в этом выражении являются model и fit (и, технически, 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 (например, functionB1) , полагаются на результат вычисления правой части, содержащей тот же символ, что и формальный аргумент. Это может быть источником незаметных ошибок, так как нужно позаботиться о том, чтобы не использовать символы, которые случайно имеют ранее существовавшие понижающие значения. Использование формальных символов (описанных в Буквы и Буквоподобные формы ) для имен аргументов может помочь решить эту проблему.

2 голосов
/ 19 мая 2011

Вы можете понять, что происходит, попробовав:

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}
*)

То, что заменяется, - это x внутри определения функции B2, а не формальный аргумент.

Редактировать

Сюжет, который вы получаете, не тот, который вы хотите. Sqrt[x] игнорируется в functionB2[...], и неявный x заменяется, как вы можете видеть здесь:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...