4

I tried modified the code given here to solve linear equations for values of x. Such as

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

by first splitting it into two expressions right and left and then using the "SolveSimpleRoot" and it worked giving the value of x. But if the linear equation was written in the form of

(3+2*x)/(5*x-2)=7, which you can mulitiply throughout by (5*x-2) and indeed is a linear then the code fails at

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

with an error of:

The input sequence was empty.Parameter name: source

It also fails to solve if the expression was like (2x+7)/x=2, which still expands out to be linear.

Any idea why?

The code is basically:

    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;
        }
    }
Community
  • 1
  • 1
Fairoz
  • 43
  • 3

1 Answers1

2

You can extend it to support such rational cases by multiplying both sides with the denominator (hence effectively taking the numerator only, with 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;
    }
}

This way it can also handle (3+2*x)/(5*x-2)=7. I also fixed case 1 to return undefined if the coefficient is not equal to zero in this case, so the solution of the other example, (2*x+7)/x=2, will be undefined as expected.

Of course this still remains a very simplistic routine which will not be able to handle any higher order problems.

Christoph Rüegg
  • 4,626
  • 1
  • 20
  • 34
  • Thanks. That worked. One question.... Is the approach the same for solving quadratic equations as well? – Fairoz Oct 25 '15 at 10:39
  • For quadratic equations we'd have to extend SolveSimpleRoot to handle `coeff.Length == 3`. However, this would require introducing the concepts of multiple results, conditional result sets and complex expressions. – Christoph Rüegg Oct 26 '15 at 19:14
  • @ChristophRüegg [Symbolism](https://github.com/dharmatech/Symbolism) handles multiple possible answers by returning them in an 'or' expression. This is similar to how Mathematica handles these cases. Were you considering a different approach for Symbolics? – dharmatech Oct 26 '15 at 22:06
  • I haven't given much thought to that yet, but something closer to common math notation would appeal to me more I think (e.g. something set-based with conditional expressions like http://reference.wolfram.com/language/ref/ConditionalExpression.html). – Christoph Rüegg Oct 27 '15 at 17:55