Подтвердить что ты не робот

Почему Replace и ReplaceAll дают разные результаты, даже если используется только одно правило и одно выражение?

Может кто-то может объяснить мне, почему Replace дает другой ответ, чем ReplaceAll, хотя я использую одно правило, и, я думаю, у меня есть одно выражение.

Согласно документации:

ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to 
the next part of expr. The first rule that applies to a particular part is used; no 
further rules are tried on that part, or on any of its subparts

и для замены

A list of rules can be given. The rules are tried in order. The result of the first 
one that applies is returned. If none of the rules apply, the original expr is 
returned.

У меня есть это выражение:

z/(0.5 -1.4 z+z^2)

и это одно правило

z -> Exp[I*w]

Следующий вход

Clear[z]
hz = z/(0.5 - 1.4 z + z^2);
Replace[hz, z -> Exp[I*w]]
ReplaceAll[hz, z -> Exp[I*w]]

дает этот результат:

z/(0.5 -1.4 z+z^2)                    (*from Replace*)
E^(I w)/(0.5 -1.4 E^(I w)+E^(2 I w))  (*from ReplaceAll*)

Итак, ReplaceAll выполнил задание, которое я ожидал, но не Replace. Единственное, что, я думаю, здесь отсутствует, - это то, что делает части выражения. Так может быть, hz не является "одним" выражением? Хорошо, хорошо, но тогда он должен был бы применить правило, по крайней мере, к одной его части. Но он ничего не заменил

FullForm[hz]
Times[z,Power[Plus[0.5`,Times[-1.4`,z],Power[z,2]],-1]]

Разве это не одно выражение? Если нет, сколько у него частей? Является ли это числом листьев в конце графика, сгенерированным TreeForm[hz]? Если да, то я вижу там 3 'z', а Replace[] должен заменить один из них

enter image description here

Я всегда использовал /., не думая об этом, что совпадает с ReplaceAll, но теперь я использовал Replace[], мышление было таким же, как /., я нашел это и заметил разные функции. (так много функций, чтобы учиться, так мало времени:)

4b9b3361

Ответ 1

Фактически, Replace и ReplaceAll не совпадают. Вы можете придумать Replace как более точную версию, так как с помощью Replace вы можете указать уровни в выражении, по которому вы хотите, чтобы замены выполнялись. Разница здесь несколько похожа на то, что между Map и MapAll, за исключением тонкости, что ReplaceAll не работает с глубиной (см. Ниже). Другое отличие, также довольно тонкое, заключается в том, что Replace принимает параметр Heads, а ReplaceAll - нет, что делает Replace еще точнее, чем ReplaceAll.

По умолчанию Replace работает только на уровне 0, который является целым выражением. Однако ваш z более глубокий:

In[220]:= Clear[z]
hz = z/(0.5 - 1.4 z + z^2);


Position[hz, z]

Out[222]= {{1}, {2, 1, 2, 2}, {2, 1, 3, 1}}

Если вы используете спецификацию уровня для Replace, вы можете добиться эффекта, подобного, но не всегда такого же, как у ReplaceAll:

In[223]:= Replace[hz,z->Exp[I*w],{0,Infinity}]

Out[223]= E^(I w)/(0.5\[VeryThinSpace]-1.4 E^(I w)+E^(2 I w))

Разница между Replace с lev.spec {0,Infinity} и ReplaceAll заключается в том, что первая действует в первом выражении, подвыражения перед выражениями, а последняя работает от более крупных выражений к их частям. Это обсуждается более подробно, например. здесь. Один пример, когда эта разница была использована для одного преимущества, можно найти в этой статье.

Возвращаясь к поведению Replace по умолчанию, которое работает со всем выражением: очень полезно, когда вы хотите преобразовать только все выражение, но ни одна из его частей (которая может случайно соответствовать шаблону в вашем правиле). Одним из примеров такого применения Replace является здесь.

Ответ 2

Я думаю, что соответствующий бит документации для Replace: "применяет правило или список правил в попытке преобразовать все выражение expr", т.е. преобразовать все выражение. Таким образом,

Replace[z, z -> Exp[I*w]]

преобразует z в Exp[I*w], но ваш пример терпит неудачу, потому что правило не соответствует всему выражению.

Обратите внимание, что Replace принимает аргумент level spec; поэтому, чтобы работать на концах листьев вашего дерева, попробуйте

Replace[hz, z -> Exp[I*w], -1]

дает

E^(I w)/(0.5 -1.4 E^(I w)+E^(2 I w))