forked from root-project/root
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RF] Improve implementation of RooCurve::average()
When integrating the discretely-sampled RooCurves, the algorithm implemented in RooCurve::average() was unnecessarily complicated. The existing midpoints were only considered for the trapezoidal rule if they are away from the interval limits with an arbitrary tolerance, which seems like a premature optimization to me. In particular, the logic was not correct if all midpoints were close to the limits without this tolerance, resulting in issue root-project#9838. Instead of making that case work correctly by implementing more code branches, this commit suggests to simply don't do this tolerace check and use all available midpoints for the trapezoidal integration rule. A unit test with the reproducer from root-project#9838 is also implemented. Closes root-project#9838.
- Loading branch information
1 parent
c3f3ca2
commit a3c1ad0
Showing
3 changed files
with
62 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Project: RooFit | ||
* Authors: | ||
* Jonas Rembser, CERN 2024 | ||
* | ||
* Copyright (c) 2024, CERN | ||
* | ||
* 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 <RooCmdArg.h> | ||
#include <RooGenericPdf.h> | ||
#include <RooHelpers.h> | ||
#include <RooPlot.h> | ||
#include <RooRealVar.h> | ||
|
||
#include "gtest_wrapper.h" | ||
|
||
// Cross-check to make sure the integration works correctly even if there is | ||
// only one midpoint on the RooCurve. Covers GitHub issue #9838 (the reproducer | ||
// in that issue was translated to this test). | ||
TEST(RooPlot, Average) | ||
{ | ||
// Silence the info about numeric integration because we don't care about it | ||
RooHelpers::LocalChangeMsgLevel chmsglvl{RooFit::WARNING, 0u, RooFit::NumIntegration, true}; | ||
|
||
RooRealVar x("x", "x", 0, 50); | ||
RooGenericPdf func("func", "Test Function", "x", x); | ||
|
||
std::unique_ptr<RooPlot> xframe{x.frame()}; | ||
|
||
func.plotOn(xframe.get(), RooFit::Name("funcCurve")); | ||
|
||
RooCurve *funcCurve = xframe->getCurve("funcCurve"); | ||
|
||
const double tol = 1e-10; | ||
|
||
for (double i = 10; i < 11; i += 0.1) { | ||
double avg = funcCurve->average(i, i + 0.1); | ||
|
||
double xFirst = funcCurve->interpolate(i, tol); | ||
double xLast = funcCurve->interpolate(i + 0.1, tol); | ||
|
||
EXPECT_NEAR(avg, 0.5 * (xLast + xFirst), tol); | ||
} | ||
} |