```// @(#)root/mathmore:\$Id\$
// Author: L. Moneta  03/2011

/**********************************************************************
*                                                                    *
* Copyright (c) 2004 ROOT Foundation,  CERN/PH-SFT                   *
*                                                                    *
* This library is free software; you can redistribute it and/or      *
* modify it under the terms of the GNU General Public License        *
* as published by the Free Software Foundation; either version 2     *
* of the License, or (at your option) any later version.             *
*                                                                    *
* This library is distributed in the hope that it will be useful,    *
* but WITHOUT ANY WARRANTY; without even the implied warranty of     *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
* General Public License for more details.                           *
*                                                                    *
* You should have received a copy of the GNU General Public License  *
* along with this library (see file COPYING); if not, write          *
* to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
* 330, Boston, MA 02111-1307 USA, or contact the author.             *
*                                                                    *
**********************************************************************/

// Header file for class GSLMultiRootFinder
//

#ifndef ROOT_Math_GSLMultiRootFinder
#define ROOT_Math_GSLMultiRootFinder

#ifndef ROOT_Math_IFunction
#include "Math/IFunction.h"
#endif

#ifndef ROOT_Math_WrappedFunction
#include "Math/WrappedFunction.h"
#endif

#include <vector>

#include <iostream>

namespace ROOT {
namespace Math {

class GSLMultiRootBaseSolver;

//________________________________________________________________________________________________________
/**
Class for  Multidimensional root finding algorithms bassed on GSL. This class is used to solve a
non-linear system of equations:

f1(x1,....xn) = 0
f2(x1,....xn) = 0
..................
fn(x1,....xn) = 0

See the GSL <A HREF="http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Root_002dFinding.html"> online manual</A> for
information on the GSL MultiRoot finding algorithms

The available GSL algorithms require the derivatives of the supplied functions or not (they are
computed internally by GSL). In the first case the user needs to provide a list of multidimensional functions implementing the
gradient interface (ROOT::Math::IMultiGradFunction) while in the second case it is enough to supply a list of
functions impelmenting the ROOT::Math::IMultiGenFunction interface.
<A HREF="http://www.gnu.org/software/gsl/manual/html_node/Algorithms-using-Derivatives.html">documentation</A> )
are the followings:
<ul>
<li><tt>ROOT::Math::GSLMultiRootFinder::kHybridSJ</tt>  with name <it>"HybridSJ"</it>: modified Powell's hybrid
method as implemented in HYBRJ in MINPACK
<li><tt>ROOT::Math::GSLMultiRootFinder::kHybridJ</tt>  with name <it>"HybridJ"</it>: unscaled version of the
previous algorithm</li>
<li><tt>ROOT::Math::GSLMultiRootFinder::kNewton</tt>  with name <it>"Newton"</it>: Newton method </li>
<li><tt>ROOT::Math::GSLMultiRootFinder::kGNewton</tt>  with name <it>"GNewton"</it>: modified Newton method </li>
</ul>
<A HREF="http://www.gnu.org/software/gsl/manual/html_node/Algorithms-without-Derivatives.html">documentation</A> )
are the followings:
<ul>
<li><tt>ROOT::Math::GSLMultiRootFinder::kHybridS</tt>  with name <it>"HybridS"</it>: same as HybridSJ but using
finate difference approximation for the derivatives</li>
<li><tt>ROOT::Math::GSLMultiRootFinder::kHybrid</tt>  with name <it>"Hybrid"</it>: unscaled version of the
previous algorithm</li>
<li><tt>ROOT::Math::GSLMultiRootFinder::kDNewton</tt>  with name <it>"DNewton"</it>: discrete Newton algorithm </li>
<li><tt>ROOT::Math::GSLMultiRootFinder::kBroyden</tt>  with name <it>"Broyden"</it>: Broyden algorithm </li>
</ul>

@ingroup MultiRoot
*/

class GSLMultiRootFinder {

public:

/**
enumeration specifying the types of GSL multi root finders
requiring the derivatives
@ingroup MultiRoot
*/
enum EDerivType {
kHybridSJ,
kHybridJ,
kNewton,
kGNewton
};
/**
enumeration specifying the types of GSL multi root finders
which do not require the derivatives
@ingroup MultiRoot
*/
enum EType {
kHybridS,
kHybrid,
kDNewton,
kBroyden
};

/// create a multi-root finder based on an algorithm not requiring function derivative
GSLMultiRootFinder(EType type);

/// create a multi-root finder based on an algorithm requiring function derivative
GSLMultiRootFinder(EDerivType type);

/*
create a multi-root finder using a string.
The names are those defined in the GSL manuals
after having remived the GSL prefix (gsl_multiroot_fsolver).
Default algorithm  is "hybrids" (without derivative).
*/
GSLMultiRootFinder(const char * name = 0);

/// destructor
virtual ~GSLMultiRootFinder();

private:
// usually copying is non trivial, so we make this unaccessible
GSLMultiRootFinder(const GSLMultiRootFinder &);
GSLMultiRootFinder & operator = (const GSLMultiRootFinder &);

public:

/// set the type for an algorithm without derivatives
void SetType(EType type) {
fType = type; fUseDerivAlgo = false;
}

/// set the type of algorithm using derivatives
void SetType(EDerivType type) {
fType = type; fUseDerivAlgo = true;
}

/// set the type using a string
void SetType(const char * name);

/*
add the list of functions f1(x1,..xn),...fn(x1,...xn). The list must contain pointers of
ROOT::Math::IMultiGenFunctions. The method requires the
the begin and end of the list iterator.
The list can be any stl container or a simple array of  ROOT::Math::IMultiGenFunctions* or
whatever implementing an iterator.
If using a derivative type algorithm the function pointers must implement the
*/
template<class FuncIterator>
bool SetFunctionList( FuncIterator begin, FuncIterator end) {
bool ret = true;
for (FuncIterator itr = begin; itr != end; ++itr) {
const ROOT::Math::IMultiGenFunction * f = *itr;
}
return ret;
}

/*
add (set) a single function fi(x1,...xn) which is part of the system of
specifying the begin and end of the iterator.
If using a derivative type algorithm the function must implement the
Return the current number of function in the list and 0 if failed to add the function
*/
int AddFunction( const ROOT::Math::IMultiGenFunction & func);

/// same method as before but using any function implementing
/// the operator(), so can be wrapped in a IMultiGenFunction interface
template <class Function>
int AddFunction( Function & f, int ndim) {
WrappedMultiFunction<Function &> wfunc(f, ndim);
}

/**
return the number of sunctions set in the class.
The number must be equal to the dimension of the functions
*/
unsigned  int Dim() const { return fFunctions.size(); }

/// clear list of functions
void Clear();

/// return the root X values solving the system
const double * X() const;

/// return the function values f(X) solving the system
/// i.e. they must be close to zero at the solution
const double * FVal() const;

/// return the last step size
const double * Dx() const;

/**
Find the root starting from the point X;
Use the number of iteration and tolerance if given otherwise use
default parameter values which can be defined by
the static method SetDefault...
*/
bool Solve(const double * x,  int maxIter = 0, double absTol = 0, double relTol = 0);

/// Return number of iterations
int Iterations() const {
return fIter;
}

/// Return the status of last root finding
int Status() const { return fStatus; }

/// Return the algorithm name
const char * Name() const;

/*
set print level
level = 0  quiet (no messages print)
= 1  print only the result
= 3  max debug. Print result at each iteration
*/
void SetPrintLevel(int level) { fPrintLevel = level; }

/// return the print level
int PrintLevel() const { return fPrintLevel; }

//-- static methods to set configurations

/// set tolerance (absolute and relative)
/// relative tolerance is only use to verify the convergence
/// do it is a minor parameter
static void SetDefaultTolerance(double abstol, double reltol = 0 );

/// set maximum number of iterations
static void SetDefaultMaxIterations(int maxiter);

/// print iteration state
void PrintState(std::ostream & os = std::cout);

protected:

// return type given a name
std::pair<bool,int> GetType(const char * name);
// clear list of functions
void ClearFunctions();

private:

int fIter;           // current numer of iterations
int fStatus;         // current status
int fPrintLevel;     // print level

// int fMaxIter;        // max number of iterations
// double fAbsTolerance;  // absolute tolerance
// double fRelTolerance;  // relative tolerance
int fType;            // type of algorithm
bool fUseDerivAlgo; // algorithm using derivative

GSLMultiRootBaseSolver * fSolver;
std::vector<ROOT::Math::IMultiGenFunction *> fFunctions;   //! transient Vector of the functions

};

// use typedef for most sensible name
typedef GSLMultiRootFinder MultiRootFinder;

} // namespace Math
} // namespace ROOT

#endif /* ROOT_Math_GSLMultiRootFinder */
```
GSLMultiRootFinder.h:1
GSLMultiRootFinder.h:2
GSLMultiRootFinder.h:3
GSLMultiRootFinder.h:4
GSLMultiRootFinder.h:5
GSLMultiRootFinder.h:6
GSLMultiRootFinder.h:7
GSLMultiRootFinder.h:8
GSLMultiRootFinder.h:9
GSLMultiRootFinder.h:10
GSLMultiRootFinder.h:11
GSLMultiRootFinder.h:12
GSLMultiRootFinder.h:13
GSLMultiRootFinder.h:14
GSLMultiRootFinder.h:15
GSLMultiRootFinder.h:16
GSLMultiRootFinder.h:17
GSLMultiRootFinder.h:18
GSLMultiRootFinder.h:19
GSLMultiRootFinder.h:20
GSLMultiRootFinder.h:21
GSLMultiRootFinder.h:22
GSLMultiRootFinder.h:23
GSLMultiRootFinder.h:24
GSLMultiRootFinder.h:25
GSLMultiRootFinder.h:26
GSLMultiRootFinder.h:27
GSLMultiRootFinder.h:28
GSLMultiRootFinder.h:29
GSLMultiRootFinder.h:30
GSLMultiRootFinder.h:31
GSLMultiRootFinder.h:32
GSLMultiRootFinder.h:33
GSLMultiRootFinder.h:34
GSLMultiRootFinder.h:35
GSLMultiRootFinder.h:36
GSLMultiRootFinder.h:37
GSLMultiRootFinder.h:38
GSLMultiRootFinder.h:39
GSLMultiRootFinder.h:40
GSLMultiRootFinder.h:41
GSLMultiRootFinder.h:42
GSLMultiRootFinder.h:43
GSLMultiRootFinder.h:44
GSLMultiRootFinder.h:45
GSLMultiRootFinder.h:46
GSLMultiRootFinder.h:47
GSLMultiRootFinder.h:48
GSLMultiRootFinder.h:49
GSLMultiRootFinder.h:50
GSLMultiRootFinder.h:51
GSLMultiRootFinder.h:52
GSLMultiRootFinder.h:53
GSLMultiRootFinder.h:54
GSLMultiRootFinder.h:55
GSLMultiRootFinder.h:56
GSLMultiRootFinder.h:57
GSLMultiRootFinder.h:58
GSLMultiRootFinder.h:59
GSLMultiRootFinder.h:60
GSLMultiRootFinder.h:61
GSLMultiRootFinder.h:62
GSLMultiRootFinder.h:63
GSLMultiRootFinder.h:64
GSLMultiRootFinder.h:65
GSLMultiRootFinder.h:66
GSLMultiRootFinder.h:67
GSLMultiRootFinder.h:68
GSLMultiRootFinder.h:69
GSLMultiRootFinder.h:70
GSLMultiRootFinder.h:71
GSLMultiRootFinder.h:72
GSLMultiRootFinder.h:73
GSLMultiRootFinder.h:74
GSLMultiRootFinder.h:75
GSLMultiRootFinder.h:76
GSLMultiRootFinder.h:77
GSLMultiRootFinder.h:78
GSLMultiRootFinder.h:79
GSLMultiRootFinder.h:80
GSLMultiRootFinder.h:81
GSLMultiRootFinder.h:82
GSLMultiRootFinder.h:83
GSLMultiRootFinder.h:84
GSLMultiRootFinder.h:85
GSLMultiRootFinder.h:86
GSLMultiRootFinder.h:87
GSLMultiRootFinder.h:88
GSLMultiRootFinder.h:89
GSLMultiRootFinder.h:90
GSLMultiRootFinder.h:91
GSLMultiRootFinder.h:92
GSLMultiRootFinder.h:93
GSLMultiRootFinder.h:94
GSLMultiRootFinder.h:95
GSLMultiRootFinder.h:96
GSLMultiRootFinder.h:97
GSLMultiRootFinder.h:98
GSLMultiRootFinder.h:99
GSLMultiRootFinder.h:100
GSLMultiRootFinder.h:101
GSLMultiRootFinder.h:102
GSLMultiRootFinder.h:103
GSLMultiRootFinder.h:104
GSLMultiRootFinder.h:105
GSLMultiRootFinder.h:106
GSLMultiRootFinder.h:107
GSLMultiRootFinder.h:108
GSLMultiRootFinder.h:109
GSLMultiRootFinder.h:110
GSLMultiRootFinder.h:111
GSLMultiRootFinder.h:112
GSLMultiRootFinder.h:113
GSLMultiRootFinder.h:114
GSLMultiRootFinder.h:115
GSLMultiRootFinder.h:116
GSLMultiRootFinder.h:117
GSLMultiRootFinder.h:118
GSLMultiRootFinder.h:119
GSLMultiRootFinder.h:120
GSLMultiRootFinder.h:121
GSLMultiRootFinder.h:122
GSLMultiRootFinder.h:123
GSLMultiRootFinder.h:124
GSLMultiRootFinder.h:125
GSLMultiRootFinder.h:126
GSLMultiRootFinder.h:127
GSLMultiRootFinder.h:128
GSLMultiRootFinder.h:129
GSLMultiRootFinder.h:130
GSLMultiRootFinder.h:131
GSLMultiRootFinder.h:132
GSLMultiRootFinder.h:133
GSLMultiRootFinder.h:134
GSLMultiRootFinder.h:135
GSLMultiRootFinder.h:136
GSLMultiRootFinder.h:137
GSLMultiRootFinder.h:138
GSLMultiRootFinder.h:139
GSLMultiRootFinder.h:140
GSLMultiRootFinder.h:141
GSLMultiRootFinder.h:142
GSLMultiRootFinder.h:143
GSLMultiRootFinder.h:144
GSLMultiRootFinder.h:145
GSLMultiRootFinder.h:146
GSLMultiRootFinder.h:147
GSLMultiRootFinder.h:148
GSLMultiRootFinder.h:149
GSLMultiRootFinder.h:150
GSLMultiRootFinder.h:151
GSLMultiRootFinder.h:152
GSLMultiRootFinder.h:153
GSLMultiRootFinder.h:154
GSLMultiRootFinder.h:155
GSLMultiRootFinder.h:156
GSLMultiRootFinder.h:157
GSLMultiRootFinder.h:158
GSLMultiRootFinder.h:159
GSLMultiRootFinder.h:160
GSLMultiRootFinder.h:161
GSLMultiRootFinder.h:162
GSLMultiRootFinder.h:163
GSLMultiRootFinder.h:164
GSLMultiRootFinder.h:165
GSLMultiRootFinder.h:166
GSLMultiRootFinder.h:167
GSLMultiRootFinder.h:168
GSLMultiRootFinder.h:169
GSLMultiRootFinder.h:170
GSLMultiRootFinder.h:171
GSLMultiRootFinder.h:172
GSLMultiRootFinder.h:173
GSLMultiRootFinder.h:174
GSLMultiRootFinder.h:175
GSLMultiRootFinder.h:176
GSLMultiRootFinder.h:177
GSLMultiRootFinder.h:178
GSLMultiRootFinder.h:179
GSLMultiRootFinder.h:180
GSLMultiRootFinder.h:181
GSLMultiRootFinder.h:182
GSLMultiRootFinder.h:183
GSLMultiRootFinder.h:184
GSLMultiRootFinder.h:185
GSLMultiRootFinder.h:186
GSLMultiRootFinder.h:187
GSLMultiRootFinder.h:188
GSLMultiRootFinder.h:189
GSLMultiRootFinder.h:190
GSLMultiRootFinder.h:191
GSLMultiRootFinder.h:192
GSLMultiRootFinder.h:193
GSLMultiRootFinder.h:194
GSLMultiRootFinder.h:195
GSLMultiRootFinder.h:196
GSLMultiRootFinder.h:197
GSLMultiRootFinder.h:198
GSLMultiRootFinder.h:199
GSLMultiRootFinder.h:200
GSLMultiRootFinder.h:201
GSLMultiRootFinder.h:202
GSLMultiRootFinder.h:203
GSLMultiRootFinder.h:204
GSLMultiRootFinder.h:205
GSLMultiRootFinder.h:206
GSLMultiRootFinder.h:207
GSLMultiRootFinder.h:208
GSLMultiRootFinder.h:209
GSLMultiRootFinder.h:210
GSLMultiRootFinder.h:211
GSLMultiRootFinder.h:212
GSLMultiRootFinder.h:213
GSLMultiRootFinder.h:214
GSLMultiRootFinder.h:215
GSLMultiRootFinder.h:216
GSLMultiRootFinder.h:217
GSLMultiRootFinder.h:218
GSLMultiRootFinder.h:219
GSLMultiRootFinder.h:220
GSLMultiRootFinder.h:221
GSLMultiRootFinder.h:222
GSLMultiRootFinder.h:223
GSLMultiRootFinder.h:224
GSLMultiRootFinder.h:225
GSLMultiRootFinder.h:226
GSLMultiRootFinder.h:227
GSLMultiRootFinder.h:228
GSLMultiRootFinder.h:229
GSLMultiRootFinder.h:230
GSLMultiRootFinder.h:231
GSLMultiRootFinder.h:232
GSLMultiRootFinder.h:233
GSLMultiRootFinder.h:234
GSLMultiRootFinder.h:235
GSLMultiRootFinder.h:236
GSLMultiRootFinder.h:237
GSLMultiRootFinder.h:238
GSLMultiRootFinder.h:239
GSLMultiRootFinder.h:240
GSLMultiRootFinder.h:241
GSLMultiRootFinder.h:242
GSLMultiRootFinder.h:243
GSLMultiRootFinder.h:244
GSLMultiRootFinder.h:245
GSLMultiRootFinder.h:246
GSLMultiRootFinder.h:247
GSLMultiRootFinder.h:248
GSLMultiRootFinder.h:249
GSLMultiRootFinder.h:250
GSLMultiRootFinder.h:251
GSLMultiRootFinder.h:252
GSLMultiRootFinder.h:253
GSLMultiRootFinder.h:254
GSLMultiRootFinder.h:255
GSLMultiRootFinder.h:256
GSLMultiRootFinder.h:257
GSLMultiRootFinder.h:258
GSLMultiRootFinder.h:259
GSLMultiRootFinder.h:260
GSLMultiRootFinder.h:261
GSLMultiRootFinder.h:262
GSLMultiRootFinder.h:263
GSLMultiRootFinder.h:264
GSLMultiRootFinder.h:265
GSLMultiRootFinder.h:266
GSLMultiRootFinder.h:267
GSLMultiRootFinder.h:268
GSLMultiRootFinder.h:269
GSLMultiRootFinder.h:270
GSLMultiRootFinder.h:271
GSLMultiRootFinder.h:272
GSLMultiRootFinder.h:273
GSLMultiRootFinder.h:274
GSLMultiRootFinder.h:275
GSLMultiRootFinder.h:276
GSLMultiRootFinder.h:277
GSLMultiRootFinder.h:278
GSLMultiRootFinder.h:279
GSLMultiRootFinder.h:280
GSLMultiRootFinder.h:281
GSLMultiRootFinder.h:282
GSLMultiRootFinder.h:283
GSLMultiRootFinder.h:284
GSLMultiRootFinder.h:285
GSLMultiRootFinder.h:286
GSLMultiRootFinder.h:287
GSLMultiRootFinder.h:288
GSLMultiRootFinder.h:289
GSLMultiRootFinder.h:290
GSLMultiRootFinder.h:291
GSLMultiRootFinder.h:292
GSLMultiRootFinder.h:293
GSLMultiRootFinder.h:294
GSLMultiRootFinder.h:295
GSLMultiRootFinder.h:296
GSLMultiRootFinder.h:297
GSLMultiRootFinder.h:298