From 103a4e0d601fc36b12df522797517823981a4dcd Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Fri, 11 Oct 2024 16:33:54 +0200 Subject: [PATCH] [RF] Move vectorised PDF tests from roottest to roofit These useful tests are relatively short (runtime 28 seconds in total) and test lower-level RooFit functionality. Moving them from roottest to roofit has the following benefits: * Faster RooFit development experience: it's not necessary anymore to also add and compile all of `roottest`, if you want to make sure locally that the vectorized pdf tests always compile and pass. * The vectorized pdf tests will be able to consider the RooFit-internal preprocessor macros at build time, like `ROOFIT_CUDA` and `ROOFIT_LEGACY_EVAL_BACKEND`. Like this we can ensure that the tests will pass no matter how RooFit was configured at compile time. This is for me personally the strongest reason and was the motivator for this commit. * Avoid code repetition in `root` and `roottest`, because now the vectorized PDF tests will be able to re-use private code from RooFit. * If you want to build standalone RooFit with all tests, you won't have to stitch together the two repositories. --- roofit/roofit/test/CMakeLists.txt | 2 + .../roofit/test/vectorisedPDFs/CMakeLists.txt | 67 +++ .../vectorisedPDFs/VectorisedPDFTests.cxx | 555 ++++++++++++++++++ .../test/vectorisedPDFs/VectorisedPDFTests.h | 191 ++++++ .../roofit/test/vectorisedPDFs/testAddPdf.cxx | 148 +++++ .../test/vectorisedPDFs/testArgusBG.cxx | 51 ++ .../test/vectorisedPDFs/testBernstein.cxx | 79 +++ .../test/vectorisedPDFs/testBifurGauss.cxx | 50 ++ .../test/vectorisedPDFs/testBreitWigner.cxx | 47 ++ .../roofit/test/vectorisedPDFs/testBukin.cxx | 61 ++ .../test/vectorisedPDFs/testCBShape.cxx | 53 ++ .../test/vectorisedPDFs/testChebychev.cxx | 81 +++ .../test/vectorisedPDFs/testChiSquarePdf.cxx | 45 ++ .../test/vectorisedPDFs/testCompatMode.cxx | 254 ++++++++ .../test/vectorisedPDFs/testDstD0BG.cxx | 46 ++ .../test/vectorisedPDFs/testExponential.cxx | 51 ++ .../roofit/test/vectorisedPDFs/testGamma.cxx | 52 ++ .../roofit/test/vectorisedPDFs/testGauss.cxx | 146 +++++ .../test/vectorisedPDFs/testGaussBinned.cxx | 141 +++++ .../test/vectorisedPDFs/testJohnson.cxx | 137 +++++ .../roofit/test/vectorisedPDFs/testLandau.cxx | 82 +++ .../test/vectorisedPDFs/testLegendre.cxx | 44 ++ .../test/vectorisedPDFs/testLognormal.cxx | 76 +++ .../test/vectorisedPDFs/testNestedPDFs.cxx | 83 +++ .../test/vectorisedPDFs/testNovosibirsk.cxx | 50 ++ .../test/vectorisedPDFs/testPoisson.cxx | 80 +++ .../test/vectorisedPDFs/testPolynomial.cxx | 83 +++ .../test/vectorisedPDFs/testProductPdf.cxx | 62 ++ .../test/vectorisedPDFs/testVoigtian.cxx | 78 +++ 29 files changed, 2895 insertions(+) create mode 100644 roofit/roofit/test/vectorisedPDFs/CMakeLists.txt create mode 100644 roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.h create mode 100644 roofit/roofit/test/vectorisedPDFs/testAddPdf.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testArgusBG.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testBernstein.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testBifurGauss.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testBreitWigner.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testBukin.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testCBShape.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testChebychev.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testChiSquarePdf.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testCompatMode.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testDstD0BG.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testExponential.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testGamma.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testGauss.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testGaussBinned.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testJohnson.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testLandau.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testLegendre.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testLognormal.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testNestedPDFs.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testNovosibirsk.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testPoisson.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testPolynomial.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testProductPdf.cxx create mode 100644 roofit/roofit/test/vectorisedPDFs/testVoigtian.cxx diff --git a/roofit/roofit/test/CMakeLists.txt b/roofit/roofit/test/CMakeLists.txt index 59449f0b47e81..a9d35d6fcb577 100644 --- a/roofit/roofit/test/CMakeLists.txt +++ b/roofit/roofit/test/CMakeLists.txt @@ -28,3 +28,5 @@ else() ROOT_EXECUTABLE(testRooFit testRooFit.cxx LIBRARIES RooFit) ROOT_ADD_TEST(test-fit-testRooFit COMMAND testRooFit) endif() + +add_subdirectory(vectorisedPDFs) diff --git a/roofit/roofit/test/vectorisedPDFs/CMakeLists.txt b/roofit/roofit/test/vectorisedPDFs/CMakeLists.txt new file mode 100644 index 0000000000000..c0885ce59a4bd --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/CMakeLists.txt @@ -0,0 +1,67 @@ +if(CMAKE_CXX_COMPILER_ID STREQUAL Intel) + if(DEFINED ENV{VTUNE_AMPLIFIER_2019_DIR}) + set(VTUNE_DIR ENV{VTUNE_AMPLIFIER_2019_DIR}) + elseif(DEFINED ENV{VTUNE_PROFILER_2020_DIR}) + set(VTUNE_DIR ENV{VTUNE_PROFILER_2020_DIR}) + endif() + # To be able to start/stop the vtune profiler, ittnotify must be available. + target_include_directories(VectorisedPDFTests PUBLIC "${VTUNE_DIR}/include/") + target_link_libraries(VectorisedPDFTests INTERFACE "${VTUNE_DIR}/lib64/libittnotify.a") +endif() + +add_library(VectorisedPDFTests STATIC VectorisedPDFTests.cxx) +target_link_libraries(VectorisedPDFTests PUBLIC gtest ROOT::Gpad ROOT::RooFitCore ROOT::RooFit) + +ROOT_ADD_GTEST(testCompatMode testCompatMode.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testGauss testGauss.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testPoisson testPoisson.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testAddPdf testAddPdf.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testExponential testExponential.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testNestedPDFs testNestedPDFs.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testProductPdf testProductPdf.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testJohnson testJohnson.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testLandau testLandau.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testBukin testBukin.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testChebychev testChebychev.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testPolynomial testPolynomial.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testBernstein testBernstein.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testArgusBG testArgusBG.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testBifurGauss testBifurGauss.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testBreitWigner testBreitWigner.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testCBShape testCBShape.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testGamma testGamma.cxx + LIBRARIES VectorisedPDFTests) +if(ROOT_mathmore_FOUND) + ROOT_ADD_GTEST(testLegendre testLegendre.cxx + LIBRARIES VectorisedPDFTests ROOT::RooFitMore) +endif() +ROOT_ADD_GTEST(testChiSquarePdf testChiSquarePdf.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testDstD0BG testDstD0BG.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testLognormal testLognormal.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testNovosibirsk testNovosibirsk.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testVoigtian testVoigtian.cxx + LIBRARIES VectorisedPDFTests) +ROOT_ADD_GTEST(testGaussBinned testGaussBinned.cxx + LIBRARIES ROOT::Gpad ROOT::RooFitCore ROOT::RooFit) + diff --git a/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.cxx b/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.cxx new file mode 100644 index 0000000000000..20748153f4e15 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.cxx @@ -0,0 +1,555 @@ +// Author: Stephan Hageboeck, CERN 26 Jul 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooRealVar.h" +#include "RooAbsPdf.h" +#include "RooDataSet.h" +#include "RooFitResult.h" +#include "RooAbsRealLValue.h" +#include "RooGaussian.h" +#include "RooPlot.h" +#include "RooRandom.h" +#include "RooConstVar.h" +#include "RooHelpers.h" +#include "RooFit/Evaluator.h" + +#include "RooFit/Detail/BatchModeDataHelpers.h" + +#include +#include + +#include +#include +#include +#include + +#ifdef __INTEL_COMPILER +#include "ittnotify.h" +#else +void __itt_resume() {} +void __itt_pause() {} +#endif + +std::vector getValues(RooAbsReal const &real, RooAbsData const &data) +{ + std::unique_ptr clone = RooFit::Detail::compileForNormSet(real, *data.get()); + RooFit::Evaluator evaluator(*clone); + std::stack> vectorBuffers; + auto dataSpans = + RooFit::Detail::BatchModeDataHelpers::getDataSpans(data, "", nullptr, /*skipZeroWeights=*/false, + /*takeGlobalObservablesFromData=*/true, vectorBuffers); + for (auto const &item : dataSpans) { + evaluator.setInput(item.first->GetName(), item.second, false); + } + std::vector out; + std::span results = evaluator.run(); + out.assign(results.begin(), results.end()); + return out; +} + +class MyTimer { +public: + MyTimer(std::string &&name) + : m_name(name), m_startTime(clock()), m_endTime(0), m_steadyStart(std::chrono::steady_clock::now()), m_steadyEnd() + { + } + + clock_t diffTime() const { return clock() - m_startTime; } + + void interval() + { + m_endTime = clock(); + m_steadyEnd = std::chrono::steady_clock::now(); + } + + void print(std::ostream &str) + { + clock_t diff = m_endTime - m_startTime; + std::chrono::duration diffSteady = m_steadyEnd - m_steadyStart; + str << "\n" + << "Timer '" << m_name << "':\t" << double(diff) / CLOCKS_PER_SEC << "s (CPU) " << diffSteady.count() + << "s (wall)" << std::endl; + } + +private: + std::string m_name; + clock_t m_startTime; + clock_t m_endTime; + std::chrono::time_point m_steadyStart; + std::chrono::time_point m_steadyEnd; +}; + +std::ostream &operator<<(std::ostream &str, MyTimer &timer) +{ + timer.interval(); + timer.print(str); + return str; +} + +PDFTest::PDFTest(std::string &&name, std::size_t nEvt) : _name(name), _nEvents(nEvt) +{ + // Shut up integration messages + auto &msg = RooMsgService::instance(); + msg.getStream(0).minLevel = RooFit::WARNING; + msg.getStream(1).minLevel = RooFit::WARNING; + + RooRandom::randomGenerator()->SetSeed(1337); +} + +void PDFTest::SetUp() +{ + _origParameters.addClone(_parameters); + _origYields.addClone(_yields); +} + +void PDFTest::makeFitData() +{ + _dataFit = std::unique_ptr{_pdf->generate(_variables, _nEvents)}; +} + +void PDFTest::makeUniformData() +{ + auto data = std::make_unique("testData", "testData", _variables); + for (auto var : _variables) { + auto lv = static_cast(var); + const double max = lv->getMax(); + const double min = lv->getMin(); + unsigned int nBatch = _nEvents / _variables.size(); + for (unsigned int i = 0; i < nBatch; ++i) { + lv->setVal(min + (max - min) / nBatch * i); + data->add(_variables); + } + } + + _dataUniform = std::move(data); +} + +void PDFTest::randomiseParameters(ULong_t seed) +{ + auto random = RooRandom::randomGenerator(); + random->SetSeed(seed); + + for (auto param : _parameters) { + auto par = static_cast(param); + const double uni = random->Uniform(); + const double min = par->getMin(); + const double max = par->getMax(); + par->setVal(min + uni * (max - min)); + } +} + +void PDFTest::makePlots(std::string &&fitStage) const +{ + for (auto elm : _variablesToPlot) { + auto var = static_cast(elm); + auto canv = std::make_unique(); + auto frame = std::unique_ptr(var->frame()); + _dataFit->plotOn(frame.get()); + _pdf->plotOn(frame.get(), RooFit::Precision(-1.)); + _pdf->paramOn(frame.get()); + frame->Draw(); + canv->Draw(); + std::string filename = _plotDirectory + _name + "_"; + filename += var->GetName(); + filename += "_" + fitStage + ".png"; + std::replace(filename.begin(), filename.end(), ' ', '_'); + canv->SaveAs(filename.c_str()); + } +} + +void PDFTest::setValuesConstant(const RooAbsCollection &coll, bool constant) const +{ + for (auto obj : coll) { + auto lvalue = dynamic_cast(obj); + if (lvalue) + lvalue->setConstant(constant); + } +} + +void PDFTest::resetParameters() +{ + _parameters.assign(_origParameters); + _yields.assign(_origYields); +} + +void PDFTest::kickParameters() +{ + + // Kick parameters away from best-fit value + for (auto param : _parameters) { + auto lval = static_cast(param); + auto orig = static_cast(_origParameters.find(param->GetName())); + if (orig->isConstant()) + continue; + + *lval = orig->getVal() * 1.3 + (orig->getVal() == 0. ? 0.1 : 0.); + } + + for (auto yield : _yields) { + auto lval = static_cast(yield); + auto orig = static_cast(_origYields.find(yield->GetName())); + if (orig->isConstant()) + continue; + + *lval = orig->getVal() * 1.3 + (orig->getVal() == 0. ? 0.1 : 0.); + } + + setValuesConstant(_otherObjects, true); +} + +void PDFTest::compareFixedValues(double &maximalError, bool normalise, bool compareLogs, bool runTimer, + unsigned int nChunks) +{ + if (!_dataUniform) + makeUniformData(); + + if (nChunks == 0) { + nChunks = 1; + } + + const RooArgSet *normSet = nullptr; + std::string timerSuffix = normalise ? " norm " : " unnorm "; + if (compareLogs) + timerSuffix = " (logs)" + timerSuffix; + + const double toleranceCompare = compareLogs ? _toleranceCompareLogs : _toleranceCompareBatches; + + std::unique_ptr observables{_pdf->getObservables(*_dataUniform)}; + std::unique_ptr parameters{_pdf->getParameters(*_dataUniform)}; + + auto callBatchFunc = [this](const RooAbsPdf &pdf) { return getValues(pdf, *_dataUniform); }; + + auto callScalarFunc = [compareLogs](const RooAbsPdf &pdf, const RooArgSet *theNormSet) { + if (compareLogs) + return pdf.getLogVal(theNormSet); + else + return pdf.getVal(theNormSet); + }; + + if (normalise) { + normSet = &_variables; + } + + std::vector> batchResults; + std::vector> resultData; + MyTimer batchTimer("Evaluate batch" + timerSuffix + _name); + __itt_resume(); + const std::size_t chunkSize = _dataUniform->numEntries() / nChunks + (_dataUniform->numEntries() % nChunks != 0); + for (unsigned int chunk = 0; chunk < nChunks; ++chunk) { + auto outputsBatch = callBatchFunc(*_pdf); + const std::size_t begin = chunkSize * chunk; + const std::size_t len = chunk + 1 < nChunks ? chunkSize : _dataUniform->numEntries() / nChunks; + batchResults.emplace_back(&(outputsBatch[0]) + begin, &(outputsBatch[0]) + begin + len); + resultData.push_back(std::move(outputsBatch)); + } + __itt_pause(); + if (runTimer) + std::cout << batchTimer; + + const auto totalSize = + std::accumulate(batchResults.begin(), batchResults.end(), 0, + [](std::size_t acc, const std::span &span) { return acc + span.size(); }); + ASSERT_EQ(totalSize, _dataUniform->numEntries()); + + for (auto &outputsBatch : batchResults) { + const double front = outputsBatch[0]; + const bool allEqual = + std::all_of(outputsBatch.begin(), outputsBatch.end(), [front](double val) { return val == front; }); + ASSERT_FALSE(allEqual) << "All return values of batch run equal. " << outputsBatch[0] << " " << outputsBatch[1] + << " " << outputsBatch[2]; + } + + _dataUniform->resetBuffers(); + + // Scalar run + std::vector outputsScalar(_dataUniform->numEntries(), -1.); + if (normalise) { + // normSet = new RooArgSet(*observables); + normSet = &_variables; + } + *parameters = _parameters; + + { + MyTimer singleTimer("Evaluate scalar" + timerSuffix + _name); + for (int i = 0; i < _dataUniform->numEntries(); ++i) { + observables->assign(*_dataUniform->get(i)); + outputsScalar[i] = callScalarFunc(*_pdf, normSet); + } + if (runTimer) + std::cout << singleTimer; + } + + const bool outputsChanged = + std::any_of(outputsScalar.begin(), outputsScalar.end(), [](double val) { return val != -1.; }); + ASSERT_TRUE(outputsChanged) << "All return values of scalar run are -1."; + + const double frontSc = outputsScalar.front(); + const bool allEqualSc = + std::all_of(outputsScalar.begin(), outputsScalar.end(), [frontSc](double val) { return val == frontSc; }); + ASSERT_FALSE(allEqualSc) << "All return values of scalar run equal.\n\t" << outputsScalar[0] << " " + << outputsScalar[1] << " " << outputsScalar[2] << " " << outputsScalar[3] << " " + << outputsScalar[4] << " " << outputsScalar[5] << " ..."; + + // Compare runs + unsigned int nOff = 0; + unsigned int nFarOff = 0; + constexpr double thresholdFarOff = 1.E-9; + + maximalError = 0.0; + ROOT::Math::KahanSum<> sumDiffs; + ROOT::Math::KahanSum<> sumVars; + auto currentBatch = batchResults.begin(); + unsigned int currentBatchIndex = 0; + for (std::size_t i = 0; i < outputsScalar.size(); ++i, ++currentBatchIndex) { + if (currentBatchIndex >= currentBatch->size()) { + ++currentBatch; + ASSERT_TRUE(currentBatch != batchResults.end()); + currentBatchIndex = 0; + } + const double batchVal = (*currentBatch)[currentBatchIndex]; + + const double relDiff = batchVal != 0. ? (outputsScalar[i] - batchVal) / batchVal : outputsScalar[i]; + + maximalError = std::max(maximalError, fabs(relDiff)); + sumDiffs += relDiff; + sumVars += relDiff * relDiff; + + // Check accuracy of computations, but give it some leniency for very small likelihoods + if ((fabs(relDiff) > toleranceCompare && fabs(outputsScalar[i]) > 1.E-50) || + (fabs(relDiff) > 1.E-10 && fabs(outputsScalar[i]) > 1.E-300) || (fabs(relDiff) > 1.E-9)) { + if (nOff < 5) { + observables->assign(*_dataUniform->get(i)); + std::cout << "Compare event " << i << "\t" << std::setprecision(15); + observables->printStream(std::cout, RooPrintable::kValue | RooPrintable::kName, RooPrintable::kStandard, + " "); + _parameters.Print("V"); + std::cout << "\n\tscalar = " << outputsScalar[i] << "\tpdf->getVal() = " << _pdf->getVal() + << "\n\tbatch = " << batchVal << "\n\trel diff = " << relDiff << std::endl; + } + ++nOff; + + if (fabs(relDiff) > thresholdFarOff) + ++nFarOff; + +#ifdef ROOFIT_CHECK_CACHED_VALUES + try { + observables->assign(*_dataUniform->get(i)); + _pdf->getVal(normSet); + + BatchInterfaceAccessor::checkBatchComputation(*_pdf, evalData[currentBatch - batchResults.begin()], + currentBatchIndex, normSet, toleranceCompare); + + } catch (std::exception &e) { + ADD_FAILURE() << " ERROR when checking batch computation for event " << i << ":\n" + << e.what() << "\n" + << "PDF is:" << std::endl; + _pdf->Print("T"); + } +#endif + } + } + + EXPECT_LT(nOff, 5u); + EXPECT_EQ(nFarOff, 0u); + EXPECT_GT(sumDiffs.Sum() / outputsScalar.size(), -toleranceCompare) << "Batch outputs biased towards negative."; + EXPECT_LT(sumDiffs.Sum() / outputsScalar.size(), toleranceCompare) << "Batch outputs biased towards positive."; + EXPECT_LT(sqrt(sumVars.Sum() / outputsScalar.size()), toleranceCompare) + << "High standard deviation for batch results vs scalar."; +} + +void PDFTest::checkParameters() +{ + ASSERT_FALSE(_parameters.overlaps(_otherObjects)) + << "Collections of parameters and other objects " + << "cannot overlap. This will lead to wrong results, as parameters get kicked before the fit, " + << "other objects are set constant. Hence, the fit cannot change them."; + ASSERT_FALSE(_yields.overlaps(_otherObjects)) + << "Collections of yields and other objects " + << "cannot overlap. This will lead to wrong results, as parameters get kicked before the fit, " + << "other objects are set constant. Hence, the fit cannot change them."; + + for (auto param : _parameters) { + auto postFit = static_cast(param); + auto preFit = static_cast(_origParameters.find(param->GetName())); + ASSERT_NE(preFit, nullptr) << "for parameter '" << param->GetName() << '\''; + const double error3sigma = 3 * postFit->getError(); + EXPECT_LE(fabs(postFit->getVal() - preFit->getVal()), error3sigma) + << "[Within 3 std-dev: " << param->GetName() << " (" << postFit->getVal() << " +- " << error3sigma << ")" + << " == " << preFit->getVal() << "]"; + + EXPECT_NEAR(postFit->getVal(), preFit->getVal(), fabs(postFit->getVal()) * 0.15) + << "[Within 15% for parameter '" << param->GetName() << "']"; + } + + if (!_yields.empty()) { + const double totalPre = + std::accumulate(_origYields.begin(), _origYields.end(), 0., [](double acc, const RooAbsArg *arg) { + return acc + static_cast(arg)->getVal(); + }); + const double totalPost = + std::accumulate(_yields.begin(), _yields.end(), 0., [](double acc, const RooAbsArg *arg) { + return acc + static_cast(arg)->getVal(); + }); + ASSERT_NE(totalPre, 0.); + ASSERT_NE(totalPost, 0.); + ASSERT_LE(fabs(totalPost - _nEvents) / _nEvents, 0.1) << "Total event yield not matching" + << " number of generated events."; + + for (auto yield : _yields) { + auto postFit = static_cast(yield); + auto preFit = static_cast(_origYields.find(yield->GetName())); + ASSERT_NE(preFit, nullptr) << "for parameter '" << yield->GetName() << '\''; + + EXPECT_NEAR(postFit->getVal() / totalPost, preFit->getVal() / totalPre, 0.01) + << "Yield " << yield->GetName() << " = " << postFit->getVal() << " does not match pre-fit ratios."; + } + } +} + +void PDFTest::runBatchVsScalar(bool clonePDF) +{ + RooAbsPdf *pdfScalar = _pdf.get(); + RooAbsPdf *pdfBatch = _pdf.get(); + std::unique_ptr cleanupScalar; + std::unique_ptr cleanupBatch; + + if (clonePDF) { + pdfScalar = static_cast(_pdf->cloneTree("PDFForScalar")); + pdfBatch = static_cast(_pdf->cloneTree("PDFForScalar")); + + cleanupScalar.reset(pdfScalar); + cleanupBatch.reset(pdfBatch); + } + + resetParameters(); + auto resultScalar = runScalarFit(pdfScalar); + + resetParameters(); + auto resultBatch = runBatchFit(pdfBatch); + + resetParameters(); + + ASSERT_NE(resultScalar, nullptr); + ASSERT_NE(resultBatch, nullptr); + + EXPECT_TRUE(resultScalar->isIdentical(*resultBatch, _toleranceParameter, _toleranceCorrelation)); +} + +std::unique_ptr PDFTest::runBatchFit(RooAbsPdf *pdf) +{ + if (!_dataFit) + makeFitData(); + + kickParameters(); + makePlots(::testing::UnitTest::GetInstance()->current_test_info()->name() + std::string("_batch_prefit")); + + auto pars = pdf->getParameters(*_dataFit); + *pars = _parameters; + + for (unsigned int index = 0; index < pars->size(); ++index) { + auto pdfParameter = static_cast((*pars)[index]); + auto origParameter = static_cast(_origParameters.find(*pdfParameter)); + if (!origParameter || origParameter->isConstant()) + continue; + + EXPECT_NE(pdfParameter->getVal(), origParameter->getVal()) + << "Parameter #" << index << "=" << pdfParameter->GetName() << " is identical after kicking."; + } + + if (HasFailure()) { + std::cout << "Pre-fit parameters:\n"; + _parameters.Print("V"); + std::cout << "Orig parameters:\n"; + _origParameters.Print("V"); + } + + MyTimer batchTimer("Fitting batch mode " + _name); + std::unique_ptr result{pdf->fitTo(*_dataFit, RooFit::EvalBackend::Cpu(), RooFit::SumW2Error(false), + RooFit::Optimize(1), RooFit::PrintLevel(_printLevel), RooFit::Save(), + _multiProcess > 0 ? RooFit::NumCPU(_multiProcess) : RooCmdArg())}; + std::cout << batchTimer; + EXPECT_NE(result, nullptr); + if (!result) + return nullptr; + + EXPECT_EQ(result->status(), 0) << "[Batch fit did not converge.]"; + + makePlots(::testing::UnitTest::GetInstance()->current_test_info()->name() + std::string("_batch_postfit")); + + return result; +} + +std::unique_ptr PDFTest::runScalarFit(RooAbsPdf *pdf) +{ + if (!_dataFit) + makeFitData(); + + kickParameters(); + makePlots(::testing::UnitTest::GetInstance()->current_test_info()->name() + std::string("_scalar_prefit")); + + std::unique_ptr pars{pdf->getParameters(*_dataFit)}; + pars->assign(_parameters); + + for (unsigned int index = 0; index < pars->size(); ++index) { + auto pdfParameter = static_cast((*pars)[index]); + auto origParameter = static_cast(_origParameters.find(*pdfParameter)); + if (!origParameter || origParameter->isConstant()) + continue; + + EXPECT_NE(pdfParameter->getVal(), origParameter->getVal()) + << "Parameter #" << index << "=" << pdfParameter->GetName() << " is identical after kicking."; + } + + if (HasFailure()) { + std::cout << "Pre-fit parameters:\n"; + _parameters.Print("V"); + std::cout << "Orig parameters:\n"; + _origParameters.Print("V"); + } + + MyTimer singleTimer("Fitting scalar mode " + _name); + std::unique_ptr result{pdf->fitTo(*_dataFit, RooFit::EvalBackend::Legacy(), RooFit::SumW2Error(false), + RooFit::PrintLevel(_printLevel), RooFit::Save(), + _multiProcess > 0 ? RooFit::NumCPU(_multiProcess) : RooCmdArg())}; + std::cout << singleTimer; + EXPECT_NE(result, nullptr); + if (!result) + return nullptr; + + EXPECT_EQ(result->status(), 0) << "[Scalar fit did not converge.]"; + + makePlots(::testing::UnitTest::GetInstance()->current_test_info()->name() + std::string("_scalar_postfit")); + + return result; +} + +void PDFTestWeightedData::makeFitData() +{ + PDFTest::makeFitData(); + RooRealVar var("gausWeight", "gausWeight", 0, 10); + RooConstVar mean("meanWeight", "", 1.); + RooConstVar sigma("sigmaWeight", "", 0.2); + RooGaussian gausDistr("gausDistr", "gausDistr", var, mean, sigma); + std::unique_ptr gaussData(gausDistr.generate(RooArgSet(var), _dataFit->numEntries())); + _dataFit->merge(gaussData.get()); + + auto wdata = new RooDataSet(_dataFit->GetName(), _dataFit->GetTitle(), *_dataFit->get(), RooFit::Import(*_dataFit), + RooFit::WeightVar("gausWeight")); + + _dataFit.reset(wdata); +} diff --git a/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.h b/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.h new file mode 100644 index 0000000000000..bbd5ddf974f2a --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.h @@ -0,0 +1,191 @@ +// Author: Stephan Hageboeck, CERN 26 Jul 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "RooArgSet.h" +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooFitResult.h" + +#include "gtest/gtest.h" + +#include + +class RooAbsPdf; + +class PDFTest : public ::testing::Test { +protected: + PDFTest(std::string &&name, std::size_t nEvt = 10000); + + void SetUp() override; + + virtual void makeFitData(); + + virtual void makeUniformData(); + + void randomiseParameters(ULong_t seed); + + void makePlots(std::string &&fitStage) const; + + void setValuesConstant(const RooAbsCollection &coll, bool constant) const; + + void resetParameters(); + + void kickParameters(); + + void compareFixedValues(double &maximalError, bool normalise, bool compareLogs, bool runTimer = false, + unsigned int nChunks = 1); + + void checkParameters(); + + void runBatchVsScalar(bool clonePDF = false); + + std::unique_ptr runBatchFit(RooAbsPdf *pdf); + + std::unique_ptr runScalarFit(RooAbsPdf *pdf); + + std::unique_ptr _pdf; + std::unique_ptr _dataUniform; + std::unique_ptr _dataFit; + + std::string _name; + std::string _plotDirectory{"/tmp/"}; + RooArgSet _variables; + RooArgSet _variablesToPlot; + RooArgSet _parameters; + RooArgSet _yields; + RooArgSet _origYields; + RooArgSet _origParameters; + RooArgSet _otherObjects; + const std::size_t _nEvents; + double _toleranceParameter{1.E-6}; + double _toleranceCorrelation{1.E-4}; + double _toleranceCompareBatches{5.E-14}; + double _toleranceCompareLogs{2.E-14}; + int _printLevel{-1}; + unsigned int _multiProcess{0}; +}; + +class PDFTestWeightedData : public PDFTest { +protected: + PDFTestWeightedData(const char *name, std::size_t events = 10000) : PDFTest(name, events) {} + + void makeFitData() override; +}; + +/// Test batch against scalar code for fixed values of observable. Don't run normalisation. +#define COMPARE_FIXED_VALUES_UNNORM(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, DISABLED_##TEST_NAME) \ + { \ + resetParameters(); \ + double relativeError, maximalRelativeError = 0.0; \ + compareFixedValues(relativeError, false, false, false); \ + maximalRelativeError = std::max(maximalRelativeError, relativeError); \ + \ + for (unsigned int i = 0; i < 5 && !HasFailure(); ++i) { \ + std::stringstream str; \ + str << "Parameter set " << i; \ + for (auto par : _parameters) { \ + auto p = static_cast(par); \ + str << "\n\t" << p->GetName() << "\t" << p->getVal(); \ + } \ + SCOPED_TRACE(str.str()); \ + compareFixedValues(relativeError, false, false, false, _multiProcess); \ + maximalRelativeError = std::max(maximalRelativeError, relativeError); \ + \ + randomiseParameters(1337 + i); \ + } \ + std::cout << "\nMaximal relative error (scalar vs batch) is: " << maximalRelativeError << "\n\n"; \ + } + +/// Test batch against scalar code for fixed values of observable with normalisation. +#define COMPARE_FIXED_VALUES_NORM(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, TEST_NAME) \ + { \ + resetParameters(); \ + double relativeError, maximalRelativeError = 0.0; \ + \ + for (unsigned int i = 0; i < 5 && !HasFailure(); ++i) { \ + std::stringstream str; \ + str << "Parameter set " << i; \ + for (auto par : _parameters) { \ + auto p = static_cast(par); \ + str << "\n\t" << p->GetName() << "\t" << p->getVal(); \ + } \ + SCOPED_TRACE(str.str()); \ + compareFixedValues(relativeError, true, false, false, _multiProcess); \ + maximalRelativeError = std::max(maximalRelativeError, relativeError); \ + \ + randomiseParameters(1337 + i); \ + } \ + std::cout << "\nMaximal relative error (scalar vs batch) is: " << maximalRelativeError << "\n\n"; \ + } + +/// Test batch against scalar code for fixed values of observable. Compute log probabilities. +#define COMPARE_FIXED_VALUES_NORM_LOG(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, DISABLED_##TEST_NAME) \ + { \ + resetParameters(); \ + double relativeError, maximalRelativeError = 0.0; \ + \ + for (unsigned int i = 0; i < 5 && !HasFailure(); ++i) { \ + std::stringstream str; \ + str << "Parameter set " << i; \ + for (auto par : _parameters) { \ + auto p = static_cast(par); \ + str << "\n\t" << p->GetName() << "\t" << p->getVal(); \ + } \ + SCOPED_TRACE(str.str()); \ + compareFixedValues(relativeError, true, true, false, _multiProcess); \ + maximalRelativeError = std::max(maximalRelativeError, relativeError); \ + \ + randomiseParameters(1337 + i); \ + } \ + std::cout << "\nMaximal relative error (scalar vs batch) is: " << maximalRelativeError << "\n\n"; \ + } + +/// Run a fit for batch and scalar code and compare results. +#define FIT_TEST_BATCH_VS_SCALAR(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, TEST_NAME) \ + { \ + runBatchVsScalar(); \ + } + +/// Run a fit for batch and scalar code and compare results. +/// Clone the PDFs before running the tests. This can run the test even if some internal state +/// is propagated / saved wrongly. +#define FIT_TEST_BATCH_VS_SCALAR_CLONE_PDF(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, TEST_NAME) \ + { \ + runBatchVsScalar(true); \ + } + +/// Run a fit in batch mode and compare results to pre-fit values. +#define FIT_TEST_BATCH(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, TEST_NAME) \ + { \ + auto result = runBatchFit(_pdf.get()); \ + ASSERT_NE(result, nullptr); \ + checkParameters(); \ + } + +/// Run a fit in legacy mode and compare results to pre-fit values. +#define FIT_TEST_SCALAR(TEST_CLASS, TEST_NAME) \ + TEST_F(TEST_CLASS, TEST_NAME) \ + { \ + auto result = runScalarFit(_pdf.get()); \ + ASSERT_NE(result, nullptr); \ + checkParameters(); \ + } diff --git a/roofit/roofit/test/vectorisedPDFs/testAddPdf.cxx b/roofit/roofit/test/vectorisedPDFs/testAddPdf.cxx new file mode 100644 index 0000000000000..0e2ebdf375090 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testAddPdf.cxx @@ -0,0 +1,148 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooAddPdf.h" +#include "RooGaussian.h" +#include "RooPoisson.h" +#include "RooExponential.h" + +class TestGaussPlusPoisson : public PDFTest { +protected: + TestGaussPlusPoisson() : PDFTest("Gauss + Poisson") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -1.5, 40.5); + x->setBins(42); // Prettier plots for Poisson + + auto mean = std::make_unique("mean", "mean of gaussian", 20., -10, 30); + auto sigma = std::make_unique("sigma", "width of gaussian", 4., 0.5, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + auto gauss = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + auto meanPois = std::make_unique("meanPois", "Mean of Poisson", 10.3, 0, 30); + auto pois = std::make_unique("Pois", "Poisson PDF", *x, *meanPois, true); + + auto fractionGaus = std::make_unique("fractionGaus", "Fraction of Gauss component", 0.5, 0., 1.); + auto sumGausPois = + std::make_unique("SumGausPois", "Sum of Gaus and Poisson", RooArgSet(*gauss, *pois), *fractionGaus); + sumGausPois->fixCoefNormalization(*x); + _pdf = std::move(sumGausPois); + + _variables.addOwned(std::move(x)); + + // _variablesToPlot.add(x); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + _parameters.addOwned(std::move(meanPois)); + _parameters.addOwned(std::move(fractionGaus)); + + _otherObjects.addOwned(std::move(gauss)); + _otherObjects.addOwned(std::move(pois)); + + // Gauss is slightly less accurate + _toleranceCompareBatches = 2.E-13; + _toleranceParameter = 5.E-5; + _toleranceCorrelation = 5.E-4; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGaussPlusPoisson, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGaussPlusPoisson, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGaussPlusPoisson, CompareFixedValuesNormLog) + +FIT_TEST_SCALAR(TestGaussPlusPoisson, DISABLED_Scalar) // Save time +FIT_TEST_BATCH(TestGaussPlusPoisson, DISABLED_Batch) // Save time +FIT_TEST_BATCH_VS_SCALAR(TestGaussPlusPoisson, CompareBatchScalar) + +class TestGaussPlusGaussPlusExp : public PDFTest { +protected: + TestGaussPlusGaussPlusExp() : PDFTest("Gauss + Gauss + Exp") + { + auto x = std::make_unique("x", "x", 0., 100.); + + auto c = std::make_unique("c", "c", -0.05, -100., -0.005); + auto expo = std::make_unique("expo", "expo", *x, *c); + + auto mean = std::make_unique("mean1", "mean of gaussian", 30., -10, 100); + auto sigma = std::make_unique("sigma1", "width of gaussian", 4., 0.1, 20); + auto gauss = std::make_unique("gauss1", "gaussian PDF", *x, *mean, *sigma); + + auto mean2 = std::make_unique("mean2", "mean of gaussian", 60., 50, 100); + auto sigma2 = std::make_unique("sigma2", "width of gaussian", 10., 0.1, 20); + auto gauss2 = std::make_unique("gauss2", "gaussian PDF", *x, *mean2, *sigma2); + + auto nGauss = std::make_unique("nGauss", "Fraction of Gauss component", 800., 0., 1.E6); + auto nGauss2 = std::make_unique("nGauss2", "Fraction of Gauss component", 600., 0., 1.E6); + auto nExp = std::make_unique("nExp", "Number of events in exp", 1000, 0, 1.E6); + auto sum2GausExp = + std::make_unique("Sum2GausExp", "Sum of Gaus and Exponentials", RooArgSet(*gauss, *gauss2, *expo), + RooArgSet(*nGauss, *nGauss2, *nExp)); + sum2GausExp->fixCoefNormalization(*x); + _pdf = std::move(sum2GausExp); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(c)); + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + _parameters.addOwned(std::move(mean2)); + _parameters.addOwned(std::move(sigma2)); + + _yields.addOwned(std::move(nGauss)); + _yields.addOwned(std::move(nGauss2)); + _yields.addOwned(std::move(nExp)); + + _otherObjects.addOwned(std::move(expo)); + _otherObjects.addOwned(std::move(gauss)); + _otherObjects.addOwned(std::move(gauss2)); + + _toleranceCompareLogs = 4.3E-14; + + // VDT stops computing exponentials below exp(-708) = 3.3075530e-308 + // Since this test runs Gaussians far from their mean, we need to be a bit more forgiving + _toleranceParameter = 5.E-5; + _toleranceCorrelation = 5.E-4; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGaussPlusGaussPlusExp, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGaussPlusGaussPlusExp, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGaussPlusGaussPlusExp, CompareFixedValuesNormLog) + +FIT_TEST_SCALAR(TestGaussPlusGaussPlusExp, DISABLED_Scalar) // Save time +FIT_TEST_BATCH(TestGaussPlusGaussPlusExp, DISABLED_Batch) // Save time +FIT_TEST_BATCH_VS_SCALAR(TestGaussPlusGaussPlusExp, CompareBatchScalar) + +#if !defined(_MSC_VER) // RooFit multiprocessing doesn't work on Windows + +class TestGaussPlusGaussPlusExp_MP : public TestGaussPlusGaussPlusExp { +public: + TestGaussPlusGaussPlusExp_MP() : TestGaussPlusGaussPlusExp() { _multiProcess = 2; } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGaussPlusGaussPlusExp_MP, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGaussPlusGaussPlusExp_MP, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGaussPlusGaussPlusExp_MP, CompareFixedValuesNormLog) + +FIT_TEST_SCALAR(TestGaussPlusGaussPlusExp_MP, DISABLED_Scalar) // Save time +FIT_TEST_BATCH(TestGaussPlusGaussPlusExp_MP, DISABLED_Batch) // Save time +FIT_TEST_BATCH_VS_SCALAR(TestGaussPlusGaussPlusExp_MP, CompareBatchScalar) + +#endif // !defined(_MSC_VER) diff --git a/roofit/roofit/test/vectorisedPDFs/testArgusBG.cxx b/roofit/roofit/test/vectorisedPDFs/testArgusBG.cxx new file mode 100644 index 0000000000000..c4b671b6d6db3 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testArgusBG.cxx @@ -0,0 +1,51 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooArgusBG.h" + +class TestArgus : public PDFTest { +protected: + TestArgus() : PDFTest("Argus") + { + auto m = std::make_unique("m", "m", 300.0, 1.0, 800.0); + auto m0 = std::make_unique("m0", "m0", 1100.0, 800.0, 1400.0); + auto c = std::make_unique("c", "c", 10.0, 5.0, 15.0); + c->setConstant(); + auto p = std::make_unique("p", "p", 1.0, 0.9, 1.3); + p->setConstant(); + _pdf = std::make_unique("argus1", "argus1", *m, *m0, *c, *p); + // for (auto var : {m}) { + // _variablesToPlot.add(*var); + // } + // _printLevel = 2; + + _variables.addOwned(std::move(m)); + + _parameters.addOwned(std::move(m0)); + _parameters.addOwned(std::move(c)); + _parameters.addOwned(std::move(p)); + + _toleranceParameter = 2.E-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestArgus, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestArgus, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestArgus, CompareFixedNormLog) +FIT_TEST_SCALAR(TestArgus, RunScalar) +FIT_TEST_BATCH(TestArgus, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestArgus, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testBernstein.cxx b/roofit/roofit/test/vectorisedPDFs/testBernstein.cxx new file mode 100644 index 0000000000000..70baa63ca96e5 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testBernstein.cxx @@ -0,0 +1,79 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooBernstein.h" + +class TestBernstein2 : public PDFTest { +protected: + TestBernstein2() : PDFTest("Bernstein2") + { + auto x = std::make_unique("x", "x", -10, 10); + auto a1 = std::make_unique("a1", "a1", 1, 0.8, 1.2); + auto a2 = new RooRealVar("a2", "a2", 1.5, 1.2, 1.8); + a2->setConstant(true); + + _pdf = std::make_unique("bernstein2", "bernstein PDF 2 coefficients", *x, RooArgSet(*a1, *a2)); + + _variables.addOwned(std::move(x)); + + //_variablesToPlot.add(*x); + + _parameters.addOwned(std::move(a1)); + + _toleranceParameter = 1.5e-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestBernstein2, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestBernstein2, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestBernstein2, CompareFixedNormLog) +FIT_TEST_SCALAR(TestBernstein2, RunScalar) +FIT_TEST_BATCH(TestBernstein2, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestBernstein2, CompareBatchScalar) + +class TestBernstein5 : public PDFTest { +protected: + TestBernstein5() : PDFTest("Bernstein5") + { + auto x = std::make_unique("x", "x", -100, 50); + auto a1 = std::make_unique("a1", "a1", 0.8, 0.6, 1.2); + auto a2 = new RooRealVar("a2", "a2", 0.0, -1.0, 1.0); + auto a3 = new RooRealVar("a3", "a3", 0.09, 0.05, 0.4); + auto a4 = new RooRealVar("a4", "a4", 0.0, 0.2, 0.8); + auto a5 = std::make_unique("a5", "a5", 0.09, 0.05, 0.5); + a4->setConstant(true); + a3->setConstant(true); + a2->setConstant(true); + + _pdf = std::make_unique("bernstein5", "bernstein PDF 5 coefficients", *x, + RooArgSet(*a1, *a2, *a3, *a4, *a5)); + + _variables.addOwned(std::move(x)); + + //_variablesToPlot.add(*x); + + _parameters.addOwned(std::move(a1)); + _parameters.addOwned(std::move(a5)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestBernstein5, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestBernstein5, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestBernstein5, CompareFixedNormLog) +FIT_TEST_SCALAR(TestBernstein5, RunScalar) +FIT_TEST_BATCH(TestBernstein5, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestBernstein5, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testBifurGauss.cxx b/roofit/roofit/test/vectorisedPDFs/testBifurGauss.cxx new file mode 100644 index 0000000000000..fdbef9a1cc965 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testBifurGauss.cxx @@ -0,0 +1,50 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooBifurGauss.h" + +class TestBifurGauss : public PDFTest { +protected: + TestBifurGauss() : PDFTest("BifurGauss") + { + auto x = std::make_unique("x", "x", 300.0, 100.0, 800.0); + auto mean = std::make_unique("mean", "mean", 350.0, 250.0, 500.0); + mean->setConstant(); + auto sigmaL = std::make_unique("sigmaL", "sigmaL", 60.0, 50.0, 150.0); + auto sigmaR = std::make_unique("sigmaR", "sigmaR", 100.0, 50.0, 150.0); + _pdf = std::make_unique("bifurGauss1", "bifurGauss1", *x, *mean, *sigmaL, *sigmaR); + + // for (auto var : {x}) { + // _variablesToPlot.add(*var); + // } + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigmaL)); + _parameters.addOwned(std::move(sigmaR)); + + _toleranceParameter = 8.E-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestBifurGauss, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestBifurGauss, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestBifurGauss, CompareFixedNormLog) +FIT_TEST_SCALAR(TestBifurGauss, RunScalar) +FIT_TEST_BATCH(TestBifurGauss, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestBifurGauss, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testBreitWigner.cxx b/roofit/roofit/test/vectorisedPDFs/testBreitWigner.cxx new file mode 100644 index 0000000000000..2b0a01d18ebc8 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testBreitWigner.cxx @@ -0,0 +1,47 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooBreitWigner.h" + +class TestBreitWigner : public PDFTest { +protected: + TestBreitWigner() : PDFTest("BreitWigner") + { + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean", 1, -7, 7); + auto width = std::make_unique("a2", "a2", 1.8, 0.5, 2.5); + + _pdf = std::make_unique("breitWigner", "breitWigner PDF", *x, *mean, *width); + + // _variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(width)); + + _toleranceCompareLogs = 5.e-13; + _toleranceCorrelation = 0.007; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestBreitWigner, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestBreitWigner, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestBreitWigner, CompareFixedNormLog) +FIT_TEST_SCALAR(TestBreitWigner, RunScalar) +FIT_TEST_BATCH(TestBreitWigner, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestBreitWigner, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testBukin.cxx b/roofit/roofit/test/vectorisedPDFs/testBukin.cxx new file mode 100644 index 0000000000000..d4beced6deef7 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testBukin.cxx @@ -0,0 +1,61 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooBukinPdf.h" + +#include "RooNumIntConfig.h" + +class TestBukin : public PDFTest { +protected: + TestBukin() : PDFTest("Bukin") + { + auto x = std::make_unique("x", "x", 0.6, -15., 10.); + auto Xp = std::make_unique("Xp", "Xp", 0.5, -3., 5.); + auto sigp = std::make_unique("sigp", "sigp", 3., 1., 5.); + auto xi = new RooRealVar("xi", "xi", -0.2, -0.3, 0.3); + auto rho1 = new RooRealVar("rho1", "rho1", -0.1, -0.3, -0.05); + auto rho2 = new RooRealVar("rho2", "rho2", 0.15, 0.05, 0.25); + _pdf = std::make_unique("bukin", "bukin", *x, *Xp, *sigp, *xi, *rho1, *rho2); + xi->setConstant(true); + rho1->setConstant(true); + rho2->setConstant(true); + + _variables.addOwned(std::move(x)); + + // for (auto var : {x}) { + //_variablesToPlot.add(*var); + //} + + _parameters.addOwned(std::move(Xp)); + _parameters.addOwned(std::move(sigp)); + + _toleranceParameter = 3e-5; + _toleranceCompareBatches = 2.5e-14; + //_toleranceCompareLogs{2.E-14}; + + // make the integrator slightly more precise (1e-6 -> 1e-7) to reduce inaccuracy in fitting + RooAbsReal::defaultIntegratorConfig()->setEpsAbs(1e-7); + RooAbsReal::defaultIntegratorConfig()->setEpsRel(1e-7); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestBukin, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestBukin, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestBukin, CompareFixedNormLog) +FIT_TEST_SCALAR(TestBukin, RunScalar) +FIT_TEST_BATCH(TestBukin, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestBukin, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testCBShape.cxx b/roofit/roofit/test/vectorisedPDFs/testCBShape.cxx new file mode 100644 index 0000000000000..95c86465b2049 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testCBShape.cxx @@ -0,0 +1,53 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooCBShape.h" + +class TestCBShape : public PDFTest { +protected: + TestCBShape() : PDFTest("CBShape") + { + auto m = std::make_unique("m", "m", -10, 10); + auto m0 = std::make_unique("m0", "m0", 1, -7, 7); + auto sigma = std::make_unique("sigma", "sigma", 1, 0.5, 2.5); + auto alpha = std::make_unique("alpha", "alpha", 1, -3, 3); + auto n = std::make_unique("n", "n", 1, 0.5, 2.5); + + _pdf = std::make_unique("CBShape", "CBShape PDF", *m, *m0, *sigma, *alpha, *n); + + //_variablesToPlot.add(*m); + + _variables.addOwned(std::move(m)); + + _parameters.addOwned(std::move(m0)); + _parameters.addOwned(std::move(sigma)); + _parameters.addOwned(std::move(alpha)); + _parameters.addOwned(std::move(n)); + + // For i686: + _toleranceParameter = 1.E-5; + _toleranceCompareBatches = 1.5E-14; + _toleranceCorrelation = 1.5E-3; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestCBShape, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestCBShape, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestCBShape, CompareFixedNormLog) +FIT_TEST_SCALAR(TestCBShape, RunScalar) +FIT_TEST_BATCH(TestCBShape, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestCBShape, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testChebychev.cxx b/roofit/roofit/test/vectorisedPDFs/testChebychev.cxx new file mode 100644 index 0000000000000..e872c087f0492 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testChebychev.cxx @@ -0,0 +1,81 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooChebychev.h" + +class TestChebychev2 : public PDFTest { +protected: + TestChebychev2() : PDFTest("Chebychev2") + { + auto x = std::make_unique("x", "x", -10, 10); + auto a1 = std::make_unique("a1", "a1", 0.3, -0.5, 0.5); + auto a2 = std::make_unique("a2", "a2", -0.2, -0.5, 0.5); + + _pdf = std::make_unique("chebychev2", "chebychev PDF 2 coefficients", *x, RooArgSet(*a1, *a2)); + + //_variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(a1)); + _parameters.addOwned(std::move(a2)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestChebychev2, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestChebychev2, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestChebychev2, CompareFixedNormLog) +FIT_TEST_SCALAR(TestChebychev2, DISABLED_RunScalar) +FIT_TEST_BATCH(TestChebychev2, DISABLED_RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestChebychev2, CompareBatchScalar) + +class TestChebychev5 : public PDFTest { +protected: + TestChebychev5() : PDFTest("Chebychev5") + { + auto x = std::make_unique("x", "x", -10, 10); + auto a1 = std::make_unique("a1", "a1", 0.15, -0.3, 0.3); + auto a2 = std::make_unique("a2", "a2", -0.15, -0.3, 0.3); + auto a3 = new RooRealVar("a3", "a3", 0.20, 0.10, 0.30); + auto a4 = std::make_unique("a4", "a4", 0.35, 0.3, 0.5); + auto a5 = std::make_unique("a5", "a5", -0.07, -0.2, 0.2); + a2->setConstant(true); + a3->setConstant(true); + + _pdf = std::make_unique("chebychev5", "chebychev PDF 5 coefficients", *x, + RooArgSet{*a1, *a2, *a3, *a4, *a5}); + + //_variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(a1)); + _parameters.addOwned(std::move(a2)); + _parameters.addOwned(std::move(a4)); + _parameters.addOwned(std::move(a5)); + + _toleranceParameter = 2e-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestChebychev5, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestChebychev5, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestChebychev5, CompareFixedNormLog) +FIT_TEST_SCALAR(TestChebychev5, RunScalar) +FIT_TEST_BATCH(TestChebychev5, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestChebychev5, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testChiSquarePdf.cxx b/roofit/roofit/test/vectorisedPDFs/testChiSquarePdf.cxx new file mode 100644 index 0000000000000..0f1b3c9dbc13b --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testChiSquarePdf.cxx @@ -0,0 +1,45 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooChiSquarePdf.h" + +class TestChiSquarePdfinX : public PDFTest { +protected: + TestChiSquarePdfinX() : PDFTest("ChiSquarePdf") + { + auto x = std::make_unique("x", "x", 0.1, 100); + auto ndof = std::make_unique("ndof", "ndof of chiSquarePdf", 2, 1, 5); + + // Build chiSquarePdf p.d.f + _pdf = std::make_unique("chiSquarePdf", "chiSquarePdf PDF", *x, *ndof); + + // _variablesToPlot.add(x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(ndof)); + + _toleranceCompareLogs = 5e-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestChiSquarePdfinX, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestChiSquarePdfinX, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestChiSquarePdfinX, CompareFixedNormLog) +FIT_TEST_SCALAR(TestChiSquarePdfinX, RunScalar) +FIT_TEST_BATCH(TestChiSquarePdfinX, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestChiSquarePdfinX, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testCompatMode.cxx b/roofit/roofit/test/vectorisedPDFs/testCompatMode.cxx new file mode 100644 index 0000000000000..b9136c9aa155e --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testCompatMode.cxx @@ -0,0 +1,254 @@ +// Author: Stephan Hageboeck, CERN 01 Jul 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooAbsReal.h" +#include "RooRealVar.h" +#include "RooPolynomial.h" +#include "TMath.h" +#include "RooRandom.h" +#include "RooFormulaVar.h" +#include + +using namespace std; + +class TestRooPolynomial : public PDFTest { +protected: + TestRooPolynomial() : PDFTest("Polynomial(...)") + { + auto x = std::make_unique("x", "x", 0, 10); + auto a1 = std::make_unique("a1", "First coefficient", 5, 0, 10); + auto a2 = std::make_unique("a2", "Second coefficient", 1, 0, 10); + auto a3 = std::make_unique("a3", "Third coefficient", "a1+a2", RooArgList(*a1, *a2)); + + _pdf = std::make_unique("pol", "Polynomial", *x, RooArgList(*a1, *a2, *a3)); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(a1)); + // _variablesToPlot.add(var); + + _parameters.addOwned(std::move(a2)); + + _otherObjects.addOwned(std::move(a3)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestRooPolynomial, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestRooPolynomial, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestRooPolynomial, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestRooPolynomial, RunScalar) +FIT_TEST_BATCH(TestRooPolynomial, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestRooPolynomial, CompareBatchScalar) + +class RooNonVecGaussian : public RooAbsPdf { +public: + RooNonVecGaussian() {}; + RooNonVecGaussian(const char *name, const char *title, RooAbsReal &_x, RooAbsReal &_mean, RooAbsReal &_sigma) + : RooAbsPdf(name, title), + x("x", "Observable", this, _x), + mean("mean", "Mean", this, _mean), + sigma("sigma", "Width", this, _sigma) + { + } + virtual TObject *clone(const char *newname) const override { return new RooNonVecGaussian(*this, newname); } + RooNonVecGaussian(const RooNonVecGaussian &other, const char *name) + : RooAbsPdf(other, name), x("x", this, other.x), mean("mean", this, other.mean), sigma("sigma", this, other.sigma) + { + } + + virtual ~RooNonVecGaussian() = default; + + Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *) const override + { + if (matchArgs(allVars, analVars, x)) + return 1; + if (matchArgs(allVars, analVars, mean)) + return 2; + return 0; + } + + Double_t analyticalIntegral(Int_t code, const char *rangeName = 0) const override + { + assert(code == 1 || code == 2); + + // The normalisation constant 1./sqrt(2*pi*sigma^2) is left out in evaluate(). + // Therefore, the integral is scaled up by that amount to make RooFit normalise + // correctly. + const double resultScale = sqrt(TMath::TwoPi()) * sigma; + + // Here everything is scaled and shifted into a standard normal distribution: + const double xscale = TMath::Sqrt2() * sigma; + double max = 0.; + double min = 0.; + if (code == 1) { + max = (x.max(rangeName) - mean) / xscale; + min = (x.min(rangeName) - mean) / xscale; + } else { // No == 2 test because of assert + max = (mean.max(rangeName) - x) / xscale; + min = (mean.min(rangeName) - x) / xscale; + } + + // Here we go for maximum precision: We compute all integrals in the UPPER + // tail of the Gaussian, because erfc has the highest precision there. + // Therefore, the different cases for range limits in the negative hemisphere are mapped onto + // the equivalent points in the upper hemisphere using erfc(-x) = 2. - erfc(x) + const double ecmin = std::erfc(std::abs(min)); + const double ecmax = std::erfc(std::abs(max)); + + const double result = resultScale * 0.5 * + (min * max < 0.0 ? 2.0 - (ecmin + ecmax) + : max <= 0. ? ecmax - ecmin + : ecmin - ecmax); + + return result != 0. ? result : 1.E-300; + } + + Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t) const override + { + if (matchArgs(directVars, generateVars, x)) + return 1; + if (matchArgs(directVars, generateVars, mean)) + return 2; + return 0; + } + + void generateEvent(Int_t code) override + { + assert(code == 1 || code == 2); + Double_t xgen; + if (code == 1) { + while (1) { + xgen = RooRandom::randomGenerator()->Gaus(mean, sigma); + if (xgen < x.max() && xgen > x.min()) { + x = xgen; + break; + } + } + } else if (code == 2) { + while (1) { + xgen = RooRandom::randomGenerator()->Gaus(x, sigma); + if (xgen < mean.max() && xgen > mean.min()) { + mean = xgen; + break; + } + } + } else { + cout << "error in RooNonVecGaussian generateEvent" << endl; + } + + return; + } + +protected: + RooRealProxy x; + RooRealProxy mean; + RooRealProxy sigma; + + Double_t evaluate() const override + { + const double arg = x - mean; + const double sig = sigma; + return exp(-0.5 * arg * arg / (sig * sig)); + } +}; + +class TestNonVecGauss : public PDFTest { +protected: + TestNonVecGauss() : PDFTest("GaussNoBatches") + { + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 1, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + _toleranceCompareLogs = 2.5E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestNonVecGauss, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestNonVecGauss, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestNonVecGauss, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestNonVecGauss, RunScalar) +FIT_TEST_BATCH(TestNonVecGauss, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestNonVecGauss, CompareBatchScalar) + +class TestNonVecGaussWeighted : public PDFTestWeightedData { +protected: + TestNonVecGaussWeighted() : PDFTestWeightedData("GaussNoBatchesWithWeights", 50000) + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 2.3, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + _toleranceCompareLogs = 2.5E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestNonVecGaussWeighted, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestNonVecGaussWeighted, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestNonVecGaussWeighted, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestNonVecGaussWeighted, + DISABLED_RunScalar) // Would need SumW2 error matrix correction, but no done in macro +FIT_TEST_BATCH(TestNonVecGaussWeighted, DISABLED_RunBatch) // As above +FIT_TEST_BATCH_VS_SCALAR(TestNonVecGaussWeighted, CompareBatchScalar) + +class TestNonVecGaussInMeanAndX : public PDFTest { +protected: + TestNonVecGaussInMeanAndX() : PDFTest("GaussNoBatches(x, mean)") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 1, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(mean)); + // _variablesToPlot.add(var); + + _parameters.addOwned(std::move(sigma)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestNonVecGaussInMeanAndX, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestNonVecGaussInMeanAndX, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestNonVecGaussInMeanAndX, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestNonVecGaussInMeanAndX, RunScalar) +FIT_TEST_BATCH(TestNonVecGaussInMeanAndX, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestNonVecGaussInMeanAndX, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testDstD0BG.cxx b/roofit/roofit/test/vectorisedPDFs/testDstD0BG.cxx new file mode 100644 index 0000000000000..bdb1ce1dff38b --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testDstD0BG.cxx @@ -0,0 +1,46 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooDstD0BG.h" + +class TestDstD0BG : public PDFTest { +protected: + TestDstD0BG() : PDFTest("DstD0BG") + { + auto m = std::make_unique("m", "m", 2.0, 1.61, 3); + auto m0 = new RooRealVar("m0", "m0", 1.6); + auto C = std::make_unique("C", "C", 1, 0.1, 2); + auto A = new RooRealVar("A", "A", -1.2); + auto B = new RooRealVar("B", "B", 0.1); + + _pdf = std::make_unique("DstD0BG", "DstD0BG", *m, *m0, *C, *A, *B); + + _variables.addOwned(std::move(m)); + + _parameters.addOwned(std::move(C)); + + _toleranceCompareBatches = 3.E-14; + _toleranceCompareLogs = 3.E-10; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestDstD0BG, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestDstD0BG, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestDstD0BG, CompareFixedNormLog) +FIT_TEST_SCALAR(TestDstD0BG, RunScalar) +FIT_TEST_BATCH(TestDstD0BG, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestDstD0BG, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testExponential.cxx b/roofit/roofit/test/vectorisedPDFs/testExponential.cxx new file mode 100644 index 0000000000000..87438e884e9fb --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testExponential.cxx @@ -0,0 +1,51 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooGaussian.h" +#include "RooAddPdf.h" +#include "RooExponential.h" + +class TestExponential : public PDFTest { +protected: + TestExponential() : PDFTest("Exp(x, c1)") + { + // Beyond ~19, the VDT polynomials break down when c1 is very negative + auto x = std::make_unique("x", "x", 0.001, 18.); + auto c1 = std::make_unique("c1", "c1", -0.2, -50., -0.001); + _pdf = std::make_unique("expo1", "expo1", *x, *c1); + + _variables.addOwned(std::move(x)); + + // for (auto var : {x}) { + // _variablesToPlot.add(*var); + // } + + _parameters.addOwned(std::move(c1)); + + _toleranceCompareLogs = 3E-13; + // For i686, this needs to be a bit less strict: + _toleranceCompareBatches = 2.E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestExponential, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestExponential, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestExponential, CompareFixedValuesNormLog) +FIT_TEST_SCALAR(TestExponential, RunScalar) +FIT_TEST_BATCH(TestExponential, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestExponential, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testGamma.cxx b/roofit/roofit/test/vectorisedPDFs/testGamma.cxx new file mode 100644 index 0000000000000..e289edbeb3045 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testGamma.cxx @@ -0,0 +1,52 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooGamma.h" + +class TestGamma : public PDFTest { +protected: + TestGamma() : PDFTest("Gamma") + { + auto x = std::make_unique("x", "x", 5, 4, 10); + auto gamma = std::make_unique("gamma", "N+1", 6, 4, 8); + gamma->setConstant(); + auto beta = std::make_unique("beta", "beta", 1.5, 0.5, 10); + auto mu = std::make_unique("mu", "mu", 0.2, -1., 1.); + mu->setConstant(); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("Gamma", "Gamma PDF", *x, *gamma, *beta, *mu); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(gamma)); + _parameters.addOwned(std::move(beta)); + _parameters.addOwned(std::move(mu)); + + // _variablesToPlot.add(*x); + _toleranceCompareBatches = 1.2E-14; + _toleranceCompareLogs = 6.E-12; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGamma, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGamma, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGamma, CompareFixedNormLog) +FIT_TEST_SCALAR(TestGamma, RunScalar) +FIT_TEST_BATCH(TestGamma, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestGamma, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testGauss.cxx b/roofit/roofit/test/vectorisedPDFs/testGauss.cxx new file mode 100644 index 0000000000000..069b9353087b5 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testGauss.cxx @@ -0,0 +1,146 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooGaussian.h" +#include "RooFormulaVar.h" + +class TestGauss : public PDFTest { +protected: + TestGauss() : PDFTest("Gauss") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 1, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + // _variablesToPlot.add(x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + // Standard of 1.E-14 is slightly too strong. + _toleranceCompareBatches = 3.E-14; + _toleranceCompareLogs = 3.E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGauss, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGauss, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGauss, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestGauss, RunScalar) +FIT_TEST_BATCH(TestGauss, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestGauss, CompareBatchScalar) + +#if !defined(_MSC_VER) // TODO: make TestGaussWeighted work on Windows + +class TestGaussWeighted : public PDFTestWeightedData { +protected: + TestGaussWeighted() : PDFTestWeightedData("GaussWithWeights") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 1, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + _multiProcess = 4; + } +}; + +FIT_TEST_BATCH(TestGaussWeighted, + DISABLED_RunBatch) // Would need SumW2 or asymptotic error correction, but that's not in test macro. +FIT_TEST_BATCH_VS_SCALAR(TestGaussWeighted, CompareBatchScalar) + +#endif // !defined(_MSC_VER) + +class TestGaussInMeanAndX : public PDFTest { +protected: + TestGaussInMeanAndX() : PDFTest("Gauss(x, mean)") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -10, 10); + auto mean = std::make_unique("mean", "mean of gaussian", 1, -10, 10); + auto sigma = std::make_unique("sigma", "width of gaussian", 1, 0.1, 10); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + // _variablesToPlot.add(var); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(mean)); + + _parameters.addOwned(std::move(sigma)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGaussInMeanAndX, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGaussInMeanAndX, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGaussInMeanAndX, CompareFixedNormLog) + +FIT_TEST_BATCH(TestGaussInMeanAndX, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestGaussInMeanAndX, CompareBatchScalar) + +class TestGaussWithFormulaParameters : public PDFTest { +protected: + TestGaussWithFormulaParameters() : PDFTest("Gauss(x, mean)") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", 0, 30); + auto a1 = std::make_unique("a1", "First coefficient", 5, 0, 10); + auto a2 = std::make_unique("a2", "Second coefficient", 1, 0, 10); + auto mean = std::make_unique("mean", "mean", "a1+a2", RooArgList(*a1, *a2)); + auto sigma = std::make_unique("sigma", "sigma", "1.7*mean", RooArgList(*mean)); + + // Build gaussian p.d.f in terms of x,mean and sigma + _pdf = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + // _variablesToPlot.add(*var); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(a1)); + + _parameters.addOwned(std::move(a2)); + + _otherObjects.addOwned(std::move(mean)); + _otherObjects.addOwned(std::move(sigma)); + + _toleranceCompareBatches = 2.E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestGaussWithFormulaParameters, FixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestGaussWithFormulaParameters, FixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestGaussWithFormulaParameters, FixedValuesNormLog) + +FIT_TEST_SCALAR(TestGaussWithFormulaParameters, RunScalar) +FIT_TEST_BATCH(TestGaussWithFormulaParameters, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestGaussWithFormulaParameters, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testGaussBinned.cxx b/roofit/roofit/test/vectorisedPDFs/testGaussBinned.cxx new file mode 100644 index 0000000000000..26d02fc7a6c99 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testGaussBinned.cxx @@ -0,0 +1,141 @@ +// Author: Stephan Hageboeck, CERN 21 Jan 2020 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +class MyTimer { +public: + MyTimer(std::string &&name) + : m_name(name), m_startTime(clock()), m_endTime(0), m_steadyStart(std::chrono::steady_clock::now()), m_steadyEnd() + { + } + + clock_t diffTime() const { return clock() - m_startTime; } + + void interval() + { + m_endTime = clock(); + m_steadyEnd = std::chrono::steady_clock::now(); + } + + void print(std::ostream &str) + { + clock_t diff = m_endTime - m_startTime; + std::chrono::duration diffSteady = m_steadyEnd - m_steadyStart; + str << "\n" + << "Timer '" << m_name << "':\t" << double(diff) / CLOCKS_PER_SEC << "s (CPU) " << diffSteady.count() + << "s (wall)" << std::endl; + } + +private: + std::string m_name; + clock_t m_startTime; + clock_t m_endTime; + std::chrono::time_point m_steadyStart; + std::chrono::time_point m_steadyEnd; +}; + +std::ostream &operator<<(std::ostream &str, MyTimer &timer) +{ + timer.interval(); + timer.print(str); + return str; +} + +class GaussBinnedFit : public testing::TestWithParam { +public: + void SetUp() override { RooRandom::randomGenerator()->SetSeed(10); } + + RooRealVar x{"x", "x", 0, -10, 10}; + RooRealVar m{"m", "m", 1., -10., 10}; + RooRealVar s{"s", "s", 1.5, 0.01, 10}; + + RooGaussian gaus{"gaus", "gaus", x, m, s}; +}; + +TEST_P(GaussBinnedFit, BatchFit) +{ + + using namespace RooFit; + + x.setBins(50); + std::unique_ptr dataHist(gaus.generateBinned(x, 10000)); + + const auto evalBackend = GetParam(); + m.setVal(-1.); + s.setVal(3.); + MyTimer timer(evalBackend == EvalBackend::Value::Cpu ? "BatchBinned" : "ScalarBinned"); + gaus.fitTo(*dataHist, EvalBackend(evalBackend), PrintLevel(-1), Optimize(0)); + timer.interval(); + std::cout << timer << std::endl; + EXPECT_NEAR(m.getVal(), 1., m.getError()); + EXPECT_NEAR(s.getVal(), 1.5, s.getError()); +} + +/// Test binned fit with a lot of bins. Because of ROOT-3874, it unfortunately +/// has a biased sigma parameter. +TEST_P(GaussBinnedFit, BatchFitFineBinsBiased) +{ + using namespace RooFit; + x.setBins(1000); + s.setVal(4.); + std::unique_ptr dataHist(gaus.generateBinned(x, 20000)); + + const auto evalBackend = GetParam(); + m.setVal(-1.); + s.setVal(3.); + MyTimer timer(evalBackend == EvalBackend::Value::Cpu ? "BatchFineBinned" : "ScalarFineBinned"); + gaus.fitTo(*dataHist, EvalBackend(evalBackend), PrintLevel(-1)); + timer.interval(); + std::cout << timer << std::endl; + EXPECT_NEAR(m.getVal(), 1., m.getError()); + EXPECT_NEAR(s.getVal(), 3.95, s.getError()) + << "It is known that binned fits with strong curvatures are biased.\n" + << "If this fails, the bias was fixed. Enable the test below, and delete this one."; +} + +/// Enable instead of BatchFitFineBinsBiased once ROOT-3874 is fixed. +TEST_P(GaussBinnedFit, DISABLED_BatchFitFineBins) +{ + using namespace RooFit; + x.setBins(1000); + s.setVal(4.); + std::unique_ptr dataHist(gaus.generateBinned(x, 20000)); + + const auto evalBackend = GetParam(); + m.setVal(-1.); + s.setVal(3.); + MyTimer timer(evalBackend == EvalBackend::Value::Cpu ? "BatchFineBinned" : "ScalarFineBinned"); + gaus.fitTo(*dataHist, EvalBackend(evalBackend), PrintLevel(-1)); + timer.interval(); + std::cout << timer << std::endl; + EXPECT_NEAR(m.getVal(), 1., m.getError()); + EXPECT_NEAR(s.getVal(), 4., s.getError()); +} + +INSTANTIATE_TEST_SUITE_P(RunFits, GaussBinnedFit, + testing::Values(RooFit::EvalBackend::Value::Legacy, RooFit::EvalBackend::Value::Cpu)); + +// TODO Test a batch fit that uses categories once categories can be passed through the batch interface. diff --git a/roofit/roofit/test/vectorisedPDFs/testJohnson.cxx b/roofit/roofit/test/vectorisedPDFs/testJohnson.cxx new file mode 100644 index 0000000000000..1c33b1b99ee5f --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testJohnson.cxx @@ -0,0 +1,137 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooJohnson.h" +#include "RooAddition.h" +#include "RooFormulaVar.h" + +class TestJohnson : public PDFTest { +protected: + TestJohnson() : PDFTest("Johnson") + { + auto mass = std::make_unique("mass", "mass", 0., 0., 500.); + auto mu = std::make_unique("mu", "Location parameter of normal distribution", 300., 0., 500.); + auto lambda = std::make_unique("lambda", "Two sigma of normal distribution", 100., 10, 200.); + auto gamma = std::make_unique("gamma", "gamma", 0.5, -10., 10.); + auto delta = std::make_unique("delta", "delta", 2., 1., 10.); + // delta is highly correlated with lambda. This troubles the fit. + delta->setConstant(); + + _pdf = std::make_unique("johnson", "johnson", *mass, *mu, *lambda, *gamma, *delta, -1.E300); + + _variables.addOwned(std::move(mass)); + + // _variablesToPlot.add(*mass); + + _parameters.addOwned(std::move(mu)); + _parameters.addOwned(std::move(lambda)); + _parameters.addOwned(std::move(gamma)); + _parameters.addOwned(std::move(delta)); + + _toleranceCompareBatches = 6.E-12; + _toleranceCompareLogs = 6.E-12; + + // For i686 + _toleranceCorrelation = 5.E-4; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestJohnson, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestJohnson, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestJohnson, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestJohnson, FitScalar) +FIT_TEST_BATCH(TestJohnson, FitBatch) +FIT_TEST_BATCH_VS_SCALAR(TestJohnson, FitBatchVsScalar) + +class TestJohnsonInMassAndMu : public PDFTest { +protected: + TestJohnsonInMassAndMu() : PDFTest("Johnson in mass and mu") + { + auto mass = std::make_unique("mass", "mass", 0., -100., 500.); + auto mu = std::make_unique("mu", "Location parameter of normal distribution", 100., 90., 110.); + auto lambda = std::make_unique("lambda", "Two sigma of normal distribution", 20., 10., 30.); + auto gamma = std::make_unique("gamma", "gamma", -0.7, -2., 2.); + auto delta = std::make_unique("delta", "delta", 1.337, 0.9, 2.); + + _pdf = std::make_unique("johnson", "johnson", *mass, *mu, *lambda, *gamma, *delta); + + _variables.addOwned(std::move(mass)); + _variables.addOwned(std::move(mu)); + + // _variablesToPlot.add(*mass); + + _parameters.addOwned(std::move(lambda)); + _parameters.addOwned(std::move(gamma)); + _parameters.addOwned(std::move(delta)); + + _toleranceCompareBatches = 6.E-12; + _toleranceCompareLogs = 6.E-12; + // _printLevel = 2; + // _toleranceParameter = 5.E-5; + _toleranceCorrelation = 1.5E-3; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestJohnsonInMassAndMu, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestJohnsonInMassAndMu, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestJohnsonInMassAndMu, CompareFixedNormLog) + +// Is it clear that the fits can infer the value of lambda when generating in mu? +FIT_TEST_SCALAR(TestJohnsonInMassAndMu, DISABLED_FitScalar) +FIT_TEST_BATCH(TestJohnsonInMassAndMu, DISABLED_FitBatch) +FIT_TEST_BATCH_VS_SCALAR(TestJohnsonInMassAndMu, CompareBatchScalar) + +class TestJohnsonWithFormulaParameters : public PDFTest { +protected: + TestJohnsonWithFormulaParameters() : PDFTest("Johnson with formula") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto mass = std::make_unique("mass", "mass", 0., -500., 500.); + auto mu = std::make_unique("mu", "Location parameter of normal distribution", -50, -150., 200.); + auto lambda = std::make_unique("lambda", "Two sigma of normal distribution", 120., 10, 180.); + auto gamma = std::make_unique("gamma", "gamma", -1.8, -10., 10.); + auto delta = std::make_unique("delta", "delta", "1.337 + 0.1*gamma", RooArgList(*gamma)); + + _pdf = std::make_unique("johnson", "johnson", *mass, *mu, *lambda, *gamma, *delta, -1.E300); + + // _variablesToPlot.add(*mass); + + _variables.addOwned(std::move(mass)); + + _parameters.addOwned(std::move(mu)); + _parameters.addOwned(std::move(lambda)); + _parameters.addOwned(std::move(gamma)); + + _otherObjects.addOwned(std::move(delta)); + + _toleranceCompareBatches = 6.E-12; + _toleranceCompareLogs = 6.E-12; + _toleranceParameter = 3.E-5; + // For i686: + _toleranceCorrelation = 1.5E-3; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestJohnsonWithFormulaParameters, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestJohnsonWithFormulaParameters, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestJohnsonWithFormulaParameters, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestJohnsonWithFormulaParameters, RunScalar) +FIT_TEST_BATCH(TestJohnsonWithFormulaParameters, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestJohnsonWithFormulaParameters, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testLandau.cxx b/roofit/roofit/test/vectorisedPDFs/testLandau.cxx new file mode 100644 index 0000000000000..72949f18d98cb --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testLandau.cxx @@ -0,0 +1,82 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooLandau.h" + +#if !defined(_MSC_VER) // TODO: make TestGaussWeighted work on Windows + +class TestLandauEvil : public PDFTest { +protected: + TestLandauEvil() : PDFTest("Landau_evil") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -250, 3000); + auto mean = std::make_unique("mean", "mean of landau", 10, -100, 300); + auto sigma = std::make_unique("sigma", "width of landau", 100, 1, 300); + + // Build landau p.d.f in terms of x, mean and sigma + _pdf = std::make_unique("landau", "landau PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + + //_variablesToPlot.add(*x); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + _toleranceParameter = 8.E-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestLandauEvil, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestLandauEvil, CompareFixedValuesNorm) +// No testing of logs because landau can return 0. +FIT_TEST_SCALAR(TestLandauEvil, DISABLED_RunScalar) // numerical integral presumably inaccurate +FIT_TEST_BATCH(TestLandauEvil, DISABLED_RunBatch) // numerical integral presumably inaccurate +FIT_TEST_BATCH_VS_SCALAR(TestLandauEvil, CompareBatchScalar) + +#endif // !defined(_MSC_VER) + +class TestLandau : public PDFTest { +protected: + TestLandau() : PDFTest("Landau_convenient") + { + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + auto x = std::make_unique("x", "x", -3, 40); + auto mean = std::make_unique("mean", "mean of landau", 1, -5, 10); + auto sigma = std::make_unique("sigma", "width of landau", 3, 1, 6); + + // Build landau p.d.f in terms of x, mean and sigma + _pdf = std::make_unique("landau", "landau PDF", *x, *mean, *sigma); + + _variables.addOwned(std::move(x)); + + // _variablesToPlot.add(x); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + + _toleranceParameter = 8.E-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestLandau, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestLandau, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestLandau, CompareFixedNormLog) +FIT_TEST_SCALAR(TestLandau, DISABLED_RunScalar) // numerical integral presumably inaccurate +FIT_TEST_BATCH(TestLandau, DISABLED_RunBatch) // numerical integral presumably inaccurate +FIT_TEST_BATCH_VS_SCALAR(TestLandau, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testLegendre.cxx b/roofit/roofit/test/vectorisedPDFs/testLegendre.cxx new file mode 100644 index 0000000000000..883623ad90807 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testLegendre.cxx @@ -0,0 +1,44 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooLegendre.h" +#include "RooRealSumPdf.h" +#include "RooUniform.h" +class TestLegendre : public PDFTest { +protected: + TestLegendre() : PDFTest("Legendre") + { + auto x = std::make_unique("x", "x", 0.5, 0.1, 1.0); + auto coef = new RooRealVar("coef", "coef", 0.5, 0.3, 1.0); + auto coef2 = new RooRealVar("coef2", "coef2", 100, 80, 120); + + auto uniform = new RooUniform("uniform", "uniform", *x); + + auto legendre = new RooLegendre("Legendre", "Legendre PDF", *x, 3, 2, 2, 1); + _pdf = std::make_unique("Sum", "sum", RooArgList{*legendre, *uniform}, RooArgList{*coef, *coef2}, + true); + + _variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestLegendre, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestLegendre, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestLegendre, CompareFixedNormLog) diff --git a/roofit/roofit/test/vectorisedPDFs/testLognormal.cxx b/roofit/roofit/test/vectorisedPDFs/testLognormal.cxx new file mode 100644 index 0000000000000..742066795f275 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testLognormal.cxx @@ -0,0 +1,76 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooLognormal.h" + +class TestLognormal : public PDFTest { +protected: + TestLognormal() : PDFTest("Lognormal") + { + auto x = std::make_unique("x", "x", 1, 0.1, 10); + auto m0 = std::make_unique("m0", "m0", 5, 0.1, 10); + auto k = std::make_unique("k", "k", 0.6, 0.1, 0.9); + + _pdf = std::make_unique("Lognormal", "Lognormal PDF", *x, *m0, *k); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(m0)); + _parameters.addOwned(std::move(k)); + + // Standard of 1.E-14 is too strong. + _toleranceCompareBatches = 8.E-14; + _toleranceParameter = 2e-6; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestLognormal, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestLognormal, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestLognormal, CompareFixedNormLog) +FIT_TEST_SCALAR(TestLognormal, RunScalar) +FIT_TEST_BATCH(TestLognormal, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestLognormal, CompareBatchScalar) + +class TestLognormalInMeanAndX : public PDFTest { +protected: + TestLognormalInMeanAndX() : PDFTest("Lognormal(x, mean)") + { + auto x = std::make_unique("x", "x", 1, 0.1, 10); + auto m0 = std::make_unique("m0", "m0", 1, 0.1, 10); + auto k = std::make_unique("k", "k", 2, 1.1, 10); + + _pdf = std::make_unique("Lognormal", "Lognormal PDF", *x, *m0, *k); + + //_variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(m0)); + + _parameters.addOwned(std::move(k)); + + // Standard of 1.E-14 is slightly too strong. + _toleranceCompareBatches = 2.E-14; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestLognormalInMeanAndX, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestLognormalInMeanAndX, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestLognormalInMeanAndX, CompareFixedNormLog) +FIT_TEST_SCALAR(TestLognormalInMeanAndX, RunScalar) +FIT_TEST_BATCH(TestLognormalInMeanAndX, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestLognormalInMeanAndX, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testNestedPDFs.cxx b/roofit/roofit/test/vectorisedPDFs/testNestedPDFs.cxx new file mode 100644 index 0000000000000..b4ddef035e963 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testNestedPDFs.cxx @@ -0,0 +1,83 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooPoisson.h" +#include "RooGaussian.h" +#include "RooExponential.h" +#include "RooProduct.h" +#include "RooConstVar.h" +#include "RooRealSumPdf.h" +#include "RooAddPdf.h" + +class TestNestedPDFs : public PDFTest { +protected: + TestNestedPDFs() : PDFTest("Gauss + RooRealSumPdf(pol2)") + { + auto x = std::make_unique("x", "x", -5., 5.); + + // Implement a polynomial. Value ranges are chosen to keep it positive. + // Note that even though the parameters are constant for the fit, they are still + // varied within their ranges when testing the function at random parameter points. + auto a0 = std::make_unique("a0", "a0", 2., 3., 10.); + auto a1 = std::make_unique("a1", "a1", -2, -2.1, -1.9); + auto a2 = std::make_unique("a2", "a2", 1., 1., 5.); + a0->setConstant(true); + a1->setConstant(true); + auto xId = new RooProduct("xId", "x", RooArgList(*x)); + auto xSq = new RooProduct("xSq", "x^2", RooArgList(*x, *x)); + auto one = new RooConstVar("one", "one", 1.); + auto pol = std::make_unique("pol", "pol", RooArgList{*one, *xId, *xSq}, RooArgList{*a0, *a1, *a2}); + + auto mean = std::make_unique("mean", "mean of gaussian", 2., 0., 20.); + auto sigma = std::make_unique("sigma", "width of gaussian", 0.337, 0.1, 10); + sigma->setConstant(); + auto gauss = std::make_unique("gauss", "gaussian PDF", *x, *mean, *sigma); + + auto nGauss = std::make_unique("nGauss", "Fraction of Gauss component", 0.05, 0., 0.5); + _pdf = std::make_unique("SumGausPol", "Sum of a Gauss and a simple polynomial", + RooArgSet{*gauss, *pol}, RooArgSet{*nGauss}); + + // _variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(sigma)); + _parameters.addOwned(std::move(a0)); + _parameters.addOwned(std::move(a1)); + _parameters.addOwned(std::move(a2)); + _parameters.addOwned(std::move(nGauss)); + + _otherObjects.addOwned(std::move(gauss)); + _otherObjects.addOwned(std::move(pol)); + + // RooMsgService::instance().getStream(0).minLevel = RooFit::DEBUG; + + // _toleranceParameter = 1.E-4; + // _toleranceCorrelation = 1.E-3; + _toleranceCompareLogs = 2.E-12; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestNestedPDFs, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestNestedPDFs, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestNestedPDFs, CompareFixedNormLog) + +FIT_TEST_SCALAR(TestNestedPDFs, RunScalar) +FIT_TEST_BATCH(TestNestedPDFs, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestNestedPDFs, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testNovosibirsk.cxx b/roofit/roofit/test/vectorisedPDFs/testNovosibirsk.cxx new file mode 100644 index 0000000000000..27fbe06d17483 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testNovosibirsk.cxx @@ -0,0 +1,50 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooNovosibirsk.h" + +class TestNovosibirsk : public PDFTest { +protected: + TestNovosibirsk() : PDFTest("Novosibirsk") + { + auto x = std::make_unique("x", "x", 0, -5, 1.1); + auto peak = std::make_unique("peak", "peak", 0.5, 0, 1); + auto width = std::make_unique("width", "width", 1.1, 0.5, 3.); + auto tail = std::make_unique("tail", "tail", 1.0, 0.5, 1.1); + + _pdf = std::make_unique("Novosibirsk", "Novosibirsk", *x, *peak, *width, *tail); + + // for (auto var : {x}) { + // _variablesToPlot.add(*var); + // } + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(peak)); + _parameters.addOwned(std::move(width)); + _parameters.addOwned(std::move(tail)); + + _toleranceParameter = 1e-4; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestNovosibirsk, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestNovosibirsk, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestNovosibirsk, CompareFixedNormLog) +FIT_TEST_SCALAR(TestNovosibirsk, RunScalar) +FIT_TEST_BATCH(TestNovosibirsk, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestNovosibirsk, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testPoisson.cxx b/roofit/roofit/test/vectorisedPDFs/testPoisson.cxx new file mode 100644 index 0000000000000..938069ae3e8c5 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testPoisson.cxx @@ -0,0 +1,80 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooPoisson.h" + +class TestPoisson : public PDFTest { +protected: + TestPoisson() : PDFTest("Poisson") + { + auto x = std::make_unique("x", "x", -10, 100); + auto mean = std::make_unique("mean", "Mean of Poisson", 2., 0., 50); + _pdf = std::make_unique("Pois", "Poisson PDF", *x, *mean); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + } +}; + +FIT_TEST_BATCH(TestPoisson, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestPoisson, CompareBatchScalar) + +class TestPoissonOddMean : public PDFTest { +protected: + TestPoissonOddMean() : PDFTest("PoissonOddMean") + { + auto x = std::make_unique("x", "x", -10, 50); + auto mean = std::make_unique("mean", "Mean of Poisson", 7.5, 0., 50); + _pdf = std::make_unique("Pois", "Poisson PDF", *x, *mean); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + } +}; + +FIT_TEST_BATCH(TestPoissonOddMean, DISABLED_RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestPoissonOddMean, CompareBatchScalar) + +class TestPoissonOddMeanNoRounding : public PDFTest { +protected: + TestPoissonOddMeanNoRounding() : PDFTest("PoissonOddMeanNoRounding") + { + auto x = std::make_unique("x", "x", 0., 100); + auto mean = std::make_unique("mean", "Mean of Poisson", 7.8529298854862928, 0., 10); + _pdf = std::make_unique("Pois", "Poisson PDF", *x, *mean, true); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + + _toleranceParameter = 1.2E-5; + // For i686, this needs to be a bit less strict: + _toleranceCompareBatches = 1.5E-13; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestPoissonOddMeanNoRounding, CompareFixedValuesUnnorm); +COMPARE_FIXED_VALUES_NORM(TestPoissonOddMeanNoRounding, CompareFixedValuesNorm); +COMPARE_FIXED_VALUES_NORM_LOG(TestPoissonOddMeanNoRounding, CompareFixedValuesNormLog); + +// Fit tests have a small bias. Unclear why. +FIT_TEST_SCALAR(TestPoissonOddMeanNoRounding, DISABLED_RunScalar) +FIT_TEST_BATCH(TestPoissonOddMeanNoRounding, DISABLED_RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestPoissonOddMeanNoRounding, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testPolynomial.cxx b/roofit/roofit/test/vectorisedPDFs/testPolynomial.cxx new file mode 100644 index 0000000000000..ad18ad9499c98 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testPolynomial.cxx @@ -0,0 +1,83 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooPolynomial.h" + +class TestPolynomial2 : public PDFTest { +protected: + TestPolynomial2() : PDFTest("Polynomial2") + { + auto x = std::make_unique("x", "x", -10, 10); + auto a1 = std::make_unique("a1", "a1", 0.3, 0.01, 0.5); + auto a2 = std::make_unique("a2", "a2", 0.2, 0.01, 0.5); + + _pdf = std::make_unique("polynomial2", "polynomial PDF 2 coefficients", *x, RooArgSet{*a1, *a2}); + + //_variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(a1)); + _parameters.addOwned(std::move(a2)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestPolynomial2, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestPolynomial2, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestPolynomial2, CompareFixedNormLog) +FIT_TEST_SCALAR(TestPolynomial2, DISABLED_RunScalar) // Save time +FIT_TEST_BATCH(TestPolynomial2, DISABLED_RunBatch) // Save time +FIT_TEST_BATCH_VS_SCALAR(TestPolynomial2, CompareBatchScalar) + +class TestPolynomial5 : public PDFTest { +protected: + TestPolynomial5() : PDFTest("Polynomial5") + { + auto x = std::make_unique("x", "x", -150, 40); + auto a0 = new RooRealVar("a0", "a0", 1000.0); + auto a1 = new RooRealVar("a1", "a1", 1.0, 0.0, 3.0); + auto a2 = std::make_unique("a2", "a2", 10.0, 9.0, 12.0); + auto a3 = new RooRealVar("a3", "a3", 0.09, 0.05, 0.1); + auto a4 = std::make_unique("a4", "a4", 0.001, 0.0005, 0.002); + auto a5 = std::make_unique("a5", "a5", 0.0000009, 0.0000005, 0.000005); + a0->setConstant(true); + a1->setConstant(true); + a3->setConstant(true); + a4->setConstant(true); + + _pdf = std::make_unique("polynomial5", "polynomial PDF 5 coefficients", *x, + RooArgSet{*a0, *a1, *a2, *a3, *a4, *a5}, 0); + + // _variablesToPlot.add(*x); + // _printLevel = 2; + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(a2)); + _parameters.addOwned(std::move(a4)); + _parameters.addOwned(std::move(a5)); + + _toleranceParameter = 2.E-5; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestPolynomial5, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestPolynomial5, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestPolynomial5, CompareFixedNormLog) +FIT_TEST_SCALAR(TestPolynomial5, DISABLED_RunScalar) // Save time +FIT_TEST_BATCH(TestPolynomial5, DISABLED_RunBatch) // Save time +FIT_TEST_BATCH_VS_SCALAR(TestPolynomial5, CompareBatchScalar) diff --git a/roofit/roofit/test/vectorisedPDFs/testProductPdf.cxx b/roofit/roofit/test/vectorisedPDFs/testProductPdf.cxx new file mode 100644 index 0000000000000..8e7c03e433bc7 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testProductPdf.cxx @@ -0,0 +1,62 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" + +#include "RooProdPdf.h" +#include "RooGaussian.h" + +class TestProdPdf : public PDFTest { +protected: + TestProdPdf() : PDFTest("Gauss(x) * Gauss(y)") + { + auto x = std::make_unique("x", "x", 1, -7, 7); + auto m1 = std::make_unique("m1", "m1", -0.3, -5., 5.); + auto s1 = std::make_unique("s1", "s1", 1.5, 0.7, 5.); + auto y = std::make_unique("y", "y", 1, -5., 5.); + auto m2 = std::make_unique("m2", "m2", 0.4, -5., 5.); + auto s2 = std::make_unique("s2", "s2", 2., 0.7, 10.); + + // Make a 2D PDF + auto g1 = std::make_unique("gaus1", "gaus1", *x, *m1, *s1); + auto g2 = std::make_unique("gaus2", "gaus2", *y, *m2, *s2); + _pdf = std::make_unique("prod", "prod", RooArgSet(*g1, *g2)); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(y)); + + _parameters.addOwned(std::move(m1)); + _parameters.addOwned(std::move(s1)); + _parameters.addOwned(std::move(m2)); + _parameters.addOwned(std::move(s2)); + + _otherObjects.addOwned(std::move(g1)); + _otherObjects.addOwned(std::move(g2)); + + // _variablesToPlot.add(*x); + // _variablesToPlot.add(*y); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestProdPdf, CompareFixedValuesUnnorm) +COMPARE_FIXED_VALUES_NORM(TestProdPdf, CompareFixedValuesNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestProdPdf, CompareFixedValuesNormLog) + +FIT_TEST_SCALAR(TestProdPdf, FitScalar) +FIT_TEST_BATCH(TestProdPdf, FitBatch) + +FIT_TEST_BATCH_VS_SCALAR(TestProdPdf, FitBatchScalar) +FIT_TEST_BATCH_VS_SCALAR_CLONE_PDF(TestProdPdf, FitBatchScalarWithCloning) diff --git a/roofit/roofit/test/vectorisedPDFs/testVoigtian.cxx b/roofit/roofit/test/vectorisedPDFs/testVoigtian.cxx new file mode 100644 index 0000000000000..ca9335ca46b96 --- /dev/null +++ b/roofit/roofit/test/vectorisedPDFs/testVoigtian.cxx @@ -0,0 +1,78 @@ +// Author: Stephan Hageboeck, CERN 26 Apr 2019 + +/***************************************************************************** + * RooFit + * Authors: * + * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * + * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * + * * + * Copyright (c) 2000-2019, Regents of the University of California * + * and Stanford University. All rights reserved. * + * * + * Redistribution and use in source and binary forms, * + * with or without modification, are permitted according to the terms * + * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * + *****************************************************************************/ + +#include "VectorisedPDFTests.h" +#include "RooVoigtian.h" + +class TestVoigtian : public PDFTest { +protected: + TestVoigtian() : PDFTest("Voigtian") + { + auto x = std::make_unique("x", "x", 1, 0.1, 10); + auto mean = std::make_unique("mean", "mean", 1, 0.1, 10); + auto width = std::make_unique("width", "width", 0.8, 0.1, 0.9); + auto sigma = std::make_unique("sigma", "sigma", 0.7, 0.1, 0.9); + + _pdf = std::make_unique("Voigtian", "Voigtian PDF", *x, *mean, *width, *sigma); + + // _variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + + _parameters.addOwned(std::move(mean)); + _parameters.addOwned(std::move(width)); + _parameters.addOwned(std::move(sigma)); + + _toleranceParameter = 2.E-5; + _toleranceCorrelation = 4.E-4; + _toleranceCompareLogs = 5.E-12; + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestVoigtian, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestVoigtian, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestVoigtian, CompareFixedNormLog) +FIT_TEST_SCALAR(TestVoigtian, RunScalar) +FIT_TEST_BATCH(TestVoigtian, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestVoigtian, CompareBatchScalar) + +class TestVoigtianInXandMean : public PDFTest { +protected: + TestVoigtianInXandMean() : PDFTest("Voigtian(x,m)") + { + auto x = std::make_unique("x", "x", 1, 0.1, 10); + auto mean = std::make_unique("mean", "mean", 1, 0.1, 10); + auto width = std::make_unique("width", "width", 0.5, 0.1, 0.9); + auto sigma = std::make_unique("sigma", "sigma", 0.5, 0.1, 0.9); + + _pdf = std::make_unique("Voigtian", "Voigtian PDF", *x, *mean, *width, *sigma); + + //_variablesToPlot.add(*x); + + _variables.addOwned(std::move(x)); + _variables.addOwned(std::move(mean)); + + _parameters.addOwned(std::move(width)); + _parameters.addOwned(std::move(sigma)); + } +}; + +COMPARE_FIXED_VALUES_UNNORM(TestVoigtianInXandMean, CompareFixedUnnorm) +COMPARE_FIXED_VALUES_NORM(TestVoigtianInXandMean, CompareFixedNorm) +COMPARE_FIXED_VALUES_NORM_LOG(TestVoigtianInXandMean, CompareFixedNormLog) +FIT_TEST_SCALAR(TestVoigtianInXandMean, RunScalar) +FIT_TEST_BATCH(TestVoigtianInXandMean, RunBatch) +FIT_TEST_BATCH_VS_SCALAR(TestVoigtianInXandMean, CompareBatchScalar)