forum.alglib.net
http://forum.alglib.net/

Solving nonlinear equations
http://forum.alglib.net/viewtopic.php?f=2&t=791
Page 1 of 1

Author:  MrTrick [ Thu Mar 07, 2013 9:08 am ]
Post subject:  Solving nonlinear equations

I'm trying to figure out how to solve this set of equations in c#.
My mathematics is very rusty!

Given unknowns:
scale_S, scale_E, offset_S, offset_E
h, f
offset_x, offset_y

And variables:
step_S, step_E
x, y

And general equations:
S = scale_S * step_S + offset_S
E = scale_E * step_E + offset_E
x = offset_x + h * cos(S) - f * cos(S+E)
y = offset_y + h * sin(S) - f * sin(S+E)

Subbing in S and E...
x = offset_x + h * cos( scale_S * step_S + offset_S ) - f * cos( scale_S * step_S + offset_S + scale_E * step_E + offset_E )
y = offset_y + h * sin( scale_S * step_S + offset_S ) - f * sin( scale_S * step_S + offset_S + scale_E * step_E + offset_E )


I'll be setting up a set of calibration points, so I'll have for a given [x,y] the step_S and step_E values.
eg 'when x is 0, y is 0, step_S is 4202 and step_E is 1198'

With 8 unknowns, I'm guessing I'll need 4 calibration points to solve it?

I've read through the documentation for nleq, but I'm completely lost! How do I transform the above equations into something solvable?

Author:  mamu [ Tue Apr 02, 2013 11:33 pm ]
Post subject:  Re: Solving nonlinear equations

My math is not so good but i am not sure you can solve a system of non linear equations where the number of unknowns is more than the equations, in your case 8 unknowns and only 4 equations

Author:  MrTrick [ Wed Apr 03, 2013 7:42 am ]
Post subject:  Re: Solving nonlinear equations

mamu wrote:
My math is not so good but i am not sure you can solve a system of non linear equations where the number of unknowns is more than the equations, in your case 8 unknowns and only 4 equations


Each calibration point has an x and a y component, so it's 8 unknowns and 4 x 2 = 8 equations.

In any case, I had no idea how to do it in alglib, so I ended up cheating; just measuring all but two unknowns, and doing a manual calibration step.

Author:  mamu [ Fri Apr 05, 2013 3:52 pm ]
Post subject:  Re: Solving nonlinear equations

Here is an example of an unconstrained nonlinear system of equations solved with nleq and minlm (dv) using C# and VB.net.

f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
f1(x0,x1,x2,x3) = x0^2 +x1^2 +x2^2 +x3 -1 = 0
f2(x0,x1,x2,x3) = x1 - x2 = 0
f3(x0,x1,x2,x3) = x2 - x3 = 0


1. nleq requires you to provide the partial derivatives for your system of equations so that the jacobian matrix can formed.

2. minlm_d_v does not require the you to provide the partial derivatives.


Using nleq with c#
Code:
using System;
using System.Text;

//
// using nleq with c#
//

namespace Project1
{
    class Program
    {
        public static void function1_func(double[] x, ref double fi, object obj)
        {
            //
            // this callback calculates the merit function
            // f(x)=F[0]^2(x)+...+F[M-1]^2(x)
            // using
            // f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
            // f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
            // f2(x0,x1,x2,x3) =  x1 - x2 = 0
            // f3(x0,x1,x2,x3) =  x2 - x3 = 0
           
            double f0 = -(x[0] * x[0]) - (x[1] * x[1]) - (x[2] * x[2]) + x[3];
            double f1 = (x[0] * x[0]) + (x[1] * x[1]) + (x[2] * x[2]) + (x[3] * x[3]) - 1.0;
            double f2 = x[0] - x[1];
            double f3 = x[1] - x[2];

            fi = Math.Pow(f0, 2) + Math.Pow(f1, 2) + Math.Pow(f2, 2) + Math.Pow(f3, 2);  // the merit function
        }

