Mathematica 中的目标简化

发布于 2024-08-11 02:47:40 字数 1861 浏览 1 评论 0原文

我生成一般形式的非常长且复杂的分析表达式:

(...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)]

“Changing Times”的东西到合适的头,如 PlusPower 来实现它可以非常准确地确定简化目标。不过,仍然存在的问题如下: Simplify< /a> 仍将下降到比 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 限制到一定程度(s)?

我意识到这种限制可能不会产生最佳结果,但这里的想法是得到“足够好”的东西。

I generate very long and complex analytic expressions of the general form:

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

When I try to use Simplify, Mathematica grinds to a halt, I am assuming due to the fact that it tries to expand the brackets and or simplify across different brackets. The brackets, while containing long expressions, are easily simplified by Mathematica on their own. Is there some way I can limit the scope of Simplify to a single bracket at a time?

Edit: Some additional info and progress.

So using the advice from you guys I have now started using something in the vein of

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)]

Changing Times to an appropriate head like Plus or Power makes it possible to target the simplification quite accurately. The problem / question that remains, though, is the following: Simplify will still descend deeper than the level specified to Replace, e.g.

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

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

simplifies the square root as well.

My plan was to iteratively use Replace from the bottom up one level at a time, but this clearly will result in vast amount of repeated work by Simplify and ultimately result in the exact same bogging down of Mathematica I experienced in the outset. Is there a way to restrict Simplify to a certain level(s)?

I realize that this sort of restriction may not produce optimal results, but the idea here is getting something that is "good enough".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冷清清 2024-08-18 02:47:40

有多种方法可以做到这一点,但这可能有点棘手,并且取决于实际表达式的结构。然而,通常括号中多项项的乘积会有头部 Times,您可以使用 FullForm 来验证这一点:

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

您可以使用高阶函数 < a href="http://reference.wolfram.com/mathematica/ref/Map.html" rel="nofollow noreferrer">Map ,其头部为 Times< 的表达式/code> 与带有头 List 的表达式使用它的方式相同,这可以让您一次简化 表达式一项,如下所示:

Map[Simplify, yourGinormousExpression]

您可以使用如果您随后需要,展开结果展开括号。

编辑添加:如果您想指定要简化的形式,可以使用替换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 的第二项。但需要记住的一件事是,某些转换是由 TimesPlus 自动完成的;例如,即使不使用 Simplifya + a 也会变成 2 a

There are a number of ways you can do this, but it can be a little tricky and depends on the structure of your actual expression. However, usually a product of a number of terms in brackets will have the head Times, and you can use FullForm to verify this:

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

You can use the higher-order function Map with expressions with head Times the same way you use it with expressions with head List, and that may allow you to Simplify the expression one term at a time, like so:

Map[Simplify, yourGinormousExpression]

You can use Expand on the result if you need to subsequently expand out the brackets.

EDIT to add: If you want to specify the forms that you do want to simplify, you can use Replace or ReplaceAll instead of one of the relatives of Map. Replace is particularly useful because it takes a level specification, allowing you to only affect the factors in the topmost product. As a simple example, consider the following:

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]

If you don't want to simplify factors that depend on a. you can do this instead:

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

Only the second term, which depends on b, has been changed. One thing to bear in mind though is that some transformations are done automatically by Times or Plus; for instance a + a will be turned into 2 a even without use of Simplify.

落花随流水 2024-08-18 02:47:40

我不敢苟同我的同事,因为使用 MapSimplify 应用于每个子表达式可能不会节省任何时间,因为它仍然会应用于每个子表达式。相反,请尝试 MapAt< /a>,如下:

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

棘手的部分是确定位置规范。不过,如果您要简化的表达式位于第一级,那么它应该不会比我上面写的更困难。


现在,如果您仍然想简化一切,但希望保留一些结构,请尝试使用选项 排除表格。过去,我曾经用来防止这种简化:

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 的第二个参数是用于假设的,并且可以极大地简化您的操作。努力将你的表达变成有用的形式。

I beg to differ with my colleagues, in that using Map to apply Simplify to each subexpression may not save any time as it will still be applied to each one. Instead try, MapAt, as follows:

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

The tricky part is determining the position specification. Although, if the expression you want to simplify is at the first level, it shouldn't be any more difficult then what I've written above.


Now if you would still like to simplify everything, but you wish to preserve some structure, try using the option ExcludedForms. In the past, I've used to prevent this simplification:

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

which Mathematica seems to like, so I do

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

Also, don't forget that the second parameter for Simplify is for assumptions, and can greatly ease your struggles in getting your expressions into a useful form.

记忆で 2024-08-18 02:47:40

您应该尝试地图
一般来说,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]

Note,您可以表示 Map[foo, expr] als foo /@ expr 如果您觉得这样更方便。

You should try Map.
In general, Map[foo, G[a, b, c, ...]] gives G[foo[a], foo[b], foo[c], ...] for any head G and any expression foo, so for

  Map[Simplify, a b c d e]

it gives

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

Note you can denote Map[foo, expr] als foo /@ expr if you find that more convenient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文