Solving system of linear equations using mathdotnet?
Asked Answered
D

1

8

I want to solve equations like,

(4-x)*2 = (y-1)*10 + 2
x = y*2 + 1

The equations are available in string form. Is there a way to express a equation in mathdotnet? I can only find ways to write expressions.

Duodenary answered 4/7, 2015 at 17:31 Comment(0)
M
9

Math.NET Numerics can solve any linear system numerically, but I suppose that's not what you're looking for.

Math.NET Symbolics can deal with symbolic expressions, although this project is in an early stage and does not yet understand the concept of equations. However, we can still use it to solve simple systems like these, with a bit of work - by doing what we would do by hand as well.

First, let's define a small function to solve a single linear equation of order up to 1:

using Expr = MathNet.Symbolics.Expression;

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

Then we can use this to solve the system as follows:

// declare variables
var x = Expr.Symbol("x");
var y = Expr.Symbol("y");

// Parse left and right side of both equations
Expr aleft = Infix.ParseOrThrow("(4-x)*2");
Expr aright = Infix.ParseOrThrow("(y-1)*10+2");
Expr bleft = Infix.ParseOrThrow("x");
Expr bright = Infix.ParseOrThrow("y*2+1");

// Solve both equations to x
Expr ax = SolveSimpleRoot(x,aleft-aright); // "8 - 5*y"
Expr bx = SolveSimpleRoot(x,bleft-bright); // "1 + 2*y"

// Equate both terms of x, solve to y
Expr cy = SolveSimpleRoot(y,ax-bx); // "1"

// Substitute term of y into one of the terms of x
Expr cx = Algebraic.Expand(Structure.Substitute(y,cy,ax)); // "3"

// Print expression in Infix notation
Console.WriteLine(Infix.Print(cx)); // x=3
Console.WriteLine(Infix.Print(cy)); // y=1
Marcin answered 4/7, 2015 at 19:47 Comment(1)
Hey Christoph! Symbolism is able to solve the first example as follows: ((4 - x) * 2 == (y - 1) * 10 + 2).IsolateVariable(x).AlgebraicExpand(). IsolateVariable is pretty ad-hoc, but it can handle many expressions I've thrown at it. Looking forward to something similar in Symbolics! :-)Kedge

© 2022 - 2024 — McMap. All rights reserved.