        public static void function1_jac(double[] x, double[] fi, double[,] jac, object obj)
        {
            //
            // this callback calculates the two-dimensional matrix of partial derivatives jac()
            // using
            // f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
            // f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
            // f2(x0,x1,x2,x3) =  x1 - x2 = 0
            // f3(x0,x1,x2,x3) =  x2 - x3 = 0


            fi[0] = -(x[0] * x[0]) - (x[1] * x[1]) - (x[2] * x[2]) + x[3];
            fi[1] = (x[0] * x[0]) + (x[1] * x[1]) + (x[2] * x[2]) + (x[3] * x[3]) - 1.0;
            fi[2] = x[0] - x[1];
            fi[3] = x[1] - x[2];

            // the analytic jacobian for this nonlinear system
            // is obtained by partially differentiating each equation by x0,x1,x2,x3

            jac[0, 0] = (-2.0) * x[0];      // partial differentiation of f0 by xo
            jac[0, 1] = (-2.0) * x[1];      // partial differentiation of f0 by x1
            jac[0, 2] = (-2.0) * x[2];      // partial differentiation of f0 by x2
            jac[0, 3] = 1.0;                // partial differentiation of f0 by x3
            jac[1, 0] = 2.0 * x[0];         // partial differentiation of f1 by xo
            jac[1, 1] = 2.0 * x[1];         // partial differentiation of f1 by x1
            jac[1, 2] = 2.0 * x[2];         // partial differentiation of f1 by x2
            jac[1, 3] = 2.0 * x[3];         // partial differentiation of f1 by x3
            jac[2, 0] = 1.0;                // partial differentiation of f2 by xo
            jac[2, 1] = -1.0;               // partial differentiation of f2 by x1
            jac[2, 2] = 0.0;                // partial differentiation of f2 by x2
            jac[2, 3] = 0.0;                // partial differentiation of f2 by x3
            jac[3, 0] = 0.0;                // partial differentiation of f3 by x0
            jac[3, 1] = 1.0;                // partial differentiation of f3 by x1
            jac[3, 2] = -1.0;               // partial differentiation of f3 by x2
            jac[3, 3] = 0.0;                // partial differentiation of f3 by x3

        }

        public static int Main(string[] args)
        {
            int n = 4;  // number of x(i)
            int m = 4;  // number of f(i) equations
            double[] x = { 1, 1, 1, 1 }; //initial values of x0,x1,x2,x3 respectively

            double epsf = 0.000001;
            int maxits = 0; // unlimited iterations
            double stpmax = 0.0;

            alglib.nleqstate state;
            alglib.nleqreport rep;

            alglib.nleqcreatelm(n, m, x, out state);
            alglib.nleqsetcond(state, epsf, maxits);
            alglib.nleqsetstpmax(state, stpmax);

            alglib.nleqsetxrep(state, false);
            alglib.nleqsolve(state, function1_func, function1_jac, null, null);
            alglib.nleqresults(state, out x, out rep);

            System.Console.WriteLine("{0}", rep.terminationtype);       // EXPECTED: 1
            System.Console.WriteLine("{0}", alglib.ap.format(x, 5));    // EXPECTED: [0.45388,0.45388,0.45388,0.61803]
            System.Console.ReadLine();
            return 0;
        }

    }
}


Using minlm_d_v with c#
Code:
using System;
using System.Text;

//
//using minlm_d_v with c#
//

namespace Project2
{
    class Program
    {
        public static void function1_fvec(double[] x, double[] fi, object obj)
        {
            // this callback calculates the two-dimensional matrix of partial derivatives jac()
            // using
            // f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
            // f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
            // f2(x0,x1,x2,x3) =  x1 - x2 = 0
            // f3(x0,x1,x2,x3) =  x2 - x3 = 0


            fi[0] = -(x[0] * x[0]) - (x[1] * x[1]) - (x[2] * x[2]) + x[3];
            fi[1] = (x[0] * x[0]) + (x[1] * x[1]) + (x[2] * x[2]) + (x[3] * x[3]) - 1.0;
            fi[2] = x[0] - x[1];
            fi[3] = x[1] - x[2];
        }
       
