【问题标题】:Get mathematica to simplify expression with another equation获取mathematica 用另一个方程简化表达式
【发布时间】:2011-11-10 00:15:00
【问题描述】:

我有一个非常复杂的数学表达式,我想通过使用一个新的、可能是无量纲的参数来简化它。

我的表达的一个例子是:

K=a*b*t/((t+f)c*d);

(实际表达式非常大,有数千个字符)。我想用 p

替换所有出现的表达式 t/(t+f)
p=t/(t+f);

这里的目标是找到一个替换,以便所有的 t 和 f 都被 p 替换。在这种情况下,替换 p 是一个无量纲参数,因此它似乎是一个很好的候选替换。

我无法弄清楚如何在数学中做到这一点(或者如果可能的话)。我试过了:

eq1= K==a*b*t/((t+f)c*d);
eq2= p==t/(t+f);
Solve[{eq1,eq2},K]

毫不奇怪,这不起作用。如果有办法强制它以 p、a、b、c、d 的形式求解 K ,这可能会奏效,但我也不知道该怎么做。想法?


编辑 #1 (11/10/11 - 1:30) [删除以简化]

好的,新的技巧。我取了 p=ton/(ton+toff) 并将 p 乘以几个表达式。我知道 p 可以完全消除。新的表达式(以 p 表示)是

testEQ = A B p + A^2 B p^2 + (A+B)p^3;

然后我替换了 p,并调用了(正常的)FullSimplify,给了我这个表达式。

