使用 Math.NET 符号求解线性方程
Solving linear equation using Math.NET Symbolics
我尝试修改给定 的代码来求解 x 值的线性方程。比如
(3*x+7)/3+(2*x)/9=6/10
首先将它分成左右两个表达式,然后使用 "SolveSimpleRoot",它给出了 x 的值。但是如果把线性方程写成
的形式
(3+2*x)/(5*x-2)=7,你可以通过 (5*x-2) 多次遍历它并且确实是线性的然后代码在
// extract coefficients, solve known forms of order up to 1
MathNet.Symbolics.Expression[] coeff = MathNet.Symbolics.Polynomial.Coefficients(variable, simple);
错误为:
The input sequence was empty.Parameter name: source
如果表达式类似于 (2x+7)/x=2,它也无法解决,它仍然扩展为线性。
知道为什么吗?
代码基本上是:
public void solveForX()
{
string eqn = "(3*x+7)/3+(2*x)/9=6/10"
string[] expString = eqn.Split('=');
var x = MathNet.Symbolics.Expression.Symbol("x");
MathNet.Symbolics.Expression aleft = MathNet.Symbolics.Infix.ParseOrThrow(expString[0]);
MathNet.Symbolics.Expression aright = MathNet.Symbolics.Infix.ParseOrThrow(expString[1]);
ans = SolveSimpleRoot(x, aleft - aright);
SelectionInsertText(MathNet.Symbolics.Infix.Print(cx));
}
private MathNet.Symbolics.Expression SolveSimpleRoot(MathNet.Symbolics.Expression variable, MathNet.Symbolics.Expression expr)
{
// try to bring expression into polynomial form
MathNet.Symbolics.Expression simple = MathNet.Symbolics.Algebraic.Expand(MathNet.Symbolics.Rational.Simplify(variable, expr));
// extract coefficients, solve known forms of order up to 1
MathNet.Symbolics.Expression[] coeff = MathNet.Symbolics.Polynomial.Coefficients(variable, simple);
switch (coeff.Length)
{
case 1: return variable;
case 2: return MathNet.Symbolics.Rational.Simplify(variable, MathNet.Symbolics.Algebraic.Expand(-coeff[0] / coeff[1]));
default: return MathNet.Symbolics.Expression.Undefined;
}
}
您可以通过将两边与分母相乘来扩展它以支持这种有理数情况(因此有效地只取分子,Rational.Numerator
):
private Expr SolveSimpleRoot(Expr variable, Expr expr)
{
// try to bring expression into polynomial form
Expr simple = Algebraic.Expand(Rational.Numerator(Rational.Simplify(variable, expr)));
// extract coefficients, solve known forms of order up to 1
Expr[] coeff = Polynomial.Coefficients(variable, simple);
switch (coeff.Length)
{
case 1: return Expr.Zero.Equals(coeff[0]) ? variable : Expr.Undefined;
case 2: return Rational.Simplify(variable, Algebraic.Expand(-coeff[0] / coeff[1]));
default: return Expr.Undefined;
}
}
这样也可以处理(3+2*x)/(5*x-2)=7
。如果在这种情况下系数不等于零,我还将情况 1 固定为 return 未定义,因此另一个示例 (2*x+7)/x=2
的解决方案将按预期未定义。
当然,这仍然是一个非常简单的例程,无法处理任何高阶问题。
我尝试修改给定
(3*x+7)/3+(2*x)/9=6/10
首先将它分成左右两个表达式,然后使用 "SolveSimpleRoot",它给出了 x 的值。但是如果把线性方程写成
的形式(3+2*x)/(5*x-2)=7,你可以通过 (5*x-2) 多次遍历它并且确实是线性的然后代码在
// extract coefficients, solve known forms of order up to 1
MathNet.Symbolics.Expression[] coeff = MathNet.Symbolics.Polynomial.Coefficients(variable, simple);
错误为:
The input sequence was empty.Parameter name: source
如果表达式类似于 (2x+7)/x=2,它也无法解决,它仍然扩展为线性。
知道为什么吗?
代码基本上是:
public void solveForX()
{
string eqn = "(3*x+7)/3+(2*x)/9=6/10"
string[] expString = eqn.Split('=');
var x = MathNet.Symbolics.Expression.Symbol("x");
MathNet.Symbolics.Expression aleft = MathNet.Symbolics.Infix.ParseOrThrow(expString[0]);
MathNet.Symbolics.Expression aright = MathNet.Symbolics.Infix.ParseOrThrow(expString[1]);
ans = SolveSimpleRoot(x, aleft - aright);
SelectionInsertText(MathNet.Symbolics.Infix.Print(cx));
}
private MathNet.Symbolics.Expression SolveSimpleRoot(MathNet.Symbolics.Expression variable, MathNet.Symbolics.Expression expr)
{
// try to bring expression into polynomial form
MathNet.Symbolics.Expression simple = MathNet.Symbolics.Algebraic.Expand(MathNet.Symbolics.Rational.Simplify(variable, expr));
// extract coefficients, solve known forms of order up to 1
MathNet.Symbolics.Expression[] coeff = MathNet.Symbolics.Polynomial.Coefficients(variable, simple);
switch (coeff.Length)
{
case 1: return variable;
case 2: return MathNet.Symbolics.Rational.Simplify(variable, MathNet.Symbolics.Algebraic.Expand(-coeff[0] / coeff[1]));
default: return MathNet.Symbolics.Expression.Undefined;
}
}
您可以通过将两边与分母相乘来扩展它以支持这种有理数情况(因此有效地只取分子,Rational.Numerator
):
private Expr SolveSimpleRoot(Expr variable, Expr expr)
{
// try to bring expression into polynomial form
Expr simple = Algebraic.Expand(Rational.Numerator(Rational.Simplify(variable, expr)));
// extract coefficients, solve known forms of order up to 1
Expr[] coeff = Polynomial.Coefficients(variable, simple);
switch (coeff.Length)
{
case 1: return Expr.Zero.Equals(coeff[0]) ? variable : Expr.Undefined;
case 2: return Rational.Simplify(variable, Algebraic.Expand(-coeff[0] / coeff[1]));
default: return Expr.Undefined;
}
}
这样也可以处理(3+2*x)/(5*x-2)=7
。如果在这种情况下系数不等于零,我还将情况 1 固定为 return 未定义,因此另一个示例 (2*x+7)/x=2
的解决方案将按预期未定义。
当然,这仍然是一个非常简单的例程,无法处理任何高阶问题。