C# 用MathNet符号提取公共项

C# 用MathNet符号提取公共项,c#,symbolic-math,math.net,mathnet-numerics,C#,Symbolic Math,Math.net,Mathnet Numerics,我正在使用MathNet符号来处理我正在处理的程序的符号代数部分。一般用途是创建一对符号公式,然后将这两个公式分开。这在大多数情况下都很有效。然而,有时,它不想做更复杂的简化。例如: (512*r*t*w + 2048*r*t^2*w) ----------------------------------------------------------------------- (512*r*t*w + 512*r^2*t*w + 3072*r*t^

我正在使用MathNet符号来处理我正在处理的程序的符号代数部分。一般用途是创建一对符号公式,然后将这两个公式分开。这在大多数情况下都很有效。然而,有时,它不想做更复杂的简化。例如:

                       (512*r*t*w + 2048*r*t^2*w)
-----------------------------------------------------------------------
(512*r*t*w + 512*r^2*t*w + 3072*r*t^2*w + 3072*r^2*t^2*w + 1024*r*t^3*w)
通过一些工作,我已经能够让它从方程中消除
w
,因为它在所有方面都是顶部和底部:

                    (512*r*t + 2048*r*t^2)
--------------------------------------------------------------
(512*r*t + 512*r^2*t + 3072*r*t^2 + 3072*r^2*t^2 + 1024*r*t^3)
但是,我不知道如何让它找到通用术语:

         (512*r*t)*(1 + 4*t)
--------------------------------------
(512*r*t)(1 + r + 6*t + 6*r*t + 2*t^2)
并删除这些术语:

         (1 + 4*t)
-----------------------------
(1 + r + 6*t + 6*r*t + 2*t^2)
我一直使用Wolfram Alpha作为我检查工作的金标准。我下午大部分时间都在编写LinqPad中的代码,这让我消除了
w

var h1=MathNet.Symbolics.Infix.ParseOrUndefined(“(1/8)*r*t*w+(1/2)*r*t^2*w”);
var h2=MathNet.Symbolics.Infix.ParseOrUndefined(“(1/8)*r*t*w+(1/8)*r^2*t*w+(3/4)*r*t^2*w+(3/4)*r^2*t^2*w+(1/4)*r*t^3*w”);
Infix.Print(Rational.Expand(h1/h2)).Dump()//打印(512*r*t*w+2048*r*t^2*w)/(512*r*t*w+512*r^2*t*w+3072*r*t^2*w+3072*r^2*t^2*w+1024*r*t^3*w)
var tot=Rational.Expand(h1/h2);
var=true;
做
{
简化=假;
foreach(Rational.Variables(tot)中的var v)
{
var结果=多项式除法(v,h1,h2);
如果(!result.Item1.Equals(MathNet.Symbolics.Expression.Zero))
{
简化=正确;
tot=结果项1;
打破
}
}
}而(简化);
tot=Rational.Expand(tot);
Infix.Print(tot.Dump()//打印(512*r*t+2048*r*t^2)/(512*r*t+512*r^2*t+3072*r*t^2+3072*r^2*t^2+1024*r*t^3)

有人能给我指点一下如何继续使用MathNet吗?我尝试了
Rational
polymonal
中的各种函数组合,但一直未能超越这一点。

我刚刚发布了一个新的Math.NET Symbolics发行版,其中包括一个新的
Rational.Reduce
例程,该例程删除了这些常见的简单因素(也作为
Rational.Expand的一部分执行):


不幸的是,相当多的单变量多项式和有理函数例程(如新的无平方分解)还没有多元对应。单变量例程需要一个符号参数,而多元例程需要一个符号集。

非常好,谢谢。除此之外,还有我周末做的一些工作(反复调用
Rational。简化每个变量的
,然后看看它是否减少了操作数),我现在得到了更自然的结果。今天晚些时候,我可能会有另一个问题,关于处理有理数,最好保留为十进制(例如:58916322729/20480000000000000000000).或者至少能够在打印等式时强制使用十进制形式。如果我们有这样一个变体,那么决定何时求值和取整的规则是什么?只有所有有理数?所有的项都不包括符号?函数也应该求值吗?我一直在思考这个问题。在我的特定用例中,它只是真正的needed有一种情况我想说要么是印刷品上的变体()这会将有理数转换为实数,或者能够在表达式中包含实数。我尝试了文档中提到的变量路径,但由于可能的系数太多,这导致表达式包含数千个项。如果在库端没有简单的解决方案,我的计划是只查找带有j的paren对ust数字和a/,然后将其替换为十进制。引入一种新的表达式类型可能是可行的,我们称之为
常量
,它的行为类似于符号,但有一个值和一些附加的自动简化规则来计算算术运算。然后,解析器可以将十进制表达式解释为这样的表达式常数而不是精确的有理数。
var h1 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/2)*r*t^2*w");
var h2 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w");

var q1 = h1/h2;
Infix.Print(q1);
// returns: ((1/8)*r*t*w + (1/2)*r*t^2*w)/((1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w)

var q2 = Rational.Expand(q1);
Infix.Print(q2);
// returns: (1 + 4*t)/(1 + r + 6*t + 6*r*t + 2*t^2)