# Solving non linear system with ROOT::Math::GSLMultiRootFinder

Hello, first of all, happy new year to everyone!

I have to solve 4 variable non linear equation systems.
I found the class “ROOT::Math::GSLMultiRootFinder” that could do that for me.
It seems to find the common root of several functions.

Here is a code that shows how I want to use the class.

``````#include "RConfigure.h"

#ifdef R__HAS_MATHMORE
#include "Math/MultiRootFinder.h"
#endif
#include "Math/WrappedMultiTF1.h"
#include "TF2.h"
#include "TError.h"

// example of using multi root finder based on GSL
// need to use an algorithm not requiring the derivative
//like hybrids (default), hybrid, dnewton, broyden

using namespace ROOT::Math;

double equation (double *x, double *p1 ) {
return ( (x*(x*p1-p1+x)/sqrt(1+pow(x,2))+x*pow((x*p1-p1+x)/sqrt(1+pow(x,2)),2))-(x*(x*p1-p1+x)/sqrt(1+pow(x,2))+x*pow((x*p1-p1+x)/sqrt(1+pow(x,2)),2))-p1 );
}
void exampleMultiRoot(const char * algo = 0, int printlevel = 1) {

#ifndef R__HAS_MATHMORE
Error("exampleMultiRoot","libMathMore is not available - cannot run this tutorial");
return;
#endif

ROOT::Math::MultiRootFinder r(algo);
//defining the function
TF1 * f1 = new TF1("f1",equation,0,100,5);
TF1 * f2 = new TF1("f2",equation,0,100,5);
TF1 * f3 = new TF1("f3",equation,0,100,5);
TF1 * f4 = new TF1("f4",equation,0,100,5);
f1->SetParameters(1,0,3,4,5);
f2->SetParameters(1,2,3,4,4);
f3->SetParameters(2,3,4,5,2);
f4->SetParameters(3,4,5,6,0);
// wrap the functions

ROOT::Math::WrappedMultiTF1 g1(*f1,4);
ROOT::Math::WrappedMultiTF1 g2(*f2,4);
ROOT::Math::WrappedMultiTF1 g3(*f3,4);
ROOT::Math::WrappedMultiTF1 g4(*f4,4);
r.SetPrintLevel(printlevel);

// starting point
double x0={-1,-1,-1,-1};
r.Solve(x0);
}

``````

The code compiles and gives a results.

``````GSLMultiRootFinder::Solve:hybrids max iterations 100 and  tolerance 1e-06
Info in <ROOT::Math::GSLMultiRootFinder::Solve>: The iteration converged
GSL Algorithm used is :  hybrids
Number of iterations  =  15
Root values     = x =      3.68559   x =      0.36675   x =     -5.31663   x =    -0.916183
Function values = f = -8.15298e-08   f = -3.14831e-08   f = -6.44772e-09   f =  1.85877e-08
``````

Something seems strange.
To enter the functions in the solver, I have to use the command ROOT::Math::WrappedMultiTF1. Nevertheless, as I’m trying to solve 4 variable system, the functions are also 4 dimensional, it seems I can’t define theme as TF1.

Is there a ROOT::Math::WrappedMultiTF1 like class that could work with TFormula (tried to look for it but I didn’t find anything)?

As you can see in my code I tricked it by using a pointer as the variable of the TF1, but i’m not sur of what happen then. And if it works, what does the “0,100” of TF1 * f1 = new TF1(“f1”,equation,0,100,5) constrains (some value of the root are not in this interval)?

Lucien Causse.

_ROOT Version: 6.08/04
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)

@moneta can surely help.

Hello Lucien,
Happy new year !!!

• The solver is for a system of N equations with N variables. Each equation is a function, for this reason the `GSLMultiRootFinder` requires as input N different function objects. What you are doing is correct

No, but you can create a TF1 from a formula string (using TFormula), this is also very conveninent

The way you create the function is correct. [0,100] is the range in x of the TF1 function, but it is not used by the algorithm, so those values are not relevant.  is the number of parameters of the function.
Actually, if you create the TF1 from a formula, you woul dnot need to pass the range and the number of parameters.