        public static int Main(string[] args)
        {
           
            int m = 4;  // number of f(i) equations
            double[] x = { 1, 1, 1, 1 }; //initial values of x0,x1,x2,x3 respectively
            double diffstep = 0.0001;

            double epsg = 0.000001;
            double epsf = 0;
            double epsx = 0;
            int maxits = 0; // unlimited iterations
           
            alglib.minlmstate state;
            alglib.minlmreport rep;

            alglib.minlmcreatev(m, x, diffstep, out state);
            alglib.minlmsetcond(state, epsg, epsf, epsx, maxits);
            alglib.minlmoptimize(state, function1_fvec, null, null);
            alglib.minlmresults(state, out x, out rep);

            System.Console.WriteLine("{0}", rep.terminationtype);       // EXPECTED: 4
            System.Console.WriteLine("{0}", alglib.ap.format(x, 5));    // EXPECTED: [0.45388,0.45388,0.45388,0.61803]
            System.Console.ReadLine();
            return 0;

        }

    }
}



Using nleq and vb.net
Code:
Module MainModule
    Public Sub func(ByVal X As Double(), ByRef fi As Double, ByVal obj As Object)

        '
        'using nleq and vb.net
        '

        ' this callback calculates the merit function
        ' f(x)=F[0]^2(x)+...+F[M-1]^2(x)
        ' using
        ' f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
        ' f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
        ' f2(x0,x1,x2,x3) =  x1 - x2 = 0
        ' f3(x0,x1,x2,x3) =  x2 - x3 = 0

        Dim f0 As Double
        Dim f1 As Double
        Dim f2 As Double
        Dim f3 As Double

        f0 = -X(0) ^ 2 - X(1) ^ 2 - X(2) ^ 2 + X(3)
        f1 = X(0) ^ 2 + X(1) ^ 2 + X(2) ^ 2 + X(3) ^ 2 - 1.0
        f2 = X(0) - X(1)
        f3 = X(1) - X(2)

        fi = f0 ^ 2 + f1 ^ 2 + f2 ^ 2 + f3 ^ 2 ' the merit function

    End Sub
    Public Sub function1_jac(ByVal x As Double(), ByVal fx As Double(), ByVal jac As Double(,), ByVal obj As Object)
        '
        ' this callback calculates the two-dimensional matrix of partial derivatives jac()
        ' using
        ' f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
        ' f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
        ' f2(x0,x1,x2,x3) =  x1 - x2 = 0
        ' f3(x0,x1,x2,x3) =  x2 - x3 = 0


        fx(0) = -x(0) ^ 2 - x(1) ^ 2 - x(2) ^ 2 + x(3)
        fx(1) = x(0) ^ 2 + x(1) ^ 2 + x(2) ^ 2 + x(3) ^ 2 - 1.0
        fx(2) = x(0) - x(1)
        fx(3) = x(1) - x(2)

        ' the analytic jacobian for this nonlinear system
        ' is obtained by partially differentiating each equation by x0,x1,x2,x3

        jac(0, 0) = -2.0 * x(0)         ' partial differentiation of f0 by xo
        jac(0, 1) = -2.0 * x(1)         ' partial differentiation of f0 by x1
        jac(0, 2) = -2.0 * x(2)         ' partial differentiation of f0 by x2
        jac(0, 3) = 1.0                 ' partial differentiation of f0 by x3
        jac(1, 0) = 2.0 * x(0)          ' partial differentiation of f1 by xo
        jac(1, 1) = 2.0 * x(1)          ' partial differentiation of f1 by x1
        jac(1, 2) = 2.0 * x(2)          ' partial differentiation of f1 by x2
        jac(1, 3) = 2.0 * x(3)          ' partial differentiation of f1 by x3
        jac(2, 0) = 1.0                 ' partial differentiation of f2 by xo
        jac(2, 1) = -1.0                ' partial differentiation of f2 by x1
        jac(2, 2) = 0.0                 ' partial differentiation of f2 by x2
        jac(2, 3) = 0.0                 ' partial differentiation of f2 by x3
        jac(3, 0) = 0.0                 ' partial differentiation of f3 by x0
        jac(3, 1) = 1.0                 ' partial differentiation of f3 by x1
        jac(3, 2) = -1.0                ' partial differentiation of f3 by x2
        jac(3, 3) = 0.0                 ' partial differentiation of f3 by x3

    End Sub
    Public Sub Main()

        Dim n As Integer = 4 ' number of x(i)
        Dim m As Integer = 4 ' number of f(i) equations
        Dim x() As Double = {1, 1, 1, 1}    'initial values of x0,x1,x2,x3 respectively
        Dim state As nleqstate = New XAlglib.nleqstate()
        Dim rep As nleqreport = New XAlglib.nleqreport()

        Dim epsf As Double = 0.000001
        Dim maxits As Integer = 0   'unlimited iterations
        Dim stpmax As Double = 0.0

        XAlglib.nleqcreatelm(n, m, x, state)
        XAlglib.nleqsetcond(state, epsf, maxits)
        XAlglib.nleqsetstpmax(state, stpmax)
        XAlglib.nleqsetxrep(state, False)

        XAlglib.nleqsolve(state, AddressOf func, AddressOf function1_jac, Nothing, Nothing)
        XAlglib.nleqresults(state, x, rep)


        System.Console.WriteLine("{0}", rep.terminationtype)    'EXPECTED: 1
        System.Console.WriteLine("{0}", alglib.ap.format(x, 5)) 'EXPECTED: [0.45388,0.45388,0.45388,0.61803]
        System.Console.ReadLine()
    End Sub

