-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathexampleFunction.py
112 lines (86 loc) · 3.09 KB
/
exampleFunction.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
## \file
## \ingroup tutorial_math
## \notebook
## Example of using Python functions as inputs to numerical algorithms
## using the ROOT Functor class.
##
## \macro_image
## \macro_output
## \macro_code
##
## \author Lorenzo Moneta
import ROOT
import array
try:
import numpy as np
except:
print("Failed to import numpy.")
exit()
## example 1D function
def f(x):
return x*x -1
func = ROOT.Math.Functor1D(f)
#example of using the integral
print("Use Functor1D for wrapping one-dimensional function and compute integral of f(x) = x^2-1")
ig = ROOT.Math.Integrator()
ig.SetFunction(func)
value = ig.Integral(0, 3)
print("integral-1D value = ", value)
expValue = 6
if (not ROOT.TMath.AreEqualRel(value, expValue, 1.E-15)) :
print("Error computing integral - computed value - different than expected, diff = ", value - expValue)
# example multi-dim function
print("\n\nUse Functor for wrapping a multi-dimensional function, the Rosenbrock Function r(x,y) and find its minimum")
def RosenbrockFunction(xx):
x = xx[0]
y = xx[1]
tmp1 = y-x*x
tmp2 = 1-x
return 100*tmp1*tmp1+tmp2*tmp2
func2D = ROOT.Math.Functor(RosenbrockFunction,2)
### minimize multi-dim function using fitter class
fitter = ROOT.Fit.Fitter()
#use a numpy array to pass initial parameter array
initialParams = np.array([0.,0.], dtype='d')
fitter.FitFCN(func2D, initialParams)
fitter.Result().Print(ROOT.std.cout)
if (not ROOT.TMath.AreEqualRel(fitter.Result().Parameter(0), 1, 1.E-3) or not ROOT.TMath.AreEqualRel(fitter.Result().Parameter(1), 1, 1.E-3)) :
print("Error minimizing Rosenbrock function ")
## example 1d grad function
## derivative of f(x)= x**2-1
print("\n\nUse GradFunctor1D for making a function object implementing f(x) and f'(x)")
def g(x): return 2 * x
gradFunc = ROOT.Math.GradFunctor1D(f, g)
#check if ROOT has mathmore
prevLevel = ROOT.gErrorIgnoreLevel
ROOT.gErrorIgnoreLevel=ROOT.kFatal
ret = ROOT.gSystem.Load("libMathMore")
ROOT.gErrorIgnoreLevel=prevLevel
if (ret < 0) :
print("ROOT has not Mathmore")
print("derivative value at x = 1", gradFunc.Derivative(1) )
else :
rf = ROOT.Math.RootFinder(ROOT.Math.RootFinder.kGSL_NEWTON)
rf.SetFunction(gradFunc, 3)
rf.Solve()
value = rf.Root()
print("Found root value x0 : f(x0) = 0 : ", value)
if (value != 1):
print("Error finding a ROOT of function f(x)=x^2-1")
print("\n\nUse GradFunctor for making a function object implementing f(x,y) and df(x,y)/dx and df(x,y)/dy")
def RosenbrockDerivatives(xx, icoord):
x = xx[0]
y = xx[1]
#derivative w.r.t x
if (icoord == 0) :
return 2*(200*x*x*x-200*x*y+x-1)
else :
return 200 * (y - x * x)
gradFunc2d = ROOT.Math.GradFunctor(RosenbrockFunction, RosenbrockDerivatives, 2)
fitter = ROOT.Fit.Fitter()
#here we use a python array to pass initial parameters
initialParams = array.array('d',[0.,0.])
fitter.FitFCN(gradFunc2d, initialParams)
fitter.Result().Print(ROOT.std.cout)
if (not ROOT.TMath.AreEqualRel(fitter.Result().Parameter(0), 1, 1.E-3) or not ROOT.TMath.AreEqualRel(fitter.Result().Parameter(1), 1, 1.E-3)) :
print("Error minimizing Rosenbrock function ")