Решение линейного уравнения с использованием Math.NET Symbolics
Я попытался изменить приведенный здесь код для решения линейных уравнений для значений х. Такие как
(3* х +7)/3+(2* х)/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);
с ошибкой:
Последовательность ввода была пустой. Имя параметра: источник
Это также не может решить, если выражение было как (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;
}
}
1 ответ
Вы можете расширить его для поддержки таких рациональных случаев, умножив обе стороны на знаменатель (следовательно, фактически взяв только числитель, с 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, чтобы он возвращал неопределенное значение, если коэффициент не равен нулю в этом случае, поэтому решение другого примера, (2*x+7)/x=2
, будет неопределенным, как и ожидалось.
Конечно, это все еще остается очень упрощенной процедурой, которая не сможет справиться с какими-либо проблемами более высокого порядка.