diff --git a/App/inc/TestFittingModule4.h b/App/inc/TestFittingModule4.h new file mode 100644 index 0000000000000000000000000000000000000000..c9a01eddd2cd04ae7d825e99c46779924fdeb262 --- /dev/null +++ b/App/inc/TestFittingModule4.h @@ -0,0 +1,54 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file App/inc/TestFittingModule4.h +//! @brief Defines class TestFittingModule4. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef TESTFITTINGMODULE4_H_ +#define TESTFITTINGMODULE4_H_ + +#include "IApplicationTest.h" +#include "OutputData.h" +#include "ISample.h" +#include "Simulation.h" +#include "ISampleBuilder.h" + +class FitSuite; + +//! Testing Genetic and SimmulatedAnnealing minimizers +//! +//! Cylinders on top of substrate without interference. Combination of two +//! minimizers is used: Genetic algorithm to run quickly through parameter space +//! to identify most promising local minima and then Migrad to explore it. + +class TestFittingModule4 : public IApplicationTest +{ +public: + TestFittingModule4(); + virtual ~TestFittingModule4(); + virtual void execute(); + +private: + void initializeSample(); + void initializeSimulation(); + void initializeRealData(); + + OutputData<double> *mp_real_data; + OutputData<double> *mp_simulated_data; + Simulation *mp_simulation; + ISample *mp_sample; + FitSuite *m_fitSuite; +}; + +#endif /* TESTFITTINGMODULE4_H_ */ + + diff --git a/App/inc/TestFumiliLMA.h b/App/inc/TestFumiliLMA.h index 8f17bea550934a9b478b35762aec786cc44bf299..f1f975dbd40233804d15929500054cad9aeb6647 100644 --- a/App/inc/TestFumiliLMA.h +++ b/App/inc/TestFumiliLMA.h @@ -32,7 +32,7 @@ class IFunctionObject; class IChiSquaredModule; class TCanvas; -//! Test of ROOT's LMA-based minimizers Fumili and GSLMultiFit +//! Test of ROOT's LMA-based minimizers Fumili and GSLLMA(GSLMultiFit) class TestFumiliLMA : public IApplicationTest { diff --git a/App/inc/TestPerformance.h b/App/inc/TestPerformance.h index 2b8abe9e7aa5e59c8ce8a21d215455c9d4b556e2..7eb3a6ec6c1b28a21aa086fa1ec20a4cde5b2568 100644 --- a/App/inc/TestPerformance.h +++ b/App/inc/TestPerformance.h @@ -2,9 +2,8 @@ // // BornAgain: simulate and fit scattering at grazing incidence // -//! @file App/inc/TestPerformance.h -//! @brief Defines classes TestPerformance, PerfTest_SpecularMatrix, -//! PerfTest_Pyramid, PerfTest_RotatedPyramid, PerfTest_MesoCrystal +//! @file App/inc/TestPerformance2.h +//! @brief Defines classe TestPerformance2 for logging performance changes // //! Homepage: apps.jcns.fz-juelich.de/BornAgain //! License: GNU General Public License v3 or higher (see COPYING) @@ -18,107 +17,74 @@ #define TESTPERFORMANCE_H #include "IApplicationTest.h" -#include "ISample.h" -#include "Simulation.h" +#include "INamed.h" #include <string> #include <vector> #include <map> #include <iostream> +class PerformanceTest; + //! Run standard tests to trace changes in the performance. class TestPerformance : public IApplicationTest { public: - //! class to hold performance information over functional test - class PerformanceTestInfo { - public: - PerformanceTestInfo(IApplicationTest *test, int nrepetitions) - : m_test(test), m_nrepetitions(nrepetitions), m_results(0){} - virtual ~PerformanceTestInfo(){ delete m_test; } - IApplicationTest *m_test; - double m_nrepetitions; - double m_results; - }; - - typedef std::vector<PerformanceTestInfo *> performance_tests_t; - TestPerformance(); virtual ~TestPerformance(); - virtual void execute(); private: - //! fill system information - void get_sysinfo(); - - //! save performance information on disk - void write_performance(); - - //! Returns delimeter between columns. - std::string get_delimeter() { return std::string(" | "); } - - std::map<std::string, std::string > m_performance_info; //!< holds system information - performance_tests_t m_tests; //!< list of tests for performance measurements - + void write_results(); + void write_header(std::ofstream &file); + void write_performance(std::ofstream &file); + void set_sysinfo(PerformanceTest *test); + std::vector<PerformanceTest *> m_tests; }; -//! @class PerfTest_SpecularMatrix -//! measurement of the performance in specular matrix calculation -class PerfTest_SpecularMatrix : public IApplicationTest -{ +//! class for performance measurements +class PerformanceTest : public IApplicationTest { public: - PerfTest_SpecularMatrix() : IApplicationTest("SpecularMatrix"), m_sample(0){} - virtual ~PerfTest_SpecularMatrix() { } - void initialise(ProgramOptions *p_options); - void execute(); - ISample *m_sample; -}; + PerformanceTest(const std::string &name, int nrepetitions) + : IApplicationTest(name) + , m_nrepetitions(nrepetitions) + , m_nthreads(0) + , m_cpu_time(0) + , m_real_time(0){} -//! @class PerfTest_Pyramid -//! measurement of the performance in pyramid form factor calculations -class PerfTest_Pyramid : public IApplicationTest -{ -public: - PerfTest_Pyramid() - : IApplicationTest("Pyramid"), m_sample(0), m_simulation(0) {} - virtual ~PerfTest_Pyramid() { delete m_simulation; } - void initialise(ProgramOptions *p_options); - void execute(); - ISample *m_sample; - Simulation *m_simulation; + virtual ~PerformanceTest(){} + + virtual void execute(); + virtual void runTests(); + + double m_nrepetitions; + int m_nthreads; + double m_cpu_time; + double m_real_time; + std::string m_datime; + std::string m_hostname; + std::string m_sysinfo; }; -//! @class PerfTest_RotatedPyramid -//! measurement of the performance in pyramid formfactor and in rotation mechanism -class PerfTest_RotatedPyramid : public IApplicationTest + +//! custom test for specular matrix +class SpecularMatrixPerformanceTest : public PerformanceTest { public: - PerfTest_RotatedPyramid() - : IApplicationTest("RotatedPyramid"), m_sample(0), m_simulation(0) {} - virtual ~PerfTest_RotatedPyramid() { delete m_simulation; } - void initialise(ProgramOptions *p_options); - void execute(); - ISample *m_sample; - Simulation *m_simulation; + SpecularMatrixPerformanceTest(const std::string &name, int nrepetitions) + : PerformanceTest(name, nrepetitions){} + virtual void runTests(); }; - -//! @class PerfTest_MesoCrystal -//! measurement of the performance iof meso crystal -class PerfTest_MesoCrystal : public IApplicationTest +//! custom test for specular magnetic +class SpecularMagneticPerformanceTest : public PerformanceTest { public: - PerfTest_MesoCrystal() - : IApplicationTest("MesoCrystal"), m_sample(0), m_simulation(0) {} - virtual ~PerfTest_MesoCrystal() { delete m_simulation; } - void initialise(ProgramOptions *p_options); - void execute(); - ISample *m_sample; - Simulation *m_simulation; + SpecularMagneticPerformanceTest(const std::string &name, int nrepetitions) + : PerformanceTest(name, nrepetitions){} + virtual void runTests(); }; -#endif // TESTPERFORMANCE_H - +#endif diff --git a/App/inc/TestPerformance2.h b/App/inc/TestPerformance2.h deleted file mode 100644 index 73227075e904c3a6bfdcac95ce502b0554c71867..0000000000000000000000000000000000000000 --- a/App/inc/TestPerformance2.h +++ /dev/null @@ -1,90 +0,0 @@ -// ************************************************************************** // -// -// BornAgain: simulate and fit scattering at grazing incidence -// -//! @file App/inc/TestPerformance2.h -//! @brief Defines classe TestPerformance2 for logging performance changes -// -//! Homepage: apps.jcns.fz-juelich.de/BornAgain -//! License: GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2013 -//! @authors Scientific Computing Group at MLZ Garching -//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke -// -// ************************************************************************** // - -#ifndef TESTPERFORMANCE2_H -#define TESTPERFORMANCE2_H - -#include "IApplicationTest.h" -#include "INamed.h" - -#include <string> -#include <vector> -#include <map> -#include <iostream> - -class PerformanceTest; - -//! Run standard tests to trace changes in the performance. - -class TestPerformance2 : public IApplicationTest -{ -public: - TestPerformance2(); - virtual ~TestPerformance2(); - virtual void execute(); -private: - void write_results(); - void write_header(std::ofstream &file); - void write_performance(std::ofstream &file); - void set_sysinfo(PerformanceTest *test); - std::vector<PerformanceTest *> m_tests; -}; - - -//! class for performance measurements -class PerformanceTest : public IApplicationTest { -public: - PerformanceTest(const std::string &name, int nrepetitions) - : IApplicationTest(name) - , m_nrepetitions(nrepetitions) - , m_nthreads(0) - , m_cpu_time(0) - , m_real_time(0){} - - virtual ~PerformanceTest(){} - - virtual void execute(); - virtual void runTests(); - - double m_nrepetitions; - int m_nthreads; - double m_cpu_time; - double m_real_time; - std::string m_datime; - std::string m_hostname; - std::string m_sysinfo; -}; - - -//! custom test for specular matrix -class SpecularMatrixPerformanceTest : public PerformanceTest -{ -public: - SpecularMatrixPerformanceTest(const std::string &name, int nrepetitions) - : PerformanceTest(name, nrepetitions){} - virtual void runTests(); -}; - -//! custom test for specular magnetic -class SpecularMagneticPerformanceTest : public PerformanceTest -{ -public: - SpecularMagneticPerformanceTest(const std::string &name, int nrepetitions) - : PerformanceTest(name, nrepetitions){} - virtual void runTests(); -}; - - -#endif diff --git a/App/src/ApplicationTestFactory.cpp b/App/src/ApplicationTestFactory.cpp index abdcd8d2a371d27094ff3a43c841671a696ef710..e087a449658ad214ae31267f882044b2122f3511 100644 --- a/App/src/ApplicationTestFactory.cpp +++ b/App/src/ApplicationTestFactory.cpp @@ -21,6 +21,7 @@ #include "TestFittingModule1.h" #include "TestFittingModule2.h" #include "TestFittingModule3.h" +#include "TestFittingModule4.h" #include "TestFormFactor.h" #include "TestFormFactors.h" #include "TestFourier.h" @@ -33,7 +34,6 @@ #include "TestMiscellaneous.h" #include "TestMultiLayerRoughness.h" #include "TestPerformance.h" -#include "TestPerformance2.h" #include "TestPolarizedDWBA.h" #include "TestPolarizedDWBATerms.h" #include "TestPolarizedMeso.h" @@ -193,22 +193,22 @@ void RegisterApplicationTests(ApplicationTestFactory *p_test_factory) p_test_factory->registerItem( "fitting1", IFactoryCreateFunction<TestFittingModule1, IApplicationTest>, - "functional test: fit module 2 params"); + "functional test: basing fitting 2 params"); p_test_factory->registerItem( "fitting2", IFactoryCreateFunction<TestFittingModule2, IApplicationTest>, - "functional test: fit module 5 params"); + "functional test: fitting with strategies"); p_test_factory->registerItem( "fitting3", IFactoryCreateFunction<TestFittingModule3, IApplicationTest>, - "functional test: fit module 4 params, 1d scans"); + "functional test: fitting via 1D cuts"); p_test_factory->registerItem( - "performance1", - IFactoryCreateFunction<TestPerformance, IApplicationTest>, - "functional test: run performance test for several predefined tasks"); + "fitting4", + IFactoryCreateFunction<TestFittingModule4, IApplicationTest>, + "functional test: testing genetic minimizer"); p_test_factory->registerItem( - "performance2", - IFactoryCreateFunction<TestPerformance2, IApplicationTest>, + "performance", + IFactoryCreateFunction<TestPerformance, IApplicationTest>, "functional test: run performance test for several predefined tasks"); p_test_factory->registerItem( "roughdwba", @@ -226,7 +226,7 @@ void RegisterApplicationTests(ApplicationTestFactory *p_test_factory) "fumili", IFactoryCreateFunction<TestFumiliLMA, IApplicationTest>, "functional test: test of ROOT's LMA-based minimizers Fumili and " - "GSLMultiFit"); + "GSLLMA"); p_test_factory->registerItem( "toyexp", IFactoryCreateFunction<TestToySimulation, IApplicationTest>, diff --git a/App/src/TestFittingModule1.cpp b/App/src/TestFittingModule1.cpp index 78ffa9bbf7604198a7baaac532dd110198ce0d69..93208858b058986faf213154af3b7ad90194c481 100644 --- a/App/src/TestFittingModule1.cpp +++ b/App/src/TestFittingModule1.cpp @@ -78,7 +78,7 @@ void TestFittingModule1::execute() //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") ); - //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") ); // LMA + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") ); @@ -141,10 +141,10 @@ void TestFittingModule1::initializeSample1() throw NullPointerException("TestFittingModule::initializeSample() -> Error! No FitSuite is defined"); } - m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::lowerLimited(0.01) ); - m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::lowerLimited(0.01) ); -// m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 10.) ); -// m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 10.) ); +// m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::lowerLimited(0.01) ); +// m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::lowerLimited(0.01) ); + m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 10.) ); + m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 10.) ); } diff --git a/App/src/TestFittingModule4.cpp b/App/src/TestFittingModule4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86fff6c6b6449aecb719b442468bbec279e5b1c9 --- /dev/null +++ b/App/src/TestFittingModule4.cpp @@ -0,0 +1,178 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file App/src/TestFittingModule4.cpp +//! @brief Implements class TestFittingModule4. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "TestFittingModule4.h" +#include "FitSuite.h" +#include "MinimizerFactory.h" +#include "Units.h" +#include "FitSuiteObserverFactory.h" +#include "HomogeneousMaterial.h" +#include "MultiLayer.h" +#include "FormFactors.h" +#include "MaterialManager.h" +#include "IsGISAXSTools.h" +#include "ROOTMinimizer.h" +#include "Math/GeneticMinimizer.h" +#include "Math/GenAlgoOptions.h" +#include "FitStrategyAdjustMinimizer.h" + +TestFittingModule4::TestFittingModule4() + : mp_real_data(0) + , mp_simulated_data(0) + , mp_simulation(0) + , mp_sample(0) + , m_fitSuite(0) +{ + m_fitSuite = new FitSuite(); +} + + +TestFittingModule4::~TestFittingModule4() +{ + delete mp_real_data; + delete mp_simulated_data; + delete mp_simulation; + delete mp_sample; +} + + +void TestFittingModule4::execute() +{ + // initializing data + initializeSample(); + initializeSimulation(); + initializeRealData(); + + ChiSquaredModule chiModule; + //chiModule.setChiSquaredFunction( SquaredFunctionSimError() ); + chiModule.setChiSquaredFunction( SquaredFunctionDefault() ); + + m_fitSuite->addSimulationAndRealData(*mp_simulation, *mp_real_data, chiModule); + + m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") ); + + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") ); + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") ); + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") ); + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") ); + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") ); + + + //m_fitSuite->getMinimizer()->getOptions().setPrintLevel(10); + + // Genetic +// m_fitSuite->getMinimizer()->getOptions().setMaxIterations(5); +// m_fitSuite->getMinimizer()->getOptions().setValue("Steps",5); +// m_fitSuite->getMinimizer()->getOptions().setValue("PopSize",100); +// m_fitSuite->getMinimizer()->getOptions().setTolerance(100); + + // GSLSimAn +// m_fitSuite->getMinimizer()->getOptions().setValue("ntries",50); +// m_fitSuite->getMinimizer()->getOptions().setValue("niters_fixed_t",5); +// m_fitSuite->getMinimizer()->getOptions().setMaxIterations(5); + +// m_fitSuite->getMinimizer()->getOptions().setValue("Strategy",2); + + //m_fitSuite->getMinimizer()->getOptions().print(); + + + m_fitSuite->attachObserver( FitSuiteObserverFactory::createPrintObserver(100) ); + m_fitSuite->attachObserver( FitSuiteObserverFactory::createDrawObserver() ); + + FitStrategyAdjustMinimizer *strategy1 = new FitStrategyAdjustMinimizer(); + strategy1->setMinimizer(MinimizerFactory::createMinimizer("Genetic")); + strategy1->getMinimizer()->getOptions().setMaxIterations(5); + strategy1->getMinimizer()->getOptions().setValue("Steps",5); + m_fitSuite->addFitStrategy(strategy1); + + FitStrategyAdjustMinimizer *strategy2 = new FitStrategyAdjustMinimizer(); + strategy2->setMinimizer(MinimizerFactory::createMinimizer("Minuit2","Migrad")); + m_fitSuite->addFitStrategy(strategy2); + + m_fitSuite->runFit(); +} + + +/* ************************************************************************* */ +// initializing simulation +/* ************************************************************************* */ +void TestFittingModule4::initializeSimulation() +{ + if( !mp_sample ) { + throw NullPointerException("TestFittingModule1::initializeSimulation() -> No sample defined"); + } + delete mp_simulation; + mp_simulation = new Simulation(mp_options); + mp_simulation->setSample(*mp_sample); + mp_simulation->setDetectorParameters(100, 0.0*Units::degree, + 2.0*Units::degree,100 , 0.0*Units::degree, 2.0*Units::degree); + mp_simulation->setBeamParameters(1.0*Units::angstrom, 0.2*Units::degree, + 0.0*Units::degree); + mp_simulation->setBeamIntensity(1e10); +} + + +/* ************************************************************************* */ +// initialize sample: layer + nanoparticles, 2 parameters +/* ************************************************************************* */ +void TestFittingModule4::initializeSample() +{ + delete mp_sample; + + MultiLayer *p_multi_layer = new MultiLayer(); + complex_t n_air(1.0, 0.0); + complex_t n_particle(1.0-6e-4, 2e-8); + const IMaterial *p_air_material = + MaterialManager::getHomogeneousMaterial("Air", n_air); + const IMaterial *particle_material = + MaterialManager::getHomogeneousMaterial("Particle", n_particle); + + Layer air_layer; + air_layer.setMaterial(p_air_material); + ParticleDecoration particle_decoration( new Particle(particle_material, + new FormFactorCylinder(5*Units::nanometer, 5*Units::nanometer))); + + air_layer.setDecoration(particle_decoration); + + p_multi_layer->addLayer(air_layer); + mp_sample = p_multi_layer; + + // defining parameters for minimization + if( !m_fitSuite ) { + throw NullPointerException("TestFittingModule::initializeSample() -> Error! No FitSuite is defined"); + } + + m_fitSuite->addFitParameter("*height", 1.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 30.) ); + m_fitSuite->addFitParameter("*radius", 20.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 30.) ); +// m_fitSuite->addFitParameter("*height", 6.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 30.) ); +// m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 30.) ); +} + + +void TestFittingModule4::initializeRealData() +{ + if( !mp_simulation ) throw NullPointerException("TestFittingModule2::initializeRealData() -> Error! No simulation of sample defined "); + + mp_simulation->runSimulation(); + mp_simulation->normalize(); + m_fitSuite->getFitObjects()->setSimulationNormalize(true); + delete mp_real_data; + mp_real_data = IsGISAXSTools::createNoisyData(*mp_simulation->getOutputData()); +} + + + + diff --git a/App/src/TestFumiliLMA.cpp b/App/src/TestFumiliLMA.cpp index fe3fc706776459db2aef10839c50515d31bdb1c4..a4d7718d166e1658fcabaca84347a2bab94351a3 100644 --- a/App/src/TestFumiliLMA.cpp +++ b/App/src/TestFumiliLMA.cpp @@ -90,7 +90,7 @@ void TestFumiliLMA::execute() //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Fumili2"); // same as ("Minuit2", "Fumili" ) //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Fumili2" ); // same as ("Minuit2", "Migrad" ), i.e. Fumili2 is wrong key m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Fumili"); // - //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("GSLMultiFit"); + //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("GSLLMA"); m_root_minimizer->SetVariable(0, "p0", 1.0, 0.01); m_root_minimizer->SetVariable(1, "p1", 0.0, 0.01); m_root_minimizer->SetVariable(2, "p2", 0.0, 0.01); diff --git a/App/src/TestIsGISAXS13.cpp b/App/src/TestIsGISAXS13.cpp index 28e5004c1a5bcc21a0dae5dc6cfdf8e70325f784..c2fd211e12bbf12ce9175a295950c2353078d513 100644 --- a/App/src/TestIsGISAXS13.cpp +++ b/App/src/TestIsGISAXS13.cpp @@ -87,7 +87,7 @@ void TestIsGISAXS13::run_isgisaxs_fit() // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") ); // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") ); // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") ); - // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") ); // LMA + // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") ); // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") ); diff --git a/App/src/TestPerformance.cpp b/App/src/TestPerformance.cpp index 0eb0d01339b9d19d09c2b522b805380a608971e7..bce60ffb8b1454a069fe18a4091abbc2fa482bf1 100644 --- a/App/src/TestPerformance.cpp +++ b/App/src/TestPerformance.cpp @@ -1,136 +1,120 @@ -// ************************************************************************** // -// -// BornAgain: simulate and fit scattering at grazing incidence -// -//! @file App/src/TestPerformance.cpp -//! @brief Implements class TestPerformance. -// -//! Homepage: apps.jcns.fz-juelich.de/BornAgain -//! License: GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2013 -//! @authors Scientific Computing Group at MLZ Garching -//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke -// -// ************************************************************************** // - #include "TestPerformance.h" -#include "Types.h" -#include "Units.h" +#include "SimulationRegistry.h" #include "Utils.h" -#include "Exceptions.h" -#include "MultiLayer.h" -#include "MaterialManager.h" -#include "SampleFactory.h" +#include "ProgramOptions.h" +#include "Units.h" #include "SpecularMatrix.h" -#include "SampleBuilderFactory.h" -#include "SimulationRegistry.h" +#include "SampleFactory.h" +#include "SpecularMagnetic.h" -#include "TSystem.h" #include "TDatime.h" +#include "TSystem.h" #include "TBenchmark.h" -#include <string> -#include <iostream> -#include <fstream> #include <sstream> +#include <fstream> #include <iomanip> -#include <time.h> +#include <boost/format.hpp> + + TestPerformance::TestPerformance() { - // preparing performance tests to run - m_tests.push_back( new PerformanceTestInfo(new PerfTest_Pyramid(), 20) ); - m_tests.push_back( new PerformanceTestInfo(new PerfTest_RotatedPyramid(), 20) ); - m_tests.push_back( new PerformanceTestInfo(new PerfTest_MesoCrystal(), 1) ); - m_tests.push_back( new PerformanceTestInfo(new PerfTest_SpecularMatrix(), 200000) ); - + m_tests.push_back(new PerformanceTest("isgisaxs02",2)); + m_tests.push_back(new PerformanceTest("isgisaxs06a",50)); + m_tests.push_back(new PerformanceTest("isgisaxs09b",50)); + m_tests.push_back(new PerformanceTest("isgisaxs11",50)); + m_tests.push_back(new PerformanceTest("isgisaxs15",20)); + m_tests.push_back(new PerformanceTest("mesocrystal01",1)); + m_tests.push_back(new SpecularMatrixPerformanceTest("specmatrix", 500000)); + m_tests.push_back(new SpecularMagneticPerformanceTest("specmagnetic", 500000)); + m_tests.push_back(new PerformanceTest("magcyl2",50)); std::cout << "TestPerformance::TestPerformance() -> Info. Preparing to run " << m_tests.size() << " performance tests." << std::endl; + } + TestPerformance::~TestPerformance() { - for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) { - delete (*it); - } + for(size_t i=0; i<m_tests.size(); ++i) delete m_tests[i]; } -//! Run performance tests. -void TestPerformance::execute() -{ - // getting system information - get_sysinfo(); - //clock_t clock1 = clock(); - //clock_t gt_clock1 = clock_get_time(); - // run tests - TBenchmark mb; - for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) { - PerformanceTestInfo *test_info = (*it); - std::string test_name = test_info->m_test->getName(); - std::cout << "Running test: " << std::setw(20) << std::left << test_name << " ... "; +void TestPerformance::execute() +{ + for(size_t i=0; i<m_tests.size(); ++i) { + PerformanceTest *test = m_tests[i]; + set_sysinfo(test); + + std::cout << "Running test: " << std::setw(20) << std::left << test->getName() << " ... "; std::cout.flush(); - test_info->m_test->initialise(mp_options); - mb.Start( test_name.c_str() ); - for(int i=0; i<test_info->m_nrepetitions; i++){ - test_info->m_test->execute(); - } - mb.Stop( test_name.c_str() ); - - // printing results - double result = mb.GetCpuTime( test_name.c_str() ); - double fhz = double(test_info->m_nrepetitions)/result; - std::cout << std::setw(6) << std::left << result << " sec, " - << std::setw(8) << std::left << fhz << " Hz (" - << std::setw(4) << std::left << test_info->m_nrepetitions << " repetitions )"<< std::endl; - // saving results - std::ostringstream os; - os << std::setprecision(6) << fhz; - m_performance_info[test_name] = os.str(); + test->execute(); + std::cout << boost::format("OK: %-6.3f (real sec), %-6.3f (cpu sec) ") % test->m_real_time % test->m_cpu_time << std::endl; } - write_performance(); - - //clock_t clock2 = clock(); + write_results(); } -//! Append results to log file. -void TestPerformance::write_performance() -{ - // appending performance information to the file -// std::string filename = Utils::FileSystem::GetHomePath() + -// "./dev-tools/log/perf_history.txt"; - std::string filename = "perf_history.txt"; +void TestPerformance::write_results() +{ + std::string filename("perf_history.txt"); std::ofstream file; file.open(filename.c_str(), std::ios_base::app); if( !file.is_open() ) { throw FileNotIsOpenException("TestPerformance::execute() -> Error. Can't open file '"+filename+"' for writing."); } - file << m_performance_info["datime"] << get_delimeter(); - file << std::left << Utils::AdjustStringLength(m_performance_info["hostname"],10) << get_delimeter(); - file << std::left << Utils::AdjustStringLength(m_performance_info["sysinfo"],23) << get_delimeter(); - for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) { - std::string test_name = (*it)->m_test->getName(); - file << std::left << Utils::AdjustStringLength(m_performance_info[test_name],11) << get_delimeter(); - } - file<<std::endl; + write_header(file); + write_performance(file); file.close(); std::cout << "TestPerformance::write_performance() -> Info. File '" << filename << "' is updated." << std::endl; } -//! Fill system information. -void TestPerformance::get_sysinfo() +//! write header in file +void TestPerformance::write_header(std::ofstream &file) +{ + file << std::endl; + file << boost::format("| %-19s | %-10s | %-13s | %2s | %-8s |") % "date " % "hostname" % "sysinfo" % "tr" % "total"; + for(size_t i=0; i<m_tests.size(); ++i) { + file << boost::format(" %-12s |") % Utils::AdjustStringLength(m_tests[i]->getName(),12); + } + file << std::endl; +} + +//! write results of performance measurements +void TestPerformance::write_performance(std::ofstream &file) +{ + PerformanceTest *test0 = m_tests[0]; + file << boost::format("| %-19s | %-10s | %-13s | %-2d |") % test0->m_datime % test0->m_hostname % test0->m_sysinfo % test0->m_nthreads; + double sum_real(0), sum_cpu(0); + for(size_t i=0; i<m_tests.size(); ++i) { + sum_real += m_tests[i]->m_real_time; + sum_cpu += m_tests[i]->m_cpu_time; + } + file << boost::format(" %-8.3f |") % sum_real; + + for(size_t i=0; i<m_tests.size(); ++i) { + file << boost::format(" %-12.3f |") % m_tests[i]->m_real_time; + } + file << std::endl; +} + + +//! read sustem information and store it in the test +void TestPerformance::set_sysinfo(PerformanceTest *test) { + test->initialise(mp_options); + // saving date and time TDatime td; - m_performance_info["datime"] = std::string(td.AsSQLString()); + test->m_datime = std::string(td.AsSQLString()); // saving host name std::string hostname(gSystem->HostName()); @@ -139,95 +123,90 @@ void TestPerformance::get_sysinfo() if(pos != std::string::npos) { hostname.erase(pos,hostname.size()-pos); } - m_performance_info["hostname"] = hostname; + test->m_hostname = hostname; // saving hardware information - //std::string sysinfo; SysInfo_t sys_info; int status = gSystem->GetSysInfo(&sys_info); if( status == -1) { - std::cout << "TestPerformance::get_sysinfo() -> Warning! Can't get system info." << std::endl; - m_performance_info["sysinfo"] = std::string("failed"); + test->m_sysinfo = std::string("Unknown hardware"); }else{ std::ostringstream os; - os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz"; - + os << std::string(gSystem->GetBuildArch()); + //os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz"; //os << ", " << sys_info.fL2Cache << " Kb"; - m_performance_info["sysinfo"] = os.str(); + test->m_sysinfo = os.str(); } -} - -//! Start PerfTest_SpecularMatrix. -void PerfTest_SpecularMatrix::initialise(ProgramOptions *p_options) -{ - IApplicationTest::initialise(p_options); - if(m_sample) delete m_sample; - m_sample = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer")); + if (mp_options->find("threads")) { + test->m_nthreads = (*mp_options)["threads"].as<int>(); + } } -//! Run PerfTest_SpecularMatrix. -void PerfTest_SpecularMatrix::execute() -{ - static double alpha_i = -0.3; - kvector_t kvec; - kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); - SpecularMatrix::MultiLayerCoeff_t coeffs; - SpecularMatrix matrixCalculator; - MultiLayer *ml = dynamic_cast<MultiLayer *>(m_sample); - matrixCalculator.execute(*ml, kvec, coeffs); -} +// ----------------------------------------------------------------------------- +// General PerformanceTest +// ----------------------------------------------------------------------------- -//! Start PerfTest_Pyramid. - -void PerfTest_Pyramid::initialise(ProgramOptions *p_options) +//! run performance measurements +void PerformanceTest::execute() { - IApplicationTest::initialise(p_options); - SimulationRegistry registry; - m_simulation = registry.createSimulation("isgisaxs09a"); - m_simulation->setProgramOptions(p_options); -} - -//! Run PerfTest_Pyramid. + TBenchmark mb; + mb.Start( getName().c_str() ); -void PerfTest_Pyramid::execute() -{ - m_simulation->runSimulation(); -} + runTests(); -//! Start PerfTest_RotatedPyramid + mb.Stop( getName().c_str() ); -void PerfTest_RotatedPyramid::initialise(ProgramOptions *p_options) -{ - IApplicationTest::initialise(p_options); - SimulationRegistry registry; - m_simulation = registry.createSimulation("isgisaxs09b"); - m_simulation->setProgramOptions(p_options); + m_cpu_time = mb.GetCpuTime(getName().c_str()); + m_real_time = mb.GetRealTime(getName().c_str()); } -//! Run PerfTest_RotatedPyramid -void PerfTest_RotatedPyramid::execute() +//! run standard simulation +void PerformanceTest::runTests() { - m_simulation->runSimulation(); + SimulationRegistry registry; + Simulation *simulation = registry.createSimulation(getName()); + simulation->setProgramOptions(mp_options); + for(int i=0; i<m_nrepetitions; i++){ + simulation->runSimulation(); + } + delete simulation; } -//! Start PerfTest_MesoCrystal. +// ----------------------------------------------------------------------------- +// custom PerformanceTest's +// ----------------------------------------------------------------------------- -void PerfTest_MesoCrystal::initialise(ProgramOptions *p_options) +void SpecularMatrixPerformanceTest::runTests() { - IApplicationTest::initialise(p_options); - SimulationRegistry registry; - m_simulation = registry.createSimulation("mesocrystal01"); - m_simulation->setProgramOptions(p_options); + MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer")); + + for(int i=0; i<m_nrepetitions; i++){ + static double alpha_i = -0.3; + kvector_t kvec; + kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); + SpecularMatrix::MultiLayerCoeff_t coeffs; + SpecularMatrix matrixCalculator; + matrixCalculator.execute(*ml, kvec, coeffs); + } + delete ml; } -//! Run PerfTest_MesoCrystal. - -void PerfTest_MesoCrystal::execute() +void SpecularMagneticPerformanceTest::runTests() { - m_simulation->runSimulation(); + MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("MultilayerSpecularMagneticTestCase")); + + for(int i=0; i<m_nrepetitions; i++){ + static double alpha_i = -0.3; + kvector_t kvec; + kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); + SpecularMagnetic::MultiLayerCoeff_t coeffs; + SpecularMagnetic magneticCalculator; + magneticCalculator.execute(*ml, kvec, coeffs); + } + delete ml; } diff --git a/App/src/TestPerformance2.cpp b/App/src/TestPerformance2.cpp deleted file mode 100644 index 460c22ce2463a12e23afb0d4029539f7a980f988..0000000000000000000000000000000000000000 --- a/App/src/TestPerformance2.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include "TestPerformance2.h" -#include "SimulationRegistry.h" -#include "Utils.h" -#include "ProgramOptions.h" -#include "Units.h" -#include "SpecularMatrix.h" -#include "SampleFactory.h" -#include "SpecularMagnetic.h" - -#include "TDatime.h" -#include "TSystem.h" -#include "TBenchmark.h" -#include <sstream> -#include <fstream> -#include <iomanip> -#include <boost/format.hpp> - - - -TestPerformance2::TestPerformance2() -{ - m_tests.push_back(new PerformanceTest("isgisaxs02",2)); - m_tests.push_back(new PerformanceTest("isgisaxs06a",50)); - m_tests.push_back(new PerformanceTest("isgisaxs09b",50)); - m_tests.push_back(new PerformanceTest("isgisaxs11",50)); - m_tests.push_back(new PerformanceTest("isgisaxs15",20)); - m_tests.push_back(new PerformanceTest("mesocrystal01",1)); - m_tests.push_back(new SpecularMatrixPerformanceTest("specmatrix", 500000)); - m_tests.push_back(new SpecularMagneticPerformanceTest("specmagnetic", 500000)); - m_tests.push_back(new PerformanceTest("magcyl2",50)); - std::cout << "TestPerformance::TestPerformance() -> Info. Preparing to run " << m_tests.size() << " performance tests." << std::endl; - -} - - -TestPerformance2::~TestPerformance2() -{ - for(size_t i=0; i<m_tests.size(); ++i) delete m_tests[i]; -} - - - - - -void TestPerformance2::execute() -{ - for(size_t i=0; i<m_tests.size(); ++i) { - PerformanceTest *test = m_tests[i]; - set_sysinfo(test); - - std::cout << "Running test: " << std::setw(20) << std::left << test->getName() << " ... "; - std::cout.flush(); - test->execute(); - std::cout << boost::format("OK: %-6.3f (real sec), %-6.3f (cpu sec) ") % test->m_real_time % test->m_cpu_time << std::endl; - } - - write_results(); -} - - - -void TestPerformance2::write_results() -{ - std::string filename("perf_history.txt"); - std::ofstream file; - file.open(filename.c_str(), std::ios_base::app); - if( !file.is_open() ) { - throw FileNotIsOpenException("TestPerformance::execute() -> Error. Can't open file '"+filename+"' for writing."); - } - - write_header(file); - write_performance(file); - - file.close(); - - std::cout << "TestPerformance::write_performance() -> Info. File '" << filename << "' is updated." << std::endl; -} - - -//! write header in file -void TestPerformance2::write_header(std::ofstream &file) -{ - file << std::endl; - file << boost::format("| %-19s | %-10s | %-13s | %2s | %-8s |") % "date " % "hostname" % "sysinfo" % "tr" % "total"; - for(size_t i=0; i<m_tests.size(); ++i) { - file << boost::format(" %-12s |") % Utils::AdjustStringLength(m_tests[i]->getName(),12); - } - file << std::endl; -} - -//! write results of performance measurements -void TestPerformance2::write_performance(std::ofstream &file) -{ - PerformanceTest *test0 = m_tests[0]; - file << boost::format("| %-19s | %-10s | %-13s | %-2d |") % test0->m_datime % test0->m_hostname % test0->m_sysinfo % test0->m_nthreads; - double sum_real(0), sum_cpu(0); - for(size_t i=0; i<m_tests.size(); ++i) { - sum_real += m_tests[i]->m_real_time; - sum_cpu += m_tests[i]->m_cpu_time; - } - file << boost::format(" %-8.3f |") % sum_real; - - for(size_t i=0; i<m_tests.size(); ++i) { - file << boost::format(" %-12.3f |") % m_tests[i]->m_real_time; - } - file << std::endl; -} - - -//! read sustem information and store it in the test -void TestPerformance2::set_sysinfo(PerformanceTest *test) -{ - test->initialise(mp_options); - - // saving date and time - TDatime td; - test->m_datime = std::string(td.AsSQLString()); - - // saving host name - std::string hostname(gSystem->HostName()); - // stripping host name after first '.' (somehost.jcns.frm2 -> somehost) - std::string::size_type pos = hostname.find_first_of('.'); - if(pos != std::string::npos) { - hostname.erase(pos,hostname.size()-pos); - } - test->m_hostname = hostname; - - // saving hardware information - SysInfo_t sys_info; - int status = gSystem->GetSysInfo(&sys_info); - if( status == -1) { - test->m_sysinfo = std::string("Unknown hardware"); - }else{ - std::ostringstream os; - os << std::string(gSystem->GetBuildArch()); - //os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz"; - //os << ", " << sys_info.fL2Cache << " Kb"; - test->m_sysinfo = os.str(); - } - - if (mp_options->find("threads")) { - test->m_nthreads = (*mp_options)["threads"].as<int>(); - } -} - - -// ----------------------------------------------------------------------------- -// General PerformanceTest -// ----------------------------------------------------------------------------- - -//! run performance measurements -void PerformanceTest::execute() -{ - TBenchmark mb; - mb.Start( getName().c_str() ); - - runTests(); - - mb.Stop( getName().c_str() ); - - m_cpu_time = mb.GetCpuTime(getName().c_str()); - m_real_time = mb.GetRealTime(getName().c_str()); -} - - -//! run standard simulation -void PerformanceTest::runTests() -{ - SimulationRegistry registry; - Simulation *simulation = registry.createSimulation(getName()); - simulation->setProgramOptions(mp_options); - for(int i=0; i<m_nrepetitions; i++){ - simulation->runSimulation(); - } - delete simulation; -} - -// ----------------------------------------------------------------------------- -// custom PerformanceTest's -// ----------------------------------------------------------------------------- - -void SpecularMatrixPerformanceTest::runTests() -{ - MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer")); - - for(int i=0; i<m_nrepetitions; i++){ - static double alpha_i = -0.3; - kvector_t kvec; - kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); - SpecularMatrix::MultiLayerCoeff_t coeffs; - SpecularMatrix matrixCalculator; - matrixCalculator.execute(*ml, kvec, coeffs); - } - delete ml; -} - -void SpecularMagneticPerformanceTest::runTests() -{ - MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("MultilayerSpecularMagneticTestCase")); - - for(int i=0; i<m_nrepetitions; i++){ - static double alpha_i = -0.3; - kvector_t kvec; - kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); - SpecularMagnetic::MultiLayerCoeff_t coeffs; - SpecularMagnetic magneticCalculator; - magneticCalculator.execute(*ml, kvec, coeffs); - } - delete ml; -} - - diff --git a/App/src/TestToySimulation.cpp b/App/src/TestToySimulation.cpp index 19368ea3f43f4623efc896fd293d148d760dbf46..edeb6978cc8ae3e6693d55fc5e9f6f2e17a786b0 100644 --- a/App/src/TestToySimulation.cpp +++ b/App/src/TestToySimulation.cpp @@ -98,7 +98,7 @@ void TestToySimulation::execute() m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") ); - //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") ); + //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") ); //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") ); //m_fitSuite->getMinimizer()->setOptions("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1"); diff --git a/Core/Algorithms/inc/ISquaredFunction.h b/Core/Algorithms/inc/ISquaredFunction.h index 4c205fe255e9c3164e6c98f145819bfd1d508d17..090faf2dff1b79958813edede36a75cdf2dc06de 100644 --- a/Core/Algorithms/inc/ISquaredFunction.h +++ b/Core/Algorithms/inc/ISquaredFunction.h @@ -51,6 +51,7 @@ private: //! //! value = (a-b)*(a-b)/norm, where //! norm = max(b, 1.0) +//! a - simulated values, b - real_values class BA_CORE_API_ SquaredFunctionDefault : public ISquaredFunction { @@ -76,6 +77,37 @@ public: }; +//! @class SquaredFunctionSimError +//! @ingroup fitting +//! @brief Squared difference between two values. +//! +//! value = (a-b)*(a-b)/norm, where +//! norm = max(a, 1.0) +//! a - simulated values, b - real_values + +class BA_CORE_API_ SquaredFunctionSimError : public ISquaredFunction +{ +public: + SquaredFunctionSimError() {} + virtual ~SquaredFunctionSimError() {} + virtual SquaredFunctionSimError *clone() const { return new SquaredFunctionSimError(); } + + virtual double calculateSquaredDifference(double real_value, double simulated_value) const + { + double diff_squared = (simulated_value-real_value)*(simulated_value-real_value); + if (diff_squared < Numeric::double_epsilon) return 0.0; + double normalization = calculateSquaredError(real_value, simulated_value); + return diff_squared/normalization; + } + + virtual double calculateSquaredError(double real_value, double simulated_value) const + { + (void) real_value; + return std::max(simulated_value,1.0); + } +}; + + //! @class SquaredFunctionMeanSquaredError //! @ingroup fitting //! @brief Squared difference between two values normalized by mean squared error diff --git a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py index 7af3a83205a524493ea4168bcf6fc055cf0d1a4a..2c3c464464953723468ecf3eaf40e599091c7d7b 100644 --- a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py +++ b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py @@ -149,7 +149,7 @@ def run_fitting(): fit_suite.addSimulationAndRealData(simulation, real_data) fit_suite.initPrint(10) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2", "Fumili")) - #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLMultiFit")) + #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLLMA")) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2","Scan")) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLSimAn")) diff --git a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py index e3dd45fadaac2ec95b1e0b9ecfcb5480aef5807f..bbb4b98b0571cf3b88734493090a28e4fce6f88e 100644 --- a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py +++ b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py @@ -167,7 +167,7 @@ def run_fitting(): fit_suite.addSimulationAndRealData(simulation, real_data) fit_suite.initPrint(10) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2", "Fumili")) - #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLMultiFit")) + #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLLMA")) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2","Scan")) #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLSimAn")) diff --git a/Fit/CMakeLists.txt b/Fit/CMakeLists.txt index fa0e453f5636545ac21b2d37838935af25e56eed..d8fa58266a14297cd38ea7fb8e6125609dbacf6d 100644 --- a/Fit/CMakeLists.txt +++ b/Fit/CMakeLists.txt @@ -18,11 +18,18 @@ file(GLOB include_files "FitKernel/inc/*.h" ) +# genetic minimizer only available if ROOT present +if(NOT ROOT_FOUND) + list(REMOVE_ITEM source_files "${CMAKE_CURRENT_SOURCE_DIR}/FitKernel/src/ROOTGeneticMinimizer.cpp") + list(REMOVE_ITEM include_files "${CMAKE_CURRENT_SOURCE_DIR}/FitKernel/inc/ROOTGeneticMinimizer.h") +endif() + if(BORNAGAIN_PYTHON) file(GLOB source_pythonapi "PythonAPI/src/*.cpp") list(APPEND source_files ${source_pythonapi}) file(GLOB include_pythonapi "PythonAPI/inc/*.h") list(APPEND include_files ${include_pythonapi}) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/PythonAPI/inc ) @@ -48,6 +55,7 @@ set(${library_name}_LIBRARY_TYPE SHARED) set(${library_name}_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE) set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE) + # --- dependencies --- include_directories( ${BornAgainCore_INCLUDE_DIRS} @@ -63,6 +71,16 @@ target_link_libraries( ${RootMinimizers_LIBRARY} ) +if(ROOT_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAS_GENETIC_MINIMIZER") + include_directories( + ${ROOT_INCLUDE_DIR} + ) + target_link_libraries(${library_name} + ${ROOT_LIBRARIES} -lGenetic -lTMVA + ) +endif() + if(BORNAGAIN_PYTHON) include_directories(${PYTHON_INCLUDE_DIRS}) target_link_libraries(${library_name} ${PYTHON_LIBRARIES}) diff --git a/Fit/Factory/inc/AttFitting.h b/Fit/Factory/inc/AttFitting.h deleted file mode 100644 index 4d5cd34274b462a38c2780f63c10e4bcdf27bafd..0000000000000000000000000000000000000000 --- a/Fit/Factory/inc/AttFitting.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************** // -// -// BornAgain: simulate and fit scattering at grazing incidence -// -//! @file Factory/inc/AttFitting.h -//! @brief Defines class AttFitting. -//! -//! @homepage http://apps.jcns.fz-juelich.de/BornAgain -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2013 -//! @authors Scientific Computing Group at MLZ Garching -//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke -// -// ************************************************************************** // - -#ifndef ATTFITTING_H -#define ATTFITTING_H - -#include "WinDllMacros.h" -#include <iostream> -#include <iomanip> - -//! General fitting attributes. - -class BA_CORE_API_ AttFitting -{ - public: - AttFitting(); - ~AttFitting(){} - - double getDerivEpsilon() const { return m_deriv_epsilon; } - void setDerivEpsilon(double deriv_epsilon) { m_deriv_epsilon = deriv_epsilon; } - - double getStepFactor() const { return m_step_factor; } - void setStepFactor(double step_factor) { m_step_factor = step_factor; } - - private: - double m_deriv_epsilon; //! epsilon for derivative calculation - double m_step_factor; //! default relative parameter step -}; - -inline AttFitting::AttFitting() - : m_deriv_epsilon(1e-09) - , m_step_factor(0.01) -{ -} - -#endif // ATTFITTING_H - - diff --git a/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h b/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h index aa3645f1dca5d5de4e28c0e03204fc5775bde222..d37826f191c1e1f709e1a570abc8d6e7cadd1442 100644 --- a/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h +++ b/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h @@ -17,6 +17,7 @@ #define FITSTRATEGYADJUSTMINIMIZER_H #include "IFitStrategy.h" +#include "IMinimizer.h" //! @class FitStrategyAdjustMinimizer //! @ingroup fitting @@ -25,6 +26,18 @@ class BA_CORE_API_ FitStrategyAdjustMinimizer : public IFitStrategy { public: + FitStrategyAdjustMinimizer() : IFitStrategy("FitStrategyAdjustMinimizer"), m_minimizer(0) {} + virtual ~FitStrategyAdjustMinimizer(){ delete m_minimizer; } + + virtual FitStrategyAdjustMinimizer *clone() const; + + IMinimizer *getMinimizer() { return m_minimizer; } + void setMinimizer(IMinimizer *minimizer) { m_minimizer = minimizer; } + + virtual void execute(); + +private: + IMinimizer *m_minimizer; }; #endif // FITSTRATEGYADJUSTMINIMIZER_H diff --git a/Fit/FitKernel/inc/FitSuite.h b/Fit/FitKernel/inc/FitSuite.h index 72ebf07fd3e259f62c247ba83b8d58aa8dff493a..ad779b20610988834ada06d48f843decd043ef50 100644 --- a/Fit/FitKernel/inc/FitSuite.h +++ b/Fit/FitKernel/inc/FitSuite.h @@ -86,7 +86,7 @@ class BA_CORE_API_ FitSuite : public IObservable size_t getNCalls() const; //! Returns the number of current strategy - size_t getNStrategy() const { return m_fit_strategies.getNStrategy(); } + size_t getNStrategy() const { return m_fit_strategies.getCurrentStrategyIndex(); } //! Prints results of the screen void printResults() const; diff --git a/Fit/FitKernel/inc/FitSuitePrintObserver.h b/Fit/FitKernel/inc/FitSuitePrintObserver.h index 6c3bf85b88440eb6a9b95859749ddf87147e1917..10ffae838440d75e44d0264f14b3a8eeb597a7e3 100644 --- a/Fit/FitKernel/inc/FitSuitePrintObserver.h +++ b/Fit/FitKernel/inc/FitSuitePrintObserver.h @@ -18,7 +18,7 @@ #include "IObserver.h" #include <boost/date_time/posix_time/posix_time.hpp> - +class FitSuite; //! @class FitSuitePrintObserver //! @ingroup fitting_internal @@ -33,9 +33,15 @@ public: void update(IObservable *subject); private: + bool skipIteration(); + void checkStrategy(); + + FitSuite *m_fitSuite; int m_print_every_nth; + int m_previous_strategy_index; boost::posix_time::ptime m_start_time; boost::posix_time::ptime m_last_call_time; + bool m_strategy_is_changed; }; #endif // FITSUITEPRINTOBSERVER_H diff --git a/Fit/FitKernel/inc/FitSuiteStrategies.h b/Fit/FitKernel/inc/FitSuiteStrategies.h index 01b713289432597ba9caf98869846b21afe24bfa..fc21d3a16adb668aded7a05846ce12ee2d0eee1e 100644 --- a/Fit/FitKernel/inc/FitSuiteStrategies.h +++ b/Fit/FitKernel/inc/FitSuiteStrategies.h @@ -40,16 +40,19 @@ class BA_CORE_API_ FitSuiteStrategies void minimize(); - size_t getNStrategy() const { return m_current_strategy_index; } + size_t getCurrentStrategyIndex() const { return m_current_strategy_index; } + std::string getCurrentStrategyName() const { return m_current_strategy_name; } iterator begin() { return m_strategies.begin(); } iterator end() { return m_strategies.end(); } + size_t size() const { return m_strategies.size(); } void clear(); private: strategies_t m_strategies; FitSuite *m_fit_suite; size_t m_current_strategy_index; + std::string m_current_strategy_name; }; #endif // FITSUITESTRATEGIES_H diff --git a/Fit/FitKernel/inc/IMinimizer.h b/Fit/FitKernel/inc/IMinimizer.h index 1bc99eadf36ff4cac189a526bfceacdf07b8c8fb..36c7f3e58de110347ef1dbaa37c493e0d3bd4bda 100644 --- a/Fit/FitKernel/inc/IMinimizer.h +++ b/Fit/FitKernel/inc/IMinimizer.h @@ -82,18 +82,27 @@ class BA_CORE_API_ IMinimizer //! Prints fit results virtual void printResults() const; - //! Returns number of calls of minimized function virtual size_t getNCalls() const; //! return minimizer options - virtual MinimizerOptions getOptions() const; + virtual MinimizerOptions &getOptions(); + virtual const MinimizerOptions &getOptions() const; //! set minimizer options virtual void setOptions(const MinimizerOptions &options); //! set minimizer option string - virtual void setOptions(const std::string& options); + virtual void setOptionString(const std::string& options); + + //! Checks if type of algorithm is Levenberg-Marquardt or similar + virtual bool isGradientBasedAgorithm(); + + //! return name of the minimizer + virtual std::string getMinimizerName() const; + + //! return name of the minimization algorithm + virtual std::string getAlgorithmName() const; }; @@ -162,7 +171,13 @@ inline size_t IMinimizer::getNCalls() const throw NotImplementedException("IMinimizer::getNCalls() -> Not implemented."); } -inline MinimizerOptions IMinimizer::getOptions() const +inline MinimizerOptions &IMinimizer::getOptions() +{ + throw NotImplementedException("IMinimizer::getOptions() -> Not implemented."); +} + + +inline const MinimizerOptions &IMinimizer::getOptions() const { throw NotImplementedException("IMinimizer::getOptions() -> Not implemented."); } @@ -172,11 +187,28 @@ inline void IMinimizer::setOptions(const MinimizerOptions &/*options*/) throw NotImplementedException("IMinimizer::setOptions() -> Not implemented."); } -inline void IMinimizer::setOptions(const std::string &/*options*/) +inline void IMinimizer::setOptionString(const std::string &/*options*/) { - throw NotImplementedException("IMinimizer::setOptions() -> Not implemented."); + throw NotImplementedException("IMinimizer::setOptionString() -> Not implemented."); } +inline bool IMinimizer::isGradientBasedAgorithm() +{ + throw NotImplementedException("IMinimizer::isGradientBasedAlgorithm() -> Not implemented."); +} + +inline std::string IMinimizer::getMinimizerName() const +{ + throw NotImplementedException("IMinimizer::getMinimizerName() -> Not implemented."); +} + +inline std::string IMinimizer::getAlgorithmName() const +{ + throw NotImplementedException("IMinimizer::getAlgorithmName() -> Not implemented."); +} + + + #endif // IMINIMIZER_H diff --git a/Fit/FitKernel/inc/MinimizerFactory.h b/Fit/FitKernel/inc/MinimizerFactory.h index 6687534775afc36720493e0b36314897f99646b7..675d57b3d8e8413555852553c5d8414cb52d3414 100644 --- a/Fit/FitKernel/inc/MinimizerFactory.h +++ b/Fit/FitKernel/inc/MinimizerFactory.h @@ -32,6 +32,9 @@ class BA_CORE_API_ MinimizerFactory static IMinimizer *createMinimizer(const std::string& minimizer, const std::string& algorithm = std::string(), const std::string& options=std::string() ); static void printCatalogue(); + //! Create minimizer using existing one. Only minimizer type and minimizer settings are propagated. + static IMinimizer *createMinimizer(const IMinimizer *minimizer); + private: //! @class map of minimizer names holding list of defined algorithms for every minimizer diff --git a/Fit/FitKernel/inc/MinimizerOptions.h b/Fit/FitKernel/inc/MinimizerOptions.h index 55a9e1e7029ef1e9af84c4377e1e4450f61705c3..92876f335ea92f391115812b41aee73586efeb2e 100644 --- a/Fit/FitKernel/inc/MinimizerOptions.h +++ b/Fit/FitKernel/inc/MinimizerOptions.h @@ -16,17 +16,23 @@ #ifndef MINIMIZEROPTIONS_H #define MINIMIZEROPTIONS_H #include "WinDllMacros.h" - +#include "Exceptions.h" +#include <string> +#include <map> +#include <iostream> +#include <iomanip> //! @class MinimizerOptions //! @ingroup fitting //! @brief The %MinimizerOptions class contains options for minimization algorithms +//! +//! It allows to set values only if they have been already registered. class BA_CORE_API_ MinimizerOptions { public: MinimizerOptions(); - virtual ~MinimizerOptions(){} + ~MinimizerOptions(){} //! return minimizer tolerance double getTolerance() const { return m_tolerance; } @@ -48,7 +54,79 @@ public: //! set maximum number of allowed function calls void setMaxFunctionCalls(int max_function_calls) { m_max_function_calls = max_function_calls; } + //! return internal print level of the minimizer + int getPrintLevel() const { return m_print_level; } + //! set internal print level of the minimizer + void setPrintLevel(int print_level){ m_print_level = print_level; } + + //! set option value + + void setValue(const std::string &name, double val) { setExistingValue(name, m_RealOpts, val); } + void setValue(const std::string &name, int val) { setExistingValue(name, m_IntOpts, val);} + void setValue(const std::string &name, const std::string &val) { setExistingValue(name, m_NamOpts, val);} + + void getValue(const std::string &name, int &val) { val = getIntValue(name); } + void getValue(const std::string &name, double &val) { val = getRealValue(name); } + void getValue(const std::string &name, std::string &val) { val = getNamedValue(name); } + + void addValue(const std::string &name, double val) { addNewValue(name, m_RealOpts, val); } + void addValue(const std::string &name, int val) { addNewValue(name, m_IntOpts, val);} + void addValue(const std::string &name, const std::string &val) { addNewValue(name, m_NamOpts, val);} + + int getIntValue(const std::string &name) { return getValue(name, m_IntOpts); } + double getRealValue(const std::string &name) { return getValue(name, m_RealOpts); } + std::string getNamedValue(const std::string &name) { return getValue(name, m_NamOpts); } + + void print() const { + print_common(std::cout); + if(m_IntOpts.size() || m_RealOpts.size() || m_NamOpts.size()) + std::cout << std::setw(24) << std::left << "Extra options " << " : " << std::endl; + print_extra(m_IntOpts, std::cout); + print_extra(m_RealOpts, std::cout); + print_extra(m_NamOpts, std::cout); + } + private: + template<class M> + static void setExistingValue(const std::string &name, M & opts, const typename M::mapped_type & value) { + typename M::iterator pos; + pos = opts.find(name); + if (pos != opts.end()) { + pos->second = value; + } else { + throw LogicErrorException("MinimizerOptions::setValue() -> Error! Not existing name '"+name+"'"); + } + } + + template<class M> + static void addNewValue(const std::string &name, M & opts, const typename M::mapped_type & value) { + typename M::iterator pos; + pos = opts.find(name); + if (pos != opts.end()) { + throw LogicErrorException("MinimizerOptions::addValue() -> Error! Already existing name '"+name+"'"); + } else { + opts.insert(typename M::value_type(name, value) ); + } + } + + template<class M> + static const typename M::mapped_type getValue(const std::string & name, const M & opts) { + typename M::const_iterator pos; + pos = opts.find(name); + if (pos == opts.end()) { + throw LogicErrorException("MinimizerOptions::getValue() -> Error! Not existing name '"+name+"'"); + } + return (*pos).second; + } + + template<class M> + static void print_extra( const M & opts, std::ostream & os) { + for (typename M::const_iterator pos = opts.begin(); pos != opts.end(); ++pos) + os << std::setw(24) << pos->first << " : " << std::setw(15) << pos->second << std::endl; + } + + void print_common(std::ostream & os) const; + double m_tolerance; //!< Tolerance on the function value at the minimum. //!< the default tolerance value is 0.01 and the minimization will stop //!< when the estimated vertical distance to the minimum (EDM) is less @@ -65,6 +143,11 @@ private: int m_max_function_calls; //!< Max number of function calls. + int m_print_level; //!< internal print level of the minimizer, 0- silent + + std::map<std::string, double> m_RealOpts; //!< additional map of the real options + std::map<std::string, int> m_IntOpts; //!< map of the integer options + std::map<std::string, std::string> m_NamOpts; //!< map of the named options }; diff --git a/Fit/FitKernel/inc/ROOTGSLNLSMinimizer.h b/Fit/FitKernel/inc/PatchedGSLNLSMinimizer.h similarity index 100% rename from Fit/FitKernel/inc/ROOTGSLNLSMinimizer.h rename to Fit/FitKernel/inc/PatchedGSLNLSMinimizer.h diff --git a/Fit/FitKernel/inc/ROOTGSLSimAnMinimizer.h b/Fit/FitKernel/inc/PatchedGSLSimAnMinimizer.h similarity index 100% rename from Fit/FitKernel/inc/ROOTGSLSimAnMinimizer.h rename to Fit/FitKernel/inc/PatchedGSLSimAnMinimizer.h diff --git a/Fit/FitKernel/inc/ROOTGeneticMinimizer.h b/Fit/FitKernel/inc/ROOTGeneticMinimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..4709dbabfd2a72c0c591ed9f19e1fff068938c90 --- /dev/null +++ b/Fit/FitKernel/inc/ROOTGeneticMinimizer.h @@ -0,0 +1,43 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/inc/ROOTGeneticMinimizer.h +//! @brief Defines class ROOTGeneticMinimizer. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ROOTGENETICMINIMIZER_H +#define ROOTGENETICMINIMIZER_H + +#include "ROOTMinimizer.h" +#include "Math/GeneticMinimizer.h" + +//! @class ROOTGeneticMinimizer +//! @ingroup fitting_internal +//! @brief Wrapper for ROOT Genetic minimizer + +class ROOTGeneticMinimizer : public ROOTMinimizer +{ +public: + ROOTGeneticMinimizer(const std::string& minimizer_name, const std::string& algo_type); + virtual ~ROOTGeneticMinimizer(){} + + virtual void setParameter(size_t index, const FitParameter *par); + +protected: + virtual void propagateOptions(); + + ROOT::Math::GeneticMinimizer *m_genetic_minimizer; + +}; + +#endif // ROOTGENETICMINIMIZER_H + + diff --git a/Fit/FitKernel/inc/ROOTLMAMinimizer.h b/Fit/FitKernel/inc/ROOTLMAMinimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..325cd801334a9da79fbebbf16a2366b9578de809 --- /dev/null +++ b/Fit/FitKernel/inc/ROOTLMAMinimizer.h @@ -0,0 +1,44 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/inc/ROOTLMAMinimizer.h +//! @brief Defines class ROOTLMAMinimizer. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ROOTMULTIFITMINIMIZER_H +#define ROOTMULTIFITMINIMIZER_H + +#include "ROOTMinimizer.h" +#include "PatchedGSLNLSMinimizer.h" + +//! @class ROOTLMAMinimizer +//! @ingroup fitting_internal +//! @brief Wrapper for Levenberg Marquard GSL minimizer + +class ROOTLMAMinimizer : public ROOTMinimizer +{ +public: + ROOTLMAMinimizer(const std::string& minimizer_name, const std::string& algo_type); + virtual ~ROOTLMAMinimizer(){} + + virtual bool isGradientBasedAgorithm() { return true; } + +protected: + virtual void propagateOptions(); + + ROOT::Patch::GSLNLSMinimizer *m_lma_minimizer; + +}; + +#endif // ROOTMULTIFITMINIMIZER_H + + + diff --git a/Fit/FitKernel/inc/ROOTMinimizer.h b/Fit/FitKernel/inc/ROOTMinimizer.h index 104c092ca4db06dde2f6a6d7fdbabf94f0bebd2a..d5430bc42463dcc570e3db75445c1e47b99c91ee 100644 --- a/Fit/FitKernel/inc/ROOTMinimizer.h +++ b/Fit/FitKernel/inc/ROOTMinimizer.h @@ -23,7 +23,6 @@ #include "FitSuiteParameters.h" #include <string> #include "Math/Minimizer.h" -#include "Math/Factory.h" #include "Math/Functor.h" @@ -66,21 +65,28 @@ class BA_CORE_API_ ROOTMinimizer : public IMinimizer virtual size_t getNCalls() const; //! return minimizer options - virtual MinimizerOptions getOptions() const; + virtual MinimizerOptions &getOptions() { return m_options; } + virtual const MinimizerOptions &getOptions() const { return m_options; } //! set minimizer options virtual void setOptions(const MinimizerOptions &options); - //! set minimizer option string - virtual void setOptions(const std::string& options); - //! Returns created minimizer ROOT::Math::Minimizer *getROOTMinimizer() { return m_root_minimizer; } + const ROOT::Math::Minimizer *getROOTMinimizer() const { return m_root_minimizer; } //! Checks if type of algorithm is Levenberg-Marquardt or similar - bool isGradientBasedAgorithm(); + virtual bool isGradientBasedAgorithm() { return false;} + + //! return name of the minimizer + virtual std::string getMinimizerName() const { return m_minimizer_name; } + + //! return name of the minimization algorithm + virtual std::string getAlgorithmName() const { return m_algo_type; } + + protected: + virtual void propagateOptions(); - private: ROOTMinimizer(const ROOTMinimizer& ); ROOTMinimizer& operator=(const ROOTMinimizer& ); @@ -91,6 +97,7 @@ class BA_CORE_API_ ROOTMinimizer : public IMinimizer ROOT::Math::Minimizer *m_root_minimizer; ROOTMinimizerChiSquaredFunction *m_chi2_func; ROOTMinimizerGradientFunction *m_gradient_func; + MinimizerOptions m_options; }; #endif // ROOTMINIMIZER_H diff --git a/Fit/FitKernel/inc/ROOTMinimizerHelper.h b/Fit/FitKernel/inc/ROOTMinimizerHelper.h index a771efd6bee8dc8807fbbdbd0c06538dd864b87b..4da05c324b33b47e6a8b65f13528a068f6a3187b 100644 --- a/Fit/FitKernel/inc/ROOTMinimizerHelper.h +++ b/Fit/FitKernel/inc/ROOTMinimizerHelper.h @@ -17,8 +17,7 @@ #define ROOTMINIMIZERHELPER_H #include "ROOTMinimizer.h" -#include "ROOTGSLSimAnMinimizer.h" - +#include "PatchedGSLSimAnMinimizer.h" //! @class ROOTMinimizerHelper @@ -37,9 +36,7 @@ class BA_CORE_API_ ROOTMinimizerHelper const std::string& options); //! Prints results of minimization - static void printResults(ROOT::Math::Minimizer *minimizer, - const std::string& minimizer_name, const std::string& algo_type); - + static void printResults(const ROOTMinimizer *minimizer); private: //! process single command @@ -55,13 +52,13 @@ class BA_CORE_API_ ROOTMinimizerHelper const std::string& command); //! Prints minimizer options - static void printOptions(ROOT::Math::Minimizer *minimizer); + static void printOptions(const ROOT::Math::Minimizer *minimizer); //! Prints minimizer status - static void printStatus(ROOT::Math::Minimizer *minimizer); + static void printStatus(const ROOT::Math::Minimizer *minimizer); //! Prints variables - static void printVariables(ROOT::Math::Minimizer *minimizer); + static void printVariables(const ROOT::Math::Minimizer *minimizer); }; diff --git a/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h b/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..4e56199935a3abc7917bc9c5fef6ae5a1f6a9a14 --- /dev/null +++ b/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h @@ -0,0 +1,42 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/inc/ROOTMinuitMinimizer.h +//! @brief Defines class ROOTMinuitMinimizer. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ROOTMINUIT2MINIMIZER_H +#define ROOTMINUIT2MINIMIZER_H + +#include "ROOTMinimizer.h" +#include "Minuit2/Minuit2Minimizer.h" + +//! @class ROOTMinuit2Minimizer +//! @ingroup fitting_internal +//! @brief Wrapper for ROOT Minuit2 minimizer + +class ROOTMinuit2Minimizer : public ROOTMinimizer +{ +public: + ROOTMinuit2Minimizer(const std::string& minimizer_name, const std::string& algo_type); + virtual ~ROOTMinuit2Minimizer(){} + + virtual bool isGradientBasedAgorithm(); + +protected: + virtual void propagateOptions(); + + ROOT::Minuit2::Minuit2Minimizer *m_minuit2_minimizer; + +}; + + +#endif diff --git a/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h b/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..0ee4ce26c9aa910a19bed2eb27394071e7840c41 --- /dev/null +++ b/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h @@ -0,0 +1,40 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/inc/ROOTMultiMinMinimizer.h +//! @brief Defines class ROOTMultiMinMinimizer. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ROOTMULTIMINMINIMIZER_H +#define ROOTMULTIMINMINIMIZER_H + +#include "ROOTMinimizer.h" +#include "Math/GSLMinimizer.h" + +//! @class ROOTMultiMinMinimizer +//! @ingroup fitting_internal +//! @brief Wrapper for GSL gradiend descent minimizer family + +class ROOTMultiMinMinimizer : public ROOTMinimizer +{ +public: + ROOTMultiMinMinimizer(const std::string& minimizer_name, const std::string& algo_type); + virtual ~ROOTMultiMinMinimizer(){} + +protected: + virtual void propagateOptions(); + + ROOT::Math::GSLMinimizer *m_gsl_minimizer; + +}; + + +#endif // ROOTMULTIMINMINIMIZER_H diff --git a/Fit/FitKernel/inc/ROOTSimAnMinimizer.h b/Fit/FitKernel/inc/ROOTSimAnMinimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..803419b71ea80ba78f4a78652e8d02fc8e75f003 --- /dev/null +++ b/Fit/FitKernel/inc/ROOTSimAnMinimizer.h @@ -0,0 +1,40 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/inc/ROOTSimAnMinimizer.h +//! @brief Defines class ROOTSimAnMinimizer. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ROOTSIMANMINIMIZER_H +#define ROOTSIMANMINIMIZER_H + +#include "ROOTMinimizer.h" +#include "PatchedGSLSimAnMinimizer.h" + + +//! @class ROOTSimAnMinimizer +//! @ingroup fitting_internal +//! @brief Wrapper for ROOT GSL simmulated annealing minimizer + +class ROOTSimAnMinimizer : public ROOTMinimizer +{ +public: + ROOTSimAnMinimizer(const std::string& minimizer_name, const std::string& algo_type); + virtual ~ROOTSimAnMinimizer(){} + +protected: + virtual void propagateOptions(); + + ROOT::Patch::GSLSimAnMinimizer *m_siman_minimizer; +}; + + +#endif // ROOTSIMANMINIMIZER_H diff --git a/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp b/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp index 6ceafc542c4a6423f226ece7023e3dd1bb43826b..146900147275852c5c6f11cbacba2f2ff11cbb7c 100644 --- a/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp +++ b/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp @@ -1,2 +1,24 @@ #include "FitStrategyAdjustMinimizer.h" #include "FitSuite.h" +#include "MinimizerFactory.h" + + +// It's not real clone +FitStrategyAdjustMinimizer *FitStrategyAdjustMinimizer::clone() const +{ + FitStrategyAdjustMinimizer *result = new FitStrategyAdjustMinimizer(); + result->setMinimizer( MinimizerFactory::createMinimizer(m_minimizer)); + return result; +} + + +void FitStrategyAdjustMinimizer::execute() +{ + + m_fit_suite->setMinimizer( MinimizerFactory::createMinimizer(m_minimizer) ); + + m_fit_suite->minimize(); + + //m_fit_suite->printResults(); + +} diff --git a/Fit/FitKernel/src/FitSuitePrintObserver.cpp b/Fit/FitKernel/src/FitSuitePrintObserver.cpp index b6c64fc36023d1c96521adb840dbfe3a8e6ac397..4461e5c708d106db565a7f26493e3a38eaa6ea4b 100644 --- a/Fit/FitKernel/src/FitSuitePrintObserver.cpp +++ b/Fit/FitKernel/src/FitSuitePrintObserver.cpp @@ -18,45 +18,84 @@ FitSuitePrintObserver::FitSuitePrintObserver(int print_every_nth) - : m_print_every_nth(print_every_nth) + : m_fitSuite(0) + , m_print_every_nth(print_every_nth) + , m_previous_strategy_index(-1) , m_start_time() , m_last_call_time() + , m_strategy_is_changed(false) { m_last_call_time = boost::posix_time::second_clock::local_time(); } void FitSuitePrintObserver::update(IObservable *subject) { - FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); - if( !fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't access FitSuite"); + m_fitSuite = dynamic_cast<FitSuite *>(subject); + if( !m_fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't access FitSuite"); - if(fitSuite->getNCalls() == 0 ) m_start_time = boost::posix_time::second_clock::local_time(); + if(skipIteration()) return; - if( (fitSuite->getNCalls() % m_print_every_nth != 0) - && fitSuite->getNCalls()!=0 - && !fitSuite->isLastIteration() - ) return; // print first iteration, every n'th and last iteration + if(m_fitSuite->getFitStrategies()->size() && m_strategy_is_changed) { + std::cout << "-------------------------------------------------------------------------------" << std::endl; + std::cout << "CurrentStrategyName: '"<< m_fitSuite->getFitStrategies()->getCurrentStrategyName() << "'" << std::endl; + std::cout << "-------------------------------------------------------------------------------" << std::endl; + } - std::cout << "FitSuitePrintObserver::update() -> Info." - << " NCall:" << fitSuite->getNCalls() - << " NStrategy:" << fitSuite->getNStrategy() - << " Chi2:" << std::scientific << std::setprecision(8) - << fitSuite->getFitObjects()->getChiSquaredValue() << std::endl; + std::cout << "FitSuitePrintObserver::update() -> Info." + << " NCall:" << m_fitSuite->getNCalls() + << " NStrategy:" << m_fitSuite->getNStrategy() + << " Chi2:" << std::scientific << std::setprecision(8) + << m_fitSuite->getFitObjects()->getChiSquaredValue() << std::endl; - boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - m_last_call_time; - std::cout << "Wall time since last call:" - << std::fixed << std::setprecision(2) + boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - m_last_call_time; + std::cout << "Wall time since last call:" + << std::fixed << std::setprecision(2) + << diff.total_milliseconds()/1000. << " sec." <<std::endl; + m_last_call_time = boost::posix_time::microsec_clock::local_time(); + + m_fitSuite->getFitParameters()->printParameters(); + + if(m_fitSuite->isLastIteration()) { + std::cout << "This was the last iteration." << std::endl; + m_fitSuite->printResults(); + diff = boost::posix_time::second_clock::local_time() - m_start_time; + std::cout << "Total time spend: " + << std::fixed << std::setprecision(2) << diff.total_milliseconds()/1000. << " sec." <<std::endl; - m_last_call_time = boost::posix_time::microsec_clock::local_time(); - - fitSuite->getFitParameters()->printParameters(); - - if(fitSuite->isLastIteration()) { - std::cout << "This was the last iteration." << std::endl; - fitSuite->printResults(); - diff = boost::posix_time::second_clock::local_time() - m_start_time; - std::cout << "Total time spend: " - << std::fixed << std::setprecision(2) - << diff.total_milliseconds()/1000. << " sec." <<std::endl; - } + } } + + +// return false if given iteration is +// * the first iteration +// * the last iteration +// * n-th iteration +// * strategy changed +bool FitSuitePrintObserver::skipIteration() +{ + if(m_fitSuite->getNCalls() == 0 ) { + m_start_time = boost::posix_time::second_clock::local_time(); + m_last_call_time = boost::posix_time::second_clock::local_time(); + } + + checkStrategy(); + + if( m_fitSuite->getNCalls() == 0 ) return false; // first iteration + if( m_fitSuite->isLastIteration() ) return false; // last iteration + if( m_fitSuite->getNCalls() % m_print_every_nth == 0 ) return false; // every n'th iteration + if(m_strategy_is_changed) return false; // strategy is changed + + return true; +} + + +void FitSuitePrintObserver::checkStrategy() +{ + m_strategy_is_changed = false; + if(m_previous_strategy_index != (int)m_fitSuite->getNStrategy()) { + m_previous_strategy_index = m_fitSuite->getNStrategy(); + m_strategy_is_changed = true; + } +} + + diff --git a/Fit/FitKernel/src/FitSuiteStrategies.cpp b/Fit/FitKernel/src/FitSuiteStrategies.cpp index 69a39c7de9c7181af84387191c622ec0c240f53a..14d88aad5bf15df455cd2b4e4b45663f236f2e13 100644 --- a/Fit/FitKernel/src/FitSuiteStrategies.cpp +++ b/Fit/FitKernel/src/FitSuiteStrategies.cpp @@ -47,10 +47,12 @@ void FitSuiteStrategies::minimize() m_fit_suite->minimize(); } else { for(strategies_t::iterator it=m_strategies.begin(); it!=m_strategies.end(); ++it) { - msglog(MSG::INFO) << "FitSuiteStrategies::minimize() -> Running strategy #" << m_current_strategy_index << " '" << (*it)->getName() << "'"; + //msglog(MSG::INFO) << "FitSuiteStrategies::minimize() -> Running strategy #" << m_current_strategy_index << " '" << (*it)->getName() << "'"; + m_current_strategy_name = (*it)->getName(); (*it)->execute(); ++m_current_strategy_index; } + --m_current_strategy_index; } } diff --git a/Fit/FitKernel/src/MinimizerFactory.cpp b/Fit/FitKernel/src/MinimizerFactory.cpp index f641af36c96596e9d4831371af2c60af7ddd19ef..576c004b160365c26f333a02dbf4610924ac72fd 100644 --- a/Fit/FitKernel/src/MinimizerFactory.cpp +++ b/Fit/FitKernel/src/MinimizerFactory.cpp @@ -14,11 +14,15 @@ // ************************************************************************** // #include "MinimizerFactory.h" -#include "ROOTGSLNLSMinimizer.h" -#include "ROOTGSLSimAnMinimizer.h" #include "MinimizerTest.h" #include "MinimizerScan.h" -#include "ROOTMinimizer.h" +#include "ROOTMinuit2Minimizer.h" +#include "ROOTMultiMinMinimizer.h" +#include "ROOTSimAnMinimizer.h" +#include "ROOTLMAMinimizer.h" +#ifdef HAS_GENETIC_MINIMIZER +#include "ROOTGeneticMinimizer.h" +#endif #include <boost/assign/list_of.hpp> #include <iomanip> @@ -29,20 +33,18 @@ MinimizerFactory::Catalogue MinimizerFactory::m_catalogue = // for every minimizer MinimizerFactory::Catalogue::Catalogue() { - // TODO FIXME As soon as we got rid from ROOT in our dependencies, we've - // lost Genetic minimizer and it is not easy to get it back - // our minimizers //m_data["Test"] = boost::assign::list_of(""); //m_data["Scan"] = boost::assign::list_of(""); // ROOT minimizers //m_data["Minuit"] = boost::assign::list_of("Migrad")("Simplex")("Combined")("Scan"); m_data["Minuit2"] = boost::assign::list_of("Migrad")("Simplex")("Combined")("Scan")("Fumili"); - //m_data["Fumili"] = boost::assign::list_of(""); m_data["GSLMultiMin"] = boost::assign::list_of("ConjugateFR")("ConjugatePR")("BFGS")("BFGS2")("SteepestDescent"); - m_data["GSLMultiFit"] = boost::assign::list_of(""); + m_data["GSLLMA"] = boost::assign::list_of(""); m_data["GSLSimAn"] = boost::assign::list_of(""); - //m_data["Genetic"] = boost::assign::list_of(""); // available only with ROOT libraries +#ifdef HAS_GENETIC_MINIMIZER + m_data["Genetic"] = boost::assign::list_of(""); // available only with ROOT libraries +#endif } @@ -80,7 +82,8 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons { if( !m_catalogue.isValid(minimizer, algorithm) ) { std::ostringstream ostr; - ostr << "MinimizerFactory::MinimizerFactory() -> Error! Wrong minimizer name. Possible names are:" << std::endl; + ostr << "MinimizerFactory::MinimizerFactory() -> Error! Wrong minimizer name '" << minimizer << "' or algorithm '" << algorithm << "'" << std::endl; + ostr << "Possible names are:" << std::endl; ostr << m_catalogue; throw LogicErrorException(ostr.str()); } @@ -88,14 +91,36 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons IMinimizer *result(0); if( minimizer == "Test" ) { result = new MinimizerTest(); + } else if( minimizer == "Scan" ) { result = new MinimizerScan(); - } else { - result = new ROOTMinimizer(minimizer, algorithm); + + } else if( minimizer == "Minuit2" ) { + result = new ROOTMinuit2Minimizer(minimizer, algorithm); + + } else if( minimizer == "GSLMultiMin" ) { + result = new ROOTMultiMinMinimizer(minimizer, algorithm); + + } else if( minimizer == "GSLLMA" ) { + result = new ROOTLMAMinimizer(minimizer, algorithm); + + } else if( minimizer == "GSLSimAn" ) { + result = new ROOTSimAnMinimizer(minimizer, algorithm); + +#ifdef HAS_GENETIC_MINIMIZER + } else if( minimizer == "Genetic" ) { + result = new ROOTGeneticMinimizer(minimizer, algorithm); +#endif + + } + + if(!result) { + throw LogicErrorException("MinimizerFactory::createMinimizer() -> Error! Wrong minimizer name '"+minimizer+"'"); } + if( !options.empty() ) { try { - result->setOptions(options); + result->setOptionString(options); } catch (NotImplementedException& e) { std::cout << "MinimizerFactory::createMinimizer() -> Warning! Minimizer doesn't have method implemented" << e.what() << std::endl; } @@ -105,3 +130,19 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons } + +//! Create minimizer using existing one. Only minimizer type and minimizer settings are propagated. +//! This method serves as a kind of 'shallow' clone for minimizer. +//! The reason why the minimizer doesn't have own clone method is because of complicate structure of +//! ROOT minimizer internals. +IMinimizer *MinimizerFactory::createMinimizer(const IMinimizer *minimizer) +{ + IMinimizer *result = createMinimizer(minimizer->getMinimizerName(), minimizer->getAlgorithmName()); + result->setOptions(minimizer->getOptions()); + return result; +} + + + + + diff --git a/Fit/FitKernel/src/MinimizerOptions.cpp b/Fit/FitKernel/src/MinimizerOptions.cpp index 4e997525acc545bcf844fe0023a1331be012761f..ffdf32360243984f9e089c7a3d26e0bd35b93628 100644 --- a/Fit/FitKernel/src/MinimizerOptions.cpp +++ b/Fit/FitKernel/src/MinimizerOptions.cpp @@ -14,13 +14,40 @@ // ************************************************************************** // #include "MinimizerOptions.h" - +#include <iomanip> MinimizerOptions::MinimizerOptions() : m_tolerance(0.01) , m_precision(-1) , m_max_iterations(0) , m_max_function_calls(0) + , m_print_level(0) +{ + +} + +//void MinimizerOptions::setRealValue(const std::string &name, double val) +//{ +// m_RealOpts[name] = val; +//} + +//void MinimizerOptions::setIntValue(const std::string &name, int val) +//{ +// m_IntOpts[name] = val; +//} + +//void MinimizerOptions::setNamedValue(const std::string &name, const std::string &val) +//{ +// m_NamOpts[name] = val; +//} + + +void MinimizerOptions::print_common(std::ostream & os) const { + os << std::setw(24) << std::left << "Tolerance " << " : " << std::setw(15) << m_tolerance << std::endl; + os << std::setw(24) << std::left << "Precision " << " : " << std::setw(15) << m_precision << std::endl; + os << std::setw(24) << std::left << "MaxIterations " << " : " << std::setw(15) << m_max_iterations << std::endl; + os << std::setw(24) << std::left << "MaxFunctionCalls " << " : " << std::setw(15) << m_max_function_calls << std::endl; + os << std::setw(24) << std::left << "PrintLevel " << " : " << std::setw(15) << m_print_level << std::endl; } diff --git a/Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp b/Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp similarity index 99% rename from Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp rename to Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp index ac687586322ea4eed3431d9c26fba7a0ad96059b..cb9234ef77f9cf0f2c7e477066edd09f03ed4e84 100644 --- a/Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp +++ b/Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp @@ -7,7 +7,7 @@ //! // ************************************************************************** // -#include "ROOTGSLNLSMinimizer.h" +#include "PatchedGSLNLSMinimizer.h" //#include "Math/GSLNLSMinimizer.h" diff --git a/Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp b/Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp similarity index 99% rename from Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp rename to Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp index d6f092f9c68c634498bce776ae5bc972c129b290..c2acf3092909db866e61e43cea93e10c2ea719f1 100644 --- a/Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp +++ b/Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp @@ -7,7 +7,7 @@ //! // ************************************************************************** // -#include "ROOTGSLSimAnMinimizer.h" +#include "PatchedGSLSimAnMinimizer.h" //#include "Math/GSLSimAnMinimizer.h" diff --git a/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp b/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..261a2adc1fe0658a15152cf96e8fe159c4c121c7 --- /dev/null +++ b/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp @@ -0,0 +1,82 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/src/ROOTGeneticMinimizer.cpp +//! @brief Implements class ROOTGeneticMinimizer. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ROOTGeneticMinimizer.h" +#include "Math/GenAlgoOptions.h" +#include "MessageService.h" + + +ROOTGeneticMinimizer::ROOTGeneticMinimizer(const std::string& minimizer_name, const std::string& algo_type) + : ROOTMinimizer(minimizer_name, algo_type) +{ + m_genetic_minimizer = new ROOT::Math::GeneticMinimizer(); + m_root_minimizer = m_genetic_minimizer; + + m_options.addValue("Cycles",3); + m_options.addValue("PopSize",300); + m_options.addValue("SC_rate",5); + m_options.addValue("SC_steps",10); + m_options.addValue("Steps",40); +// m_options.addValue("ConvCrit",0.1); // It's defined from tolerance inside GeneticMinimizer (ConvCrit=10*Tolerance()) + m_options.addValue("SC_factor",0.95); +} + + +void ROOTGeneticMinimizer::setParameter(size_t index, const FitParameter *par) +{ + if( !par->isFixed() && !par->hasLowerAndUpperLimits()) { + std::ostringstream ostr; + ostr << "ROOTGeneticMinimizer::setParameter() -> Error! "; + ostr << "Genetic minimizer requires either fixed or limited AttLimits::limited(left,right) parameter. "; + ostr << " Parameter name '" << par->getName() << "', isFixed():" << par->isFixed() << " hasLowerandUpperLimits:" << par->hasLowerAndUpperLimits(); + throw LogicErrorException(ostr.str()); + } + ROOTMinimizer::setParameter(index, par); +} + + +// this function serve as a bridge and propagates MinimizerOptions inside GeneticMinimizer +// (which has own messy options) +void ROOTGeneticMinimizer::propagateOptions() +{ + ROOTMinimizer::propagateOptions(); + + if( m_options.getMaxIterations() > 0 && m_options.getMaxIterations() < m_options.getIntValue("Steps")) { + msglog(MSG::WARNING) << "ROOTGeneticMinimizer::propagateOptions() -> Max iterations smaller than Steps. "; + msglog(MSG::WARNING) << "Setting equal to steps " << m_options.getIntValue("Steps") << "."; + m_options.setMaxIterations(m_options.getIntValue("Steps")); + } + + // accessing minimizer + ROOT::Math::MinimizerOptions options = m_genetic_minimizer->Options(); + + options.SetTolerance(m_options.getTolerance()); + options.SetPrecision(m_options.getPrecision()); + options.SetMaxFunctionCalls(m_options.getMaxFunctionCalls()); + options.SetMaxIterations(m_options.getMaxIterations()); + + ROOT::Math::IOptions *geneticOpt = options.ExtraOptions(); + geneticOpt->SetValue("Cycles", m_options.getIntValue("Cycles")); + geneticOpt->SetValue("PopSize", m_options.getIntValue("PopSize")); + geneticOpt->SetValue("SC_rate", m_options.getIntValue("SC_rate")); + geneticOpt->SetValue("SC_steps", m_options.getIntValue("SC_steps")); + geneticOpt->SetValue("Steps", m_options.getIntValue("Steps") ); + geneticOpt->SetValue("ConvCrit", 10.*m_options.getTolerance()); + geneticOpt->SetValue("SC_factor", m_options.getRealValue("SC_factor")); + + m_genetic_minimizer->SetOptions(options); + +} + diff --git a/Fit/FitKernel/src/ROOTLMAMinimizer.cpp b/Fit/FitKernel/src/ROOTLMAMinimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2db92fa1b5134d02644ddf4110a0736a7b531ee2 --- /dev/null +++ b/Fit/FitKernel/src/ROOTLMAMinimizer.cpp @@ -0,0 +1,32 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/src/ROOTMultiFitMinimizer.cpp +//! @brief Implements class ROOTMultiFitMinimizer. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ROOTLMAMinimizer.h" +#include "Math/GenAlgoOptions.h" + + +ROOTLMAMinimizer::ROOTLMAMinimizer(const std::string& minimizer_name, const std::string& algo_type) + : ROOTMinimizer(minimizer_name, algo_type) +{ + m_lma_minimizer = new ROOT::Patch::GSLNLSMinimizer(2); + m_root_minimizer = m_lma_minimizer; +} + +// this function serve as a bridge and propagates MinimizerOptions inside GSLNLSMinimizer +void ROOTLMAMinimizer::propagateOptions() +{ + ROOTMinimizer::propagateOptions(); +} + diff --git a/Fit/FitKernel/src/ROOTMinimizer.cpp b/Fit/FitKernel/src/ROOTMinimizer.cpp index 2fdfd7ae7aed2940e151f9a441063e163a026b25..f92107e0f2311f5888d27670b7fc06040cc0d941 100644 --- a/Fit/FitKernel/src/ROOTMinimizer.cpp +++ b/Fit/FitKernel/src/ROOTMinimizer.cpp @@ -22,12 +22,15 @@ #include <sstream> #include <boost/assign/list_of.hpp> #include <boost/assign/list_of.hpp> -#include "ROOTGSLNLSMinimizer.h" -#include "ROOTGSLSimAnMinimizer.h" #include "ROOTMinimizerHelper.h" #include "MinimizerOptions.h" +#ifdef HAS_GENETIC_MINIMIZER +#include "Math/GeneticMinimizer.h" +#endif + + // ---------------------------------------------------------------------------- // ROOTMinimizer c-tor // @@ -37,23 +40,40 @@ ROOTMinimizer::ROOTMinimizer(const std::string& minimizer_name, const std::string& algo_type) : m_minimizer_name(minimizer_name) , m_algo_type(algo_type) + , m_root_minimizer(0) , m_chi2_func(0) , m_gradient_func(0) { - if( m_minimizer_name == "GSLMultiFit") { - // hacked version of ROOT's GSL Levenberg-Marquardt minimizer - m_root_minimizer = new ROOT::Patch::GSLNLSMinimizer(2); - }else if( m_minimizer_name == "GSLSimAn") { - // hacked version of ROOT's GSL Simulated annealing minimizer - m_root_minimizer = new ROOT::Patch::GSLSimAnMinimizer(); - // changing default options to more appropriate - setOptions("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1"); - } else { - m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type ); - } - if(!m_root_minimizer) { - throw LogicErrorException("Can't create minimizer with name '"+minimizer_name+"', algo '" + algo_type+"'"); - } +// if( m_minimizer_name == "GSLMultiFit") { +// // hacked version of ROOT's GSL Levenberg-Marquardt minimizer +// m_root_minimizer = new ROOT::Patch::GSLNLSMinimizer(2); +// }else if( m_minimizer_name == "GSLSimAn") { +// // hacked version of ROOT's GSL Simulated annealing minimizer +// m_root_minimizer = new ROOT::Patch::GSLSimAnMinimizer(); +// // changing default options to more appropriate +// setOptionString("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1"); + +// }else if( m_minimizer_name == "Minuit2") { +// m_root_minimizer = new ROOT::Minuit2::Minuit2Minimizer(algo_type.c_str()); + +// } else if( m_minimizer_name == "GSLMultiMin") { +// m_root_minimizer = new ROOT::Math::GSLMinimizer(algo_type.c_str()); + +//#ifdef HAS_GENETIC_MINIMIZER +// } else if (m_minimizer_name == "Genetic") { +// m_root_minimizer = new ROOT::Math::GeneticMinimizer(); +//#endif + +//// } else { +//// m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type ); +// } +// if(!m_root_minimizer) { +// throw LogicErrorException("Can't create minimizer with name '"+minimizer_name+"', algo '" + algo_type+"'"); +// } + + + + } @@ -64,17 +84,6 @@ ROOTMinimizer::~ROOTMinimizer() delete m_gradient_func; } - -// check if algorithm needs gradient function (Levenberg-Marquardt, Fumili) -bool ROOTMinimizer::isGradientBasedAgorithm() -{ - if (m_minimizer_name == "Fumili" || - m_minimizer_name == "GSLMultiFit" || - (m_minimizer_name == "Minuit2" && m_algo_type == "Fumili") ) return true; - return false; -} - - void ROOTMinimizer::setParameters(const FitSuiteParameters& parameters) { size_t index(0); @@ -104,22 +113,14 @@ void ROOTMinimizer::setParameter(size_t index, const FitParameter *par) } else if( !par->hasUpperLimit() && !par->hasLowerLimit() && !par->isFixed() ) { success=m_root_minimizer->SetVariable((int)index, par->getName().c_str(), par->getValue(), par->getStep()); } else { - throw LogicErrorException("ROOTMinimizer::setVariable() -> Strange place... I wish I knew how I got here."); - } - - if( m_minimizer_name == "Genetic" && (!par->isFixed() && !par->hasLowerAndUpperLimits()) ) { - std::ostringstream ostr; - ostr << "ROOTMinimizdr::setParameter() -> Error! "; - ostr << "Genetic minimizer requires either fixed or limited AttLimits::limited(left,right) parameter. "; - ostr << " Parameter name '" << par->getName() << "', isFixed():" << par->isFixed() << " hasLowerandUpperLimits:" << par->hasLowerAndUpperLimits(); - throw LogicErrorException(ostr.str()); + throw DomainErrorException("ROOTMinimizer::setVariable() -> Error!"); } if( !success ) { std::ostringstream ostr; ostr << "ROOTMinimizer::setVariable() -> Error! Minimizer returned false while setting the variable." << std::endl; - ostr << " Probably given index has been already used for another variable name." << std::endl; - ostr << " Index:" << index << " name '" << par->getName() << "'" << std::endl; + ostr << "Probably given index has been already used for another variable name." << std::endl; + ostr << "Index:" << index << " name '" << par->getName() << "'" << std::endl; throw LogicErrorException(ostr.str()); } } @@ -127,6 +128,7 @@ void ROOTMinimizer::setParameter(size_t index, const FitParameter *par) void ROOTMinimizer::minimize() { + propagateOptions(); m_root_minimizer->Minimize(); } @@ -138,6 +140,7 @@ void ROOTMinimizer::setChiSquaredFunction(function_chi2_t fun_chi2, size_t npara if( !isGradientBasedAgorithm() ) m_root_minimizer->SetFunction(*m_chi2_func); } + void ROOTMinimizer::setGradientFunction(function_gradient_t fun_gradient, size_t nparameters, size_t ndatasize) { delete m_gradient_func; @@ -168,7 +171,7 @@ std::vector<double > ROOTMinimizer::getErrorOfVariables() const void ROOTMinimizer::printResults() const { - ROOTMinimizerHelper::printResults(m_root_minimizer, m_minimizer_name, m_algo_type); + ROOTMinimizerHelper::printResults(this); } @@ -178,29 +181,21 @@ size_t ROOTMinimizer::getNCalls() const } -MinimizerOptions ROOTMinimizer::getOptions() const -{ - MinimizerOptions options; - options.setTolerance(m_root_minimizer->Tolerance()); - options.setPrecision(m_root_minimizer->Precision()); - options.setMaxFunctionCalls(m_root_minimizer->MaxFunctionCalls()); - options.setMaxIterations(m_root_minimizer->MaxIterations()); - return options; -} - void ROOTMinimizer::setOptions(const MinimizerOptions &options) { - m_root_minimizer->SetTolerance(options.getTolerance()); - m_root_minimizer->SetPrecision(options.getPrecision()); - m_root_minimizer->SetMaxFunctionCalls(options.getMaxFunctionCalls()); - m_root_minimizer->SetMaxIterations(options.getMaxIterations()); + m_options = options; + propagateOptions(); } -void ROOTMinimizer::setOptions(const std::string& options) + +void ROOTMinimizer::propagateOptions() { - ROOTMinimizerHelper::setOptions(m_root_minimizer, options); + m_root_minimizer->SetTolerance(m_options.getTolerance()); + m_root_minimizer->SetPrecision(m_options.getPrecision()); + m_root_minimizer->SetMaxFunctionCalls(m_options.getMaxFunctionCalls()); + m_root_minimizer->SetMaxIterations(m_options.getMaxIterations()); + m_root_minimizer->SetPrintLevel(m_options.getPrintLevel()); } - diff --git a/Fit/FitKernel/src/ROOTMinimizerHelper.cpp b/Fit/FitKernel/src/ROOTMinimizerHelper.cpp index 6e1f7dbb1610971f6fd4fbffa16167d5592778af..35006c2be91cfcfea233267b43baab9e0cb1c7a4 100644 --- a/Fit/FitKernel/src/ROOTMinimizerHelper.cpp +++ b/Fit/FitKernel/src/ROOTMinimizerHelper.cpp @@ -14,9 +14,10 @@ // ************************************************************************** // #include "ROOTMinimizerHelper.h" -#include "ROOTGSLSimAnMinimizer.h" +#include "PatchedGSLSimAnMinimizer.h" #include "Utils.h" #include <boost/lexical_cast.hpp> +#include "Math/GenAlgoOptions.h" // ---------------------------------------------------------------------------- // translate text with options into appropriate calls of minimizer's set method @@ -125,23 +126,24 @@ bool ROOTMinimizerHelper::processCommandGSLSimAn(ROOT::Patch::GSLSimAnMinimizer return success; } - // Printing minimizer results on the screen -void ROOTMinimizerHelper::printResults(ROOT::Math::Minimizer *minimizer, const std::string& minimizer_name, const std::string& algo_type) +void ROOTMinimizerHelper::printResults(const ROOTMinimizer *minimizer) { std::cout << "--------------------------------------------------------------------------------" << std::endl; - std::cout << std::setw(25) << std::left << " MinimizerType" << ": " << minimizer_name << std::endl; - std::cout << std::setw(25) << std::left << " MinimizerAlgorithm" << ": " << algo_type << std::endl; - printOptions(minimizer); - printStatus(minimizer); - printVariables(minimizer); + std::cout << std::setw(25) << std::left << " MinimizerType" << ": " << minimizer->getMinimizerName() << std::endl; + std::cout << std::setw(25) << std::left << " MinimizerAlgorithm" << ": " << minimizer->getAlgorithmName() << std::endl; + //printOptions(minimizer->getROOTMinimizer()); + std::cout << "--- Options --------------------------------------------------------------------" << std::endl; + minimizer->getOptions().print(); + printStatus(minimizer->getROOTMinimizer()); + printVariables(minimizer->getROOTMinimizer()); // own print method of the minimizer //m_root_minimizer->PrintResults(); } // print minimizer description -void ROOTMinimizerHelper::printOptions(ROOT::Math::Minimizer *minimizer) +void ROOTMinimizerHelper::printOptions(const ROOT::Math::Minimizer *minimizer) { std::cout << "--- Options --------------------------------------------------------------------" << std::endl; ROOT::Math::MinimizerOptions opt = minimizer->Options(); @@ -151,11 +153,16 @@ void ROOTMinimizerHelper::printOptions(ROOT::Math::Minimizer *minimizer) std::cout << std::setw(25) << std::left << " MaxIterations" << ": " << minimizer->MaxIterations() << std::endl; std::cout << std::setw(25) << std::left << " Precision" << ": " << minimizer->Precision() << std::endl; std::cout << std::setw(25) << std::left << " ErrorDefinition" << ": " << minimizer->ErrorDef() << " (1-chi2, 0.5 likelihood)" << std::endl; - std::cout << std::setw(25) << std::left << " ExtraOptions" << ": " << opt.ExtraOptions() << std::endl; + //std::cout << std::setw(25) << std::left << " ExtraOptions" << ": " << opt.ExtraOptions() << std::endl; + if(opt.ExtraOptions()) { + std::cout << "--- Extra Options --------------------------------------------------------------" << std::endl; + opt.ExtraOptions()->Print(); + } + } -void ROOTMinimizerHelper::printStatus(ROOT::Math::Minimizer *minimizer) +void ROOTMinimizerHelper::printStatus(const ROOT::Math::Minimizer *minimizer) { std::cout << "--- Status --------------------------------------------------------------------- " << std::endl; std::map<int, std::string> minimizerStatus; @@ -194,7 +201,7 @@ void ROOTMinimizerHelper::printStatus(ROOT::Math::Minimizer *minimizer) } -void ROOTMinimizerHelper::printVariables(ROOT::Math::Minimizer *minimizer) +void ROOTMinimizerHelper::printVariables(const ROOT::Math::Minimizer *minimizer) { std::cout << "--- Variables ------------------------------------------------------------------" << std::endl; std::cout << std::setw(25) << std::left << " NumberOfVariables" << ": " diff --git a/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp b/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d3771c75a47386e0db0f4ea5c234221dd57f150 --- /dev/null +++ b/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp @@ -0,0 +1,46 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/src/ROOTMinuit2Minimizer.cpp +//! @brief Implements class ROOTMinuit2Minimizer. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ROOTMinuit2Minimizer.h" + + +ROOTMinuit2Minimizer::ROOTMinuit2Minimizer(const std::string& minimizer_name, const std::string& algo_type) + : ROOTMinimizer(minimizer_name, algo_type) +{ + m_minuit2_minimizer = new ROOT::Minuit2::Minuit2Minimizer(algo_type.c_str()); + m_root_minimizer = m_minuit2_minimizer; + + m_options.addValue("Strategy", 1); + m_options.addValue("ErrorDef", 1); + +} + + +bool ROOTMinuit2Minimizer::isGradientBasedAgorithm() +{ + if(m_algo_type == "Fumili") return true; + return false; +} + + +// this function serve as a bridge and propagates MinimizerOptions inside Minuit2Minimizer +void ROOTMinuit2Minimizer::propagateOptions() +{ + ROOTMinimizer::propagateOptions(); + m_minuit2_minimizer->SetStrategy(m_options.getIntValue("Strategy")); + m_minuit2_minimizer->SetErrorDef(m_options.getIntValue("ErrorDef")); +} + + diff --git a/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp b/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5be846056daad0d865cb7f859692d6871d12451f --- /dev/null +++ b/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp @@ -0,0 +1,33 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/src/ROOTMultiMinMinimizer.cpp +//! @brief Implements class ROOTMultiMinMinimizer. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ROOTMultiMinMinimizer.h" + + +ROOTMultiMinMinimizer::ROOTMultiMinMinimizer(const std::string& minimizer_name, const std::string& algo_type) + : ROOTMinimizer(minimizer_name, algo_type) +{ + m_gsl_minimizer = new ROOT::Math::GSLMinimizer(algo_type.c_str()); + m_root_minimizer = m_gsl_minimizer; +} + + +// this function serve as a bridge and propagates MinimizerOptions inside Minuit2Minimizer +void ROOTMultiMinMinimizer::propagateOptions() +{ + ROOTMinimizer::propagateOptions(); +} + + diff --git a/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp b/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3215d3602f3c24b0196f0549213314374bdbe7e --- /dev/null +++ b/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp @@ -0,0 +1,48 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file FitKernel/src/ROOTSimAnMinimizer.cpp +//! @brief Implements class ROOTSimAnMinimizer. +// +//! Homepage: apps.jcns.fz-juelich.de/BornAgain +//! License: GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "ROOTSimAnMinimizer.h" + +ROOTSimAnMinimizer::ROOTSimAnMinimizer(const std::string& minimizer_name, const std::string& algo_type) + : ROOTMinimizer(minimizer_name, algo_type) +{ + m_siman_minimizer = new ROOT::Patch::GSLSimAnMinimizer(); + m_root_minimizer = m_siman_minimizer; + + m_options.addValue("ntries", 100); + m_options.addValue("niters_fixed_t", 10); + m_options.addValue("step_size", 1.0); + m_options.addValue("k", 1.0); + m_options.addValue("t_initial", 50.0); + m_options.addValue("mu", 1.05); + m_options.addValue("t_min", 0.1); + m_options.setMaxIterations(100); +} + + +// this function serve as a bridge and propagates MinimizerOptions inside GSLSimAnMinimizer +void ROOTSimAnMinimizer::propagateOptions() +{ + ROOTMinimizer::propagateOptions(); + + ROOT::Math::GSLSimAnParams& pars = m_siman_minimizer->getSolver().Params(); + m_options.getValue("ntries", pars.n_tries); + m_options.getValue("niters_fixed_t", pars.iters_fixed_T); + m_options.getValue("step_size", pars.step_size); + m_options.getValue("k", pars.k); + m_options.getValue("t_initial", pars.t_initial); + m_options.getValue("mu", pars.mu); + m_options.getValue("t_min", pars.t_min); +} diff --git a/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h b/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h new file mode 100644 index 0000000000000000000000000000000000000000..2de9ca4390b569e9a8aa32a352e08c6623c5cc9d --- /dev/null +++ b/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h @@ -0,0 +1,11 @@ +// This file has been generated by Py++. + +// BornAgain: simulate and fit scattering at grazing incidence +//! @brief automatically generated boost::python code for PythonCoreAPI + +#ifndef SquaredFunctionSimError_hpp__pyplusplus_wrapper +#define SquaredFunctionSimError_hpp__pyplusplus_wrapper + +void register_SquaredFunctionSimError_class(); + +#endif//SquaredFunctionSimError_hpp__pyplusplus_wrapper diff --git a/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp b/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp index 484e94f4552f4ca187f73d9840d6bb0d1363ff00..510f4de2dcc605751b4a40d05879260082197d29 100644 --- a/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp +++ b/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp @@ -16,21 +16,42 @@ namespace bp = boost::python; struct FitStrategyAdjustMinimizer_wrapper : FitStrategyAdjustMinimizer, bp::wrapper< FitStrategyAdjustMinimizer > { - FitStrategyAdjustMinimizer_wrapper() - : FitStrategyAdjustMinimizer() + FitStrategyAdjustMinimizer_wrapper(FitStrategyAdjustMinimizer const & arg ) + : FitStrategyAdjustMinimizer( arg ) , bp::wrapper< FitStrategyAdjustMinimizer >(){ - // null constructor + // copy constructor } - virtual ::IFitStrategy * clone( ) const { - bp::override func_clone = this->get_override( "clone" ); - return func_clone( ); + FitStrategyAdjustMinimizer_wrapper( ) + : FitStrategyAdjustMinimizer( ) + , bp::wrapper< FitStrategyAdjustMinimizer >(){ + // null constructor + } - virtual void execute( ){ - bp::override func_execute = this->get_override( "execute" ); - func_execute( ); + virtual ::FitStrategyAdjustMinimizer * clone( ) const { + if( bp::override func_clone = this->get_override( "clone" ) ) + return func_clone( ); + else + return this->FitStrategyAdjustMinimizer::clone( ); + } + + + ::FitStrategyAdjustMinimizer * default_clone( ) const { + return FitStrategyAdjustMinimizer::clone( ); + } + + virtual void execute( ) { + if( bp::override func_execute = this->get_override( "execute" ) ) + func_execute( ); + else + this->FitStrategyAdjustMinimizer::execute( ); + } + + + void default_execute( ) { + FitStrategyAdjustMinimizer::execute( ); } }; @@ -38,26 +59,50 @@ struct FitStrategyAdjustMinimizer_wrapper : FitStrategyAdjustMinimizer, bp::wrap void register_FitStrategyAdjustMinimizer_class(){ { //::FitStrategyAdjustMinimizer - typedef bp::class_< FitStrategyAdjustMinimizer_wrapper, bp::bases< IFitStrategy >, boost::noncopyable > FitStrategyAdjustMinimizer_exposer_t; - FitStrategyAdjustMinimizer_exposer_t FitStrategyAdjustMinimizer_exposer = FitStrategyAdjustMinimizer_exposer_t( "FitStrategyAdjustMinimizer" ); + typedef bp::class_< FitStrategyAdjustMinimizer_wrapper, bp::bases< IFitStrategy > > FitStrategyAdjustMinimizer_exposer_t; + FitStrategyAdjustMinimizer_exposer_t FitStrategyAdjustMinimizer_exposer = FitStrategyAdjustMinimizer_exposer_t( "FitStrategyAdjustMinimizer", bp::init< >() ); bp::scope FitStrategyAdjustMinimizer_scope( FitStrategyAdjustMinimizer_exposer ); - { //::IFitStrategy::clone + { //::FitStrategyAdjustMinimizer::clone - typedef ::IFitStrategy * ( ::IFitStrategy::*clone_function_type )( ) const; + typedef ::FitStrategyAdjustMinimizer * ( ::FitStrategyAdjustMinimizer::*clone_function_type )( ) const; + typedef ::FitStrategyAdjustMinimizer * ( FitStrategyAdjustMinimizer_wrapper::*default_clone_function_type )( ) const; FitStrategyAdjustMinimizer_exposer.def( "clone" - , bp::pure_virtual( clone_function_type(&::IFitStrategy::clone) ) + , clone_function_type(&::FitStrategyAdjustMinimizer::clone) + , default_clone_function_type(&FitStrategyAdjustMinimizer_wrapper::default_clone) , bp::return_value_policy< bp::manage_new_object >() ); } - { //::IFitStrategy::execute + { //::FitStrategyAdjustMinimizer::execute - typedef void ( ::IFitStrategy::*execute_function_type )( ) ; + typedef void ( ::FitStrategyAdjustMinimizer::*execute_function_type )( ) ; + typedef void ( FitStrategyAdjustMinimizer_wrapper::*default_execute_function_type )( ) ; FitStrategyAdjustMinimizer_exposer.def( "execute" - , bp::pure_virtual( execute_function_type(&::IFitStrategy::execute) ) ); + , execute_function_type(&::FitStrategyAdjustMinimizer::execute) + , default_execute_function_type(&FitStrategyAdjustMinimizer_wrapper::default_execute) ); + + } + { //::FitStrategyAdjustMinimizer::getMinimizer + + typedef ::IMinimizer * ( ::FitStrategyAdjustMinimizer::*getMinimizer_function_type )( ) ; + + FitStrategyAdjustMinimizer_exposer.def( + "getMinimizer" + , getMinimizer_function_type( &::FitStrategyAdjustMinimizer::getMinimizer ) + , bp::return_value_policy< bp::reference_existing_object >() ); + + } + { //::FitStrategyAdjustMinimizer::setMinimizer + + typedef void ( ::FitStrategyAdjustMinimizer::*setMinimizer_function_type )( ::IMinimizer * ) ; + + FitStrategyAdjustMinimizer_exposer.def( + "setMinimizer" + , setMinimizer_function_type( &::FitStrategyAdjustMinimizer::setMinimizer ) + , ( bp::arg("minimizer") ) ); } } diff --git a/Fit/PythonAPI/src/IMinimizer.pypp.cpp b/Fit/PythonAPI/src/IMinimizer.pypp.cpp index 692986d6c7952638bb5402f67f4ec14b20eae6da..2ca3a9995dccae2cfbe454093505fb843cb4be06 100644 --- a/Fit/PythonAPI/src/IMinimizer.pypp.cpp +++ b/Fit/PythonAPI/src/IMinimizer.pypp.cpp @@ -35,6 +35,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > { IMinimizer::clear( ); } + virtual ::std::string getAlgorithmName( ) const { + if( bp::override func_getAlgorithmName = this->get_override( "getAlgorithmName" ) ) + return func_getAlgorithmName( ); + else + return this->IMinimizer::getAlgorithmName( ); + } + + + ::std::string default_getAlgorithmName( ) const { + return IMinimizer::getAlgorithmName( ); + } + virtual double getErrorOfVariable( ::std::size_t arg0 ) const { if( bp::override func_getErrorOfVariable = this->get_override( "getErrorOfVariable" ) ) return func_getErrorOfVariable( arg0 ); @@ -71,6 +83,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > { return IMinimizer::getMinValue( ); } + virtual ::std::string getMinimizerName( ) const { + if( bp::override func_getMinimizerName = this->get_override( "getMinimizerName" ) ) + return func_getMinimizerName( ); + else + return this->IMinimizer::getMinimizerName( ); + } + + + ::std::string default_getMinimizerName( ) const { + return IMinimizer::getMinimizerName( ); + } + virtual ::std::size_t getNCalls( ) const { if( bp::override func_getNCalls = this->get_override( "getNCalls" ) ) return func_getNCalls( ); @@ -95,18 +119,6 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > { return IMinimizer::getNumberOfVariables( ); } - virtual ::MinimizerOptions getOptions( ) const { - if( bp::override func_getOptions = this->get_override( "getOptions" ) ) - return func_getOptions( ); - else - return this->IMinimizer::getOptions( ); - } - - - ::MinimizerOptions default_getOptions( ) const { - return IMinimizer::getOptions( ); - } - virtual double getValueOfVariableAtMinimum( ::std::size_t arg0 ) const { if( bp::override func_getValueOfVariableAtMinimum = this->get_override( "getValueOfVariableAtMinimum" ) ) return func_getValueOfVariableAtMinimum( arg0 ); @@ -131,6 +143,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > { return IMinimizer::getValueOfVariablesAtMinimum( ); } + virtual bool isGradientBasedAgorithm( ) { + if( bp::override func_isGradientBasedAgorithm = this->get_override( "isGradientBasedAgorithm" ) ) + return func_isGradientBasedAgorithm( ); + else + return this->IMinimizer::isGradientBasedAgorithm( ); + } + + + bool default_isGradientBasedAgorithm( ) { + return IMinimizer::isGradientBasedAgorithm( ); + } + virtual void minimize( ){ bp::override func_minimize = this->get_override( "minimize" ); func_minimize( ); @@ -148,28 +172,28 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > { IMinimizer::printResults( ); } - virtual void setOptions( ::MinimizerOptions const & arg0 ) { - if( bp::override func_setOptions = this->get_override( "setOptions" ) ) - func_setOptions( boost::ref(arg0) ); + virtual void setOptionString( ::std::string const & arg0 ) { + if( bp::override func_setOptionString = this->get_override( "setOptionString" ) ) + func_setOptionString( arg0 ); else - this->IMinimizer::setOptions( boost::ref(arg0) ); + this->IMinimizer::setOptionString( arg0 ); } - void default_setOptions( ::MinimizerOptions const & arg0 ) { - IMinimizer::setOptions( boost::ref(arg0) ); + void default_setOptionString( ::std::string const & arg0 ) { + IMinimizer::setOptionString( arg0 ); } - virtual void setOptions( ::std::string const & arg0 ) { + virtual void setOptions( ::MinimizerOptions const & arg0 ) { if( bp::override func_setOptions = this->get_override( "setOptions" ) ) - func_setOptions( arg0 ); + func_setOptions( boost::ref(arg0) ); else - this->IMinimizer::setOptions( arg0 ); + this->IMinimizer::setOptions( boost::ref(arg0) ); } - void default_setOptions( ::std::string const & arg0 ) { - IMinimizer::setOptions( arg0 ); + void default_setOptions( ::MinimizerOptions const & arg0 ) { + IMinimizer::setOptions( boost::ref(arg0) ); } virtual void setParameters( ::FitSuiteParameters const & arg0 ) { @@ -202,6 +226,17 @@ void register_IMinimizer_class(){ , clear_function_type(&::IMinimizer::clear) , default_clear_function_type(&IMinimizer_wrapper::default_clear) ); + } + { //::IMinimizer::getAlgorithmName + + typedef ::std::string ( ::IMinimizer::*getAlgorithmName_function_type )( ) const; + typedef ::std::string ( IMinimizer_wrapper::*default_getAlgorithmName_function_type )( ) const; + + IMinimizer_exposer.def( + "getAlgorithmName" + , getAlgorithmName_function_type(&::IMinimizer::getAlgorithmName) + , default_getAlgorithmName_function_type(&IMinimizer_wrapper::default_getAlgorithmName) ); + } { //::IMinimizer::getErrorOfVariable @@ -236,6 +271,17 @@ void register_IMinimizer_class(){ , getMinValue_function_type(&::IMinimizer::getMinValue) , default_getMinValue_function_type(&IMinimizer_wrapper::default_getMinValue) ); + } + { //::IMinimizer::getMinimizerName + + typedef ::std::string ( ::IMinimizer::*getMinimizerName_function_type )( ) const; + typedef ::std::string ( IMinimizer_wrapper::*default_getMinimizerName_function_type )( ) const; + + IMinimizer_exposer.def( + "getMinimizerName" + , getMinimizerName_function_type(&::IMinimizer::getMinimizerName) + , default_getMinimizerName_function_type(&IMinimizer_wrapper::default_getMinimizerName) ); + } { //::IMinimizer::getNCalls @@ -261,13 +307,12 @@ void register_IMinimizer_class(){ } { //::IMinimizer::getOptions - typedef ::MinimizerOptions ( ::IMinimizer::*getOptions_function_type )( ) const; - typedef ::MinimizerOptions ( IMinimizer_wrapper::*default_getOptions_function_type )( ) const; + typedef ::MinimizerOptions & ( ::IMinimizer::*getOptions_function_type )( ) ; IMinimizer_exposer.def( "getOptions" , getOptions_function_type(&::IMinimizer::getOptions) - , default_getOptions_function_type(&IMinimizer_wrapper::default_getOptions) ); + , bp::return_internal_reference< >() ); } { //::IMinimizer::getValueOfVariableAtMinimum @@ -292,6 +337,17 @@ void register_IMinimizer_class(){ , getValueOfVariablesAtMinimum_function_type(&::IMinimizer::getValueOfVariablesAtMinimum) , default_getValueOfVariablesAtMinimum_function_type(&IMinimizer_wrapper::default_getValueOfVariablesAtMinimum) ); + } + { //::IMinimizer::isGradientBasedAgorithm + + typedef bool ( ::IMinimizer::*isGradientBasedAgorithm_function_type )( ) ; + typedef bool ( IMinimizer_wrapper::*default_isGradientBasedAgorithm_function_type )( ) ; + + IMinimizer_exposer.def( + "isGradientBasedAgorithm" + , isGradientBasedAgorithm_function_type(&::IMinimizer::isGradientBasedAgorithm) + , default_isGradientBasedAgorithm_function_type(&IMinimizer_wrapper::default_isGradientBasedAgorithm) ); + } { //::IMinimizer::minimize @@ -313,22 +369,22 @@ void register_IMinimizer_class(){ , default_printResults_function_type(&IMinimizer_wrapper::default_printResults) ); } - { //::IMinimizer::setOptions + { //::IMinimizer::setOptionString - typedef void ( ::IMinimizer::*setOptions_function_type )( ::MinimizerOptions const & ) ; - typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::MinimizerOptions const & ) ; + typedef void ( ::IMinimizer::*setOptionString_function_type )( ::std::string const & ) ; + typedef void ( IMinimizer_wrapper::*default_setOptionString_function_type )( ::std::string const & ) ; IMinimizer_exposer.def( - "setOptions" - , setOptions_function_type(&::IMinimizer::setOptions) - , default_setOptions_function_type(&IMinimizer_wrapper::default_setOptions) + "setOptionString" + , setOptionString_function_type(&::IMinimizer::setOptionString) + , default_setOptionString_function_type(&IMinimizer_wrapper::default_setOptionString) , ( bp::arg("arg0") ) ); } { //::IMinimizer::setOptions - typedef void ( ::IMinimizer::*setOptions_function_type )( ::std::string const & ) ; - typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::std::string const & ) ; + typedef void ( ::IMinimizer::*setOptions_function_type )( ::MinimizerOptions const & ) ; + typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::MinimizerOptions const & ) ; IMinimizer_exposer.def( "setOptions" diff --git a/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp b/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp index 40c2e5b47b3311c315ac6dbc8982a44ccd783302..f5102837bca21a738f397d30cd9752699c273ab9 100644 --- a/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp +++ b/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp @@ -20,6 +20,46 @@ void register_MinimizerOptions_class(){ typedef bp::class_< MinimizerOptions > MinimizerOptions_exposer_t; MinimizerOptions_exposer_t MinimizerOptions_exposer = MinimizerOptions_exposer_t( "MinimizerOptions", bp::init< >() ); bp::scope MinimizerOptions_scope( MinimizerOptions_exposer ); + { //::MinimizerOptions::addValue + + typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,double ) ; + + MinimizerOptions_exposer.def( + "addValue" + , addValue_function_type( &::MinimizerOptions::addValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::addValue + + typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,int ) ; + + MinimizerOptions_exposer.def( + "addValue" + , addValue_function_type( &::MinimizerOptions::addValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::addValue + + typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,::std::string const & ) ; + + MinimizerOptions_exposer.def( + "addValue" + , addValue_function_type( &::MinimizerOptions::addValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::getIntValue + + typedef int ( ::MinimizerOptions::*getIntValue_function_type )( ::std::string const & ) ; + + MinimizerOptions_exposer.def( + "getIntValue" + , getIntValue_function_type( &::MinimizerOptions::getIntValue ) + , ( bp::arg("name") ) ); + + } { //::MinimizerOptions::getMaxFunctionCalls typedef int ( ::MinimizerOptions::*getMaxFunctionCalls_function_type )( ) const; @@ -37,6 +77,16 @@ void register_MinimizerOptions_class(){ "getMaxIterations" , getMaxIterations_function_type( &::MinimizerOptions::getMaxIterations ) ); + } + { //::MinimizerOptions::getNamedValue + + typedef ::std::string ( ::MinimizerOptions::*getNamedValue_function_type )( ::std::string const & ) ; + + MinimizerOptions_exposer.def( + "getNamedValue" + , getNamedValue_function_type( &::MinimizerOptions::getNamedValue ) + , ( bp::arg("name") ) ); + } { //::MinimizerOptions::getPrecision @@ -46,6 +96,25 @@ void register_MinimizerOptions_class(){ "getPrecision" , getPrecision_function_type( &::MinimizerOptions::getPrecision ) ); + } + { //::MinimizerOptions::getPrintLevel + + typedef int ( ::MinimizerOptions::*getPrintLevel_function_type )( ) const; + + MinimizerOptions_exposer.def( + "getPrintLevel" + , getPrintLevel_function_type( &::MinimizerOptions::getPrintLevel ) ); + + } + { //::MinimizerOptions::getRealValue + + typedef double ( ::MinimizerOptions::*getRealValue_function_type )( ::std::string const & ) ; + + MinimizerOptions_exposer.def( + "getRealValue" + , getRealValue_function_type( &::MinimizerOptions::getRealValue ) + , ( bp::arg("name") ) ); + } { //::MinimizerOptions::getTolerance @@ -55,6 +124,45 @@ void register_MinimizerOptions_class(){ "getTolerance" , getTolerance_function_type( &::MinimizerOptions::getTolerance ) ); + } + { //::MinimizerOptions::getValue + + typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,int & ) ; + + MinimizerOptions_exposer.def( + "getValue" + , getValue_function_type( &::MinimizerOptions::getValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::getValue + + typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,double & ) ; + + MinimizerOptions_exposer.def( + "getValue" + , getValue_function_type( &::MinimizerOptions::getValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::getValue + + typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,::std::string & ) ; + + MinimizerOptions_exposer.def( + "getValue" + , getValue_function_type( &::MinimizerOptions::getValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::print + + typedef void ( ::MinimizerOptions::*print_function_type )( ) const; + + MinimizerOptions_exposer.def( + "print" + , print_function_type( &::MinimizerOptions::print ) ); + } { //::MinimizerOptions::setMaxFunctionCalls @@ -85,6 +193,16 @@ void register_MinimizerOptions_class(){ , setPrecision_function_type( &::MinimizerOptions::setPrecision ) , ( bp::arg("precision") ) ); + } + { //::MinimizerOptions::setPrintLevel + + typedef void ( ::MinimizerOptions::*setPrintLevel_function_type )( int ) ; + + MinimizerOptions_exposer.def( + "setPrintLevel" + , setPrintLevel_function_type( &::MinimizerOptions::setPrintLevel ) + , ( bp::arg("print_level") ) ); + } { //::MinimizerOptions::setTolerance @@ -96,6 +214,36 @@ void register_MinimizerOptions_class(){ , ( bp::arg("tolerance") ) ); } + { //::MinimizerOptions::setValue + + typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,double ) ; + + MinimizerOptions_exposer.def( + "setValue" + , setValue_function_type( &::MinimizerOptions::setValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::setValue + + typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,int ) ; + + MinimizerOptions_exposer.def( + "setValue" + , setValue_function_type( &::MinimizerOptions::setValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } + { //::MinimizerOptions::setValue + + typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,::std::string const & ) ; + + MinimizerOptions_exposer.def( + "setValue" + , setValue_function_type( &::MinimizerOptions::setValue ) + , ( bp::arg("name"), bp::arg("val") ) ); + + } } } diff --git a/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp b/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..484555f829fd5ee07ebe7f61700186dac8790370 --- /dev/null +++ b/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp @@ -0,0 +1,108 @@ +// This file has been generated by Py++. + +// BornAgain: simulate and fit scattering at grazing incidence +//! @brief automatically generated boost::python code for PythonCoreAPI + +#include "Macros.h" +GCC_DIAG_OFF(unused-parameter); +GCC_DIAG_OFF(missing-field-initializers); +#include "boost/python.hpp" +GCC_DIAG_ON(unused-parameter); +GCC_DIAG_ON(missing-field-initializers); +#include "PythonFitList.h" +#include "SquaredFunctionSimError.pypp.h" + +namespace bp = boost::python; + +struct SquaredFunctionSimError_wrapper : SquaredFunctionSimError, bp::wrapper< SquaredFunctionSimError > { + + SquaredFunctionSimError_wrapper( ) + : SquaredFunctionSimError( ) + , bp::wrapper< SquaredFunctionSimError >(){ + // null constructor + + } + + virtual double calculateSquaredDifference( double real_value, double simulated_value ) const { + if( bp::override func_calculateSquaredDifference = this->get_override( "calculateSquaredDifference" ) ) + return func_calculateSquaredDifference( real_value, simulated_value ); + else + return this->SquaredFunctionSimError::calculateSquaredDifference( real_value, simulated_value ); + } + + + double default_calculateSquaredDifference( double real_value, double simulated_value ) const { + return SquaredFunctionSimError::calculateSquaredDifference( real_value, simulated_value ); + } + + virtual double calculateSquaredError( double real_value, double simulated_value ) const { + if( bp::override func_calculateSquaredError = this->get_override( "calculateSquaredError" ) ) + return func_calculateSquaredError( real_value, simulated_value ); + else + return this->SquaredFunctionSimError::calculateSquaredError( real_value, simulated_value ); + } + + + double default_calculateSquaredError( double real_value, double simulated_value ) const { + return SquaredFunctionSimError::calculateSquaredError( real_value, simulated_value ); + } + + virtual ::SquaredFunctionSimError * clone( ) const { + if( bp::override func_clone = this->get_override( "clone" ) ) + return func_clone( ); + else + return this->SquaredFunctionSimError::clone( ); + } + + + ::SquaredFunctionSimError * default_clone( ) const { + return SquaredFunctionSimError::clone( ); + } + +}; + +void register_SquaredFunctionSimError_class(){ + + { //::SquaredFunctionSimError + typedef bp::class_< SquaredFunctionSimError_wrapper, bp::bases< ISquaredFunction >, boost::noncopyable > SquaredFunctionSimError_exposer_t; + SquaredFunctionSimError_exposer_t SquaredFunctionSimError_exposer = SquaredFunctionSimError_exposer_t( "SquaredFunctionSimError", bp::init< >() ); + bp::scope SquaredFunctionSimError_scope( SquaredFunctionSimError_exposer ); + { //::SquaredFunctionSimError::calculateSquaredDifference + + typedef double ( ::SquaredFunctionSimError::*calculateSquaredDifference_function_type )( double,double ) const; + typedef double ( SquaredFunctionSimError_wrapper::*default_calculateSquaredDifference_function_type )( double,double ) const; + + SquaredFunctionSimError_exposer.def( + "calculateSquaredDifference" + , calculateSquaredDifference_function_type(&::SquaredFunctionSimError::calculateSquaredDifference) + , default_calculateSquaredDifference_function_type(&SquaredFunctionSimError_wrapper::default_calculateSquaredDifference) + , ( bp::arg("real_value"), bp::arg("simulated_value") ) ); + + } + { //::SquaredFunctionSimError::calculateSquaredError + + typedef double ( ::SquaredFunctionSimError::*calculateSquaredError_function_type )( double,double ) const; + typedef double ( SquaredFunctionSimError_wrapper::*default_calculateSquaredError_function_type )( double,double ) const; + + SquaredFunctionSimError_exposer.def( + "calculateSquaredError" + , calculateSquaredError_function_type(&::SquaredFunctionSimError::calculateSquaredError) + , default_calculateSquaredError_function_type(&SquaredFunctionSimError_wrapper::default_calculateSquaredError) + , ( bp::arg("real_value"), bp::arg("simulated_value") ) ); + + } + { //::SquaredFunctionSimError::clone + + typedef ::SquaredFunctionSimError * ( ::SquaredFunctionSimError::*clone_function_type )( ) const; + typedef ::SquaredFunctionSimError * ( SquaredFunctionSimError_wrapper::*default_clone_function_type )( ) const; + + SquaredFunctionSimError_exposer.def( + "clone" + , clone_function_type(&::SquaredFunctionSimError::clone) + , default_clone_function_type(&SquaredFunctionSimError_wrapper::default_clone) + , bp::return_value_policy< bp::manage_new_object >() ); + + } + } + +} diff --git a/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp b/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp index 1fbdb98bee2a160680b829116aac05d49b94ea33..65d1e93013e0b550c5684f88831f9d4d02efcb03 100644 --- a/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp +++ b/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp @@ -28,7 +28,7 @@ TestFit01::TestFit01() m_minimizers.push_back( Minimizer("Minuit2","Fumili") ); m_minimizers.push_back( Minimizer("GSLMultiMin","BFGS") ); m_minimizers.push_back( Minimizer("GSLMultiMin","SteepestDescent") ); - m_minimizers.push_back( Minimizer("GSLMultiFit","") ); // this is Levenberg-Marquard + m_minimizers.push_back( Minimizer("GSLLMA","") ); // this is Levenberg-Marquard // m_minimizers.push_back( Minimizer("GSLSimAn","") ); // m_minimizers.push_back( Minimizer("Genetic","") ); } diff --git a/Tests/FunctionalTests/TestPyFit/testfit01.py b/Tests/FunctionalTests/TestPyFit/testfit01.py index 284c9eeb14a6951e7bea322a9022f40f11ddd28a..0d4bfda215cc44d0a6fb1750107b4613337fa91b 100644 --- a/Tests/FunctionalTests/TestPyFit/testfit01.py +++ b/Tests/FunctionalTests/TestPyFit/testfit01.py @@ -26,11 +26,11 @@ cylinder_radius = 5*nanometer # minimizer name and type of minimization algorithm Minimizers = [ - ("Minuit2","Migrad"), - ("Minuit2","Fumili"), - ("GSLMultiMin","BFGS"), - ("GSLMultiMin","SteepestDescent"), - ("GSLMultiFit",""), + ("Minuit2", "Migrad"), + ("Minuit2", "Fumili"), + ("GSLMultiMin", "BFGS"), + ("GSLMultiMin", "SteepestDescent"), + ("GSLLMA", ""), # ("GSLSimAn","") ] diff --git a/Tests/UnitTests/TestFit/MinimizerOptionsTest.h b/Tests/UnitTests/TestFit/MinimizerOptionsTest.h new file mode 100644 index 0000000000000000000000000000000000000000..8cdca48e08cabeaeb0bee668330a1858f42a84ed --- /dev/null +++ b/Tests/UnitTests/TestFit/MinimizerOptionsTest.h @@ -0,0 +1,57 @@ +#include "MinimizerOptions.h" + +class MinimizerOptionsTest : public ::testing::Test +{ + protected: + MinimizerOptionsTest(){} + virtual ~MinimizerOptionsTest(){} + +}; + + +TEST_F(MinimizerOptionsTest, InitialState) +{ + MinimizerOptions options; + EXPECT_EQ(0.01, options.getTolerance()); + EXPECT_EQ(-1, options.getPrecision()); + EXPECT_EQ(0, options.getMaxIterations()); + EXPECT_EQ(0, options.getMaxFunctionCalls()); + + ASSERT_THROW(options.setValue("some_value",1.0), LogicErrorException); +} + + +TEST_F(MinimizerOptionsTest, SetValues) +{ + MinimizerOptions options; + + options.setTolerance(0.02); + options.setPrecision(2); + options.setMaxIterations(10); + options.setMaxFunctionCalls(100); + EXPECT_EQ(0.02, options.getTolerance()); + EXPECT_EQ(2, options.getPrecision()); + EXPECT_EQ(10, options.getMaxIterations()); + EXPECT_EQ(100, options.getMaxFunctionCalls()); + + options.addValue("some_int",1); + options.addValue("some_double",9.9); + options.addValue("some_string","xxx"); + + ASSERT_THROW(options.addValue("some_int",1), LogicErrorException); + EXPECT_EQ(options.getIntValue("some_int"), 1); + EXPECT_EQ(options.getRealValue("some_double"), 9.9); + EXPECT_EQ(options.getNamedValue("some_string"), "xxx"); + + ASSERT_THROW(options.getIntValue("some_int2"), LogicErrorException); + + MinimizerOptions opt2 = options; + EXPECT_EQ(0.02, opt2.getTolerance()); + EXPECT_EQ(2, opt2.getPrecision()); + EXPECT_EQ(10, opt2.getMaxIterations()); + EXPECT_EQ(100, opt2.getMaxFunctionCalls()); + EXPECT_EQ(opt2.getIntValue("some_int"), 1); + EXPECT_EQ(opt2.getRealValue("some_double"), 9.9); + EXPECT_EQ(opt2.getNamedValue("some_string"), "xxx"); +} + diff --git a/Tests/UnitTests/TestFit/main.cpp b/Tests/UnitTests/TestFit/main.cpp index af2495f06ab145937ee5d4a9da056375887ede59..a2b45c939ea9ed15d8006f94f7e00efbb1ad126a 100644 --- a/Tests/UnitTests/TestFit/main.cpp +++ b/Tests/UnitTests/TestFit/main.cpp @@ -6,6 +6,8 @@ #include "AttLimitsTest.h" #include "FitParameterTest.h" #include "FitParameterLinkedTest.h" +#include "MinimizerOptionsTest.h" + struct ErrorStreamRedirect { ErrorStreamRedirect( std::streambuf * new_buffer ) diff --git a/ThirdParty/RootMinimizers/inc/Math/Factory.h b/ThirdParty/RootMinimizers/inc/Math/Factory.h deleted file mode 100644 index 26fb52c759fe210538715008da9b3ad8d0a55ebc..0000000000000000000000000000000000000000 --- a/ThirdParty/RootMinimizers/inc/Math/Factory.h +++ /dev/null @@ -1,58 +0,0 @@ -// @(#)root/mathcore:$Id$ -// Author: L. Moneta Fri Dec 22 14:43:33 2006 - -/********************************************************************** - * * - * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * - * * - * * - **********************************************************************/ - -// Header file for class Factory - -#ifndef ROOT_Math_Factory -#define ROOT_Math_Factory - -#include <string> - - -namespace ROOT { - - namespace Math { - - class Minimizer; - class DistSampler; - -//___________________________________________________________________________ -/** - Factory class holding static functions to create the interfaces like ROOT::Math::Minimizer - via the Plugin Manager -*/ -class Factory { - public: - - /** - static method to create the corresponding Minimizer given the string - Supported Minimizers types are: - Minuit (TMinuit), Minuit2, GSLMultiMin, GSLMultiFit, GSLSimAn, Linear, Fumili, Genetic - If no name is given use default values defined in MinimizerOptions - */ - static ROOT::Math::Minimizer * CreateMinimizer(const std::string & minimizerType = "", const std::string & algoType = ""); - - /** - static method to create the distribution sampler class given a string specifying the type - Supported sampler types are: - Unuran, Foam - If no name is given use default values defined in DistSamplerOptions - */ - static ROOT::Math::DistSampler * CreateDistSampler(const std::string & samplerType =""); - - -}; - - } // end namespace Fit - -} // end namespace ROOT - - -#endif /* ROOT_Fit_MinimizerFactory */ diff --git a/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h b/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h index 67fd5f217855ec3c27728a32b1ac08af2b3ca186..f1abd5324015646559e9b280f80a56a1c5891163 100644 --- a/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h +++ b/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h @@ -77,6 +77,16 @@ namespace Math { */ GSLRandomEngine( GSLRngWrapper * rng); + /** + Copy constructor : clone the contained GSL generator + */ + GSLRandomEngine(const GSLRandomEngine & eng); + + /** + Assignment operator : make a deep copy of the contained GSL generator + */ + GSLRandomEngine & operator=(const GSLRandomEngine & eng); + /** initialize the generator If no rng is present the default one based on Mersenne and Twister is created diff --git a/ThirdParty/RootMinimizers/inc/Math/Minimizer.h b/ThirdParty/RootMinimizers/inc/Math/Minimizer.h index 4cb3b647b497b797298e6f404620ec41fd79e7b6..6e8826a6f81ccdbc790bc4082150c4b8fd4e71d7 100644 --- a/ThirdParty/RootMinimizers/inc/Math/Minimizer.h +++ b/ThirdParty/RootMinimizers/inc/Math/Minimizer.h @@ -52,7 +52,7 @@ namespace ROOT { plug-in manager. Provides interface for setting the function to be minimized. - The function must implement the multi-dimensional generic interface + The function must implemente the multi-dimensional generic interface ROOT::Math::IBaseFunctionMultiDim. If the function provides gradient calculation (implements the ROOT::Math::IGradientFunctionMultiDim interface) this will be diff --git a/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h b/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h index d74b2124971cd39b5b453c7b6c8630fcc17eaab4..f060f7d7a1d11dabbbb7f4509bdded70d8b4a78a 100644 --- a/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h +++ b/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h @@ -102,8 +102,11 @@ public: clone */ virtual OneDimMultiFunctionAdapter * Clone( ) const { - if (fOwn) - return new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams); + if (fOwn) { + OneDimMultiFunctionAdapter * f = new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams); + std::copy(fX, fX+fDim, f->fX); + return f; + } else return new OneDimMultiFunctionAdapter( fFunc, fX, fCoord, fParams); } diff --git a/ThirdParty/RootMinimizers/src/Math/Factory.cxx b/ThirdParty/RootMinimizers/src/Math/Factory.cxx deleted file mode 100644 index b72504b85b9949b0fec4c385ca7aca8f0dc93dfd..0000000000000000000000000000000000000000 --- a/ThirdParty/RootMinimizers/src/Math/Factory.cxx +++ /dev/null @@ -1,185 +0,0 @@ -// @(#)root/mathcore:$Id$ -// Author: L. Moneta Fri Dec 22 14:43:33 2006 - -/********************************************************************** - * * - * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * - * * - * * - **********************************************************************/ - -// Implementation file for class MinimizerFactory - -#include "Math/Factory.h" -#include "Math/Error.h" - -//#include "RConfigure.h" - -#include "Math/Minimizer.h" -#include "Math/MinimizerOptions.h" - -//#include "Math/DistSampler.h" -//#include "Math/DistSamplerOptions.h" - -#ifndef MATH_NO_PLUGIN_MANAGER -// use ROOT Plug-in manager -#include "TPluginManager.h" -#include "TROOT.h" -#else -// all the minimizer implementation classes -//#define HAS_MINUIT2 -#ifdef HAS_MINUIT2 -#include "Minuit2/Minuit2Minimizer.h" -#endif -#ifdef HAS_MINUIT -#include "TMinuitMinimizer.h" -#endif -#ifdef R__HAS_MATHMORE -#include "Math/GSLMinimizer.h" -#include "Math/GSLNLSMinimizer.h" -#include "Math/GSLSimAnMinimizer.h" -#endif - -#endif - -#include <algorithm> -#include <cassert> - -//#define DEBUG -#ifdef DEBUG -#include <iostream> -#endif - -#ifndef MATH_NO_PLUGIN_MANAGER -// use ROOT Plugin Manager to create Minimizer concrete classes - -ROOT::Math::Minimizer * ROOT::Math::Factory::CreateMinimizer(const std::string & minimizerType,const std::string & algoType) -{ - // create Minimizer using the pluBg-in manager given the type of Minimizer (MINUIT, MINUIT2, FUMILI, etc..) and - // algorithm (MIGRAD, SIMPLEX, etc..) - - const char * minim = minimizerType.c_str(); - const char * algo = algoType.c_str(); - - //case of fumili2 - std::string s1,s2; - if (minimizerType == "Fumili2" ) { - s1 = "Minuit2"; - s2 = "fumili"; - minim = s1.c_str(); - algo = s2.c_str(); - } - if (minimizerType == "TMinuit") { - s1 = "Minuit"; - minim = s1.c_str(); - } - - if (minimizerType.empty() ) minim = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str(); - - // create Minimizer using the PM - TPluginHandler *h; - //gDebug = 3; - if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::Minimizer",minim ))) { - if (h->LoadPlugin() == -1) { -#ifdef DEBUG - std::cout << "Error Loading ROOT::Math::Minimizer " << minim << std::endl; -#endif - return 0; - } - - // create plug-in with required algorithm - ROOT::Math::Minimizer * min = reinterpret_cast<ROOT::Math::Minimizer *>( h->ExecPlugin(1,algo ) ); -#ifdef DEBUG - if (min != 0) - std::cout << "Loaded Minimizer " << minimizerType << " " << algoType << std::endl; - else - std::cout << "Error creating Minimizer " << minimizerType << " " << algoType << std::endl; -#endif - - return min; - } - return 0; - -} - -#else - -// use directly classes instances - -ROOT::Math::Minimizer * ROOT::Math::Factory::CreateMinimizer(const std::string & minimizerType, const std::string & algoType) -{ - // static method to create a minimizer . - // not using PM so direct dependency on all libraries (Minuit, Minuit2, MathMore, etc...) - // The default is the Minuit2 minimizer or GSL Minimizer - - // should use enumerations instead of string ? - - Minimizer * min = 0; - std::string algo = algoType; - - -#ifdef HAS_MINUIT2 - if (minimizerType == "Minuit2") - min = new ROOT::Minuit2::Minuit2Minimizer(algoType.c_str()); - if (minimizerType == "Fumili2") - min = new ROOT::Minuit2::Minuit2Minimizer("fumili"); -#endif - -#ifdef HAS_MINUIT - // use TMinuit - if (minimizerType == "Minuit" || minimizerType == "TMinuit") - min = new ROOT::Fit::TMinuitMinimizer(algoType.c_str()); -#endif - -#ifdef R__HAS_MATHMORE - // use GSL minimizer - if (minimizerType == "GSL") - min = new ROOT::Math::GSLMinimizer(algoType.c_str()); - - else if (minimizerType == "GSL_NLS") - min = new ROOT::Math::GSLNLSMinimizer(); - - else if (minimizerType == "GSL_SIMAN") - min = new ROOT::Math::GSLSimAnMinimizer(); -#endif - - -#ifdef HAS_MINUIT2 - // DEFAULT IS MINUIT2 based on MIGRAD id minuit2 exists - else - min = new ROOT::Minuit2::Minuit2Minimizer(); -#endif - - return min; -} - -#endif - -// ROOT::Math::DistSampler * ROOT::Math::Factory::CreateDistSampler(const std::string & type) { -// #ifdef MATH_NO_PLUGIN_MANAGER -// MATH_ERROR_MSG("Factory::CreateDistSampler","ROOT plug-in manager not available"); -// return 0; -// #else -// // create a DistSampler class using the ROOT plug-in manager -// const char * typeName = type.c_str(); -// if (type.empty() ) typeName = ROOT::Math::DistSamplerOptions::DefaultSampler().c_str(); -// -// TPluginManager *pm = gROOT->GetPluginManager(); -// assert(pm != 0); -// TPluginHandler *h = pm->FindHandler("ROOT::Math::DistSampler", typeName ); -// if (h != 0) { -// if (h->LoadPlugin() == -1) { -// MATH_ERROR_MSG("Factory::CreateDistSampler","Error loading DistSampler plug-in"); -// return 0; -// } -// -// ROOT::Math::DistSampler * smp = reinterpret_cast<ROOT::Math::DistSampler *>( h->ExecPlugin(0) ); -// assert(smp != 0); -// return smp; -// } -// MATH_ERROR_MSGVAL("Factory::CreateDistSampler","Error finding DistSampler plug-in",typeName); -// return 0; -// #endif -// } - - diff --git a/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx b/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx index f22b9db420765d60c2debac03bb1fed63d4de039..eef00b72820af056ef0dd9c6ae3fb732d217d630 100644 --- a/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx +++ b/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx @@ -236,6 +236,11 @@ void GSLNLSMinimizer::SetFunction(const ROOT::Math::IMultiGenFunction & func) { return; } fSize = chi2Func->NPoints(); + + if (fSize == 0) { + MATH_WARN_MSG("GSLNLSMinimizer::SetFunction","Objective function has zero elements"); + } + fDim = chi2Func->NDim(); fNFree = fDim; @@ -266,6 +271,12 @@ bool GSLNLSMinimizer::Minimize() { return false; } + if (fSize == 0) { + MATH_ERROR_MSG("GSLNLSMinimizer::Minimize","Number of data points is zero"); + return false; + } + + unsigned int npar = fValues.size(); if (npar == 0 || npar < fDim) { MATH_ERROR_MSGVAL("GSLNLSMinimizer::Minimize","Wrong number of parameters",npar); diff --git a/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx b/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx index 89c92e9978a648cd0a4d23817cd10b6285b8107d..6faac2b08714559487012f4185dccbf87f699feb 100644 --- a/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx +++ b/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx @@ -68,17 +68,28 @@ namespace Math { fCurTime(0) {} -// // constructor from external rng -// GSLRandomEngine( GSLRngWrapper & rng) : -// fRng(new GSLRngWrapper(rng) ), -// fCurTime(0) -// {} + // copy constructor + GSLRandomEngine::GSLRandomEngine(const GSLRandomEngine & eng) : + fRng(new GSLRngWrapper(*eng.fRng) ), + fCurTime(0) + {} GSLRandomEngine::~GSLRandomEngine() { // destructor : call terminate if not yet called if (fRng) Terminate(); } + // assignment operator + GSLRandomEngine & GSLRandomEngine::operator=(const GSLRandomEngine & eng) { + if (this == &eng) return *this; + if (fRng) + *fRng = *eng.fRng; + else + fRng = new GSLRngWrapper(*eng.fRng); + fCurTime = eng.fCurTime; + return *this; + } + void GSLRandomEngine::Initialize() { // initialize the generator by allocating the GSL object diff --git a/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h b/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h index 55a34ea197a3152ead7433cb50615ca46b765d6b..3cc65b1d61b9428cc5de0e8fe42b99dd628eaa12 100644 --- a/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h +++ b/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h @@ -59,18 +59,32 @@ public: } /** - Copy constructor - pass ownership (need not to be const) - Just copy the pointer and do not manage it + Copy constructor - clone the GSL object and manage it */ GSLRngWrapper(GSLRngWrapper & r) : - fOwn(r.fOwn), - fRng(r.fRng), + fOwn(1), fRngType(r.fRngType) { - // in case an rng exists must release it - if (fRng && fOwn) r.fOwn = false; + fRng = gsl_rng_clone(r.fRng); } + /** + Assignment operator + */ + GSLRngWrapper & operator = (const GSLRngWrapper & rhs) { + if (this == &rhs) return *this; // time saving self-test + fRngType = rhs.fRngType; + int iret = 0; + if (fRngType == rhs.fRngType) { + iret = gsl_rng_memcpy(fRng, rhs.fRng); + if (!iret) return *this; + } + // otherwise create a new copy + if (fOwn) Free(); + fRng = gsl_rng_clone(rhs.fRng); + fOwn = true; + return *this; + } /** Destructor (free the rng if not done before) @@ -104,24 +118,14 @@ public: fRngType = gsl_rng_default; } - + void PrintState() const { + gsl_rng_print_state(fRng); + } inline gsl_rng * Rng() { return fRng; } inline const gsl_rng * Rng() const { return fRng; } -private: - // usually copying is non trivial, so we make this unaccessible - - - /** - Assignment operator - Disable since if don't want to change an already created wrapper - */ - GSLRngWrapper & operator = (const GSLRngWrapper & rhs) { - if (this == &rhs) return *this; // time saving self-test - return *this; - } private: diff --git a/dev-tools/python-bindings/MakePyFit.py b/dev-tools/python-bindings/MakePyFit.py index c197b3feb376bcd70cfd3d0640739e654581d751..a967f7f81e1950580f380c0389fb1e02b5cfc0e4 100644 --- a/dev-tools/python-bindings/MakePyFit.py +++ b/dev-tools/python-bindings/MakePyFit.py @@ -59,6 +59,7 @@ include_classes = [ "SquaredFunctionMeanSquaredError", "SquaredFunctionGaussianError", "SquaredFunctionSystematicError", + "SquaredFunctionSimError", ] @@ -69,6 +70,13 @@ def ManualClassTunings(mb): cl = mb.class_("IMinimizer") cl.member_function("setChiSquaredFunction").exclude() cl.member_function("setGradientFunction").exclude() + for fun in cl.member_functions(): + if "getOptions" in fun.name: + if "::MinimizerOptions const & ( ::IMinimizer::* )( ) const" in fun.decl_string: + fun.exclude() + else: + fun.call_policies = call_policies.return_internal_reference() + # cl = mb.class_("FitSuite") #cl.member_functions().exclude() @@ -76,6 +84,7 @@ def ManualClassTunings(mb): #if "addFitParameter" in fun.name: #fun.include() cl.member_function("getMinimizer").include() + cl.member_function( "getMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) cl.member_function("setMinimizer").include() #cl.member_function("addSimulationAndRealData").include() #cl.member_function("runFit").include() @@ -92,14 +101,20 @@ def ManualClassTunings(mb): #fun.exclude() # cl = mb.class_("MinimizerFactory") - cl.member_function( "createMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) + #cl.member_function( "createMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) + for fun in cl.member_functions(): + if "createMinimizer" in fun.name: + fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) + + cl = mb.class_("FitStrategyAdjustMinimizer") + cl.member_function( "getMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) + cl.member_function( "setMinimizer" ).include() cl = mb.class_("IObserver") cl.member_function("update").include() cl = mb.class_("FitSuiteParameters") for fun in cl.member_functions(): - print fun.decl_string if "__gnu_cxx::__normal_iterator" in fun.decl_string: fun.exclude()