vec*_*r07 16 wolfram-mathematica simplify
我有一个非常复杂的mathematica表达式,我想通过使用一个新的,可能无量纲的参数来简化.
我的表达的一个例子是:
K=a*b*t/((t+f)c*d);
Run Code Online (Sandbox Code Playgroud)
(实际表达式是巨大的,数千个字符).我想用p替换所有出现的表达式t /(t + f)
p=t/(t+f);
Run Code Online (Sandbox Code Playgroud)
这里的目标是找到一个替代品,以便所有的t和f都被p代替.在这种情况下,替换p是一个无量纲化的参数,因此它似乎是一个很好的候选替代品.
我无法弄清楚如何在mathematica中做到这一点(或者如果可能的话).我试过了:
eq1= K==a*b*t/((t+f)c*d);
eq2= p==t/(t+f);
Solve[{eq1,eq2},K]
Run Code Online (Sandbox Code Playgroud)
毫不奇怪,这不起作用.如果有一种方法可以强制它用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;
Run Code Online (Sandbox Code Playgroud)
然后我替换p,并调用(正常)FullSimplify,给我这个表达式.
testEQ2= (ton (B ton^2 + A^2 B ton (toff + ton) +
A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;
Run Code Online (Sandbox Code Playgroud)
最后,我尝试了下面的所有建议,除了最后一个(不知道它是如何工作的!)
只有消除选项有效.所以我想我会从现在开始尝试这种方法.谢谢.
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
Run Code Online (Sandbox Code Playgroud)
我应该补充一点,如果目标是进行所有可能的替换,剩下剩下的,我仍然不知道该怎么做.但似乎如果替换可以完全消除一些变量,那么Eliminate []效果最好.
Nik*_*iki 11
你试过这个吗?
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)
Run Code Online (Sandbox Code Playgroud)
编辑:哦,你知道Eliminiate吗?
Eliminate[{eq1, eq2}, {t,f}]
-> a b p == c d K && c != 0 && d != 0
Solve[%, K]
-> {{K -> (a b p)/(c d)}}
Run Code Online (Sandbox Code Playgroud)
编辑2:此外,在这个简单的情况下,解决K和t同时似乎也可以做到这一点:
Solve[{eq1, eq2}, {K, t}]
-> {{K -> (a b p)/(c d), t -> -((f p)/(-1 + p))}}
Run Code Online (Sandbox Code Playgroud)
这些行中的内容将在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]]]]]]
Run Code Online (Sandbox Code Playgroud)
您的示例现在如下.我们接受输入,也替换.对于后者,我们通过清除分母来制作等价多项式.
kK = a*b*t/((t + f) c*d);
rep = Numerator[Together[p - t/(t + f)]];
Run Code Online (Sandbox Code Playgroud)
现在我们可以调用替换.我们列出了我们感兴趣的替换变量,将'p'作为参数处理.这样它的排序将低于其他排序,这意味着替换将尝试删除它们而不是'p'.
In[127]:= replacementFunction[kK, rep, {t, f}]
Out[127]= (a b p)/(c d)
Run Code Online (Sandbox Code Playgroud)
这种方法在确定列出的"变量"应该是什么时有一些魔力.可能会进行一些进一步的调整以改善这一点.但我相信,一般来说,根本不会列出我们想要用作新替代品的东西是正确的方法.
多年来,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]]
Run Code Online (Sandbox Code Playgroud)
---结束编辑2 ---
Daniel Lichtblau
K = a*b*t/((t+f)c*d);
FullSimplify[ K,
TransformationFunctions -> {(# /. t/(t + f) -> p &), Automatic}]
Run Code Online (Sandbox Code Playgroud)
(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]
Run Code Online (Sandbox Code Playgroud)
a1 == p (A B + A^2 B p + (A + B) p^2)
我不知道此时这是否有任何价值,但希望至少它有效.