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)