testEQ2= (ton (B ton^2 + A^2 B ton (toff + ton) + 
   A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;

最后,我尝试了以下所有建议,除了最后一个(还不确定它是如何工作的!)

只有消除选项有效。所以我想我会从现在开始尝试这种方法。谢谢。

EQ1 = a1 == (ton (B ton^2 + A^2 B ton (toff + ton) + 
        A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;
EQ2 = P1 == ton/(ton + toff);
Eliminate[{EQ1, EQ2}, {ton, toff}]

A B P1 + A^2 B P1^2 + (A + B) P1^3 == a1

我应该补充一点,如果目标是进行所有可能的替换,留下其余部分,我仍然不知道该怎么做。但似乎如果一个替换可以完全消除一些变量,Eliminate[] 效果最好。

【问题讨论】:

  • f 是否也出现在要替换的表达式之外?因为否则只是替换 f->t/p-t 应该可以解决问题。
  • celt--替换 f->t/p-t 不会消除 t! f 可能会或可能不会出现在“p”之外的情况中。这是一个 31,000 个字符的表达式,但如果所有的 t、f 都被扩展,它可能只是一个简单的替换。巫师——会看看那些家伙。
  • 它应该消除所有t/(t+f)s(简化后),因为 t/(t+(t/p-t)) = t/(t/p) = p。但无论如何,如果 f 可以出现在该表达式之外,那么这个解决方案当然不适用。
  • 好的,这些很有帮助。对 Mathematica 来说还是比较新的,给我一点尝试这些想法。

标签: wolfram-mathematica simplify


【解决方案1】:

你试过了吗?

K = a*b*t/((t + f) c*d);
Solve[p == t/(t + f), t]
 -> {{t -> -((f p)/(-1 + p))}}

Simplify[K /. %[[1]] ]
 -> (a b p)/(c d)

编辑:哦,你知道Eliminiate吗?

Eliminate[{eq1, eq2}, {t,f}]
 -> a b p == c d K && c != 0 && d != 0

Solve[%, K]
 -> {{K -> (a b p)/(c d)}}

编辑 2: 此外,在这个简单的情况下,同时求解 Kt 似乎也可以解决问题:

Solve[{eq1, eq2}, {K, t}]
 -> {{K -> (a b p)/(c d), t -> -((f p)/(-1 + p))}}

【讨论】:

    【解决方案2】:

    MathGroup 帖子中讨论了这些方面的内容

    http://forums.wolfram.com/mathgroup/archive/2009/Oct/msg00023.html

    (我看到它有一个非常相关的伪经注释,至少与该帖子的作者非常相关。)

    这是在上面示例中的应用方式。为了保持这种独立性,我将重复替换代码。

    replacementFunction[expr_, rep_, vars_] := 
     Module[{num = Numerator[expr], den = Denominator[expr], 
       hed = Head[expr], base, expon}, 
      If[PolynomialQ[num, vars] && 
        PolynomialQ[den, vars] && ! NumberQ[den], 
       replacementFunction[num, rep, vars]/
        replacementFunction[den, rep, vars], 
       If[hed === Power && Length[expr] == 2, 
        base = replacementFunction[expr[[1]], rep, vars];
        expon = replacementFunction[expr[[2]], rep, vars];
        PolynomialReduce[base^expon, rep, vars][[2]], 
        If[Head[hed] === Symbol && 
          MemberQ[Attributes[hed], NumericFunction], 
         Map[replacementFunction[#, rep, vars] &, expr], 
         PolynomialReduce[expr, rep, vars][[2]]]]]]
    

    您的示例现在如下所示。我们接受输入,也接受替换。对于后者,我们通过清除分母来制作等价多项式。

    kK = a*b*t/((t + f) c*d);
    rep = Numerator[Together[p - t/(t + f)]];
    

    现在我们可以调用替换了。我们列出了我们有兴趣替换的变量,将“p”视为参数。这样,它的排序会比其他排序低,这意味着替换将尝试删除它们以支持 'p'。

    In[127]:= replacementFunction[kK, rep, {t, f}]
    Out[127]= (a b p)/(c d)
    

    这种方法在确定哪些应该是列出的“变量”方面有点神奇。可能会进行一些进一步的调整以改善这一点。但我相信,一般来说,简单地不列出我们想要用作新替代品的东西是正确的做法。

    多年来,MathGroup 上出现了这种想法的变体。其他一些可能更适合您希望处理的特定表达式。

    --- 编辑---

    这背后的想法是使用 PolynomialReduce 进行代数替换。也就是说,我们不尝试进行模式匹配,而是使用多项式“规范化”的一种方法。但总的来说,我们不使用多项式输入。因此,我们将这个想法递归地应用于 NumericQ 函数中的 PolynomialQ 参数。

    这个想法的早期版本以及更多解释可以在下面引用的注释中找到,以及它引用的注释(解释性递归如何?)。

    http://forums.wolfram.com/mathgroup/archive/2006/Aug/msg00283.html

    ---结束编辑---

    --- 编辑 2 ---

    正如在野外观察到的那样,这种方法并不总是一种简化方法。它进行代数替换,这在底层涉及“术语排序”的概念(粗略地说,“哪些事物被哪些其他事物替换?”)因此简单的变量可能会扩展到更长的表达式。

    另一种形式的术语重写是通过模式匹配进行句法替换,其他回复讨论了使用这种方法。它有一个不同的缺点,因为要考虑的模式的普遍性可能会变得压倒性的。例如,当规则是用 q 替换 k/(w + p^4) 时,如何处理 k^2/(w + p^4)^3? (具体来说,我们如何识别这等价于 (k/(w + p^4))^2*1/(w + p^4)?)

    结果是人们需要了解想要什么以及哪些方法可能是可行的。当然,这通常是针对特定问题的。

    发生的一件事是,您可能希望找到所有常见的“复杂”表达式并将其替换为更简单的表达式。这称为公共子表达式消除 (CSE)。在 Mathematica 中,这可以使用一个名为 Experimental`OptimizeExpression[] 的函数来完成。以下是讨论此问题的 MathGroup 帖子的几个链接。

    http://forums.wolfram.com/mathgroup/archive/2009/Jul/msg00138.html

    http://forums.wolfram.com/mathgroup/archive/2007/Nov/msg00270.html

    http://forums.wolfram.com/mathgroup/archive/2006/Sep/msg00300.html

    http://forums.wolfram.com/mathgroup/archive/2005/Jan/msg00387.html

    http://forums.wolfram.com/mathgroup/archive/2002/Jan/msg00369.html

    这是其中一个注释的示例。

    InputForm[Experimental`OptimizeExpression[(3 + 3*a^2 + Sqrt[5 + 6*a + 5*a^2] +
          a*(4 + Sqrt[5 + 6*a + 5*a^2]))/6]]
    
    Out[206]//InputForm=
    Experimental`OptimizedExpression[Block[{Compile`$1, Compile`$3, Compile`$4, 
       Compile`$5, Compile`$6}, Compile`$1 = a^2; Compile`$3 = 6*a; 
       Compile`$4 = 5*Compile`$1; Compile`$5 = 5 + Compile`$3 + Compile`$4; 
       Compile`$6 = Sqrt[Compile`$5]; (3 + 3*Compile`$1 + Compile`$6 + 
         a*(4 + Compile`$6))/6]]
    

    --- 结束编辑 2 ---

    丹尼尔·利希特布劳

    【讨论】:

    • Daniel,您能解释一下这段代码的作用吗?好像有点牵扯。
    • 我在使用向导 - 我很感兴趣,但我不知道函数中发生了什么。特别是,我对它的理解还不够,无法针对稍微不同的问题对其进行修改。
    • @Daniel Lichtblau,好的,我试着搞砸这个。我将您的函数视为黑盒,因为我真正不了解它是如何工作的。其实挺可爱的。对于我试图简化的实际表达式,它有时会变得更简单,有时不会!即使它无法消除变量,它也会进行替换,这在某些情况下很好,但在其他情况下则不然。为了好玩,我正在我的 GIANT 表达式上运行该函数,这可能需要几个小时。稍后会发布结果。
    • @vector07 见第二次编辑讨论这种“放大”现象和相关问题。
    • 又一个我从未见过的有趣的内部函数。请告诉我,为什么至少从 2002 年起这就是实验性的? (顺便说一句,已经 +1)
    【解决方案3】:
    K = a*b*t/((t+f)c*d);
    
    FullSimplify[ K, 
     TransformationFunctions -> {(# /. t/(t + f) -> p &), Automatic}]
    
    (a b p) / (c d)

    更正更新以显示另一种方法:

    EQ1 = a1 == (ton (B ton^2 + A^2 B ton (toff + ton) + 
            A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;
    
    f = # /. ton + toff -> ton/p &;
    
    FullSimplify[f @ EQ1]
    
    a1 == p (A B + A^2 B p + (A + B) p^2)

    目前我不知道这是否有任何价值,但希望至少它有效。

    【讨论】:

    • 好的,试过了。能够重现您在此处获得的结果,但对于稍微复杂的情况则无法重现。但是,条件是,我实际上并不知道替换 t/t+f 是否实际上足以从等式中消除 t 和 f。我在问题中添加了一个更复杂的示例。
    • @vector Eliminate 似乎确实更适合这项任务,尽管我更强大的转换函数可能也可以工作。在链接到评论中的类似问题后,我发布此答案主要是为了完整性。我会看看我是否可以使这种方法适用于您的新测试用例,但我怀疑其他答案会更好。我认为丹尼尔的回答是最有力的,但在我给它投票之前,我正在等待他的解释。
    • Wiz - 您的新解决方案是否将 ton 设置为 1?
    • @vector 嗯...是的。昨天我以为我有一个合乎逻辑的理由,但现在我不知道我在想什么。我会再试一次。感谢您给我打电话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多