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 ---
丹尼尔·利赫特布劳