Binding detailed example: Minuit2#
Let’s try a non-trivial example: Minuit2 (6.26.10 standalone edition)
Expectations#
Be able to minimize a very simple function and get some parameters
import sys
Step 1: Get source#
Download Minuit2 source (already provided in
minuit2
)
Step 2: Plan interface#
You should know what the C++ looks like, and know what you want the Python to look like
For now, let’s replicate the C++ experience
For example: a simple minimizer for \(f(x) = x^2\) (should quickly find 0 as minimum):
Define FCN
Setup parameters
Minimize
Print result
Will use print out for illustration (instead of MnPrint::SetLevel
)
%%writefile SimpleFCN.h
#pragma once
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnPrint.h>
#include <Minuit2/MnMigrad.h>
#include <iostream>
using namespace ROOT::Minuit2;
class SimpleFCN : public FCNBase {
// Always 0.5 for these sorts of fits
double Up() const override {return 0.5;}
// This computes whatever you are going to minimize
double operator()(const std::vector<double> &v) const override {
std::cout << "val = " << v.at(0) << std::endl;
return v.at(0)*v.at(0);
}
};
Writing SimpleFCN.h
%%writefile simpleminuit.cpp
#include "SimpleFCN.h"
int main() {
SimpleFCN fcn;
MnUserParameters upar;
upar.Add("x", 1., 0.1);
MnMigrad migrad(fcn, upar);
FunctionMinimum min = migrad();
std::cout << min << std::endl;
}
Writing simpleminuit.cpp
%%writefile CMakeLists.txt
cmake_minimum_required(VERSION 3.18...3.29)
project(Minuit2SimpleExamle LANGUAGES CXX)
include(FetchContent)
FetchContent_Declare(
minuit2
URL https://github.com/root-project/root/archive/refs/tags/v6-26-10.tar.gz
URL_HASH SHA256=a84ed095252614c6e2084987fce9ce4a5a62057bfd5a4a2725123ca9f60f674f
SOURCE_SUBDIR math/minuit2
DOWNLOAD_NO_PROGRESS
)
FetchContent_MakeAvailable(minuit2)
add_executable(simpleminuit simpleminuit.cpp SimpleFCN.h)
target_link_libraries(simpleminuit PRIVATE Minuit2::Minuit2)
Writing CMakeLists.txt
Standard CMake configure and build (using Ninja instead of Make for speed)
!cmake -GNinja -S . -B build
!cmake --build build
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Deprecation Warning at build/_deps/minuit2-src/math/minuit2/CMakeLists.txt:7 (cmake_minimum_required):
Compatibility with CMake < 3.10 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
CMake Deprecation Warning at build/_deps/minuit2-src/math/minuit2/StandAlone.cmake:1 (cmake_minimum_required):
Compatibility with CMake < 3.10 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
Call Stack (most recent call first):
build/_deps/minuit2-src/math/minuit2/CMakeLists.txt:250 (include)
-- Configuring done (16.9s)
-- Generating done (0.0s)
-- Build files have been written to: /home/runner/work/se-for-sci/se-for-sci/content/week09/03-pybind/build
[0/80] Building CXX object _deps/minui..._/__/mathcore/src/GenAlgoOptions.cxx.o
[0/80] Building CXX object _deps/minui...__/mathcore/src/MinimizerOptions.cxx.o
[0/80] Building CXX object _deps/minui...dir/AnalyticalGradientCalculator.cxx.o
[0/80] Building CXX object _deps/minui...les/Minuit2.dir/BFGSErrorUpdator.cxx.o
[0/80] Building CXX object _deps/minui...nuit2.dir/CombinedMinimumBuilder.cxx.o
[0/80] Building CXX object _deps/minui.../Minuit2.dir/DavidonErrorUpdator.cxx.o
[1/80] Building CXX object _deps/minui.../Minuit2.dir/DavidonErrorUpdator.cxx.o
[1/80] Building CXX object _deps/minui...ternalInternalGradientCalculator.cxx.o
[2/80] Building CXX object _deps/minui...__/mathcore/src/MinimizerOptions.cxx.o
[2/80] Building CXX object _deps/minui...eFiles/Minuit2.dir/FumiliBuilder.cxx.o
[3/80] Building CXX object _deps/minui...les/Minuit2.dir/BFGSErrorUpdator.cxx.o
[3/80] Building CXX object _deps/minui...s/Minuit2.dir/FumiliErrorUpdator.cxx.o
[4/80] Building CXX object _deps/minui...dir/AnalyticalGradientCalculator.cxx.o
[4/80] Building CXX object _deps/minui...it2.dir/FumiliGradientCalculator.cxx.o
[5/80] Building CXX object _deps/minui...nuit2.dir/CombinedMinimumBuilder.cxx.o
[5/80] Building CXX object _deps/minui...iles/Minuit2.dir/FumiliMinimizer.cxx.o
[6/80] Building CXX object _deps/minui..._/__/mathcore/src/GenAlgoOptions.cxx.o
[6/80] Building CXX object _deps/minui...inuit2.dir/FumiliStandardChi2FCN.cxx.o
[7/80] Building CXX object _deps/minui...ternalInternalGradientCalculator.cxx.o
[7/80] Building CXX object _deps/minui...miliStandardMaximumLikelihoodFCN.cxx.o
[8/80] Building CXX object _deps/minui...inuit2.dir/FumiliStandardChi2FCN.cxx.o
[8/80] Building CXX object _deps/minui...t2.dir/HessianGradientCalculator.cxx.o
[9/80] Building CXX object _deps/minui...s/Minuit2.dir/FumiliErrorUpdator.cxx.o
[9/80] Building CXX object _deps/minui...t2.dir/InitialGradientCalculator.cxx.o
[10/80] Building CXX object _deps/minu...it2.dir/FumiliGradientCalculator.cxx.o
[10/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/LaEigenValues.cxx.o
[11/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/LaEigenValues.cxx.o
[11/80] Building CXX object _deps/minu...Files/Minuit2.dir/LaInnerProduct.cxx.o
[12/80] Building CXX object _deps/minu...iles/Minuit2.dir/FumiliMinimizer.cxx.o
[12/80] Building CXX object _deps/minu...CMakeFiles/Minuit2.dir/LaInverse.cxx.o
[13/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/FumiliBuilder.cxx.o
[13/80] Building CXX object _deps/minu...Files/Minuit2.dir/LaOuterProduct.cxx.o
[14/80] Building CXX object _deps/minu...miliStandardMaximumLikelihoodFCN.cxx.o
[14/80] Building CXX object _deps/minu...iles/Minuit2.dir/LaSumOfElements.cxx.o
[15/80] Building CXX object _deps/minu...Files/Minuit2.dir/LaInnerProduct.cxx.o
[15/80] Building CXX object _deps/minu...les/Minuit2.dir/LaVtMVSimilarity.cxx.o
[16/80] Building CXX object _deps/minu...Files/Minuit2.dir/LaOuterProduct.cxx.o
[16/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MPIProcess.cxx.o
[17/80] Building CXX object _deps/minu...CMakeFiles/Minuit2.dir/LaInverse.cxx.o
[17/80] Building CXX object _deps/minu...Files/Minuit2.dir/MinimumBuilder.cxx.o
[18/80] Building CXX object _deps/minu...iles/Minuit2.dir/LaSumOfElements.cxx.o
[18/80] Building CXX object _deps/minu...les/Minuit2.dir/Minuit2Minimizer.cxx.o
[19/80] Building CXX object _deps/minu...t2.dir/HessianGradientCalculator.cxx.o
[19/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/MnApplication.cxx.o
[20/80] Building CXX object _deps/minu...t2.dir/InitialGradientCalculator.cxx.o
[20/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MnContours.cxx.o
[21/80] Building CXX object _deps/minu...les/Minuit2.dir/LaVtMVSimilarity.cxx.o
[21/80] Building CXX object _deps/minu.../Minuit2.dir/MnCovarianceSqueeze.cxx.o
[22/80] Building CXX object _deps/minu...Files/Minuit2.dir/MinimumBuilder.cxx.o
[22/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnEigen.cxx.o
[23/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MPIProcess.cxx.o
[23/80] Building CXX object _deps/minu...src/CMakeFiles/Minuit2.dir/MnFcn.cxx.o
[24/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnEigen.cxx.o
[24/80] Building CXX object _deps/minu...les/Minuit2.dir/MnFumiliMinimize.cxx.o
[25/80] Building CXX object _deps/minu...src/CMakeFiles/Minuit2.dir/MnFcn.cxx.o
[25/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnFunctionCross.cxx.o
[26/80] Building CXX object _deps/minu.../Minuit2.dir/MnCovarianceSqueeze.cxx.o
[26/80] Building CXX object _deps/minu...it2.dir/MnGlobalCorrelationCoeff.cxx.o
[27/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/MnApplication.cxx.o
[27/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnHesse.cxx.o
[28/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MnContours.cxx.o
[28/80] Building CXX object _deps/minu...keFiles/Minuit2.dir/MnLineSearch.cxx.o
[29/80] Building CXX object _deps/minu...it2.dir/MnGlobalCorrelationCoeff.cxx.o
[29/80] Building CXX object _deps/minu...s/Minuit2.dir/MnMachinePrecision.cxx.o
[30/80] Building CXX object _deps/minu...les/Minuit2.dir/MnFumiliMinimize.cxx.o
[30/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnMinos.cxx.o
[31/80] Building CXX object _deps/minu...s/Minuit2.dir/MnMachinePrecision.cxx.o
[31/80] Building CXX object _deps/minu...es/Minuit2.dir/MnParabolaFactory.cxx.o
[32/80] Building CXX object _deps/minu...les/Minuit2.dir/Minuit2Minimizer.cxx.o
[32/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnParameterScan.cxx.o
[33/80] Building CXX object _deps/minu...es/Minuit2.dir/MnParabolaFactory.cxx.o
[33/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnPlot.cxx.o
[34/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnFunctionCross.cxx.o
[34/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/MnPosDef.cxx.o
[35/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnPlot.cxx.o
[35/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnPrint.cxx.o
[36/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnHesse.cxx.o
[36/80] Building CXX object _deps/minu...akeFiles/Minuit2.dir/MnPrintImpl.cxx.o
[37/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnParameterScan.cxx.o
[37/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnScan.cxx.o
[38/80] Building CXX object _deps/minu...keFiles/Minuit2.dir/MnLineSearch.cxx.o
[38/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnSeedGenerator.cxx.o
[39/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnMinos.cxx.o
[39/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MnStrategy.cxx.o
[40/80] Building CXX object _deps/minu...akeFiles/Minuit2.dir/MnPrintImpl.cxx.o
[40/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnTiny.cxx.o
[41/80] Building CXX object _deps/minu...MakeFiles/Minuit2.dir/MnStrategy.cxx.o
[41/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/MnTraceObject.cxx.o
[42/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnTiny.cxx.o
[42/80] Building CXX object _deps/minu...CMakeFiles/Minuit2.dir/MnUserFcn.cxx.o
[43/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/MnPosDef.cxx.o
[43/80] Building CXX object _deps/minu...Minuit2.dir/MnUserParameterState.cxx.o
[44/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/MnPrint.cxx.o
[44/80] Building CXX object _deps/minu...les/Minuit2.dir/MnUserParameters.cxx.o
[45/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/MnScan.cxx.o
[45/80] Building CXX object _deps/minu...Minuit2.dir/MnUserTransformation.cxx.o
[46/80] Building CXX object _deps/minu...iles/Minuit2.dir/MnSeedGenerator.cxx.o
[46/80] Building CXX object _deps/minu...it2.dir/ModularFunctionMinimizer.cxx.o
[47/80] Building CXX object _deps/minu...CMakeFiles/Minuit2.dir/MnUserFcn.cxx.o
[47/80] Building CXX object _deps/minu...Minuit2.dir/NegativeG2LineSearch.cxx.o
[48/80] Building CXX object _deps/minu...eFiles/Minuit2.dir/MnTraceObject.cxx.o
[48/80] Building CXX object _deps/minu...ir/Numerical2PGradientCalculator.cxx.o
[49/80] Building CXX object _deps/minu...les/Minuit2.dir/MnUserParameters.cxx.o
[49/80] Building CXX object _deps/minu...s/Minuit2.dir/ParametricFunction.cxx.o
[50/80] Building CXX object _deps/minu...Minuit2.dir/MnUserParameterState.cxx.o
[50/80] Building CXX object _deps/minu...akeFiles/Minuit2.dir/ScanBuilder.cxx.o
[51/80] Building CXX object _deps/minu...it2.dir/ModularFunctionMinimizer.cxx.o
[51/80] Building CXX object _deps/minu...Files/Minuit2.dir/SimplexBuilder.cxx.o
[52/80] Building CXX object _deps/minu...Minuit2.dir/NegativeG2LineSearch.cxx.o
[52/80] Building CXX object _deps/minu...es/Minuit2.dir/SimplexParameters.cxx.o
[53/80] Building CXX object _deps/minu...Minuit2.dir/MnUserTransformation.cxx.o
[53/80] Building CXX object _deps/minu...Minuit2.dir/SimplexSeedGenerator.cxx.o
[54/80] Building CXX object _deps/minu...ir/Numerical2PGradientCalculator.cxx.o
[54/80] Building CXX object _deps/minu...2.dir/SinParameterTransformation.cxx.o
[55/80] Building CXX object _deps/minu...es/Minuit2.dir/SimplexParameters.cxx.o
[55/80] Building CXX object _deps/minu...r/SqrtLowParameterTransformation.cxx.o
[56/80] Building CXX object _deps/minu...s/Minuit2.dir/ParametricFunction.cxx.o
[56/80] Building CXX object _deps/minu...ir/SqrtUpParameterTransformation.cxx.o
[57/80] Building CXX object _deps/minu...2.dir/SinParameterTransformation.cxx.o
[57/80] Building CXX object _deps/minu...inuit2.dir/VariableMetricBuilder.cxx.o
[58/80] Building CXX object _deps/minu...r/SqrtLowParameterTransformation.cxx.o
[58/80] Building CXX object _deps/minu...2.dir/VariableMetricEDMEstimator.cxx.o
[59/80] Building CXX object _deps/minu...ir/SqrtUpParameterTransformation.cxx.o
[59/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnbins.cxx.o
[60/80] Building CXX object _deps/minu...akeFiles/Minuit2.dir/ScanBuilder.cxx.o
[60/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndasum.cxx.o
[61/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnbins.cxx.o
[61/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndaxpy.cxx.o
[62/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndaxpy.cxx.o
[62/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnddot.cxx.o
[63/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndasum.cxx.o
[63/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndscal.cxx.o
[64/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnddot.cxx.o
[64/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndspmv.cxx.o
[65/80] Building CXX object _deps/minu...Minuit2.dir/SimplexSeedGenerator.cxx.o
[65/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mndspr.cxx.o
[66/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndscal.cxx.o
[66/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mnlsame.cxx.o
[67/80] Building CXX object _deps/minu...2.dir/VariableMetricEDMEstimator.cxx.o
[67/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/mnteigen.cxx.o
[68/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mndspmv.cxx.o
[68/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mntplot.cxx.o
[69/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mnlsame.cxx.o
[69/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnvert.cxx.o
[70/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mndspr.cxx.o
[70/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/mnxerbla.cxx.o
[71/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/mnteigen.cxx.o
[71/80] Linking CXX static library _deps/minuit2-build/src/math/libMinuit2Math.a
[72/80] Building CXX object _deps/minu...Files/Minuit2.dir/SimplexBuilder.cxx.o
[72/80] Building CXX object CMakeFiles/simpleminuit.dir/simpleminuit.cpp.o
[73/80] Building CXX object _deps/minu.../CMakeFiles/Minuit2.dir/mnxerbla.cxx.o
[74/80] Building CXX object _deps/minu...c/CMakeFiles/Minuit2.dir/mntplot.cxx.o
[75/80] Building CXX object _deps/minu...rc/CMakeFiles/Minuit2.dir/mnvert.cxx.o
[76/80] Building CXX object _deps/minu...inuit2.dir/VariableMetricBuilder.cxx.o
[77/80] Linking CXX static library _deps/minuit2-build/src/math/libMinuit2Math.a
[77/80] Linking CXX static library _deps/minuit2-build/src/libMinuit2.a
[78/80] Building CXX object CMakeFiles/simpleminuit.dir/simpleminuit.cpp.o
[79/80] Linking CXX static library _deps/minuit2-build/src/libMinuit2.a
[79/80] Linking CXX executable simpleminuit
[80/80] Linking CXX executable simpleminuit
!./build/simpleminuit
val = 1
val = 1.001
val = 0.999
val = 1.0006
val = 0.999402
val = -8.23008e-11
val = 0.000345267
val = -0.000345267
val = -8.23008e-11
val = 0.000345267
val = -0.000345267
val = 6.90533e-05
val = -6.90535e-05
Valid : yes
Function calls: 13
Minimum value : 6.773427082e-21
Edm : 6.773427082e-21
Internal parameters:
-8.230083282e-11
Internal covariance matrix:
1
External parameters:
Pos | Name | type | Value | Error +/-
0 | x | free | -8.230083282e-11 | 0.7071067812
Step 3: Bind parts we need#
subclassable FCNBase
MnUserParameters (constructor and
Add(string, double, double)
)MnMigrad (constructor and operator())
FunctionMinimum (cout)
%mkdir src
Recommended structure of a Pybind11 program#
main.cpp#
Builds module
Avoids imports (fast compile)
include <pybind11/pybind11.h>
namespace py = pybind11;
void init_part1(py::module &);
void init_part2(py::module &);
PYBIND11_MODULE(mymodule, m) {
m.doc() = "Real code would never have such poor documentation...";
init_part1(m);
init_part2(m);
}
%%writefile src/pyminuit2.cpp
#include <pybind11/pybind11.h>
namespace py = pybind11;
void init_FCNBase(py::module &);
void init_MnUserParameters(py::module &);
void init_MnMigrad(py::module &);
void init_FunctionMinimum(py::module &);
PYBIND11_MODULE(minuit2, m) {
init_FCNBase(m);
init_MnUserParameters(m);
init_MnMigrad(m);
init_FunctionMinimum(m);
}
Writing src/pyminuit2.cpp
We will put all headers in a collective header (not a good idea unless you are trying to show files one per slide).
%%writefile src/PyHeader.h
#pragma once
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Minuit2/FCNBase.h>
#include <Minuit2/MnMigrad.h>
#include <Minuit2/MnApplication.h>
#include <Minuit2/MnUserParameters.h>
#include <Minuit2/FunctionMinimum.h>
namespace py = pybind11;
using namespace pybind11::literals;
using namespace ROOT::Minuit2;
Writing src/PyHeader.h
Overloads#
Pure virtual methods cannot be instantiated in C++
Have to provide “Trampoline class” to provide Python class
%%writefile src/FCNBase.cpp
#include "PyHeader.h"
class PyFCNBase : public FCNBase {
public:
using FCNBase::FCNBase;
double operator()(const std::vector<double> &v) const override {
PYBIND11_OVERLOAD_PURE_NAME(
double, FCNBase, "__call__", operator(), v);}
double Up() const override {
PYBIND11_OVERLOAD_PURE(double, FCNBase, Up, );}
};
void init_FCNBase(py::module &m) {
py::class_<FCNBase, PyFCNBase>(m, "FCNBase")
.def(py::init<>())
.def("__call__", &FCNBase::operator())
.def("Up", &FCNBase::Up);
}
Writing src/FCNBase.cpp
Overloaded function signatures:#
C++11 syntax:
(bool (MnUserParameters::*)(const std::string &, double)) &MnUserParameters::Add
C++14 syntax:
py::overload_cast<const std::string &, double>(&MnUserParameters::Add)
%%writefile src/MnUserParameters.cpp
#include "PyHeader.h"
void init_MnUserParameters(py::module &m) {
py::class_<MnUserParameters>(m, "MnUserParameters")
.def(py::init<>())
.def("Add", (bool (MnUserParameters::*)(const std::string &, double)) &MnUserParameters::Add)
.def("Add", (bool (MnUserParameters::*)(const std::string &, double, double)) &MnUserParameters::Add)
;
}
Writing src/MnUserParameters.cpp
Adding default arguments (and named arguments)#
Using
""_a
literal, names and even defaults can be added
%%writefile src/MnMigrad.cpp
#include "PyHeader.h"
void init_MnMigrad(py::module &m) {
py::class_<MnApplication>(m, "MnApplication")
.def("__call__",
&MnApplication::operator(),
"Minimize the function, returns a function minimum",
py::arg("maxfcn") = 0,
"tolerance"_a = 0.1);
py::class_<MnMigrad, MnApplication>(m, "MnMigrad")
.def(py::init<const FCNBase &, const MnUserParameters &, unsigned int>(),
"fcn"_a, "par"_a, "stra"_a = 1)
;
}
Writing src/MnMigrad.cpp
Lambda functions#
Pybind11 accepts lambda functions, as well
%%writefile src/FunctionMinimum.cpp
#include "PyHeader.h"
#include <sstream>
#include <Minuit2/MnPrint.h>
void init_FunctionMinimum(py::module &m) {
py::class_<FunctionMinimum>(m, "FunctionMinimum")
.def("__str__", [](const FunctionMinimum &self) {
std::stringstream os;
os << self;
return os.str();
})
;
}
Writing src/FunctionMinimum.cpp
%%writefile CMakeLists.txt
cmake_minimum_required(VERSION 3.18...3.25)
project(Minuit2SimpleExamle LANGUAGES CXX)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(FetchContent)
FetchContent_Declare(
minuit2
URL https://github.com/root-project/root/archive/refs/tags/v6-26-10.tar.gz
URL_HASH SHA256=a84ed095252614c6e2084987fce9ce4a5a62057bfd5a4a2725123ca9f60f674f
SOURCE_SUBDIR math/minuit2
DOWNLOAD_NO_PROGRESS
EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(minuit2)
set(PYBIND11_FINDPYTHON ON)
find_package(pybind11)
file(GLOB OUTPUT src/*.cpp)
pybind11_add_module(minuit2 ${OUTPUT})
target_link_libraries(minuit2 PUBLIC Minuit2::Minuit2)
install(TARGETS minuit2 DESTINATION .)
Overwriting CMakeLists.txt
We can use this CMakeLists from scikit-build-core:
%%writefile pyproject.toml
[build-system]
requires = ["scikit-build-core>=0.8", "pybind11>=2.10"]
build-backend = "scikit_build_core.build"
[project]
name = "minuit2"
version = "6.26.10"
Writing pyproject.toml
!{sys.executable} -m pip wheel . -v
Processing /home/runner/work/se-for-sci/se-for-sci/content/week09/03-pybind
Running command pip subprocess to install build dependencies
Using pip 24.2 from /home/runner/work/se-for-sci/se-for-sci/.pixi/envs/default/lib/python3.12/site-packages/pip (python 3.12)
Collecting scikit-build-core>=0.8
Obtaining dependency information for scikit-build-core>=0.8 from https://files.pythonhosted.org/packages/88/fe/90476c4f6a1b2f922efa00d26e876dd40c7279e28ec18f08f0851ad21ba6/scikit_build_core-0.10.7-py3-none-any.whl.metadata
Downloading scikit_build_core-0.10.7-py3-none-any.whl.metadata (21 kB)
Collecting pybind11>=2.10
Obtaining dependency information for pybind11>=2.10 from https://files.pythonhosted.org/packages/13/2f/0f24b288e2ce56f51c920137620b4434a38fd80583dbbe24fc2a1656c388/pybind11-2.13.6-py3-none-any.whl.metadata
Downloading pybind11-2.13.6-py3-none-any.whl.metadata (9.5 kB)
Collecting packaging>=21.3 (from scikit-build-core>=0.8)
Obtaining dependency information for packaging>=21.3 from https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl.metadata
Downloading packaging-24.2-py3-none-any.whl.metadata (3.2 kB)
Collecting pathspec>=0.10.1 (from scikit-build-core>=0.8)
Obtaining dependency information for pathspec>=0.10.1 from https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl.metadata
Downloading pathspec-0.12.1-py3-none-any.whl.metadata (21 kB)
Downloading scikit_build_core-0.10.7-py3-none-any.whl (165 kB)
Downloading pybind11-2.13.6-py3-none-any.whl (243 kB)
Downloading packaging-24.2-py3-none-any.whl (65 kB)
Downloading pathspec-0.12.1-py3-none-any.whl (31 kB)
Installing collected packages: pybind11, pathspec, packaging, scikit-build-core
Creating /tmp/pip-build-env-651oruzt/overlay/bin
changing mode of /tmp/pip-build-env-651oruzt/overlay/bin/pybind11-config to 755
Successfully installed packaging-24.2 pathspec-0.12.1 pybind11-2.13.6 scikit-build-core-0.10.7
Installing build dependencies ... ?25l?25hdone
Running command Getting requirements to build wheel
Getting requirements to build wheel ... ?25l?25hdone
Running command Preparing metadata (pyproject.toml)
*** scikit-build-core 0.10.7 using CMake 3.31.0 (metadata_wheel)
2024-11-20 23:57:28,967 - scikit_build_core - WARNING - No license files found, set wheel.license-files to [] to suppress this warning
Preparing metadata (pyproject.toml) ... ?25l?25hdone
Building wheels for collected packages: minuit2
Running command Building wheel for minuit2 (pyproject.toml)
*** scikit-build-core 0.10.7 using CMake 3.31.0 (wheel)
2024-11-20 23:57:29,101 - scikit_build_core - WARNING - No license files found, set wheel.license-files to [] to suppress this warning
*** Configuring CMake...
loading initial cache file /tmp/tmpgn0p2f72/build/CMakeInit.txt
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Deprecation Warning at /tmp/tmpgn0p2f72/build/_deps/minuit2-src/math/minuit2/CMakeLists.txt:7 (cmake_minimum_required):
Compatibility with CMake < 3.10 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
CMake Deprecation Warning at /tmp/tmpgn0p2f72/build/_deps/minuit2-src/math/minuit2/StandAlone.cmake:1 (cmake_minimum_required):
Compatibility with CMake < 3.10 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
Call Stack (most recent call first):
/tmp/tmpgn0p2f72/build/_deps/minuit2-src/math/minuit2/CMakeLists.txt:250 (include)
-- Found Python: /home/runner/work/se-for-sci/se-for-sci/.pixi/envs/default/bin/python (found suitable version "3.12.7", minimum required is "3.7") found components: Interpreter Development.Module Development.Embed
-- Performing Test HAS_FLTO
-- Performing Test HAS_FLTO - Success
-- Found pybind11: /home/runner/work/se-for-sci/se-for-sci/.pixi/envs/default/lib/python3.12/site-packages/pybind11/include (found version "2.13.6")
-- Configuring done (17.3s)
-- Generating done (0.0s)
-- Build files have been written to: /tmp/tmpgn0p2f72/build
*** Building project with Ninja...
[1/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/BFGSErrorUpdator.cxx.o
[2/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/DavidonErrorUpdator.cxx.o
[3/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/AnalyticalGradientCalculator.cxx.o
[4/84] Building CXX object _deps/minuit2-build/src/math/CMakeFiles/Minuit2Math.dir/__/__/__/minuit2-src/math/mathcore/src/MinimizerOptions.cxx.o
[5/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/CombinedMinimumBuilder.cxx.o
[6/84] Building CXX object _deps/minuit2-build/src/math/CMakeFiles/Minuit2Math.dir/__/__/__/minuit2-src/math/mathcore/src/GenAlgoOptions.cxx.o
[7/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliErrorUpdator.cxx.o
[8/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/ExternalInternalGradientCalculator.cxx.o
[9/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliStandardChi2FCN.cxx.o
[10/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliGradientCalculator.cxx.o
[11/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliMinimizer.cxx.o
[12/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliStandardMaximumLikelihoodFCN.cxx.o
[13/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaEigenValues.cxx.o
[14/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaInverse.cxx.o
[15/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/HessianGradientCalculator.cxx.o
[16/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaInnerProduct.cxx.o
[17/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaOuterProduct.cxx.o
[18/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaVtMVSimilarity.cxx.o
[19/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/LaSumOfElements.cxx.o
[20/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/FumiliBuilder.cxx.o
[21/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MinimumBuilder.cxx.o
[22/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MPIProcess.cxx.o
[23/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/InitialGradientCalculator.cxx.o
[24/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnEigen.cxx.o
[25/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnFcn.cxx.o
[26/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnCovarianceSqueeze.cxx.o
[27/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnApplication.cxx.o
[28/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnGlobalCorrelationCoeff.cxx.o
[29/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnFumiliMinimize.cxx.o
[30/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnMachinePrecision.cxx.o
[31/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnContours.cxx.o
[32/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnParabolaFactory.cxx.o
[33/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnLineSearch.cxx.o
[34/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/Minuit2Minimizer.cxx.o
[35/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnPlot.cxx.o
[36/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnFunctionCross.cxx.o
[37/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnParameterScan.cxx.o
[38/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnHesse.cxx.o
[39/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnPrintImpl.cxx.o
[40/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnStrategy.cxx.o
[41/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnTiny.cxx.o
[42/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnMinos.cxx.o
[43/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnPosDef.cxx.o
[44/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnScan.cxx.o
[45/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnPrint.cxx.o
[46/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnUserFcn.cxx.o
[47/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnTraceObject.cxx.o
[48/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnUserParameters.cxx.o
[49/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnSeedGenerator.cxx.o
[50/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnUserParameterState.cxx.o
[51/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/NegativeG2LineSearch.cxx.o
[52/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/MnUserTransformation.cxx.o
[53/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/ModularFunctionMinimizer.cxx.o
[54/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SimplexParameters.cxx.o
[55/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/ParametricFunction.cxx.o
[56/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SinParameterTransformation.cxx.o
[57/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/Numerical2PGradientCalculator.cxx.o
[58/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SqrtLowParameterTransformation.cxx.o
[59/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SqrtUpParameterTransformation.cxx.o
[60/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnbins.cxx.o
[61/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/VariableMetricEDMEstimator.cxx.o
[62/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mndasum.cxx.o
[63/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mndaxpy.cxx.o
[64/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SimplexSeedGenerator.cxx.o
[65/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/ScanBuilder.cxx.o
[66/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mndscal.cxx.o
[67/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnddot.cxx.o
[68/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnlsame.cxx.o
[69/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mndspr.cxx.o
[70/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mndspmv.cxx.o
[71/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/SimplexBuilder.cxx.o
[72/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mntplot.cxx.o
[73/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnteigen.cxx.o
[74/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnvert.cxx.o
[75/84] Linking CXX static library _deps/minuit2-build/src/math/libMinuit2Math.a
[76/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/mnxerbla.cxx.o
[77/84] Building CXX object _deps/minuit2-build/src/CMakeFiles/Minuit2.dir/VariableMetricBuilder.cxx.o
[78/84] Linking CXX static library _deps/minuit2-build/src/libMinuit2.a
[79/84] Building CXX object CMakeFiles/minuit2.dir/src/pyminuit2.cpp.o
[80/84] Building CXX object CMakeFiles/minuit2.dir/src/FunctionMinimum.cpp.o
[81/84] Building CXX object CMakeFiles/minuit2.dir/src/MnMigrad.cpp.o
[82/84] Building CXX object CMakeFiles/minuit2.dir/src/FCNBase.cpp.o
[83/84] Building CXX object CMakeFiles/minuit2.dir/src/MnUserParameters.cpp.o
[84/84] Linking CXX shared module minuit2.cpython-312-x86_64-linux-gnu.so
lto-wrapper: warning: using serial compilation of 3 LTRANS jobs
*** Installing project into wheel...
-- Install configuration: "Release"
-- Installing: /tmp/tmpgn0p2f72/wheel/platlib/./minuit2.cpython-312-x86_64-linux-gnu.so
*** Making wheel...
*** Created minuit2-6.26.10-cp312-cp312-linux_x86_64.whl
Building wheel for minuit2 (pyproject.toml) ... ?25l?25hdone
Created wheel for minuit2: filename=minuit2-6.26.10-cp312-cp312-linux_x86_64.whl size=245485 sha256=7970c8c44b74f1f17d1887a435c5f0557f936312c42395abb0d91e7b21fc8f1b
Stored in directory: /home/runner/.cache/pip/wheels/a4/eb/74/ff000d32154f6bcbd24e7b0472e3ff3daedae47ddc6c6bc9b6
Successfully built minuit2
Usage#
We can now use our module! We’ll just grab the file we need out of the wheel instead of installing it:
import zipfile
from pathlib import Path
with zipfile.ZipFile(*Path.cwd().glob("minuit2-6.26.10-*.whl")) as f:
for member in f.filelist:
print(member.filename)
if member.filename.startswith("minuit2."):
f.extract(member, ".")
minuit2.cpython-312-x86_64-linux-gnu.so
minuit2-6.26.10.dist-info/METADATA
minuit2-6.26.10.dist-info/WHEEL
minuit2-6.26.10.dist-info/RECORD
import minuit2
class SimpleFCN(minuit2.FCNBase):
def Up(self):
return 0.5
def __call__(self, v):
print("val =", v[0])
return v[0] ** 2
fcn = SimpleFCN()
upar = minuit2.MnUserParameters()
upar.Add("x", 1.0, 0.1)
migrad = minuit2.MnMigrad(fcn, upar)
minimum = migrad()
val = 1.0
val = 1.001
val = 0.999
val = 1.0005980198587356
val = 0.9994019801412644
val = -8.230083281546285e-11
val = 0.00034526688527999595
val = -0.0003452670498816616
val = -8.230083281546285e-11
val = 0.00034526688527999595
val = -0.0003452670498816616
val = 6.905331121533294e-05
val = -6.905347581699857e-05
print(minimum)
Valid : yes
Function calls: 13
Minimum value : 6.773427082e-21
Edm : 6.773427082e-21
Internal parameters:
-8.230083282e-11
Internal covariance matrix:
1
External parameters:
Pos | Name | type | Value | Error +/-
0 | x | free | -8.230083282e-11 | 0.7071067812
Done#
See GooFit’s built in Minuit2 bindings for a more complete example
Pybind11 bindings can talk to each other at the C level!