Целевое Упрощение в Mathematica - PullRequest
6 голосов
/ 17 ноября 2009

Я генерирую очень длинные и сложные аналитические выражения общего вида:

(...something not so complex...)(...ditto...)(...ditto...)...lots...

Когда я пытаюсь использовать Simplify, Mathematica останавливается, я полагаю, из-за того, что он пытается расширить скобки или упростить их в разных скобках. Скобки, хотя и содержат длинные выражения, легко упрощаются Mathematica самостоятельно. Можно ли как-то ограничить область действия Simplify одной скобкой за раз?

Редактировать: Некоторая дополнительная информация и прогресс.

Поэтому, пользуясь советом от вас, ребята, я теперь начал использовать что-то в духе

In[1]:= trouble = Log[(x + I y) (x - I y) + Sqrt[(a + I b) (a - I b)]];

In[2]:= Replace[trouble, form_ /; (Head[form] == Times) :> Simplify[form],{3}]

Out[2]= Log[Sqrt[a^2 + b^2] + (x - I y) (x + I y)]

Изменение Times на соответствующую головку, такую ​​как Plus или Power, позволяет достаточно точно нацелиться на упрощение. Проблема / вопрос, который остается, тем не менее, заключается в следующем: Simplify все равно будет опускаться глубже, чем уровень, указанный в Replace, например,

In[3]:= Replace[trouble, form_ /; (Head[form] == Plus) :> Simplify[form], {1}]

Out[3]= Log[Sqrt[a^2 + b^2] + x^2 + y^2]

также упрощает квадратный корень.

Мой план состоял в том, чтобы итеративно использовать Replace снизу вверх на один уровень за раз, но это, очевидно, приведет к огромному количеству повторных работ к Simplify и в конечном итоге это приводит к тому же тупому падению Mathematica, которое я испытал в самом начале. Есть ли способ ограничить Simplify определенным уровнем (уровнями)?

Я понимаю, что такого рода ограничения могут не дать оптимальных результатов, но идея в том, чтобы получить что-то "достаточно хорошее".

Ответы [ 3 ]

4 голосов
/ 17 ноября 2009

Есть несколько способов сделать это, но это может быть немного сложнее и зависит от структуры вашего фактического выражения. Однако обычно продукт, состоящий из нескольких терминов в скобках, имеет заголовок Times, и вы можете использовать FullForm, чтобы проверить это:

In[1]:= FullForm[(a+b)(c+d)]
Out[1]= Times[Plus[a, b], Plus[c, d]]

Вы можете использовать функцию высшего порядка Map с выражениями с головой Times так же, как вы используете ее с выражениями с головой List, и это может позволить вам Simplify выражение по одному члену за раз, например, так:

Map[Simplify, yourGinormousExpression]

Вы можете использовать Expand для результата, если вам необходимо впоследствии расширить скобки.

ИЗМЕНИТЬ, чтобы добавить: Если вы хотите указать формы, которые вы хотите упростить, вы можете использовать Replace или ReplaceAll вместо одного из родственников Map. Replace особенно полезен, поскольку он требует спецификации уровня , что позволяет вам влиять только на факторы в самом верхнем продукте. В качестве простого примера рассмотрим следующее:

In[1]:= expr = Sqrt[(a + 1)/a] Sqrt[(b + 1)/b];

In[2]:= Simplify[expr]
Out[2]= Sqrt[1 + 1/a] Sqrt[1 + 1/b]

Если вы не хотите упрощать факторы, зависящие от a. Вы можете сделать это вместо:

In[3]:= Replace[expr, form_ /; FreeQ[form, a] :> Simplify[form], {1}]
Out[3]= Sqrt[(1 + a)/a] Sqrt[1 + 1/b]

Был изменен только второй член, который зависит от b. Однако следует иметь в виду, что некоторые преобразования выполняются автоматически с помощью Times или Plus; например, a + a будет преобразовано в 2 a даже без использования Simplify.

2 голосов
/ 17 ноября 2009

Я позволю себе не согласиться с моими коллегами, поскольку использование Map для применения Simplify к каждому подвыражению может не сэкономить время, поскольку оно все равно будет применяться к каждому. Вместо этого попробуйте MapAt следующим образом:

In[1]:= MapAt[f, SomeHead[a,b,c,d], {4}]
Out[1]:= SomeHead[a, b, c, f[d]]

Сложная часть определяет спецификацию позиции. Хотя, если выражение, которое вы хотите упростить, находится на первом уровне, оно не должно быть более сложным, чем то, что я написал выше.


Теперь, если вы все еще хотите все упростить, но хотите сохранить некоторую структуру, попробуйте использовать опцию ExcludedForms. В прошлом я использовал для предотвращения этого упрощения:

In[2]:= Simplify[d Exp[I (a + b)] Cos[c/2]]
Out[2]:= Exp[I(a + b + c)](d + d Exp[c])

что Mathematica, кажется, нравится, поэтому я делаю

In[3]:= Simplify[d Exp[I (a + b)] Cos[c/2], ExcludedForms -> {_Cos,_Sin}]
Out[3]:= d Exp[I (a + b)] Cos[c/2]

Кроме того, не забывайте, что второй параметр для Simplify предназначен для допущений и может значительно облегчить вашу работу по переводу выражений в полезную форму.

1 голос
/ 17 ноября 2009

Вы должны попробовать Map.
В общем, Map[foo, G[a, b, c, ...]] дает G[foo[a], foo[b], foo[c], ...] для любой головы G и любого выражения foo, поэтому для

  Map[Simplify, a b c d e]

дает

  Simplify[a] Simplify[b] Simplify[c] Simplify[d] Simplify[e]

Обратите внимание, что вы можете обозначить Map[foo, expr] als foo /@ expr, если считаете это более удобным.

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