Minuit2 numerical function minimization in Python

Reference

Install

You have to install Minuit2 independently. More detail is described here. If you have already installed ROOT with --enable-minuit2, you need not to install Minuit2 individually.

Install Minuit2

mkdir -p /home/usrname/make/Minuit2
wget http://www.cern.ch/mathlibs/sw/5_28_00/Minuit2/Minuit2-5.28.00.tar.gz
tar zxvf Minuit2-5.28.00.tar.gz
mkdir -p /home/usrname/opt/pkgs/Minuit2-5.28.00
./configure --prefix=/home/usrname/opt/pkgs/Minuit2-5.28.00
make
make check
make install
cd /home/username/opt
ln -sf pkgs/Minuit2-5.28.00 Minuit2

Install pyminuit2

After installing Minuit2, you get source of pyminuit2:

mkdir -p  /home/username/make/pyminuit2
cd /home/username/make/pyminuit2
svn checkout http://pyminuit2.googlecode.com/svn/trunk/ pyminuit2-read-only
cd pyminuit2-read-only

You have to modify setup.py to show your own environment like below:

#!/usr/bin/env python

from distutils.core import setup, Extension
import os, sys, subprocess
.......
.......
libs = ["Minuit2"]
libdirs = ['/home/username/opt/root/lib/root/']
incdirs = ['/home/username/opt/root/include/root/Minuit2/']

The above is an example for the case that you installed ROOT with --enable-minuit2. Then make install:

mkdir -p /home/username/opt/pkgs/pyminuit2/
python setup.py install --prefix=/home/username/opt/pkgs/pyminuit2/
cd /home/username/opt
ln -sf pkgs/pyminuit2/lib/python2.6/site-packages pyminuit2

and also add PYTHONPATH like below:

export PYTHONPATH=${OPT}/pyminuit2:${PYTHONPATH}

How to use

pyminuit2.png
#!/usr/bin/env python


import os
import sys
import numpy as np
import minuit2
from ROOT import gROOT, TGraphErrors, TF1, TCanvas, TLatex


gROOT.SetStyle('Plain')


XMIN, XMAX = -10., +10.
NUMS = 100
A = 2.
B = 3.
C = 10.
NPARAMS = 3
TITLE = 'PyMinuit2 demo'


def func(x, par):
    a, b, c = par
    return a + b * x + c * np.sin(x/2.)


class Func:
   def __call__(self, x, par):
       return func(x[0], par)


class FCN:
    def __init__(self, x, y, ey):
        self.x = x
        self.y = y
        self.ey = ey

    def chi2(self, a, b, c):
        par = a, b, c
        return np.sum(np.power((self.y - func(self.x, par)) / self.ey, 2.))


def main(argv):
    # make data
    x = np.linspace(XMIN, XMAX, NUMS)
    y = func(x, (A, B, C)) + np.random.normal(size=NUMS)
    ey = np.ones(NUMS)

    # make FCN for minuit, then minimize it
    fcn = FCN(x, y, ey)
    m = minuit2.Minuit2(fcn.chi2, a=1., b=2, c=3.)
    m.printMode = 1
    m.migrad()

    # plot
    c = TCanvas('name', 'title', 640, 480)

    # plot data
    g = TGraphErrors(NUMS, x, y, np.zeros(NUMS), ey)
    g.SetLineColor(4)
    g.SetTitle(TITLE)
    g.Draw('AP')

    # plot model
    f = TF1('func', Func(), XMIN, XMAX, NPARAMS)
    f.SetLineColor(2)
    f.SetLineWidth(1)
    f.SetParameters(m.values['a'], m.values['b'], m.values['c'])
    f.Draw('same')

    # plot text
    l = TLatex()
    l.DrawLatex(XMIN, f.GetMaximum(),   'A(%.1lf)=%.3lf \pm %.3lf' % (A, m.values['a'], m.errors['a']))
    l.DrawLatex(XMIN, f.GetMaximum()-4, 'B(%.1lf)=%.3lf \pm %.3lf' % (B, m.values['b'], m.errors['b']))
    l.DrawLatex(XMIN, f.GetMaximum()-8, 'C(%.1lf)=%.3lf \pm %.3lf' % (C, m.values['c'], m.errors['c']))
    l.SetTextAlign(31)
    l.DrawLatex(XMAX, f.GetMinimum(), '\chi^{2}/ndf=%.3lf/%d' % (m.fval, NUMS - NPARAMS))

    c.Print('pyminuit2.eps')
    c.Print('pyminuit2.png')


if __name__ == '__main__':
    main(sys.argv)
    pass

添付ファイル: filepyminuit2.png 356件 [詳細]