End Module



Using minlm (dv) with vb.net
Code:
Module Module1
    Public Sub function1_fvec(ByVal x As Double(), ByVal fi As Double(), ByVal obj As Object)

        '
        'using minlm (dv) with vb.net
        '

        '
        ' this callback calculates
        ' f0(x0,x1,x2,x3) = -x0^2 -x1^2 -x2^2 +x3 = 0
        ' f1(x0,x1,x2,x3) =  x0^2 +x1^2 +x2^2 +x3 -1 = 0
        ' f2(x0,x1,x2,x3) =  x1 - x2 = 0
        ' f3(x0,x1,x2,x3) =  x2 - x3 = 0

        fi(0) = -x(0) ^ 2 - x(1) ^ 2 - x(2) ^ 2 + x(3)
        fi(1) = x(0) ^ 2 + x(1) ^ 2 + x(2) ^ 2 + x(3) ^ 2 - 1.0
        fi(2) = x(0) - x(1)
        fi(3) = x(1) - x(2)
    End Sub

    Sub Main()
        Dim m As Integer = 4 ' number of Equations
        Dim diffstep As Double = 0.0001
        Dim x() As Double = New Double() {1, 1, 1, 1} ' initial values of x0, x1, x2, x3 respectively

        Dim epsg As Double = 0.000001
        Dim epsf As Double = 0
        Dim epsx As Double = 0
        Dim maxits As Integer = 0   'unlimited iterations

        Dim state As minlmstate = New XAlglib.minlmstate()
        Dim rep As minlmreport = New XAlglib.minlmreport()

        XAlglib.minlmcreatev(m, x, diffstep, state)
        XAlglib.minlmsetcond(state, epsg, epsf, epsx, maxits)
        XAlglib.minlmoptimize(state, AddressOf function1_fvec, Nothing, Nothing)
        XAlglib.minlmresults(state, x, rep)

        System.Console.WriteLine("{0}", rep.terminationtype)    'EXPECTED: 4
        System.Console.WriteLine("{0}", alglib.ap.format(x, 5)) 'EXPECTED: [0.45388,0.45388,0.45388,0.61803]
        System.Console.ReadLine()
        Environment.Exit(0)
    End Sub

End Module


Author:  MrTrick [ Tue Apr 09, 2013 12:08 am ]
Post subject:  Re: Solving nonlinear equations

Thanks mamu,

That makes sense! :-)

Page 1 of 1 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/