From 2aa6d6708034b2413640fb201adab20289e616aa Mon Sep 17 00:00:00 2001 From: Ed Savage Date: Fri, 13 Mar 2026 10:10:40 +1300 Subject: [PATCH 1/5] [ML] Fix compiler warnings across the codebase Reduce Clang warnings from ~2500 to 86 (all remaining are -Wunsafe-buffer-usage which require a std::span migration). Compiler flag suppressions (clang.cmake): - -Wno-switch-default: conflicts with the more useful -Wswitch-enum - -Wno-nrvo: purely informational C++23 diagnostic - -Wno-missing-noreturn: remaining cases are lambdas where [[noreturn]] cannot be applied pre-C++23 Code fixes across 59 files: - Remove 37 unused const variables (dead code from state serialisation refactors) - Remove 2 unused functions and 2 unused-but-set variables - Fix 9 shadow warnings by renaming inner variables - Fix 8 implicit int-to-float conversions with static_cast - Fix 2 tautological-compare logic bugs where the condition !(p >= 0.0 || p <= 1.0) was always false - Remove 2 redundant default cases in exhaustive enum switches - Fix 1 pessimizing-move, 1 range-loop-bind-reference, 1 sign-compare, 1 shorten-64-to-32, 1 CTAD issue - Remove unnecessary virtual from method in final class - Add [[noreturn]] to named function throws() - Add missing newline at EOF Made-with: Cursor --- bin/pytorch_inference/Main.cc | 5 +- cmake/compiler/clang.cmake | 3 + include/maths/common/CBasicStatistics.h | 2 +- include/maths/common/CBootstrapClusterer.h | 9 +- include/model/CMetricModelFactory.h | 2 +- lib/api/CDataFrameAnalysisInstrumentation.cc | 3 - lib/api/CDetectionRulesJsonParser.cc | 1 - lib/api/CFieldDataCategorizer.cc | 6 +- lib/api/CForecastRunner.cc | 2 +- lib/api/CModelSizeStatsJsonWriter.cc | 1 - lib/api/CSingleFieldDataCategorizer.cc | 12 +- lib/api/unittest/CAnomalyJobTest.cc | 12 +- .../CDataFrameAnalyzerTrainingTest.cc | 2 +- .../unittest/CInferenceModelMetadataTest.cc | 2 +- lib/api/unittest/CTestAnomalyJob.cc | 2 +- lib/core/CJsonStateRestoreTraverser.cc | 3 - lib/core/CStateMachine.cc | 5 - lib/core/unittest/CConcurrencyTest.cc | 2 +- lib/maths/analytics/CBoostedTreeFactory.cc | 1 - lib/maths/analytics/CBoostedTreeLoss.cc | 1 - .../analytics/unittest/CDataFrameUtilsTest.cc | 3 +- lib/maths/common/CCategoricalTools.cc | 4 +- lib/maths/common/CGammaRateConjugate.cc | 1 - .../common/CLogNormalMeanPrecConjugate.cc | 1 - lib/maths/common/CModel.cc | 1 - lib/maths/common/CMultimodalPrior.cc | 2 - lib/maths/common/CMultinomialConjugate.cc | 2 - .../common/CMultivariateConstantPrior.cc | 2 - lib/maths/common/CNaturalBreaksClassifier.cc | 1 - lib/maths/common/CNormalMeanPrecConjugate.cc | 1 - lib/maths/common/COneOfNPrior.cc | 2 - lib/maths/common/CPoissonMeanConjugate.cc | 1 - lib/maths/common/CPriorStateSerialiser.cc | 2 - lib/maths/common/CStatisticalTests.cc | 1 - lib/maths/common/CXMeansOnline1d.cc | 2 - .../CMultivariateNormalConjugateTest.cc | 135 ------------------ lib/maths/common/unittest/CToolsTest.cc | 3 +- lib/maths/time_series/CAdaptiveBucketing.cc | 1 - lib/maths/time_series/CCalendarComponent.cc | 1 - .../CCalendarComponentAdaptiveBucketing.cc | 1 - lib/maths/time_series/CCalendarCyclicTest.cc | 4 +- .../time_series/CDecompositionComponent.cc | 2 - lib/maths/time_series/CSeasonalComponent.cc | 1 - .../CSeasonalComponentAdaptiveBucketing.cc | 1 - .../time_series/CTimeSeriesDecomposition.cc | 2 - .../CTimeSeriesDecompositionDetail.cc | 6 +- ...CTimeSeriesDecompositionStateSerialiser.cc | 1 - .../unittest/CCalendarCyclicTestTest.cc | 3 +- lib/model/CAnnotatedProbability.cc | 1 - lib/model/CDataGatherer.cc | 2 - lib/model/CDetectorEqualizer.cc | 8 +- lib/model/CEventRateModel.cc | 2 +- lib/model/CMetricBucketGatherer.cc | 1 - lib/model/CResourceMonitor.cc | 1 - lib/model/CSearchKey.cc | 3 - lib/model/FunctionTypes.cc | 1 - lib/model/unittest/CModelMemoryTest.cc | 2 - .../unittest/CTokenListDataCategorizerTest.cc | 4 +- lib/model/unittest/ModelTestHelpers.h | 4 +- 59 files changed, 56 insertions(+), 236 deletions(-) diff --git a/bin/pytorch_inference/Main.cc b/bin/pytorch_inference/Main.cc index 00adee1dfc..76177ccee4 100644 --- a/bin/pytorch_inference/Main.cc +++ b/bin/pytorch_inference/Main.cc @@ -48,7 +48,8 @@ const std::unordered_set FORBIDDEN_OPERATIONS = {"aten::from_f void verifySafeModel(const torch::jit::script::Module& module_) { try { const auto method = module_.get_method("forward"); - for (const auto graph = method.graph(); const auto& node : graph->nodes()) { + const auto& graph = method.graph(); + for (const auto* node : graph->nodes()) { if (const std::string opName = node->kind().toQualString(); FORBIDDEN_OPERATIONS.contains(opName)) { HANDLE_FATAL(<< "Loading the inference process failed because it contains forbidden operation: " @@ -282,7 +283,7 @@ int main(int argc, char** argv) { // allocations rather than per allocation. But macOS is not supported for // production, but just as a convenience for developers. So the most // important thing is that the threading works as intended on Linux. - at::set_num_threads(threadSettings.numThreadsPerAllocation()); + at::set_num_threads(static_cast(threadSettings.numThreadsPerAllocation())); // This is not used as we don't call at::launch anywhere. // Setting it to 1 to ensure there is no thread pool sitting around. diff --git a/cmake/compiler/clang.cmake b/cmake/compiler/clang.cmake index cc4042dbc7..7dd8adf360 100644 --- a/cmake/compiler/clang.cmake +++ b/cmake/compiler/clang.cmake @@ -32,6 +32,9 @@ list(APPEND ML_C_FLAGS "-Wno-padded" "-Wno-poison-system-directories" "-Wno-sign-conversion" + "-Wno-missing-noreturn" + "-Wno-nrvo" + "-Wno-switch-default" "-Wno-unknown-warning-option" "-Wno-unreachable-code" "-Wno-used-but-marked-unused" diff --git a/include/maths/common/CBasicStatistics.h b/include/maths/common/CBasicStatistics.h index 260c10e15d..5e89f41ecc 100644 --- a/include/maths/common/CBasicStatistics.h +++ b/include/maths/common/CBasicStatistics.h @@ -1420,7 +1420,7 @@ struct SCentralMomentsCustomAdd { static inline void add(const U& x, typename SCoordinate::Type n, CBasicStatistics::SSampleCentralMoments& moments) { - moments.add(x, n, 0); + moments.add(x, static_cast(n), 0); } }; } diff --git a/include/maths/common/CBootstrapClusterer.h b/include/maths/common/CBootstrapClusterer.h index 1577d2f783..6618cc5ad6 100644 --- a/include/maths/common/CBootstrapClusterer.h +++ b/include/maths/common/CBootstrapClusterer.h @@ -677,8 +677,6 @@ class CBootstrapClusterer { this->visit(next, graph, parities, state); double lowestCost = state.cost(); - double bestCut = state.s_Cut; - std::size_t bestA = state.s_A; TBoolVec best = parities; while (state.s_A + 1 < V) { @@ -725,8 +723,6 @@ class CBootstrapClusterer { double cutCost = state.cost(); if (cutCost < lowestCost) { lowestCost = cutCost; - bestCut = state.s_Cut; - bestA = state.s_A; best = parities; } } @@ -734,7 +730,10 @@ class CBootstrapClusterer { cost = lowestCost; parities.swap(best); - LOG_TRACE(<< "Best cut = " << bestCut << ", |A| = " << bestA << ", |B| = " << V - bestA + LOG_TRACE(<< "Best cut |A| = " + << static_cast(std::count(parities.begin(), parities.end(), true)) + << ", |B| = " + << V - static_cast(std::count(parities.begin(), parities.end(), true)) << ", cost = " << cost << ", threshold = " << threshold); return cost < threshold; diff --git a/include/model/CMetricModelFactory.h b/include/model/CMetricModelFactory.h index c14f7aca66..8cd4687bf8 100644 --- a/include/model/CMetricModelFactory.h +++ b/include/model/CMetricModelFactory.h @@ -135,7 +135,7 @@ class MODEL_EXPORT CMetricModelFactory final : public CModelFactory { void features(const TFeatureVec& features) override; //! Set the modeled bucket length. - virtual void bucketLength(core_t::TTime bucketLength); + void bucketLength(core_t::TTime bucketLength); //@} //! Get the minimum seasonal variance scale diff --git a/lib/api/CDataFrameAnalysisInstrumentation.cc b/lib/api/CDataFrameAnalysisInstrumentation.cc index 06725b33ca..717e478c77 100644 --- a/lib/api/CDataFrameAnalysisInstrumentation.cc +++ b/lib/api/CDataFrameAnalysisInstrumentation.cc @@ -56,14 +56,11 @@ const std::string MEMORY_TYPE_TAG{"analytics_memory_usage"}; const std::string OUTLIER_DETECTION_STATS{"outlier_detection_stats"}; const std::string PARAMETERS_TAG{"parameters"}; const std::string PEAK_MEMORY_USAGE_TAG{"peak_usage_bytes"}; -const std::string PROGRESS_TAG{"progress"}; const std::string REGRESSION_STATS_TAG{"regression_stats"}; -const std::string STEP_TAG{"step"}; const std::string TIMESTAMP_TAG{"timestamp"}; const std::string TIMING_ELAPSED_TIME_TAG{"elapsed_time"}; const std::string TIMING_ITERATION_TIME_TAG{"iteration_time"}; const std::string TIMING_STATS_TAG{"timing_stats"}; -const std::string TYPE_TAG{"type"}; const std::string VALIDATION_FOLD_TAG{"fold"}; const std::string VALIDATION_FOLD_VALUES_TAG{"fold_values"}; const std::string VALIDATION_LOSS_TAG{"validation_loss"}; diff --git a/lib/api/CDetectionRulesJsonParser.cc b/lib/api/CDetectionRulesJsonParser.cc index 3171c9e3b4..f2bb7797a3 100644 --- a/lib/api/CDetectionRulesJsonParser.cc +++ b/lib/api/CDetectionRulesJsonParser.cc @@ -22,7 +22,6 @@ namespace { const std::string ACTIONS("actions"); const std::string ACTUAL("actual"); const std::string APPLIES_TO("applies_to"); -const std::string CONDITION("condition"); const std::string CONDITIONS("conditions"); const std::string DIFF_FROM_TYPICAL("diff_from_typical"); const std::string EXCLUDE("exclude"); diff --git a/lib/api/CFieldDataCategorizer.cc b/lib/api/CFieldDataCategorizer.cc index 6badb81c48..77d8cc6e12 100644 --- a/lib/api/CFieldDataCategorizer.cc +++ b/lib/api/CFieldDataCategorizer.cc @@ -603,11 +603,11 @@ bool CFieldDataCategorizer::periodicPersistStateInBackground() { // Do NOT pass the captures by reference - they // MUST be copied for thread safety if (m_PersistenceManager->addPersistFunc([ - this, partitionFieldValues = std::move(partitionFieldValues), - dataCategorizerPersistFuncs = std::move(dataCategorizerPersistFuncs), + this, partitionFieldValuesInner = std::move(partitionFieldValues), + dataCategorizerPersistFuncsInner = std::move(dataCategorizerPersistFuncs), categorizerAllocationFailures = m_CategorizerAllocationFailures ](core::CDataAdder & persister) { - return this->doPersistState(partitionFieldValues, dataCategorizerPersistFuncs, + return this->doPersistState(partitionFieldValuesInner, dataCategorizerPersistFuncsInner, categorizerAllocationFailures, persister); }) == false) { LOG_ERROR(<< "Failed to add categorizer background persistence function"); diff --git a/lib/api/CForecastRunner.cc b/lib/api/CForecastRunner.cc index c6c4fcf465..ea639832fb 100644 --- a/lib/api/CForecastRunner.cc +++ b/lib/api/CForecastRunner.cc @@ -442,7 +442,7 @@ bool CForecastRunner::parseAndValidateForecastRequest(const std::string& control if (forecastJob.s_MaxForecastModelMemory != DEFAULT_MAX_FORECAST_MODEL_MEMORY && (forecastJob.s_MaxForecastModelMemory >= MAX_FORECAST_MODEL_PERSISTANCE_MEMORY || forecastJob.s_MaxForecastModelMemory >= - static_cast(jobBytesSizeLimit * 0.40))) { + static_cast(static_cast(jobBytesSizeLimit) * 0.40))) { errorFunction(forecastJob, ERROR_BAD_MODEL_MEMORY_LIMIT); return false; } diff --git a/lib/api/CModelSizeStatsJsonWriter.cc b/lib/api/CModelSizeStatsJsonWriter.cc index 68b5b80c88..1deb4deac4 100644 --- a/lib/api/CModelSizeStatsJsonWriter.cc +++ b/lib/api/CModelSizeStatsJsonWriter.cc @@ -25,7 +25,6 @@ const std::string JOB_ID{"job_id"}; const std::string MODEL_SIZE_STATS{"model_size_stats"}; const std::string MODEL_BYTES{"model_bytes"}; const std::string PEAK_MODEL_BYTES{"peak_model_bytes"}; -const std::string SYSTEM_MEMORY_BYTES{"system_memory_bytes"}; const std::string MAX_SYSTEM_MEMORY_BYTES{"max_system_memory_bytes"}; const std::string MODEL_BYTES_EXCEEDED{"model_bytes_exceeded"}; const std::string MODEL_BYTES_MEMORY_LIMIT{"model_bytes_memory_limit"}; diff --git a/lib/api/CSingleFieldDataCategorizer.cc b/lib/api/CSingleFieldDataCategorizer.cc index c993a8d78d..a54e2c232f 100644 --- a/lib/api/CSingleFieldDataCategorizer.cc +++ b/lib/api/CSingleFieldDataCategorizer.cc @@ -104,10 +104,10 @@ CSingleFieldDataCategorizer::makeForegroundPersistFunc() const { model::CDataCategorizer::TPersistFunc categorizerPersistFunc{ m_DataCategorizer->makeForegroundPersistFunc()}; - return [ categorizerPersistFunc = std::move(categorizerPersistFunc), + return [ categorizerPersistFuncInner = std::move(categorizerPersistFunc), this ](core::CStatePersistInserter & inserter) { CSingleFieldDataCategorizer::acceptPersistInserter( - categorizerPersistFunc, m_DataCategorizer->examplesCollector(), + categorizerPersistFuncInner, m_DataCategorizer->examplesCollector(), *m_CategoryIdMapper, inserter); }; } @@ -126,12 +126,12 @@ CSingleFieldDataCategorizer::makeBackgroundPersistFunc() const { // function must be able to operate in a different thread on a snapshot of // the data at the time it was created. return [ - categorizerPersistFunc = std::move(categorizerPersistFunc), - examplesCollector = std::move(examplesCollector), - categoryIdMapperClone = std::move(categoryIdMapperClone) + categorizerPersistFuncInner = std::move(categorizerPersistFunc), + examplesCollectorInner = std::move(examplesCollector), + categoryIdMapperCloneInner = std::move(categoryIdMapperClone) ](core::CStatePersistInserter & inserter) { CSingleFieldDataCategorizer::acceptPersistInserter( - categorizerPersistFunc, examplesCollector, *categoryIdMapperClone, inserter); + categorizerPersistFuncInner, examplesCollectorInner, *categoryIdMapperCloneInner, inserter); }; } diff --git a/lib/api/unittest/CAnomalyJobTest.cc b/lib/api/unittest/CAnomalyJobTest.cc index d5384327ef..d59e1af4e0 100644 --- a/lib/api/unittest/CAnomalyJobTest.cc +++ b/lib/api/unittest/CAnomalyJobTest.cc @@ -306,8 +306,8 @@ BOOST_AUTO_TEST_CASE(testOutputBucketResultsUntilGivenIncompleteInitialBucket) { "testfiles/testLogErrors.boost.log.ini")); // Start by creating a detector with non-trivial state - static const core_t::TTime BUCKET_SIZE{900}; - static const std::string JOB_ID{"pop_sum_bytes_by_status_over_clientip"}; + static const core_t::TTime testBucketSize{900}; + static const std::string testJobId{"pop_sum_bytes_by_status_over_clientip"}; // Open the input and output files std::ifstream inputStrm{inputFileName.c_str()}; @@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(testOutputBucketResultsUntilGivenIncompleteInitialBucket) { BOOST_TEST_REQUIRE(jobConfig.initFromFile(configFileName)); model::CAnomalyDetectorModelConfig modelConfig = - model::CAnomalyDetectorModelConfig::defaultConfig(BUCKET_SIZE, model_t::E_None, + model::CAnomalyDetectorModelConfig::defaultConfig(testBucketSize, model_t::E_None, "", 0, false); core::CJsonOutputStreamWrapper wrappedOutputStream{outputStrm}; @@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(testOutputBucketResultsUntilGivenIncompleteInitialBucket) { std::string origSnapshotId; std::size_t numOrigDocs{0}; - CTestAnomalyJob origJob{JOB_ID, + CTestAnomalyJob origJob{testJobId, limits, jobConfig, modelConfig, @@ -367,7 +367,7 @@ BOOST_AUTO_TEST_CASE(testOutputBucketResultsUntilGivenIncompleteInitialBucket) { std::size_t numRestoredDocs{0}; CTestAnomalyJob restoredJob{ - JOB_ID, + testJobId, limits, jobConfig, modelConfig, @@ -879,7 +879,7 @@ BOOST_AUTO_TEST_CASE(testConfigUpdate) { auto generateRandomAlpha = [](int strLen) { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dis(0, 25); + std::uniform_int_distribution dis(0, 25); std::string str; for (int i = 0; i < strLen; ++i) { diff --git a/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc b/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc index 1224055d75..07e84ca65e 100644 --- a/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc +++ b/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc @@ -2233,7 +2233,7 @@ BOOST_AUTO_TEST_CASE(testProgressMonitoringFromRestart) { analyzer.handleRecord(fieldNames, {"", "", "", "", "", "", "", "$"}); TStrVec persistedStates{ - splitOnNull(std::stringstream{std::move(persistenceStream->str())})}; + splitOnNull(std::stringstream{persistenceStream->str()})}; LOG_DEBUG(<< "# states = " << persistedStates.size()); diff --git a/lib/api/unittest/CInferenceModelMetadataTest.cc b/lib/api/unittest/CInferenceModelMetadataTest.cc index c0aa6ee652..d7bbddcf89 100644 --- a/lib/api/unittest/CInferenceModelMetadataTest.cc +++ b/lib/api/unittest/CInferenceModelMetadataTest.cc @@ -306,7 +306,7 @@ BOOST_AUTO_TEST_CASE(testDataSummarization) { // check correct number of rows up to a rounding error BOOST_REQUIRE_CLOSE_ABSOLUTE(static_cast(dataSummarizationNumRows), - numRows * summarizationFraction, 1.0); + static_cast(numRows) * summarizationFraction, 1.0); } BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/api/unittest/CTestAnomalyJob.cc b/lib/api/unittest/CTestAnomalyJob.cc index 5a3f678932..6e10bf0d7d 100644 --- a/lib/api/unittest/CTestAnomalyJob.cc +++ b/lib/api/unittest/CTestAnomalyJob.cc @@ -71,4 +71,4 @@ ml::api::CAnomalyJobConfig CTestAnomalyJob::makeJobConfig(const std::string& det ml::api::CAnomalyJobConfig jobConfig; jobConfig.analysisConfig().parseDetectorsConfig(obj); return jobConfig; -} \ No newline at end of file +} diff --git a/lib/core/CJsonStateRestoreTraverser.cc b/lib/core/CJsonStateRestoreTraverser.cc index c28ebfde68..333af1f56b 100644 --- a/lib/core/CJsonStateRestoreTraverser.cc +++ b/lib/core/CJsonStateRestoreTraverser.cc @@ -360,9 +360,6 @@ bool CJsonStateRestoreTraverser::start() { case SBoostJsonHandler::E_TokenStringPart: tokenTypeName = "string_part"; break; - default: - tokenTypeName = "unknown"; - break; } LOG_ERROR(<< "JSON state must be object at root. Found token type: " << tokenTypeName diff --git a/lib/core/CStateMachine.cc b/lib/core/CStateMachine.cc index 3d79b324d6..725c6b0285 100644 --- a/lib/core/CStateMachine.cc +++ b/lib/core/CStateMachine.cc @@ -31,11 +31,6 @@ namespace { //const std::string MACHINE_TAG("a"); No longer used const core::TPersistenceTag STATE_TAG("b", "state"); -// CStateMachine::SMachine -const std::string ALPHABET_TAG("a"); -const std::string STATES_TAG("b"); -const std::string TRANSITION_FUNCTION_TAG("c"); - std::size_t BAD_MACHINE = std::numeric_limits::max(); CFastMutex mutex; } diff --git a/lib/core/unittest/CConcurrencyTest.cc b/lib/core/unittest/CConcurrencyTest.cc index a6893f32fb..fcb9159192 100644 --- a/lib/core/unittest/CConcurrencyTest.cc +++ b/lib/core/unittest/CConcurrencyTest.cc @@ -30,7 +30,7 @@ namespace { using TIntVec = std::vector; using TIntVecVec = std::vector; -double throws() { +[[noreturn]] double throws() { throw std::runtime_error("don't run me"); }; diff --git a/lib/maths/analytics/CBoostedTreeFactory.cc b/lib/maths/analytics/CBoostedTreeFactory.cc index 65f0ef53b6..ca29d1111c 100644 --- a/lib/maths/analytics/CBoostedTreeFactory.cc +++ b/lib/maths/analytics/CBoostedTreeFactory.cc @@ -1903,7 +1903,6 @@ const std::string FACTORY_TAG{"factory"}; const std::string GAIN_PER_NODE_1ST_PERCENTILE_TAG{"gain_per_node_1st_percentile"}; const std::string GAIN_PER_NODE_50TH_PERCENTILE_TAG{"gain_per_node_50th_percentile"}; const std::string GAIN_PER_NODE_90TH_PERCENTILE_TAG{"gain_per_node_90th_percentile"}; -const std::string HYPERPARAMETERS_LOSSES_TAG{"hyperparameters_losses"}; const std::string INITIALIZATION_CHECKPOINT_TAG{"initialization_checkpoint"}; const std::string LOSS_GAP_TAG{"loss_gap"}; const std::string NUMBER_TREES_TAG{"number_trees"}; diff --git a/lib/maths/analytics/CBoostedTreeLoss.cc b/lib/maths/analytics/CBoostedTreeLoss.cc index e3a3835762..fe486d263b 100644 --- a/lib/maths/analytics/CBoostedTreeLoss.cc +++ b/lib/maths/analytics/CBoostedTreeLoss.cc @@ -57,7 +57,6 @@ const std::size_t HUBER_OPTIMIZATION_ITERATIONS{15}; const std::string NUMBER_CLASSES_TAG{"number_classes"}; const std::string OFFSET_TAG{"offset"}; const std::string DELTA_TAG{"delta"}; -const std::string NAME_TAG{"name"}; double logOneMinusLogistic(double logOdds) { // For large x logistic(x) = 1 - e^(-x) + O(e^(-2x)) diff --git a/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc b/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc index d2b036bc5a..8f838bb39f 100644 --- a/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc +++ b/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc @@ -846,7 +846,8 @@ BOOST_AUTO_TEST_CASE(testDistributionPreservingSamplingRowMasks) { BOOST_REQUIRE_EQUAL(actualCategoryCounts.size(), expectedCategoryCounts.size()); for (std::size_t i = 0; i < expectedCategoryCounts.size(); ++i) { - BOOST_REQUIRE_EQUAL(actualCategoryCounts[i], expectedCategoryCounts[i]); + BOOST_REQUIRE_EQUAL(actualCategoryCounts[i], + expectedCategoryCounts[static_cast(i)]); } } diff --git a/lib/maths/common/CCategoricalTools.cc b/lib/maths/common/CCategoricalTools.cc index f90d9c57ed..c59c7bfb74 100644 --- a/lib/maths/common/CCategoricalTools.cc +++ b/lib/maths/common/CCategoricalTools.cc @@ -41,7 +41,7 @@ logBinomialProbabilityFastLowerBound(std::size_t n, double p, std::size_t m, dou result = 0.0; - if (!(p >= 0.0 || p <= 1.0)) { + if (!(p >= 0.0 && p <= 1.0)) { LOG_ERROR(<< "Bad probability: " << p); return maths_t::E_FpFailed; } @@ -588,7 +588,7 @@ CCategoricalTools::logMultinomialProbability(const TDoubleVec& probabilities, double ni_ = static_cast(ni[i]); if (ni_ > 0.0) { double pi_ = probabilities[i]; - if (!(pi_ >= 0.0 || pi_ <= 1.0)) { + if (!(pi_ >= 0.0 && pi_ <= 1.0)) { LOG_ERROR(<< "Bad probability: " << pi_); return maths_t::E_FpFailed; } diff --git a/lib/maths/common/CGammaRateConjugate.cc b/lib/maths/common/CGammaRateConjugate.cc index f3a1045d6b..bc27ddf7bd 100644 --- a/lib/maths/common/CGammaRateConjugate.cc +++ b/lib/maths/common/CGammaRateConjugate.cc @@ -724,7 +724,6 @@ const core::TPersistenceTag DECAY_RATE_TAG("j", "decay_rate"); const std::string MEAN_TAG("mean"); const std::string STANDARD_DEVIATION_TAG("standard_deviation"); const std::string EMPTY_STRING; -const std::string UNKNOWN_VALUE_STRING(""); } CGammaRateConjugate::CGammaRateConjugate(maths_t::EDataType dataType, diff --git a/lib/maths/common/CLogNormalMeanPrecConjugate.cc b/lib/maths/common/CLogNormalMeanPrecConjugate.cc index e49a4cd931..980c424404 100644 --- a/lib/maths/common/CLogNormalMeanPrecConjugate.cc +++ b/lib/maths/common/CLogNormalMeanPrecConjugate.cc @@ -630,7 +630,6 @@ const core::TPersistenceTag NUMBER_SAMPLES_TAG("f", "number_samples"); const core::TPersistenceTag DECAY_RATE_TAG("i", "decay_rate"); const std::string MEAN_TAG("mean"); const std::string STANDARD_DEVIATION_TAG("standard_deviation"); -const std::string EMPTY_STRING; } CLogNormalMeanPrecConjugate::CLogNormalMeanPrecConjugate(maths_t::EDataType dataType, diff --git a/lib/maths/common/CModel.cc b/lib/maths/common/CModel.cc index 7c23b5b677..12107c3aa1 100644 --- a/lib/maths/common/CModel.cc +++ b/lib/maths/common/CModel.cc @@ -26,7 +26,6 @@ namespace maths { namespace common { namespace { -const std::string EMPTY_STRING; const double EFFECTIVE_COUNT[]{1.0, 0.8, 0.7, 0.65, 0.6, 0.57, 0.54, 0.52, 0.51}; diff --git a/lib/maths/common/CMultimodalPrior.cc b/lib/maths/common/CMultimodalPrior.cc index eb7d9968a9..86635cdc7d 100644 --- a/lib/maths/common/CMultimodalPrior.cc +++ b/lib/maths/common/CMultimodalPrior.cc @@ -131,8 +131,6 @@ const core::TPersistenceTag SEED_PRIOR_TAG("b", "seed_prior"); const core::TPersistenceTag MODE_TAG("c", "mode"); const core::TPersistenceTag NUMBER_SAMPLES_TAG("d", "number_samples"); const core::TPersistenceTag DECAY_RATE_TAG("g", "decay_rate"); - -const std::string EMPTY_STRING; } //////// CMultimodalPrior Implementation //////// diff --git a/lib/maths/common/CMultinomialConjugate.cc b/lib/maths/common/CMultinomialConjugate.cc index f2e96bafaf..fc4e3f4576 100644 --- a/lib/maths/common/CMultinomialConjugate.cc +++ b/lib/maths/common/CMultinomialConjugate.cc @@ -248,8 +248,6 @@ const core::TPersistenceTag CONCENTRATION_TAG("c", "concentration"); const core::TPersistenceTag TOTAL_CONCENTRATION_TAG("d", "total_concentration"); const core::TPersistenceTag NUMBER_SAMPLES_TAG("e", "number_samples"); const core::TPersistenceTag DECAY_RATE_TAG("h", "decay_rate"); - -const std::string EMPTY_STRING; } CMultinomialConjugate::CMultinomialConjugate() diff --git a/lib/maths/common/CMultivariateConstantPrior.cc b/lib/maths/common/CMultivariateConstantPrior.cc index 619483ae52..d55a530734 100644 --- a/lib/maths/common/CMultivariateConstantPrior.cc +++ b/lib/maths/common/CMultivariateConstantPrior.cc @@ -56,8 +56,6 @@ void setConstant(std::size_t dimension, TDouble10Vec value, TOptionalDouble10Vec // We use short field names to reduce the state size const std::string CONSTANT_TAG("a"); - -const std::string EMPTY_STRING; } CMultivariateConstantPrior::CMultivariateConstantPrior(std::size_t dimension, diff --git a/lib/maths/common/CNaturalBreaksClassifier.cc b/lib/maths/common/CNaturalBreaksClassifier.cc index 443cbc3de8..f07a3eac3c 100644 --- a/lib/maths/common/CNaturalBreaksClassifier.cc +++ b/lib/maths/common/CNaturalBreaksClassifier.cc @@ -40,7 +40,6 @@ const core::TPersistenceTag SPACE_TAG("a", "space"); const core::TPersistenceTag CATEGORY_TAG("b", "category"); const core::TPersistenceTag POINTS_TAG("c", "points"); const core::TPersistenceTag DECAY_RATE_TAG("d", "decay_rate"); -const std::string EMPTY_STRING; const double ALMOST_ONE = 0.99999; } diff --git a/lib/maths/common/CNormalMeanPrecConjugate.cc b/lib/maths/common/CNormalMeanPrecConjugate.cc index e3fedb4d51..7c81d1112d 100644 --- a/lib/maths/common/CNormalMeanPrecConjugate.cc +++ b/lib/maths/common/CNormalMeanPrecConjugate.cc @@ -450,7 +450,6 @@ const core::TPersistenceTag NUMBER_SAMPLES_TAG("e", "number_samples"); const core::TPersistenceTag DECAY_RATE_TAG("h", "decay_rate"); const std::string MEAN_TAG("mean"); const std::string STANDARD_DEVIATION_TAG("standard_deviation"); -const std::string EMPTY_STRING; } CNormalMeanPrecConjugate::CNormalMeanPrecConjugate(maths_t::EDataType dataType, diff --git a/lib/maths/common/COneOfNPrior.cc b/lib/maths/common/COneOfNPrior.cc index b71e4a45e0..0383eaa483 100644 --- a/lib/maths/common/COneOfNPrior.cc +++ b/lib/maths/common/COneOfNPrior.cc @@ -77,8 +77,6 @@ const std::string DECAY_RATE_OLD_TAG("e"); const core::TPersistenceTag WEIGHT_TAG("a", "weight"); const core::TPersistenceTag PRIOR_TAG("b", "prior"); -const std::string EMPTY_STRING; - //! Persist state for a models by passing information to \p inserter. void modelAcceptPersistInserter(const CModelWeight& weight, const CPrior& prior, diff --git a/lib/maths/common/CPoissonMeanConjugate.cc b/lib/maths/common/CPoissonMeanConjugate.cc index 5caac8ad69..8b140cde14 100644 --- a/lib/maths/common/CPoissonMeanConjugate.cc +++ b/lib/maths/common/CPoissonMeanConjugate.cc @@ -169,7 +169,6 @@ const core::TPersistenceTag OFFSET_TAG("d", "offset"); const core::TPersistenceTag DECAY_RATE_TAG("g", "decay_rate"); const std::string MEAN_TAG("mean"); const std::string STANDARD_DEVIATION_TAG("standard_deviation"); -const std::string EMPTY_STRING; } CPoissonMeanConjugate::CPoissonMeanConjugate(double offset, double shape, double rate, double decayRate /*= 0.0*/) diff --git a/lib/maths/common/CPriorStateSerialiser.cc b/lib/maths/common/CPriorStateSerialiser.cc index 1608131468..34e5af5efb 100644 --- a/lib/maths/common/CPriorStateSerialiser.cc +++ b/lib/maths/common/CPriorStateSerialiser.cc @@ -48,8 +48,6 @@ const core::TPersistenceTag POISSON_TAG("f", "poisson"); const core::TPersistenceTag MULTINOMIAL_TAG("g", "multimonial"); const core::TPersistenceTag CONSTANT_TAG("h", "constant"); -const std::string EMPTY_STRING; - //! Implements restore for std::shared_ptr. template void doRestore(std::shared_ptr& ptr, core::CStateRestoreTraverser& traverser) { diff --git a/lib/maths/common/CStatisticalTests.cc b/lib/maths/common/CStatisticalTests.cc index 60d2352dc2..60d12539c6 100644 --- a/lib/maths/common/CStatisticalTests.cc +++ b/lib/maths/common/CStatisticalTests.cc @@ -65,7 +65,6 @@ double significance(double lambda) { const std::string SIZE_TAG("a"); const std::string T_TAG("b"); const std::string F_TAG("c"); -const std::string EMPTY_STRING; } double CStatisticalTests::leftTailFTest(double v0, double v1, double df0, double df1) { diff --git a/lib/maths/common/CXMeansOnline1d.cc b/lib/maths/common/CXMeansOnline1d.cc index bbfadf8dd1..908251d318 100644 --- a/lib/maths/common/CXMeansOnline1d.cc +++ b/lib/maths/common/CXMeansOnline1d.cc @@ -634,8 +634,6 @@ const core::TPersistenceTag HISTORY_LENGTH_TAG("k", "history_length"); const core::TPersistenceTag INDEX_TAG("a", "index"); const core::TPersistenceTag STRUCTURE_TAG("b", "structure"); const core::TPersistenceTag PRIOR_TAG("c", "prior"); - -const std::string EMPTY_STRING; } CAvailableModeDistributions::CAvailableModeDistributions(int value) diff --git a/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc b/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc index 37444a2cd1..5254f375b4 100644 --- a/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc +++ b/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc @@ -83,141 +83,6 @@ void gaussianSamples(test::CRandomNumbers& rng, LOG_DEBUG(<< "# samples = " << samples.size()); } -void calibrationExperiment() { - using TVector10 = maths::common::CVectorNx1; - using TMatrix10 = maths::common::CSymmetricMatrixNxN; - - double means[] = {10.0, 10.0, 20.0, 20.0, 30.0, - 20.0, 10.0, 40.0, 30.0, 20.0}; - double covariances[] = { - 10.0, 9.0, 10.0, -5.0, 1.0, 6.0, -8.0, 9.0, 4.0, 20.0, 8.0, - 3.0, 1.0, 12.0, 12.0, -4.0, 2.0, 1.0, 1.0, 4.0, 4.0, 5.0, - 1.0, 3.0, 8.0, 10.0, 3.0, 10.0, 9.0, 9.0, 5.0, 19.0, 11.0, - 3.0, 9.0, 25.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 20.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; - TVector10 mean(means, means + std::size(means)); - TMatrix10 covariance(covariances, covariances + std::size(covariances)); - - test::CRandomNumbers rng; - TDoubleVecVec samples_; - rng.generateMultivariateNormalSamples(mean.toVector(), - covariance.toVectors(), - 2000, samples_); - - TDouble10Vec1Vec samples; - samples.reserve(samples.size() + samples_.size()); - for (std::size_t j = 0; j < samples_.size(); ++j) { - samples.push_back(TDouble10Vec(samples_[j].begin(), samples_[j].end())); - } - - maths::common::CMultivariateNormalConjugate<2> filters[] = { - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior(maths_t::E_ContinuousData), - maths::common::CMultivariateNormalConjugate<2>::nonInformativePrior( - maths_t::E_ContinuousData)}; - std::size_t indices[][2] = {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, - {0, 6}, {0, 7}, {0, 8}, {0, 9}}; - - for (std::size_t i = 0; i < 200; ++i) { - for (std::size_t j = 0; j < std::size(filters); ++j) { - TDouble10Vec1Vec sample(1, TDouble10Vec(2)); - sample[0][0] = samples[i][indices[j][0]]; - sample[0][1] = samples[i][indices[j][1]]; - filters[j].addSamples( - sample, maths_t::CUnitWeights::singleUnit(2)); - } - } - - TDoubleVecVec p(std::size(filters)); - TDoubleVec mp; - TDoubleVec ep; - for (std::size_t i = 200; i < 2000; ++i) { - double mpi = 1.0; - maths::common::CProbabilityOfExtremeSample epi; - for (std::size_t j = 0; j < std::size(filters); ++j) { - TDouble10Vec1Vec sample(1, TDouble10Vec(2)); - sample[0][0] = samples[i][indices[j][0]]; - sample[0][1] = samples[i][indices[j][1]]; - double lb, ub; - maths::common::CMultivariatePrior::TTail10Vec tail; - filters[j].probabilityOfLessLikelySamples( - maths_t::E_TwoSided, sample, - maths_t::CUnitWeights::singleUnit(2), lb, ub, tail); - p[j].push_back((lb + ub) / 2.0); - mpi = std::min(mpi, (lb + ub) / 2.0); - epi.add((lb + ub) / 2.0, 0.5); - } - mp.push_back(mpi); - double pi; - epi.calculate(pi); - ep.push_back(pi); - } - - for (std::size_t i = 0; i < p.size(); ++i) { - std::sort(p[i].begin(), p[i].end()); - } - std::sort(mp.begin(), mp.end()); - std::sort(ep.begin(), ep.end()); - - double test[] = {0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99}; - for (std::size_t i = 0; i < std::size(test); ++i) { - for (std::size_t j = 0; j < p.size(); ++j) { - LOG_DEBUG(<< j << ") " << test[i] << " " - << static_cast( - std::lower_bound(p[j].begin(), p[j].end(), test[i]) - - p[j].begin()) / - static_cast(p[j].size())); - } - LOG_DEBUG(<< "min " << test[i] << " " - << static_cast( - std::lower_bound(mp.begin(), mp.end(), test[i]) - mp.begin()) / - static_cast(mp.size())); - LOG_DEBUG(<< "corrected min " << test[i] << " " - << static_cast( - std::lower_bound(ep.begin(), ep.end(), test[i]) - ep.begin()) / - static_cast(ep.size())); - } -} - -void dataGenerator() { - const double means[][2] = {{10.0, 20.0}, {30.0, 25.0}, {50.0, 5.0}, {100.0, 50.0}}; - const double covariances[][3] = { - {3.0, 2.0, 2.0}, {6.0, -4.0, 5.0}, {4.0, 1.0, 3.0}, {20.0, -12.0, 12.0}}; - - double anomalies[][4] = {{7000.0, 0.0, 2.8, -2.8}, {7001.0, 0.0, 2.8, -2.8}, - {7002.0, 0.0, 2.8, -2.8}, {7003.0, 0.0, 2.8, -2.8}, - {8000.0, 3.0, 3.5, 4.9}, {8001.0, 3.0, 3.5, 4.9}, - {8002.0, 3.0, 3.5, 4.9}, {8003.0, 3.0, 3.5, 4.9}, - {8004.0, 3.0, 3.5, 4.9}, {8005.0, 3.0, 3.5, 4.9}}; - - test::CRandomNumbers rng; - - TDouble10Vec1Vec samples[4]; - for (std::size_t i = 0; i < std::size(means); ++i) { - gaussianSamples(rng, 10000, means[i], covariances[i], samples[i]); - } - for (std::size_t i = 0; i < std::size(anomalies); ++i) { - std::size_t j = static_cast(anomalies[i][1]); - std::size_t k = static_cast(anomalies[i][0]); - samples[j][k][0] += anomalies[i][2]; - samples[j][k][1] += anomalies[i][3]; - } - - std::ofstream f("four_2d_gaussian.csv"); - core_t::TTime time = 1451606400; - for (std::size_t i = 0; i < 10000; ++i, time += 30) { - for (std::size_t j = 0; j < std::size(samples); ++j) { - f << time << ",x" << 2 * j << "," << samples[j][i][0] << "\n"; - f << time << ",x" << 2 * j + 1 << "," << samples[j][i][1] << "\n"; - } - } -} } BOOST_AUTO_TEST_CASE(testMultipleUpdate) { diff --git a/lib/maths/common/unittest/CToolsTest.cc b/lib/maths/common/unittest/CToolsTest.cc index 12a648518a..5c721e4de7 100644 --- a/lib/maths/common/unittest/CToolsTest.cc +++ b/lib/maths/common/unittest/CToolsTest.cc @@ -1071,7 +1071,8 @@ BOOST_AUTO_TEST_CASE(testMixtureProbabilityOfLessLikelySample) { double pExpected = pTails; CTruncatedPdf pdf(mixture, std::exp(logFx)); for (double xi = a, l = 0, step = 0.5 * (b - a) / std::floor(b - a); - l < 2 * static_cast(b - a); xi += step, ++l) { + l < static_cast(2 * static_cast(b - a)); + xi += step, ++l) { double pi; maths::common::CIntegration::gaussLegendre( pdf, xi, xi + step, pi); diff --git a/lib/maths/time_series/CAdaptiveBucketing.cc b/lib/maths/time_series/CAdaptiveBucketing.cc index 06aac7561a..f892ec824c 100644 --- a/lib/maths/time_series/CAdaptiveBucketing.cc +++ b/lib/maths/time_series/CAdaptiveBucketing.cc @@ -129,7 +129,6 @@ const core::TPersistenceTag LAST_LARGE_ERROR_BUCKET_TAG{"h", "last_large_error_b const core::TPersistenceTag LAST_LARGE_ERROR_PERIOD_TAG{"i", "last_large_error_period"}; const core::TPersistenceTag LARGE_ERROR_COUNT_P_VALUES_TAG{"j", "large_error_counts_p_values"}; const core::TPersistenceTag MEAN_WEIGHT_TAG{"k", "mean weight"}; -const std::string EMPTY_STRING; const double SMOOTHING_FUNCTION[]{0.25, 0.5, 0.25}; const std::size_t WIDTH{std::size(SMOOTHING_FUNCTION) / 2}; diff --git a/lib/maths/time_series/CCalendarComponent.cc b/lib/maths/time_series/CCalendarComponent.cc index a6a317f786..1856f9801f 100644 --- a/lib/maths/time_series/CCalendarComponent.cc +++ b/lib/maths/time_series/CCalendarComponent.cc @@ -33,7 +33,6 @@ namespace { const core::TPersistenceTag DECOMPOSITION_COMPONENT_TAG{"a", "decomposition_component"}; const core::TPersistenceTag BUCKETING_TAG{"b", "bucketing"}; const core::TPersistenceTag LAST_INTERPOLATION_TAG{"c", "last_interpolation_time"}; -const std::string EMPTY_STRING; } CCalendarComponent::CCalendarComponent(const CCalendarFeature& feature, diff --git a/lib/maths/time_series/CCalendarComponentAdaptiveBucketing.cc b/lib/maths/time_series/CCalendarComponentAdaptiveBucketing.cc index e87c16c887..098cc6ceb7 100644 --- a/lib/maths/time_series/CCalendarComponentAdaptiveBucketing.cc +++ b/lib/maths/time_series/CCalendarComponentAdaptiveBucketing.cc @@ -37,7 +37,6 @@ const core::TPersistenceTag ADAPTIVE_BUCKETING_TAG{"a", "adaptive_bucketing"}; const core::TPersistenceTag FEATURE_TAG{"b", "feature"}; const core::TPersistenceTag VALUES_TAG{"c", "values"}; const core::TPersistenceTag TIME_ZONE_OFFSET_TAG{"d", "time_zone"}; -const std::string EMPTY_STRING; } CCalendarComponentAdaptiveBucketing::CCalendarComponentAdaptiveBucketing() diff --git a/lib/maths/time_series/CCalendarCyclicTest.cc b/lib/maths/time_series/CCalendarCyclicTest.cc index 215b396280..955b263167 100644 --- a/lib/maths/time_series/CCalendarCyclicTest.cc +++ b/lib/maths/time_series/CCalendarCyclicTest.cc @@ -415,7 +415,9 @@ double CCalendarCyclicTest::errorsPValue(double n, double nl, double nv) const { double CCalendarCyclicTest::sufficientCountToMeasureLargeErrors() const { // Cap the how long we'll wait identify large errors. - return std::min(static_cast(20 * core::constants::DAY) / m_BucketLength, 100.0); + return std::min(static_cast(20 * core::constants::DAY) / + static_cast(m_BucketLength), + 100.0); } double CCalendarCyclicTest::largeErrorPercentile() const { diff --git a/lib/maths/time_series/CDecompositionComponent.cc b/lib/maths/time_series/CDecompositionComponent.cc index a7587a7f01..11cf5da8f6 100644 --- a/lib/maths/time_series/CDecompositionComponent.cc +++ b/lib/maths/time_series/CDecompositionComponent.cc @@ -50,8 +50,6 @@ const core::TPersistenceTag ESTIMATED_TAG{"a", "estimated"}; const core::TPersistenceTag KNOTS_TAG{"b", "knots"}; const core::TPersistenceTag VALUES_TAG{"c", "values"}; const core::TPersistenceTag VARIANCES_TAG{"d", "variances"}; - -const std::string EMPTY_STRING; } CDecompositionComponent::CDecompositionComponent(std::size_t maxSize, diff --git a/lib/maths/time_series/CSeasonalComponent.cc b/lib/maths/time_series/CSeasonalComponent.cc index 4cfe20870f..1fd66a3f54 100644 --- a/lib/maths/time_series/CSeasonalComponent.cc +++ b/lib/maths/time_series/CSeasonalComponent.cc @@ -39,7 +39,6 @@ const core::TPersistenceTag LAST_INTERPOLATION_TAG{"d", "last_interpolation_time const core::TPersistenceTag TOTAL_SHIFT_TAG{"e", "total_shift"}; const core::TPersistenceTag CURRENT_MEAN_SHIFT_TAG{"f", "current_mean"}; const core::TPersistenceTag MAX_TIME_SHIFT_PER_PERIOD_TAG{"g", "max_time_shift_per_period"}; -const std::string EMPTY_STRING; } CSeasonalComponent::CSeasonalComponent(const CSeasonalTime& time, diff --git a/lib/maths/time_series/CSeasonalComponentAdaptiveBucketing.cc b/lib/maths/time_series/CSeasonalComponentAdaptiveBucketing.cc index 3ea8ea8f97..51b368f70d 100644 --- a/lib/maths/time_series/CSeasonalComponentAdaptiveBucketing.cc +++ b/lib/maths/time_series/CSeasonalComponentAdaptiveBucketing.cc @@ -74,7 +74,6 @@ const core::TPersistenceTag VARIANCE_6_3_TAG{"f", "variance"}; const core::TPersistenceTag FIRST_UPDATE_6_3_TAG{"g", "first_update"}; const core::TPersistenceTag LAST_UPDATE_6_3_TAG{"h", "last_update"}; -const std::string EMPTY_STRING; const core_t::TTime UNSET_TIME{0}; const double SUFFICIENT_INTERVAL_TO_ESTIMATE_SLOPE{2.5}; } diff --git a/lib/maths/time_series/CTimeSeriesDecomposition.cc b/lib/maths/time_series/CTimeSeriesDecomposition.cc index d772b3c37e..0701de7233 100644 --- a/lib/maths/time_series/CTimeSeriesDecomposition.cc +++ b/lib/maths/time_series/CTimeSeriesDecomposition.cc @@ -45,8 +45,6 @@ const core::TPersistenceTag SEASONALITY_TEST_7_11_TAG{"d", "seasonality_test"}; const core::TPersistenceTag CALENDAR_CYCLIC_TEST_7_11_TAG{"e", "calendar_cyclic_test"}; const core::TPersistenceTag COMPONENTS_7_11_TAG{"f", "components"}; const core::TPersistenceTag TIME_SHIFT_7_11_TAG{"g", "time_shift"}; - -const std::string EMPTY_STRING; } CTimeSeriesDecomposition::CTimeSeriesDecomposition(double decayRate, diff --git a/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc b/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc index f8a5f50344..dde65088d3 100644 --- a/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc +++ b/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc @@ -2101,10 +2101,12 @@ void CTimeSeriesDecompositionDetail::CComponents::addSeasonalComponents( LOG_TRACE(<< "remove mask = " << components.seasonalToRemoveMask()); LOG_TRACE(<< "Estimate size change = " - << m_Seasonal->estimateSizeChange(components, m_DecayRate, m_BucketLength)); + << m_Seasonal->estimateSizeChange(components, m_DecayRate, + static_cast(m_BucketLength))); if (memoryCircuitBreaker.areAllocationsAllowed() == false && - m_Seasonal->estimateSizeChange(components, m_DecayRate, m_BucketLength) > 0) { + m_Seasonal->estimateSizeChange(components, m_DecayRate, + static_cast(m_BucketLength)) > 0) { // In the hard_limit state, we do not change the state of components if // adding new components will consume more memory than removing old ones. LOG_TRACE(<< "Not adding new seasonal components because we are in the hard limit state"); diff --git a/lib/maths/time_series/CTimeSeriesDecompositionStateSerialiser.cc b/lib/maths/time_series/CTimeSeriesDecompositionStateSerialiser.cc index e60b10b266..564f6ab79c 100644 --- a/lib/maths/time_series/CTimeSeriesDecompositionStateSerialiser.cc +++ b/lib/maths/time_series/CTimeSeriesDecompositionStateSerialiser.cc @@ -36,7 +36,6 @@ namespace { // DO NOT change the existing tags if new sub-classes are added. const core::TPersistenceTag TIME_SERIES_DECOMPOSITION_TAG("a", "time_series_decomposition"); const core::TPersistenceTag TIME_SERIES_DECOMPOSITION_STUB_TAG("b", "time_series_decomposition_stub"); -const std::string EMPTY_STRING; //! Implements restore for std::shared_ptr. template diff --git a/lib/maths/time_series/unittest/CCalendarCyclicTestTest.cc b/lib/maths/time_series/unittest/CCalendarCyclicTestTest.cc index 3bf891cea1..00f1376dc7 100644 --- a/lib/maths/time_series/unittest/CCalendarCyclicTestTest.cc +++ b/lib/maths/time_series/unittest/CCalendarCyclicTestTest.cc @@ -527,7 +527,8 @@ BOOST_AUTO_TEST_CASE(testLongBuckets) { TDoubleVec error; for (core_t::TTime time = 0, i = 0; time <= end; time += DAY) { rng.generateNormalSamples(0.0, 9.0, 1, error); - if (time >= months[i] && time < months[i] + DAY && i < months.size() - 1) { + if (time >= months[i] && time < months[i] + DAY && + static_cast(i) < months.size() - 1) { error[0] += 20.0; ++i; } diff --git a/lib/model/CAnnotatedProbability.cc b/lib/model/CAnnotatedProbability.cc index 1fd1389854..69d6a48e8d 100644 --- a/lib/model/CAnnotatedProbability.cc +++ b/lib/model/CAnnotatedProbability.cc @@ -30,7 +30,6 @@ const std::string BASELINE_BUCKET_COUNT_TAG("h"); const std::string BASELINE_BUCKET_MEAN_TAG("i"); const std::string ATTRIBUTE_TAG("j"); const std::string FEATURE_TAG("k"); -const std::string DESCRIPTIVE_DATA_TAG("l"); const std::string ANOMALY_TYPE_TAG("m"); const std::string CORRELATED_ATTRIBUTE_TAG("n"); const std::string MULTI_BUCKET_IMPACT_TAG("o"); diff --git a/lib/model/CDataGatherer.cc b/lib/model/CDataGatherer.cc index 8699d508a7..15c41a8b44 100644 --- a/lib/model/CDataGatherer.cc +++ b/lib/model/CDataGatherer.cc @@ -46,8 +46,6 @@ const std::string DEFAULT_ATTRIBUTE_NAME("-"); const std::string PERSON("person"); const std::string ATTRIBUTE("attribute"); -const std::string EMPTY_STRING; - namespace detail { //! Make sure \p features only includes supported features, doesn't diff --git a/lib/model/CDetectorEqualizer.cc b/lib/model/CDetectorEqualizer.cc index cc382b7ca7..69105e5356 100644 --- a/lib/model/CDetectorEqualizer.cc +++ b/lib/model/CDetectorEqualizer.cc @@ -36,8 +36,8 @@ void CDetectorEqualizer::acceptPersistInserter(core::CStatePersistInserter& inse } for (const auto& sketch : m_Sketches) { inserter.insertValue(DETECTOR_TAG, sketch.first); - inserter.insertLevel(SKETCH_TAG, [& sketch = sketch.second](auto& inserter_) { - sketch.acceptPersistInserter(inserter_); + inserter.insertLevel(SKETCH_TAG, [& sketch = sketch.second](auto& subInserter) { + sketch.acceptPersistInserter(subInserter); }); } } @@ -54,8 +54,8 @@ bool CDetectorEqualizer::acceptRestoreTraverser(core::CStateRestoreTraverser& tr LOG_ABORT(<< "Expected the detector label first"); } m_Sketches.emplace_back(*detector, maths::common::CQuantileSketch{SKETCH_SIZE}); - if (traverser.traverseSubLevel([& sketch = m_Sketches.back().second](auto& traverser_) { - return sketch.acceptRestoreTraverser(traverser_); + if (traverser.traverseSubLevel([& sketch = m_Sketches.back().second](auto& subTraverser) { + return sketch.acceptRestoreTraverser(subTraverser); }) == false) { LOG_ERROR(<< "Failed to restore SKETCH_TAG, got " << traverser.value()); m_Sketches.pop_back(); diff --git a/lib/model/CEventRateModel.cc b/lib/model/CEventRateModel.cc index faa16f0e21..ee95c94e43 100644 --- a/lib/model/CEventRateModel.cc +++ b/lib/model/CEventRateModel.cc @@ -490,7 +490,7 @@ bool CEventRateModel::computeProbability(std::size_t pid, bool everSeenBefore = this->firstBucketTimes()[pid] != startTime; auto typicalConcentration = m_Probabilities.medianConcentration(); double actualConcentration; - if (m_ProbabilityPrior.concentration(pid, actualConcentration) && + if (m_ProbabilityPrior.concentration(static_cast(pid), actualConcentration) && typicalConcentration.has_value()) { anomalyScoreExplanation.s_ByFieldActualConcentration = actualConcentration; anomalyScoreExplanation.s_ByFieldTypicalConcentration = diff --git a/lib/model/CMetricBucketGatherer.cc b/lib/model/CMetricBucketGatherer.cc index 19cfb8ccb3..826d6d4372 100644 --- a/lib/model/CMetricBucketGatherer.cc +++ b/lib/model/CMetricBucketGatherer.cc @@ -108,7 +108,6 @@ const std::string MULTIVARIATE_MAX_TAG("k"); const std::string MEDIAN_TAG("l"); const std::string VARIANCE_TAG("m"); const std::string EMPTY_STRING; -const TDoubleVec EMPTY_DOUBLE_VEC; // Nested tags. const std::string ATTRIBUTE_TAG("a"); diff --git a/lib/model/CResourceMonitor.cc b/lib/model/CResourceMonitor.cc index ae175a719a..f08603b57b 100644 --- a/lib/model/CResourceMonitor.cc +++ b/lib/model/CResourceMonitor.cc @@ -415,7 +415,6 @@ std::size_t CResourceMonitor::applyMemoryStrategy(std::size_t usage) const { modifiedUsage = core::CProcessStats::maxResidentSetSize(); break; } - default: { LOG_WARN(<< "Unknown memory strategy"); } } return modifiedUsage; } diff --git a/lib/model/CSearchKey.cc b/lib/model/CSearchKey.cc index 3aacf9eec0..aa95bb773b 100644 --- a/lib/model/CSearchKey.cc +++ b/lib/model/CSearchKey.cc @@ -43,9 +43,6 @@ const std::string EXCLUDE_FREQUENT_TAG("g"); const std::string INFLUENCE_FIELD_NAME_TAG("h"); const std::string IDENTIFIER_TAG("i"); -// AggregateSearchKey -const std::string KEY_TAG("a"); - const std::string EMPTY_STRING; } diff --git a/lib/model/FunctionTypes.cc b/lib/model/FunctionTypes.cc index 78c6274d0c..6e8a4cd262 100644 --- a/lib/model/FunctionTypes.cc +++ b/lib/model/FunctionTypes.cc @@ -1060,7 +1060,6 @@ const TFeatureVec END(detail::POPULATION_SUM_VELOCITY_FEATURES)); const TFeatureVec EMPTY_FEATURES; -const TFunctionVec EMPTY_FUNCTIONS; #undef BEGIN #undef END diff --git a/lib/model/unittest/CModelMemoryTest.cc b/lib/model/unittest/CModelMemoryTest.cc index 87dca727ac..b7550b3560 100644 --- a/lib/model/unittest/CModelMemoryTest.cc +++ b/lib/model/unittest/CModelMemoryTest.cc @@ -67,8 +67,6 @@ void addArrival(CDataGatherer& gatherer, core_t::TTime time, const std::string& CResourceMonitor resourceMonitor; gatherer.addArrival(fieldValues, eventData, resourceMonitor); } - -const std::string EMPTY_STRING; } BOOST_AUTO_TEST_CASE(testOnlineEventRateModel) { diff --git a/lib/model/unittest/CTokenListDataCategorizerTest.cc b/lib/model/unittest/CTokenListDataCategorizerTest.cc index be4e82a83d..88f3b77133 100644 --- a/lib/model/unittest/CTokenListDataCategorizerTest.cc +++ b/lib/model/unittest/CTokenListDataCategorizerTest.cc @@ -524,8 +524,8 @@ BOOST_FIXTURE_TEST_CASE(testPersist, CTestFixture) { std::istringstream origJsonStrm("{\"topLevel\" : " + origJson.str() + "}"); ml::core::CJsonStateRestoreTraverser traverser{origJsonStrm}; BOOST_TEST_REQUIRE(traverser.traverseSubLevel( - [&restoredCategorizer](ml::core::CStateRestoreTraverser& traverser) { - return restoredCategorizer.acceptRestoreTraverser(traverser); + [&restoredCategorizer](ml::core::CStateRestoreTraverser& subTraverser) { + return restoredCategorizer.acceptRestoreTraverser(subTraverser); })); } diff --git a/lib/model/unittest/ModelTestHelpers.h b/lib/model/unittest/ModelTestHelpers.h index 69554cac30..7170fdf2d1 100644 --- a/lib/model/unittest/ModelTestHelpers.h +++ b/lib/model/unittest/ModelTestHelpers.h @@ -27,7 +27,7 @@ namespace model { const CSearchKey KEY; const std::string EMPTY_STRING; -static void testPersistence(const SModelParams& params, +[[maybe_unused]] static void testPersistence(const SModelParams& params, const CDataGatherer& origGatherer, model_t::EAnalysisCategory category) { // Test persistence. (We check for idempotency.) @@ -63,7 +63,7 @@ static void testPersistence(const SModelParams& params, BOOST_REQUIRE_EQUAL(origJson.str(), newJson.str()); } -static void testGathererAttributes(const CDataGatherer& gatherer, +[[maybe_unused]] static void testGathererAttributes(const CDataGatherer& gatherer, core_t::TTime startTime, core_t::TTime bucketLength) { From 1edba0af990ec5cee7878217fbe01a4a0a8040ec Mon Sep 17 00:00:00 2001 From: Ed Savage Date: Fri, 13 Mar 2026 14:04:29 +1300 Subject: [PATCH 2/5] [ML] Run clang-format on compiler warning fixes Made-with: Cursor --- include/maths/common/CBootstrapClusterer.h | 6 ++++-- lib/api/CSingleFieldDataCategorizer.cc | 8 +++++--- lib/api/unittest/CAnomalyJobTest.cc | 4 ++-- lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc | 3 +-- lib/maths/analytics/unittest/CDataFrameUtilsTest.cc | 2 +- .../common/unittest/CMultivariateNormalConjugateTest.cc | 1 - lib/maths/time_series/CTimeSeriesDecompositionDetail.cc | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/maths/common/CBootstrapClusterer.h b/include/maths/common/CBootstrapClusterer.h index 6618cc5ad6..727dbf13c4 100644 --- a/include/maths/common/CBootstrapClusterer.h +++ b/include/maths/common/CBootstrapClusterer.h @@ -731,9 +731,11 @@ class CBootstrapClusterer { parities.swap(best); LOG_TRACE(<< "Best cut |A| = " - << static_cast(std::count(parities.begin(), parities.end(), true)) + << static_cast( + std::count(parities.begin(), parities.end(), true)) << ", |B| = " - << V - static_cast(std::count(parities.begin(), parities.end(), true)) + << V - static_cast( + std::count(parities.begin(), parities.end(), true)) << ", cost = " << cost << ", threshold = " << threshold); return cost < threshold; diff --git a/lib/api/CSingleFieldDataCategorizer.cc b/lib/api/CSingleFieldDataCategorizer.cc index a54e2c232f..8dc854eb51 100644 --- a/lib/api/CSingleFieldDataCategorizer.cc +++ b/lib/api/CSingleFieldDataCategorizer.cc @@ -104,8 +104,9 @@ CSingleFieldDataCategorizer::makeForegroundPersistFunc() const { model::CDataCategorizer::TPersistFunc categorizerPersistFunc{ m_DataCategorizer->makeForegroundPersistFunc()}; - return [ categorizerPersistFuncInner = std::move(categorizerPersistFunc), - this ](core::CStatePersistInserter & inserter) { + return [ + categorizerPersistFuncInner = std::move(categorizerPersistFunc), this + ](core::CStatePersistInserter & inserter) { CSingleFieldDataCategorizer::acceptPersistInserter( categorizerPersistFuncInner, m_DataCategorizer->examplesCollector(), *m_CategoryIdMapper, inserter); @@ -131,7 +132,8 @@ CSingleFieldDataCategorizer::makeBackgroundPersistFunc() const { categoryIdMapperCloneInner = std::move(categoryIdMapperClone) ](core::CStatePersistInserter & inserter) { CSingleFieldDataCategorizer::acceptPersistInserter( - categorizerPersistFuncInner, examplesCollectorInner, *categoryIdMapperCloneInner, inserter); + categorizerPersistFuncInner, examplesCollectorInner, + *categoryIdMapperCloneInner, inserter); }; } diff --git a/lib/api/unittest/CAnomalyJobTest.cc b/lib/api/unittest/CAnomalyJobTest.cc index d59e1af4e0..7bfc25d3a9 100644 --- a/lib/api/unittest/CAnomalyJobTest.cc +++ b/lib/api/unittest/CAnomalyJobTest.cc @@ -321,8 +321,8 @@ BOOST_AUTO_TEST_CASE(testOutputBucketResultsUntilGivenIncompleteInitialBucket) { BOOST_TEST_REQUIRE(jobConfig.initFromFile(configFileName)); model::CAnomalyDetectorModelConfig modelConfig = - model::CAnomalyDetectorModelConfig::defaultConfig(testBucketSize, model_t::E_None, - "", 0, false); + model::CAnomalyDetectorModelConfig::defaultConfig( + testBucketSize, model_t::E_None, "", 0, false); core::CJsonOutputStreamWrapper wrappedOutputStream{outputStrm}; diff --git a/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc b/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc index 07e84ca65e..f3f48e57f5 100644 --- a/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc +++ b/lib/api/unittest/CDataFrameAnalyzerTrainingTest.cc @@ -2232,8 +2232,7 @@ BOOST_AUTO_TEST_CASE(testProgressMonitoringFromRestart) { TLossFunctionType::E_MseRegression, fieldNames, fieldValues, analyzer, 400); analyzer.handleRecord(fieldNames, {"", "", "", "", "", "", "", "$"}); - TStrVec persistedStates{ - splitOnNull(std::stringstream{persistenceStream->str()})}; + TStrVec persistedStates{splitOnNull(std::stringstream{persistenceStream->str()})}; LOG_DEBUG(<< "# states = " << persistedStates.size()); diff --git a/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc b/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc index 8f838bb39f..439ee31977 100644 --- a/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc +++ b/lib/maths/analytics/unittest/CDataFrameUtilsTest.cc @@ -847,7 +847,7 @@ BOOST_AUTO_TEST_CASE(testDistributionPreservingSamplingRowMasks) { BOOST_REQUIRE_EQUAL(actualCategoryCounts.size(), expectedCategoryCounts.size()); for (std::size_t i = 0; i < expectedCategoryCounts.size(); ++i) { BOOST_REQUIRE_EQUAL(actualCategoryCounts[i], - expectedCategoryCounts[static_cast(i)]); + expectedCategoryCounts[static_cast(i)]); } } diff --git a/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc b/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc index 5254f375b4..6f969d887d 100644 --- a/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc +++ b/lib/maths/common/unittest/CMultivariateNormalConjugateTest.cc @@ -82,7 +82,6 @@ void gaussianSamples(test::CRandomNumbers& rng, } LOG_DEBUG(<< "# samples = " << samples.size()); } - } BOOST_AUTO_TEST_CASE(testMultipleUpdate) { diff --git a/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc b/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc index dde65088d3..5f75725702 100644 --- a/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc +++ b/lib/maths/time_series/CTimeSeriesDecompositionDetail.cc @@ -2106,7 +2106,7 @@ void CTimeSeriesDecompositionDetail::CComponents::addSeasonalComponents( if (memoryCircuitBreaker.areAllocationsAllowed() == false && m_Seasonal->estimateSizeChange(components, m_DecayRate, - static_cast(m_BucketLength)) > 0) { + static_cast(m_BucketLength)) > 0) { // In the hard_limit state, we do not change the state of components if // adding new components will consume more memory than removing old ones. LOG_TRACE(<< "Not adding new seasonal components because we are in the hard limit state"); From 27e3df79f7aab1f5675f55a08ac04467744317a0 Mon Sep 17 00:00:00 2001 From: Ed Savage Date: Fri, 13 Mar 2026 14:38:00 +1300 Subject: [PATCH 3/5] [ML] Fix deprecated implicit this capture via [=] in C++20 Change [=] to [this, f] in CConcurrentWrapper to silence -Wdeprecated on GCC 13 and Clang. Made-with: Cursor --- include/core/CConcurrentWrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/core/CConcurrentWrapper.h b/include/core/CConcurrentWrapper.h index 610277f637..54ee254a45 100644 --- a/include/core/CConcurrentWrapper.h +++ b/include/core/CConcurrentWrapper.h @@ -58,7 +58,7 @@ class CConcurrentWrapper final : private CNonCopyable { //! The code inside of this lambda is guaranteed to be executed in an atomic fashion. template void operator()(F f) const { - m_Queue.push([=] { f(m_Resource); }); + m_Queue.push([this, f] { f(m_Resource); }); } //! Debug the memory used by this component. From 5e44996c84bc83465832b8e6aa543b6655aef300 Mon Sep 17 00:00:00 2001 From: Ed Savage Date: Fri, 13 Mar 2026 15:22:18 +1300 Subject: [PATCH 4/5] Formatting --- lib/model/unittest/ModelTestHelpers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/model/unittest/ModelTestHelpers.h b/lib/model/unittest/ModelTestHelpers.h index 7170fdf2d1..4155187c3a 100644 --- a/lib/model/unittest/ModelTestHelpers.h +++ b/lib/model/unittest/ModelTestHelpers.h @@ -28,8 +28,8 @@ const CSearchKey KEY; const std::string EMPTY_STRING; [[maybe_unused]] static void testPersistence(const SModelParams& params, - const CDataGatherer& origGatherer, - model_t::EAnalysisCategory category) { + const CDataGatherer& origGatherer, + model_t::EAnalysisCategory category) { // Test persistence. (We check for idempotency.) std::ostringstream origJson; core::CJsonStatePersistInserter::persist( @@ -64,8 +64,8 @@ const std::string EMPTY_STRING; } [[maybe_unused]] static void testGathererAttributes(const CDataGatherer& gatherer, - core_t::TTime startTime, - core_t::TTime bucketLength) { + core_t::TTime startTime, + core_t::TTime bucketLength) { BOOST_REQUIRE_EQUAL(1, gatherer.numberActivePeople()); BOOST_REQUIRE_EQUAL(1, gatherer.numberByFieldValues()); From fe09511ef4345f80d1132eb46f7b994ad134ce19 Mon Sep 17 00:00:00 2001 From: Ed Savage Date: Tue, 24 Mar 2026 15:11:51 +1300 Subject: [PATCH 5/5] [ML] Initialise tokenTypeName to "unknown" for future-proofing Address Copilot review: if a new enum value is added to SBoostJsonHandler, the switch won't cover it and the log message would contain an empty string. Initialising to "unknown" keeps the error log informative. Made-with: Cursor --- lib/core/CJsonStateRestoreTraverser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/CJsonStateRestoreTraverser.cc b/lib/core/CJsonStateRestoreTraverser.cc index 333af1f56b..2b62c4478f 100644 --- a/lib/core/CJsonStateRestoreTraverser.cc +++ b/lib/core/CJsonStateRestoreTraverser.cc @@ -319,7 +319,7 @@ bool CJsonStateRestoreTraverser::start() { } // Enhanced error logging with comprehensive debugging information - std::string tokenTypeName; + std::string tokenTypeName{"unknown"}; switch (m_Handler.s_Type) { case SBoostJsonHandler::E_TokenNull: tokenTypeName = "null";