Помощь с Mathematica: использование /. заменить метод на условие IF[]

Позвольте мне сначала сказать, что я новичок в Mathematica, и на этот вопрос, вероятно, легко ответить, но я до сих пор не смог найти никакой помощи для этой конкретной проблемы в Интернете. Здесь я в основном резюмировал, что мне нужно, чтобы мой код делал. Возникла проблема с использованием команды замены /. с условным оператором IF. По сути, у меня есть очень длинная функция, которая содержит другую функцию, которая определяется глобально с помощью условного выражения IF. Эти несколько строк кода демонстрируют ошибку, с которой я сталкиваюсь...

In[1]:= y[x_, z_] = 2*x + 3*z;

In[2]:= zz[x_, z_] := If[y[x, z] < 0, 4*y[x, z], y[x, z]]

In[3]:= zz[-1, -2]

Out[3]= -32

Но мне нужно...

In[4]:= zz[x_, z_] /. x -> -1 /. z -> -2

Out[4]= If[3 Pattern[-2, _] + 2 Pattern[-1, _] < 0, 
 4 y[Pattern[-1, _], Pattern[-2, _]], 
 y[Pattern[-1, _], Pattern[-2, _]]]

что не дает ожидаемого числового члена. Заранее благодарю всех за помощь, как бы глупо ни звучал этот вопрос. Примечание. Я должен использовать команду замены, а не напрямую присваивать значение x и z.

ДОБАВЛЕНИЕ:

Я слишком упростил свой пример. Возьмите этот пример:

In[91]:= a[b_, c_] = -3*b + 2*c + d + e + f;

In[92]:= g[b_, c_] := If[a[b, c] < 0, -3*a[b, c], a[b, c]];

In[10]:= g[2, 4] /. d -> 1 /. e -> 2 /. f -> 3

Out[10]= 2 + d + e + f

Но я ожидаю увидеть результат Out[10]= 8

Надеюсь, еще одно легкое исправление.


person ZB18749    schedule 24.05.2011    source источник
comment
Вы пробовали zz[x, z] /. x -> -1 /. z -> -2 без символа подчеркивания?   -  person Howard    schedule 24.05.2011
comment
Спасибо, вы оба правы... Я слишком упростил свой пример. Возьмем такой пример: In[91]:= a[b_, c_] = -3*b + 2*c + d + e + f; В [92]:= g[b_, c_] := If[a[b, c] ‹ 0, -3*a[b, c], a[b, c]]; In[10]:= g[2, 4] /. д -> 1 /. е -> 2 /. f -> 3 Out[10]= 2 + d + e + f Но я ожидаю увидеть результат Out[10]= 8 Надеюсь, еще одно легкое исправление.   -  person ZB18749    schedule 25.05.2011


Ответы (2)


Когда вы определяете функцию, вы используете x_, что говорит системе mathematica найти шаблон с именем x и применить к нему определение. Итак, f[x_]=x^2 говорит "взять выражение x и преобразовать его как Power[x,2]".

Когда вы вызываете функцию, вы больше не используете шаблон, а используете переменную или значение, которое mathematica в конечном итоге заменяет x. Таким образом, f[a] даст вам a^2, если a не определено, или используйте определение для a и выдайте соответствующий результат.

Итак, как упомянул Ховард в комментарии, если вы просто удалите символы подчеркивания, вы получите желаемое выражение.

In[1]:= zz[x, z] /. x -> -1 /. z -> -2

Out[1]= -32

ИЗМЕНИТЬ

Чтобы ответить на ваш комментарий,

If оценивает второй и третий аргументы только после оценки условия. Итак, если вы посмотрите на g[2,4], вы получите

If[2 + d + e + f < 0, -3 a[2, 4], a[2, 4]]

вы видите, что операторы "тогда" и "иначе" остаются невычисленными, хотя a[2,4] сам по себе дает вам 2 + d + e + f.

Таким образом, когда вы делаете замены, mathematica начинает заменять d,e,f везде, где она находит в выражении (которое есть только в условии), и как только она оценивает условие и достигает шагов «тогда» или «еще», больше нечего делать. заменять.

Что вам нужно использовать, так это ReplaceAll или //., которые многократно применяют правила до тех пор, пока их больше нельзя будет применять. Вот как

In[2]:= rules = {d -> 1, e -> 2, f -> 3};
        g[2, 4] //. rules
Out[2]= 8
person abcd    schedule 24.05.2011
comment
Спасибо, вы оба правы... Я слишком упростил свой пример. Возьмем такой пример: In[91]:= a[b_, c_] = -3*b + 2*c + d + e + f; В [92]:= g[b_, c_] := If[a[b, c] ‹ 0, -3*a[b, c], a[b, c]]; In[10]:= g[2, 4] /. д -> 1 /. е -> 2 /. f -> 3 Out[10]= 2 + d + e + f Но я ожидаю увидеть результат Out[10]= 8 Надеюсь, еще одно легкое исправление. - person ZB18749; 25.05.2011
comment
'код' В [91]: = a[b_, c_] = -3*b + 2*c + d + e + f; В [92]:= g[b_, c_] := If[a[b, c] ‹ 0, -3*a[b, c], a[b, c]]; In[10]:= g[2, 4] /. д -> 1 /. е -> 2 /. f -> 3 Out[10]= 2 + d + e + f 'code' Но я ожидаю увидеть результат Out[10]= 8 - person ZB18749; 25.05.2011

Я предлагаю этот вариант вашего кода «Добавления»:

a[b_, c_] = -3*b + 2*c + d + e + f;

g[b_, c_] := If[# < 0, -3*#, #] & @ a[b, c]

g[2, 4] /. {d -> 1, e -> 2, f -> 3}

(* Out = 8 *)

Изменения:

  1. Переместите оператор If в чистую функцию, отдельную от a[b, c]. Таким образом, a[b, c] оценивается только один раз, что обычно является хорошей практикой.

  2. Переместите свои замены в одну /. операцию и список правил. Опять же, хорошая практика, если вы действительно не собираетесь серийную замену.

В этом случае первое изменение решает вашу проблему, потому что g[2, 4] оценивается как:

If[2 + d + e + f < 0, -3 (2 + d + e + f), 2 + d + e + f]

который явно использует d, e и f. Таким образом, они видны ReplaceAll (/.), и замены работают корректно.

Вполне вероятно, что есть лучший способ достичь вашей цели, но я воздержусь от угадывания остальной части вашего кода.

person Mr.Wizard    schedule 25.05.2011