/ / Resolviendo ecuaciones lineales usando Math.NET Symbolics - symbolic-math, mathdotnet

Resolviendo ecuaciones lineales usando Math.NET Symbolics - symbolic-math, mathdotnet

Intenté modificar el código dado aquí Resolver ecuaciones lineales para valores de x. Como

(3 * x + 7) / 3 + (2 * x) / 9 = 6/10

Primero dividiéndolo en dos expresiones derecha e izquierda y luego usando "SolveSimpleRoot" y funcionó dando el valor de x. Pero si la ecuación lineal fue escrita en la forma de

(3 + 2 * x) / (5 * x-2) = 7, que puede multiplicarse por (5 * x-2) y, de hecho, es lineal, el código falla en

// extract coefficients, solve known forms of order up to 1
MathNet.Symbolics.Expression[] coeff = MathNet.Symbolics.Polynomial.Coefficients(variable, simple);

con un error de:

La secuencia de entrada estaba vacía. Nombre de parámetro: fuente

Tampoco se resuelve si la expresión era como (2x + 7) / x = 2, que aún se expande para ser lineal.

¿Alguna idea de por qué?

El código es básicamente:

    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;
}
}

Respuestas

2 para la respuesta № 1

Puede extenderlo para admitir tales casos racionales multiplicando ambos lados con el denominador (por lo tanto, al tomar el numerador solo con 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;
}
}

De esta manera también puede manejar (3+2*x)/(5*x-2)=7. También arreglé el caso 1 para devolver indefinido si el coeficiente no es igual a cero en este caso, por lo que la solución del otro ejemplo, (2*x+7)/x=2, quedará indefinido como se esperaba.

Por supuesto, esto sigue siendo una rutina muy simplista que no podrá manejar ningún problema de orden superior.