From 54ed36496be0535fbed923eaa280d4f04cbd8e84 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 1 Jun 2026 06:10:14 +0200 Subject: [PATCH] [math] Drop R interface from stressGoFTest The `#ifdef ROOT_HAS_R` blocks in UnitTest3/4/5 used the R interface at runtime to overwrite the hardcoded expected A2 and Dn values with freshly computed ones. The hardcoded values already match what R produces on the same generated sample, so this added a build-time dependency on the R interface (and the `-DROOT_HAS_R` define) for no real benefit. Remove the runtime R calls, the `TRInterface.h` include and the private `R_ADTest` / `R_KSTest` helpers. Each hardcoded reference value now carries an inline `// R: ...` comment quoting the exact `ad.test` / `ks.test` call it was derived from, and the file header documents how to reproduce them by dumping the sample and running R on it. Also drop the now-unused `if(r)` block from the test CMakeLists, since no other test in this directory uses the R interface. This is done in proparation to removing the deprecated R interface. --- math/mathcore/test/CMakeLists.txt | 5 -- math/mathcore/test/stressGoFTest.cxx | 84 +++++++--------------------- 2 files changed, 20 insertions(+), 69 deletions(-) diff --git a/math/mathcore/test/CMakeLists.txt b/math/mathcore/test/CMakeLists.txt index 35800dd561f98..86af5e00b7c5f 100644 --- a/math/mathcore/test/CMakeLists.txt +++ b/math/mathcore/test/CMakeLists.txt @@ -45,11 +45,6 @@ if(mathmore) list(APPEND Libraries MathMore) endif() -if(r) - add_definitions(-DROOT_HAS_R) - list(APPEND Libraries RInterface) -endif() - #---Build and add all the defined test in the list--------------- foreach(file ${TestSource}) get_filename_component(testname ${file} NAME_WE) diff --git a/math/mathcore/test/stressGoFTest.cxx b/math/mathcore/test/stressGoFTest.cxx index 06fea0dedd4b0..3f14a7554b14a 100644 --- a/math/mathcore/test/stressGoFTest.cxx +++ b/math/mathcore/test/stressGoFTest.cxx @@ -12,17 +12,21 @@ #include "TRandom3.h" -#ifdef ROOT_HAS_R -#include "TRInterface.h" -#endif - #include #include -/*N.B.: The tests' expected values (expectedDn and expectedA2) were computed on Pcphsft54.cern.ch i386 GNU/Linux computer (slc4_ia32_gcc34) +/*N.B.: The tests' expected values (expectedDn and expectedA2) were computed on Pcphsft54.cern.ch i386 GNU/Linux + computer (slc4_ia32_gcc34) LM. (16/9/14) Expected values for AD2 test have been computed with R kSamples package + + For the 1-sample tests (UnitTest3, UnitTest4, UnitTest5) the expected A2 and Dn + values quoted next to each test were obtained by running the corresponding R + commands (base R's ks.test and the goftest package's ad.test) on the very same + sample that the C++ code generates. To regenerate them, dump `sample` to a text + file from the test and run the R commands quoted in the inline comments on + `x <- scan("sample.txt")`. */ struct GoFTStress { @@ -185,20 +189,16 @@ struct GoFTStress { Double_t A2 = goft.AndersonDarlingTest("t"); Double_t pvalueAD = goft.AndersonDarlingTest(); - Double_t expectedA2 = 1.09849; // value computed using R below -#ifdef ROOT_HAS_R - Double_t rA2 = R_ADTest(sample,"\"pnorm\", mean=300, sd=50"); - if (rA2 != -999) expectedA2 = rA2; -#endif + // R: library(goftest); ad.test(x, "pnorm", mean=300, sd=50)$statistic + Double_t expectedA2 = 1.09849; + Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD); Double_t Dn = goft.KolmogorovSmirnovTest("t"); Double_t pvalueKS = goft.KolmogorovSmirnovTest(); + // R: ks.test(x, "pnorm", mean=300, sd=50)$statistic Double_t expectedDn = 0.0328567; -#ifdef ROOT_HAS_R - expectedDn = R_KSTest(sample,"\"pnorm\", mean=300, sd=50"); -#endif result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS); return result; @@ -225,21 +225,17 @@ struct GoFTStress { Double_t A2 = goft.AndersonDarlingTest("t"); Double_t pvalueAD = goft(); - Double_t expectedA2 = 0.54466; // value computed using R below -#ifdef ROOT_HAS_R - Double_t rA2 = R_ADTest(sample,"\"pexp\", rate=1.54"); - if (rA2 != -999) expectedA2 = rA2; -#endif + // R: library(goftest); ad.test(x, "pexp", rate=1.54)$statistic + Double_t expectedA2 = 0.54466; + Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD); // Double_t Dn = goft->KolmogorovSmirnovTest("t"); Double_t Dn = goft(ROOT::Math::GoFTest::kKS, "t"); Double_t pvalueKS = goft.KolmogorovSmirnovTest(); + // R: ks.test(x, "pexp", rate=1.54)$statistic Double_t expectedDn = 0.021343; -#ifdef ROOT_HAS_R - expectedDn = R_KSTest(sample,"\"pexp\", rate=1.54"); -#endif result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS); return result; @@ -271,11 +267,8 @@ Int_t UnitTest5() { Double_t A2 = goft(ROOT::Math::GoFTest::kAD, "t"); Double_t pvalueAD = goft.AndersonDarlingTest(); + // R: library(goftest); ad.test(x, "plnorm", meanlog=5, sdlog=2)$statistic Double_t expectedA2 = 0.458346; -#ifdef ROOT_HAS_R - Double_t rA2 = R_ADTest(sample,"\"plnorm\", meanlog=5, sdlog=2"); - if (rA2 != -999) expectedA2 = rA2; -#endif Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD); @@ -283,10 +276,9 @@ Int_t UnitTest5() { // Double_t pvalueKS = goft->KolmogorovSmirnovTest(); Double_t pvalueKS = goft(ROOT::Math::GoFTest::kKS); + // R: ks.test(x, "plnorm", meanlog=5, sdlog=2)$statistic Double_t expectedDn = 0.0214143; -#ifdef ROOT_HAS_R - expectedDn = R_KSTest(sample,"\"plnorm\", meanlog=5, sdlog=2"); -#endif + result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS); return result; @@ -446,42 +438,6 @@ Int_t UnitTest5() { return EXIT_FAILURE; } } - - private: - - // function to test using R interface -#ifdef ROOT_HAS_R - ROOT::R::TRInterface &R = ROOT::R::TRInterface::Instance(); - double R_KSTest(const std::vector & sample, TString testDist) { - R["x"] = sample; - R << "result = ks.test(x," + testDist + ")"; - R << "pval = result$p.value"; - R << "stat = result$statistic"; - double pvalue = R["pval"]; - double tstat = R["stat"]; - if (GoFTStress::fgDebugLevel >= GoFTStress::kStandardDebug) { - std::cout << "R KS result : Dn = " << tstat << " pvalue = " << pvalue << std::endl; - } - return tstat; - } - double R_ADTest(const std::vector & sample, TString testDist) { - R << "ret = library(\"goftest\", logical.return = TRUE)"; - bool ok = R["ret"]; - if (!ok) { - return -999; - } - R["x"] = sample; - R << "result = ad.test(x," + testDist + ")"; - R << "pval = result$p.value"; - R << "stat = result$statistic"; - double pvalue = R["pval"]; - double tstat = R["stat"]; - if (GoFTStress::fgDebugLevel >= GoFTStress::kStandardDebug) { - std::cout << "R AD result : A2 = " << tstat << " pvalue = " << pvalue << std::endl; - } - return tstat; - } -#endif };