From eb8f1b76031430a0d1fa64ddde187a434d7a0620 Mon Sep 17 00:00:00 2001 From: Tom Veasey Date: Fri, 6 Jul 2018 09:40:27 +0100 Subject: [PATCH] [ML] Decrease the memory used by distribution models (#146) --- docs/CHANGELOG.asciidoc | 1 + include/maths/CGammaRateConjugate.h | 8 +-- include/maths/CLogNormalMeanPrecConjugate.h | 10 +-- include/maths/CNaturalBreaksClassifier.h | 29 ++++---- include/maths/CNormalMeanPrecConjugate.h | 6 +- include/maths/CPoissonMeanConjugate.h | 6 +- include/maths/CXMeansOnline.h | 67 +++++++++---------- include/maths/CXMeansOnline1d.h | 27 ++++---- include/maths/MathsTypes.h | 18 ++++- lib/maths/CGammaRateConjugate.cc | 14 ++-- lib/maths/CLogNormalMeanPrecConjugate.cc | 19 +++--- lib/maths/CNaturalBreaksClassifier.cc | 4 +- lib/maths/CNormalMeanPrecConjugate.cc | 15 ++--- lib/maths/CPoissonMeanConjugate.cc | 12 ++-- lib/maths/CXMeansOnline1d.cc | 58 ++++++++-------- lib/maths/unittest/CMultimodalPriorTest.cc | 2 +- .../unittest/CNormalMeanPrecConjugateTest.cc | 4 +- lib/maths/unittest/COneOfNPriorTest.cc | 2 +- .../unittest/CPoissonMeanConjugateTest.cc | 2 +- lib/maths/unittest/CPriorTest.cc | 2 +- lib/maths/unittest/CXMeansOnline1dTest.cc | 4 +- lib/model/unittest/CMetricModelTest.cc | 2 +- 22 files changed, 160 insertions(+), 152 deletions(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 48b4cf9f3d..e0c5854c0c 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -26,6 +26,7 @@ Improve partition analysis memory usage ({pull}97[#97]) Reduce model memory by storing state for periodicity testing in a compressed format ({pull}100[#100]) Improve the accuracy of model memory control ({pull}122[#122]) Improve adaption of the modelling of cyclic components to very localised features ({pull}134[#134]) +Reduce the memory consumed by distribution models ({pull}146[#146]) Forecasting of Machine Learning job time series is now supported for large jobs by temporarily storing model state on disk ({pull}89[#89]) diff --git a/include/maths/CGammaRateConjugate.h b/include/maths/CGammaRateConjugate.h index 8f9125ec2b..2440afb941 100644 --- a/include/maths/CGammaRateConjugate.h +++ b/include/maths/CGammaRateConjugate.h @@ -371,10 +371,10 @@ class MATHS_EXPORT CGammaRateConjugate : public CPrior { //! We assume that the data are described by \f$X = Y - u\f$, where //! \f$u\f$ is a constant and \f$Y\f$ is gamma distributed. This allows //! us to model data with negative values greater than \f$-u\f$. - double m_Offset; + CFloatStorage m_Offset; //! The margin between the smallest value and the support left end. - double m_OffsetMargin; + CFloatStorage m_OffsetMargin; //! The maximum likelihood estimate of the shape parameter. double m_LikelihoodShape; @@ -386,10 +386,10 @@ class MATHS_EXPORT CGammaRateConjugate : public CPrior { TMeanVarAccumulator m_SampleMoments; //! The initial shape parameter of the prior gamma distribution. - double m_PriorShape; + CFloatStorage m_PriorShape; //! The initial rate parameter of the prior gamma distribution. - double m_PriorRate; + CFloatStorage m_PriorRate; }; } } diff --git a/include/maths/CLogNormalMeanPrecConjugate.h b/include/maths/CLogNormalMeanPrecConjugate.h index 68c0b8dda0..b276d3a66d 100644 --- a/include/maths/CLogNormalMeanPrecConjugate.h +++ b/include/maths/CLogNormalMeanPrecConjugate.h @@ -390,22 +390,22 @@ class MATHS_EXPORT CLogNormalMeanPrecConjugate : public CPrior { //! We assume that the data are described by \f$X = e^Y - u\f$, where //! \f$u\f$ is a constant and \f$Y\f$ is normally distributed. This //! allows us to model data with negative values greater than \f$-u\f$. - double m_Offset; + CFloatStorage m_Offset; //! The margin between the smallest value and the support left end. - double m_OffsetMargin; + CFloatStorage m_OffsetMargin; //! The mean of the prior conditional distribution for the mean of the //! exponentiated normal (conditioned on its precision). - double m_GaussianMean; + CFloatStorage m_GaussianMean; //! The precision of the prior conditional distribution for the mean //! of the exponentiated normal (conditioned on its precision). - double m_GaussianPrecision; + CFloatStorage m_GaussianPrecision; //! The shape of the marginal gamma distribution for the precision of the //! exponentiated normal. - double m_GammaShape; + CFloatStorage m_GammaShape; //! The rate of the marginal gamma distribution for the precision of the //! exponentiated normal. diff --git a/include/maths/CNaturalBreaksClassifier.h b/include/maths/CNaturalBreaksClassifier.h index 45454edc2f..758624f288 100644 --- a/include/maths/CNaturalBreaksClassifier.h +++ b/include/maths/CNaturalBreaksClassifier.h @@ -98,8 +98,8 @@ class MATHS_EXPORT CNaturalBreaksClassifier { public: using TSizeVec = std::vector; using TDoubleVec = std::vector; - using TDoubleDoublePr = std::pair; - using TDoubleDoublePrVec = std::vector; + using TFloatFloatPr = std::pair; + using TFloatFloatPrVec = std::vector; using TDoubleTuple = CBasicStatistics::SSampleMeanVar::TAccumulator; using TDoubleTupleVec = std::vector; using TTuple = CBasicStatistics::SSampleMeanVar::TAccumulator; @@ -270,16 +270,6 @@ class MATHS_EXPORT CNaturalBreaksClassifier { private: using TSizeSizePr = std::pair; -private: - //! Implementation called by naturalBreaks with explicit - //! tuple types. - template - static bool naturalBreaksImpl(const std::vector& categories, - std::size_t n, - std::size_t p, - EObjective target, - TSizeVec& result); - private: //! The minimum permitted size for the classifier. static const std::size_t MINIMUM_SPACE; @@ -295,6 +285,15 @@ class MATHS_EXPORT CNaturalBreaksClassifier { double minimumCategoryCount, TTupleVec& categories); + //! Implementation called by naturalBreaks with explicit + //! tuple types. + template + static bool naturalBreaksImpl(const std::vector& categories, + std::size_t n, + std::size_t p, + EObjective target, + TSizeVec& result); + //! Reduce the number of tuples until we satisfy the space constraint. void reduce(); @@ -323,16 +322,16 @@ class MATHS_EXPORT CNaturalBreaksClassifier { std::size_t m_Space; //! The rate at which the categories lose information. - double m_DecayRate; + CFloatStorage m_DecayRate; //! The minimum permitted count for a category. - double m_MinimumCategoryCount; + CFloatStorage m_MinimumCategoryCount; //! The categories we are maintaining. TTupleVec m_Categories; //! A buffer of the points added while the space constraint is satisfied. - TDoubleDoublePrVec m_PointsBuffer; + TFloatFloatPrVec m_PointsBuffer; }; } } diff --git a/include/maths/CNormalMeanPrecConjugate.h b/include/maths/CNormalMeanPrecConjugate.h index a7ee6e2aee..ff5ef71170 100644 --- a/include/maths/CNormalMeanPrecConjugate.h +++ b/include/maths/CNormalMeanPrecConjugate.h @@ -335,15 +335,15 @@ class MATHS_EXPORT CNormalMeanPrecConjugate : public CPrior { private: //! The mean of the prior conditional distribution for the mean of the //! normal variable (conditioned on its precision). - double m_GaussianMean; + CFloatStorage m_GaussianMean; //! The precision of the prior conditional distribution for the mean //! of the normal variable (conditioned on its precision). - double m_GaussianPrecision; + CFloatStorage m_GaussianPrecision; //! The shape of the marginal gamma distribution for the precision of the //! normal variable. - double m_GammaShape; + CFloatStorage m_GammaShape; //! The rate of the marginal gamma distribution for the precision of the //! normal variable. diff --git a/include/maths/CPoissonMeanConjugate.h b/include/maths/CPoissonMeanConjugate.h index 9667b72baa..4f7aa2b88a 100644 --- a/include/maths/CPoissonMeanConjugate.h +++ b/include/maths/CPoissonMeanConjugate.h @@ -287,14 +287,14 @@ class MATHS_EXPORT CPoissonMeanConjugate : public CPrior { //! We assume that the data are described by \f$X = Y - u\f$, where //! \f$u\f$ is a constant and \f$Y\f$ is Poisson distributed. This //! allows us to model data with negative values greater than \f$-u\f$. - double m_Offset; + CFloatStorage m_Offset; //! The shape parameter for the gamma distribution. - double m_Shape; + CFloatStorage m_Shape; //! The rate parameter for the gamma distribution. We work with the inverse //! scale parameter because it makes defining the non-informative prior easy. - double m_Rate; + CFloatStorage m_Rate; }; } } diff --git a/include/maths/CXMeansOnline.h b/include/maths/CXMeansOnline.h index c102a38e89..6ce85dadaa 100644 --- a/include/maths/CXMeansOnline.h +++ b/include/maths/CXMeansOnline.h @@ -588,8 +588,8 @@ class CXMeansOnline : public CClusterer> { const CClustererTypes::TSplitFunc& splitFunc = CClustererTypes::CDoNothing(), const CClustererTypes::TMergeFunc& mergeFunc = CClustererTypes::CDoNothing()) : CClusterer(splitFunc, mergeFunc), m_DataType(dataType), - m_InitialDecayRate(decayRate), m_DecayRate(decayRate), - m_HistoryLength(0.0), m_WeightCalc(weightCalc), + m_WeightCalc(weightCalc), m_InitialDecayRate(decayRate), + m_DecayRate(decayRate), m_HistoryLength(0.0), m_MinimumClusterFraction(minimumClusterFraction), m_MinimumClusterCount(minimumClusterCount), m_MinimumCategoryCount(minimumCategoryCount), @@ -598,10 +598,9 @@ class CXMeansOnline : public CClusterer> { //! Construct by traversing a state document. CXMeansOnline(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser) : CClusterer(CClustererTypes::CDoNothing(), CClustererTypes::CDoNothing()), - m_DataType(params.s_DataType), m_InitialDecayRate(params.s_DecayRate), - m_DecayRate(params.s_DecayRate), m_HistoryLength(), - m_WeightCalc(maths_t::E_ClustersEqualWeight), - m_MinimumClusterFraction(), m_MinimumClusterCount(), + m_DataType(params.s_DataType), m_WeightCalc(maths_t::E_ClustersEqualWeight), + m_InitialDecayRate(params.s_DecayRate), m_DecayRate(params.s_DecayRate), + m_HistoryLength(), m_MinimumClusterFraction(), m_MinimumClusterCount(), m_MinimumCategoryCount(params.s_MinimumCategoryCount) { traverser.traverseSubLevel(boost::bind(&CXMeansOnline::acceptRestoreTraverser, this, boost::cref(params), _1)); @@ -613,9 +612,9 @@ class CXMeansOnline : public CClusterer> { const CClustererTypes::TMergeFunc& mergeFunc, core::CStateRestoreTraverser& traverser) : CClusterer(splitFunc, mergeFunc), m_DataType(params.s_DataType), + m_WeightCalc(maths_t::E_ClustersEqualWeight), m_InitialDecayRate(params.s_DecayRate), m_DecayRate(params.s_DecayRate), - m_HistoryLength(), m_WeightCalc(maths_t::E_ClustersEqualWeight), - m_MinimumClusterFraction(), m_MinimumClusterCount(), + m_HistoryLength(), m_MinimumClusterFraction(), m_MinimumClusterCount(), m_MinimumCategoryCount(params.s_MinimumCategoryCount) { traverser.traverseSubLevel(boost::bind(&CXMeansOnline::acceptRestoreTraverser, this, boost::cref(params), _1)); @@ -623,17 +622,18 @@ class CXMeansOnline : public CClusterer> { //! The x-means clusterer has value semantics. CXMeansOnline(const CXMeansOnline& other) - : CClusterer(other.splitFunc(), other.mergeFunc()), - m_Rng(other.m_Rng), m_DataType(other.m_DataType), + : CClusterer(other.splitFunc(), other.mergeFunc()), m_Rng(other.m_Rng), + m_DataType(other.m_DataType), m_WeightCalc(other.m_WeightCalc), m_InitialDecayRate(other.m_InitialDecayRate), m_DecayRate(other.m_DecayRate), m_HistoryLength(other.m_HistoryLength), - m_WeightCalc(other.m_WeightCalc), m_MinimumClusterFraction(other.m_MinimumClusterFraction), m_MinimumClusterCount(other.m_MinimumClusterCount), m_MinimumCategoryCount(other.m_MinimumCategoryCount), m_ClusterIndexGenerator(other.m_ClusterIndexGenerator.deepCopy()), m_Clusters(other.m_Clusters) {} + ~CXMeansOnline() = default; + //! The x-means clusterer has value semantics. CXMeansOnline& operator=(const CXMeansOnline& other) { if (this != &other) { @@ -644,17 +644,15 @@ class CXMeansOnline : public CClusterer> { } //@} - virtual ~CXMeansOnline() {} - //! Efficiently swap the contents of two k-means objects. void swap(CXMeansOnline& other) { this->CClusterer::swap(other); std::swap(m_Rng, other.m_Rng); std::swap(m_DataType, other.m_DataType); + std::swap(m_WeightCalc, other.m_WeightCalc); std::swap(m_InitialDecayRate, other.m_InitialDecayRate); std::swap(m_DecayRate, other.m_DecayRate); std::swap(m_HistoryLength, other.m_HistoryLength); - std::swap(m_WeightCalc, other.m_WeightCalc); std::swap(m_MinimumClusterFraction, other.m_MinimumClusterFraction); std::swap(m_MinimumClusterCount, other.m_MinimumClusterCount); std::swap(m_MinimumCategoryCount, other.m_MinimumCategoryCount); @@ -675,13 +673,13 @@ class CXMeansOnline : public CClusterer> { inserter.insertLevel(CLUSTER_TAG, boost::bind(&CCluster::acceptPersistInserter, &cluster, _1)); } - inserter.insertValue(DECAY_RATE_TAG, m_DecayRate, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(HISTORY_LENGTH_TAG, m_HistoryLength, - core::CIEEE754::E_SinglePrecision); + inserter.insertValue(DECAY_RATE_TAG, m_DecayRate.toString()); + inserter.insertValue(HISTORY_LENGTH_TAG, m_HistoryLength.toString()); inserter.insertValue(RNG_TAG, m_Rng.toString()); inserter.insertValue(WEIGHT_CALC_TAG, static_cast(m_WeightCalc)); - inserter.insertValue(MINIMUM_CLUSTER_FRACTION_TAG, m_MinimumClusterFraction); - inserter.insertValue(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount); + inserter.insertValue(MINIMUM_CLUSTER_FRACTION_TAG, + m_MinimumClusterFraction.toString()); + inserter.insertValue(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount.toString()); inserter.insertLevel(CLUSTER_INDEX_GENERATOR_TAG, boost::bind(&CClustererTypes::CIndexGenerator::acceptPersistInserter, &m_ClusterIndexGenerator, _1)); @@ -999,18 +997,17 @@ class CXMeansOnline : public CClusterer> { RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(HISTORY_LENGTH_TAG, m_HistoryLength) + RESTORE(HISTORY_LENGTH_TAG, m_HistoryLength.fromString(traverser.value())) RESTORE(RNG_TAG, m_Rng.fromString(traverser.value())); RESTORE(CLUSTER_INDEX_GENERATOR_TAG, traverser.traverseSubLevel(boost::bind( &CClustererTypes::CIndexGenerator::acceptRestoreTraverser, &m_ClusterIndexGenerator, _1))) - RESTORE_SETUP_TEARDOWN( - WEIGHT_CALC_TAG, int weightCalc, - core::CStringUtils::stringToType(traverser.value(), weightCalc), - m_WeightCalc = static_cast(weightCalc)) - RESTORE_BUILT_IN(MINIMUM_CLUSTER_FRACTION_TAG, m_MinimumClusterFraction) - RESTORE_BUILT_IN(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount) + RESTORE_ENUM(WEIGHT_CALC_TAG, m_WeightCalc, maths_t::EClusterWeightCalc) + RESTORE(MINIMUM_CLUSTER_FRACTION_TAG, + m_MinimumClusterFraction.fromString(traverser.value())) + RESTORE(MINIMUM_CLUSTER_COUNT_TAG, + m_MinimumClusterCount.fromString(traverser.value())) } while (traverser.next()); return true; @@ -1223,26 +1220,26 @@ class CXMeansOnline : public CClusterer> { //! The type of data being clustered. maths_t::EDataType m_DataType; + //! The style of the cluster weight calculation (see maths_t::EClusterWeightCalc). + maths_t::EClusterWeightCalc m_WeightCalc; + //! The initial rate at which information is lost. - double m_InitialDecayRate; + CFloatStorage m_InitialDecayRate; //! The rate at which information is lost. - double m_DecayRate; + CFloatStorage m_DecayRate; //! A measure of the length of history of the data clustered. - double m_HistoryLength; - - //! The style of the cluster weight calculation (see maths_t::EClusterWeightCalc). - maths_t::EClusterWeightCalc m_WeightCalc; + CFloatStorage m_HistoryLength; //! The minimum cluster fractional count. - double m_MinimumClusterFraction; + CFloatStorage m_MinimumClusterFraction; //! The minimum cluster count. - double m_MinimumClusterCount; + CFloatStorage m_MinimumClusterCount; //! The minimum count for a category in the sketch to cluster. - double m_MinimumCategoryCount; + CFloatStorage m_MinimumCategoryCount; //! A generator of unique cluster indices. CClustererTypes::CIndexGenerator m_ClusterIndexGenerator; diff --git a/include/maths/CXMeansOnline1d.h b/include/maths/CXMeansOnline1d.h index ebf6a8ef93..8a4e360cea 100644 --- a/include/maths/CXMeansOnline1d.h +++ b/include/maths/CXMeansOnline1d.h @@ -103,7 +103,7 @@ class MATHS_EXPORT CAvailableModeDistributions { //! is expected to give largely order (of points processed) invariant //! unsupervised clustering of the data which identifies reasonably //! well separated clusters. -class MATHS_EXPORT CXMeansOnline1d : public CClusterer1d { +class MATHS_EXPORT CXMeansOnline1d final : public CClusterer1d { public: class CCluster; using TDoubleVec = CClusterer1d::TPointPreciseVec; @@ -374,9 +374,8 @@ class MATHS_EXPORT CXMeansOnline1d : public CClusterer1d { CIndexGenerator& indexGenerator(); private: - using TMinAccumulator = CBasicStatistics::COrderStatisticsStack; - using TMaxAccumulator = - CBasicStatistics::COrderStatisticsStack>; + using TMinAccumulator = CBasicStatistics::SMin::TAccumulator; + using TMaxAccumulator = CBasicStatistics::SMax::TAccumulator; private: //! The minimum Kullback-Leibler divergence at which we'll @@ -425,32 +424,32 @@ class MATHS_EXPORT CXMeansOnline1d : public CClusterer1d { //! The type of data being clustered. maths_t::EDataType m_DataType; + //! The style of the cluster weight calculation (see maths_t::EClusterWeightCalc). + maths_t::EClusterWeightCalc m_WeightCalc; + //! The distributions available to model the clusters. CAvailableModeDistributions m_AvailableDistributions; //! The initial rate at which information is lost. - double m_InitialDecayRate; + CFloatStorage m_InitialDecayRate; //! The rate at which information is lost. - double m_DecayRate; + CFloatStorage m_DecayRate; //! A measure of the length of history of the data clustered. - double m_HistoryLength; - - //! The style of the cluster weight calculation (see maths_t::EClusterWeightCalc). - maths_t::EClusterWeightCalc m_WeightCalc; + CFloatStorage m_HistoryLength; //! The minimum cluster fractional count. - double m_MinimumClusterFraction; + CFloatStorage m_MinimumClusterFraction; //! The minimum cluster count. - double m_MinimumClusterCount; + CFloatStorage m_MinimumClusterCount; //! The minimum count for a category in the sketch to cluster. - double m_MinimumCategoryCount; + CFloatStorage m_MinimumCategoryCount; //! The data central confidence interval on which to Winsorise. - double m_WinsorisationConfidenceInterval; + CFloatStorage m_WinsorisationConfidenceInterval; //! A generator of unique cluster indices. CIndexGenerator m_ClusterIndexGenerator; diff --git a/include/maths/MathsTypes.h b/include/maths/MathsTypes.h index 5dafbe62ef..6e267bf67d 100644 --- a/include/maths/MathsTypes.h +++ b/include/maths/MathsTypes.h @@ -42,7 +42,12 @@ using TCalendarComponentVec = std::vector; //! -# ContinuousData: which indicates the takes real values. //! -# MixedData: which indicates the data can be decomposed into //! some combination of the other three data types. -enum EDataType { E_DiscreteData, E_IntegerData, E_ContinuousData, E_MixedData }; +enum EDataType { + E_DiscreteData, + E_IntegerData, + E_ContinuousData, + E_MixedData +}; //! An enumeration of the types of weight which can be applied //! when adding samples, calculating marginal likelihood or @@ -388,14 +393,21 @@ bool hasCountVarianceScale(const core::CSmallVector, 1>& wei //! for the sample minimum or larger values for the sample maximum. //! Note that we normalize the one sided probabilities so they equal //! 1 at the distribution median. -enum EProbabilityCalculation { E_OneSidedBelow, E_TwoSided, E_OneSidedAbove }; +enum EProbabilityCalculation { + E_OneSidedBelow, + E_TwoSided, + E_OneSidedAbove +}; //! This controls the calculation of the cluster probabilities. //! There are two styles available: //! -# Equal: all clusters have equal weight. //! -# Fraction: the weight of a cluster is proportional to the //! number of points which have been assigned to the cluster. -enum EClusterWeightCalc { E_ClustersEqualWeight, E_ClustersFractionWeight }; +enum EClusterWeightCalc { + E_ClustersEqualWeight, + E_ClustersFractionWeight +}; //! A set of statuses which track the result of a floating point //! calculations. These provide finer grained information than diff --git a/lib/maths/CGammaRateConjugate.cc b/lib/maths/CGammaRateConjugate.cc index 78cf2bfc06..b81e7880c9 100644 --- a/lib/maths/CGammaRateConjugate.cc +++ b/lib/maths/CGammaRateConjugate.cc @@ -729,12 +729,12 @@ bool CGammaRateConjugate::acceptRestoreTraverser(core::CStateRestoreTraverser& t RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(OFFSET_TAG, m_Offset) + RESTORE(OFFSET_TAG, m_Offset.fromString(traverser.value())) RESTORE_BUILT_IN(LIKELIHOOD_SHAPE_TAG, m_LikelihoodShape) RESTORE(LOG_SAMPLES_MEAN_TAG, m_LogSamplesMean.fromDelimited(traverser.value())) RESTORE(SAMPLE_MOMENTS_TAG, m_SampleMoments.fromDelimited(traverser.value())) - RESTORE_BUILT_IN(PRIOR_SHAPE_TAG, m_PriorShape) - RESTORE_BUILT_IN(PRIOR_RATE_TAG, m_PriorRate) + RESTORE(PRIOR_SHAPE_TAG, m_PriorShape.fromString(traverser.value())) + RESTORE(PRIOR_RATE_TAG, m_PriorRate.fromString(traverser.value())) RESTORE_SETUP_TEARDOWN(NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), this->numberSamples(numberSamples)) @@ -1516,13 +1516,13 @@ std::size_t CGammaRateConjugate::staticSize() const { void CGammaRateConjugate::acceptPersistInserter(core::CStatePersistInserter& inserter) const { inserter.insertValue(DECAY_RATE_TAG, this->decayRate(), core::CIEEE754::E_SinglePrecision); - inserter.insertValue(OFFSET_TAG, m_Offset, core::CIEEE754::E_SinglePrecision); + inserter.insertValue(OFFSET_TAG, m_Offset.toString()); inserter.insertValue(LIKELIHOOD_SHAPE_TAG, m_LikelihoodShape, - core::CIEEE754::E_SinglePrecision); + core::CIEEE754::E_DoublePrecision); inserter.insertValue(LOG_SAMPLES_MEAN_TAG, m_LogSamplesMean.toDelimited()); inserter.insertValue(SAMPLE_MOMENTS_TAG, m_SampleMoments.toDelimited()); - inserter.insertValue(PRIOR_SHAPE_TAG, m_PriorShape, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(PRIOR_RATE_TAG, m_PriorRate, core::CIEEE754::E_SinglePrecision); + inserter.insertValue(PRIOR_SHAPE_TAG, m_PriorShape.toString()); + inserter.insertValue(PRIOR_RATE_TAG, m_PriorRate.toString()); inserter.insertValue(NUMBER_SAMPLES_TAG, this->numberSamples(), core::CIEEE754::E_SinglePrecision); } diff --git a/lib/maths/CLogNormalMeanPrecConjugate.cc b/lib/maths/CLogNormalMeanPrecConjugate.cc index 3864113fd0..931474fc5a 100644 --- a/lib/maths/CLogNormalMeanPrecConjugate.cc +++ b/lib/maths/CLogNormalMeanPrecConjugate.cc @@ -636,10 +636,10 @@ bool CLogNormalMeanPrecConjugate::acceptRestoreTraverser(core::CStateRestoreTrav RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(OFFSET_TAG, m_Offset) - RESTORE_BUILT_IN(GAUSSIAN_MEAN_TAG, m_GaussianMean) - RESTORE_BUILT_IN(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision) - RESTORE_BUILT_IN(GAMMA_SHAPE_TAG, m_GammaShape) + RESTORE(OFFSET_TAG, m_Offset.fromString(traverser.value())) + RESTORE(GAUSSIAN_MEAN_TAG, m_GaussianMean.fromString(traverser.value())) + RESTORE(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision.fromString(traverser.value())) + RESTORE(GAMMA_SHAPE_TAG, m_GammaShape.fromString(traverser.value())) RESTORE_BUILT_IN(GAMMA_RATE_TAG, m_GammaRate) RESTORE_SETUP_TEARDOWN(NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), @@ -1489,12 +1489,11 @@ std::size_t CLogNormalMeanPrecConjugate::staticSize() const { void CLogNormalMeanPrecConjugate::acceptPersistInserter(core::CStatePersistInserter& inserter) const { inserter.insertValue(DECAY_RATE_TAG, this->decayRate(), core::CIEEE754::E_SinglePrecision); - inserter.insertValue(OFFSET_TAG, m_Offset, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAUSSIAN_MEAN_TAG, m_GaussianMean, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision, - core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAMMA_SHAPE_TAG, m_GammaShape, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAMMA_RATE_TAG, m_GammaRate, core::CIEEE754::E_SinglePrecision); + inserter.insertValue(OFFSET_TAG, m_Offset.toString()); + inserter.insertValue(GAUSSIAN_MEAN_TAG, m_GaussianMean.toString()); + inserter.insertValue(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision.toString()); + inserter.insertValue(GAMMA_SHAPE_TAG, m_GammaShape.toString()); + inserter.insertValue(GAMMA_RATE_TAG, m_GammaRate, core::CIEEE754::E_DoublePrecision); inserter.insertValue(NUMBER_SAMPLES_TAG, this->numberSamples(), core::CIEEE754::E_SinglePrecision); } diff --git a/lib/maths/CNaturalBreaksClassifier.cc b/lib/maths/CNaturalBreaksClassifier.cc index 436faf5709..56b231c5cd 100644 --- a/lib/maths/CNaturalBreaksClassifier.cc +++ b/lib/maths/CNaturalBreaksClassifier.cc @@ -78,7 +78,7 @@ bool CNaturalBreaksClassifier::acceptRestoreTraverser(const SDistributionRestore do { const std::string& name = traverser.name(); - RESTORE_BUILT_IN(DECAY_RATE_TAG, m_DecayRate) + RESTORE(DECAY_RATE_TAG, m_DecayRate.fromString(traverser.value())) RESTORE_BUILT_IN(SPACE_TAG, m_Space) RESTORE(CATEGORY_TAG, core::CPersistUtils::restore(CATEGORY_TAG, m_Categories, traverser)) RESTORE(POINTS_TAG, core::CPersistUtils::fromString(traverser.value(), m_PointsBuffer)) @@ -88,7 +88,7 @@ bool CNaturalBreaksClassifier::acceptRestoreTraverser(const SDistributionRestore } void CNaturalBreaksClassifier::acceptPersistInserter(core::CStatePersistInserter& inserter) const { - inserter.insertValue(DECAY_RATE_TAG, m_DecayRate); + inserter.insertValue(DECAY_RATE_TAG, m_DecayRate.toString()); inserter.insertValue(SPACE_TAG, m_Space); core::CPersistUtils::persist(CATEGORY_TAG, m_Categories, inserter); inserter.insertValue(POINTS_TAG, core::CPersistUtils::toString(m_PointsBuffer)); diff --git a/lib/maths/CNormalMeanPrecConjugate.cc b/lib/maths/CNormalMeanPrecConjugate.cc index b81b7fb4f1..c2e5952f4e 100644 --- a/lib/maths/CNormalMeanPrecConjugate.cc +++ b/lib/maths/CNormalMeanPrecConjugate.cc @@ -463,9 +463,9 @@ bool CNormalMeanPrecConjugate::acceptRestoreTraverser(core::CStateRestoreTravers RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(GAUSSIAN_MEAN_TAG, m_GaussianMean) - RESTORE_BUILT_IN(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision) - RESTORE_BUILT_IN(GAMMA_SHAPE_TAG, m_GammaShape) + RESTORE(GAUSSIAN_MEAN_TAG, m_GaussianMean.fromString(traverser.value())) + RESTORE(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision.fromString(traverser.value())) + RESTORE(GAMMA_SHAPE_TAG, m_GammaShape.fromString(traverser.value())) RESTORE_BUILT_IN(GAMMA_RATE_TAG, m_GammaRate) RESTORE_SETUP_TEARDOWN(NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), @@ -1238,11 +1238,10 @@ std::size_t CNormalMeanPrecConjugate::staticSize() const { void CNormalMeanPrecConjugate::acceptPersistInserter(core::CStatePersistInserter& inserter) const { inserter.insertValue(DECAY_RATE_TAG, this->decayRate(), core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAUSSIAN_MEAN_TAG, m_GaussianMean, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision, - core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAMMA_SHAPE_TAG, m_GammaShape, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(GAMMA_RATE_TAG, m_GammaRate, core::CIEEE754::E_SinglePrecision); + inserter.insertValue(GAUSSIAN_MEAN_TAG, m_GaussianMean.toString()); + inserter.insertValue(GAUSSIAN_PRECISION_TAG, m_GaussianPrecision.toString()); + inserter.insertValue(GAMMA_SHAPE_TAG, m_GammaShape.toString()); + inserter.insertValue(GAMMA_RATE_TAG, m_GammaRate, core::CIEEE754::E_DoublePrecision); inserter.insertValue(NUMBER_SAMPLES_TAG, this->numberSamples(), core::CIEEE754::E_SinglePrecision); } diff --git a/lib/maths/CPoissonMeanConjugate.cc b/lib/maths/CPoissonMeanConjugate.cc index 3a45a9b62a..e31cc73ee0 100644 --- a/lib/maths/CPoissonMeanConjugate.cc +++ b/lib/maths/CPoissonMeanConjugate.cc @@ -192,9 +192,9 @@ bool CPoissonMeanConjugate::acceptRestoreTraverser(core::CStateRestoreTraverser& RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(OFFSET_TAG, m_Offset) - RESTORE_BUILT_IN(SHAPE_TAG, m_Shape) - RESTORE_BUILT_IN(RATE_TAG, m_Rate) + RESTORE(OFFSET_TAG, m_Offset.fromString(traverser.value())) + RESTORE(SHAPE_TAG, m_Shape.fromString(traverser.value())) + RESTORE(RATE_TAG, m_Rate.fromString(traverser.value())) RESTORE_SETUP_TEARDOWN(NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), this->numberSamples(numberSamples)) @@ -864,9 +864,9 @@ std::size_t CPoissonMeanConjugate::staticSize() const { void CPoissonMeanConjugate::acceptPersistInserter(core::CStatePersistInserter& inserter) const { inserter.insertValue(DECAY_RATE_TAG, this->decayRate(), core::CIEEE754::E_SinglePrecision); - inserter.insertValue(OFFSET_TAG, m_Offset, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(SHAPE_TAG, m_Shape, core::CIEEE754::E_SinglePrecision); - inserter.insertValue(RATE_TAG, m_Rate, core::CIEEE754::E_SinglePrecision); + inserter.insertValue(OFFSET_TAG, m_Offset.toString()); + inserter.insertValue(SHAPE_TAG, m_Shape.toString()); + inserter.insertValue(RATE_TAG, m_Rate.toString()); inserter.insertValue(NUMBER_SAMPLES_TAG, this->numberSamples(), core::CIEEE754::E_SinglePrecision); } diff --git a/lib/maths/CXMeansOnline1d.cc b/lib/maths/CXMeansOnline1d.cc index 7e94cc18f5..d325d48a53 100644 --- a/lib/maths/CXMeansOnline1d.cc +++ b/lib/maths/CXMeansOnline1d.cc @@ -653,24 +653,24 @@ CXMeansOnline1d::CXMeansOnline1d(maths_t::EDataType dataType, const TSplitFunc& splitFunc, const TMergeFunc& mergeFunc) : CClusterer1d(splitFunc, mergeFunc), m_DataType(dataType), - m_AvailableDistributions(availableDistributions), - m_InitialDecayRate(decayRate), m_DecayRate(decayRate), m_HistoryLength(0.0), - m_WeightCalc(weightCalc), m_MinimumClusterFraction(minimumClusterFraction), + m_WeightCalc(weightCalc), m_InitialDecayRate(decayRate), m_DecayRate(decayRate), + m_HistoryLength(0.0), m_MinimumClusterFraction(minimumClusterFraction), m_MinimumClusterCount(minimumClusterCount), m_MinimumCategoryCount(minimumCategoryCount), m_WinsorisationConfidenceInterval(winsorisationConfidenceInterval), + m_AvailableDistributions(availableDistributions), m_Clusters(1, CCluster(*this)) { } CXMeansOnline1d::CXMeansOnline1d(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser) : CClusterer1d(CDoNothing(), CDoNothing()), m_DataType(params.s_DataType), - m_AvailableDistributions(CAvailableModeDistributions::ALL), + m_WeightCalc(maths_t::E_ClustersEqualWeight), m_InitialDecayRate(params.s_DecayRate), m_DecayRate(params.s_DecayRate), - m_HistoryLength(), m_WeightCalc(maths_t::E_ClustersEqualWeight), - m_MinimumClusterFraction(), m_MinimumClusterCount(), + m_HistoryLength(), m_MinimumClusterFraction(), m_MinimumClusterCount(), m_MinimumCategoryCount(params.s_MinimumCategoryCount), - m_WinsorisationConfidenceInterval() { + m_WinsorisationConfidenceInterval(), + m_AvailableDistributions(CAvailableModeDistributions::ALL) { traverser.traverseSubLevel(boost::bind(&CXMeansOnline1d::acceptRestoreTraverser, this, boost::cref(params), _1)); } @@ -680,25 +680,26 @@ CXMeansOnline1d::CXMeansOnline1d(const SDistributionRestoreParams& params, const TMergeFunc& mergeFunc, core::CStateRestoreTraverser& traverser) : CClusterer1d(splitFunc, mergeFunc), m_DataType(params.s_DataType), - m_AvailableDistributions(CAvailableModeDistributions::ALL), + m_WeightCalc(maths_t::E_ClustersEqualWeight), m_InitialDecayRate(params.s_DecayRate), m_DecayRate(params.s_DecayRate), - m_HistoryLength(), m_WeightCalc(maths_t::E_ClustersEqualWeight), - m_MinimumClusterFraction(), m_MinimumClusterCount(), + m_HistoryLength(), m_MinimumClusterFraction(), m_MinimumClusterCount(), m_MinimumCategoryCount(params.s_MinimumCategoryCount), - m_WinsorisationConfidenceInterval() { + m_WinsorisationConfidenceInterval(), + m_AvailableDistributions(CAvailableModeDistributions::ALL) { traverser.traverseSubLevel(boost::bind(&CXMeansOnline1d::acceptRestoreTraverser, this, boost::cref(params), _1)); } CXMeansOnline1d::CXMeansOnline1d(const CXMeansOnline1d& other) - : CClusterer1d(other.splitFunc(), other.mergeFunc()), m_DataType(other.m_DataType), - m_AvailableDistributions(other.m_AvailableDistributions), - m_InitialDecayRate(other.m_InitialDecayRate), m_DecayRate(other.m_DecayRate), - m_HistoryLength(other.m_HistoryLength), m_WeightCalc(other.m_WeightCalc), + : CClusterer1d(other.splitFunc(), other.mergeFunc()), + m_DataType(other.m_DataType), m_WeightCalc(other.m_WeightCalc), + m_InitialDecayRate(other.m_InitialDecayRate), + m_DecayRate(other.m_DecayRate), m_HistoryLength(other.m_HistoryLength), m_MinimumClusterFraction(other.m_MinimumClusterFraction), m_MinimumClusterCount(other.m_MinimumClusterCount), m_MinimumCategoryCount(other.m_MinimumCategoryCount), m_WinsorisationConfidenceInterval(other.m_WinsorisationConfidenceInterval), + m_AvailableDistributions(other.m_AvailableDistributions), m_ClusterIndexGenerator(other.m_ClusterIndexGenerator.deepCopy()), m_Smallest(other.m_Smallest), m_Largest(other.m_Largest), m_Clusters(other.m_Clusters) { @@ -715,15 +716,15 @@ CXMeansOnline1d& CXMeansOnline1d::operator=(const CXMeansOnline1d& other) { void CXMeansOnline1d::swap(CXMeansOnline1d& other) { this->CClusterer1d::swap(other); std::swap(m_DataType, other.m_DataType); - std::swap(m_AvailableDistributions, other.m_AvailableDistributions); + std::swap(m_WeightCalc, other.m_WeightCalc); std::swap(m_InitialDecayRate, other.m_InitialDecayRate); std::swap(m_DecayRate, other.m_DecayRate); std::swap(m_HistoryLength, other.m_HistoryLength); - std::swap(m_WeightCalc, other.m_WeightCalc); std::swap(m_MinimumClusterFraction, other.m_MinimumClusterFraction); std::swap(m_MinimumClusterCount, other.m_MinimumClusterCount); std::swap(m_MinimumCategoryCount, other.m_MinimumCategoryCount); std::swap(m_WinsorisationConfidenceInterval, other.m_WinsorisationConfidenceInterval); + std::swap(m_AvailableDistributions, other.m_AvailableDistributions); std::swap(m_ClusterIndexGenerator, other.m_ClusterIndexGenerator); std::swap(m_Smallest, other.m_Smallest); std::swap(m_Largest, other.m_Largest); @@ -745,9 +746,10 @@ void CXMeansOnline1d::acceptPersistInserter(core::CStatePersistInserter& inserte inserter.insertValue(SMALLEST_TAG, m_Smallest.toDelimited()); inserter.insertValue(LARGEST_TAG, m_Largest.toDelimited()); inserter.insertValue(WEIGHT_CALC_TAG, static_cast(m_WeightCalc)); - inserter.insertValue(MINIMUM_CLUSTER_FRACTION_TAG, m_MinimumClusterFraction); - inserter.insertValue(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount); - inserter.insertValue(WINSORISATION_CONFIDENCE_INTERVAL_TAG, m_WinsorisationConfidenceInterval); + inserter.insertValue(MINIMUM_CLUSTER_FRACTION_TAG, m_MinimumClusterFraction.toString()); + inserter.insertValue(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount.toString()); + inserter.insertValue(WINSORISATION_CONFIDENCE_INTERVAL_TAG, + m_WinsorisationConfidenceInterval.toString()); inserter.insertLevel(CLUSTER_INDEX_GENERATOR_TAG, boost::bind(&CIndexGenerator::acceptPersistInserter, &m_ClusterIndexGenerator, _1)); @@ -1109,19 +1111,19 @@ bool CXMeansOnline1d::acceptRestoreTraverser(const SDistributionRestoreParams& p RESTORE_SETUP_TEARDOWN(DECAY_RATE_TAG, double decayRate, core::CStringUtils::stringToType(traverser.value(), decayRate), this->decayRate(decayRate)) - RESTORE_BUILT_IN(HISTORY_LENGTH_TAG, m_HistoryLength); + RESTORE(HISTORY_LENGTH_TAG, m_HistoryLength.fromString(traverser.value())); RESTORE(SMALLEST_TAG, m_Smallest.fromDelimited(traverser.value())) RESTORE(LARGEST_TAG, m_Largest.fromDelimited(traverser.value())) RESTORE(CLUSTER_INDEX_GENERATOR_TAG, traverser.traverseSubLevel(boost::bind(&CIndexGenerator::acceptRestoreTraverser, &m_ClusterIndexGenerator, _1))) - RESTORE_SETUP_TEARDOWN( - WEIGHT_CALC_TAG, int weightCalc, - core::CStringUtils::stringToType(traverser.value(), weightCalc), - m_WeightCalc = static_cast(weightCalc)) - RESTORE_BUILT_IN(MINIMUM_CLUSTER_FRACTION_TAG, m_MinimumClusterFraction) - RESTORE_BUILT_IN(MINIMUM_CLUSTER_COUNT_TAG, m_MinimumClusterCount) - RESTORE_BUILT_IN(WINSORISATION_CONFIDENCE_INTERVAL_TAG, m_WinsorisationConfidenceInterval) + RESTORE_ENUM(WEIGHT_CALC_TAG, m_WeightCalc, maths_t::EClusterWeightCalc) + RESTORE(MINIMUM_CLUSTER_FRACTION_TAG, + m_MinimumClusterFraction.fromString(traverser.value())) + RESTORE(MINIMUM_CLUSTER_COUNT_TAG, + m_MinimumClusterCount.fromString(traverser.value())) + RESTORE(WINSORISATION_CONFIDENCE_INTERVAL_TAG, + m_WinsorisationConfidenceInterval.fromString(traverser.value())) } while (traverser.next()); return true; diff --git a/lib/maths/unittest/CMultimodalPriorTest.cc b/lib/maths/unittest/CMultimodalPriorTest.cc index dbfa7921b8..143f8b9c5e 100644 --- a/lib/maths/unittest/CMultimodalPriorTest.cc +++ b/lib/maths/unittest/CMultimodalPriorTest.cc @@ -1044,7 +1044,7 @@ void CMultimodalPriorTest::testMarginalLikelihoodConfidenceInterval() { CPPUNIT_ASSERT(maths::CBasicStatistics::mean(median) > i90.first); CPPUNIT_ASSERT(maths::CBasicStatistics::mean(median) < i90.second); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-112.0, i90.first, 0.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-111.0, i90.first, 0.5); CPPUNIT_ASSERT_DOUBLES_EQUAL(158952.0, i90.second, 0.5); } } diff --git a/lib/maths/unittest/CNormalMeanPrecConjugateTest.cc b/lib/maths/unittest/CNormalMeanPrecConjugateTest.cc index b6d1bb12cd..e89f31ddbe 100644 --- a/lib/maths/unittest/CNormalMeanPrecConjugateTest.cc +++ b/lib/maths/unittest/CNormalMeanPrecConjugateTest.cc @@ -78,7 +78,7 @@ void CNormalMeanPrecConjugateTest::testMultipleUpdate() { LOG_DEBUG(<< filter1.print()); LOG_DEBUG(<< "vs"); LOG_DEBUG(<< filter2.print()); - TEqual equal(maths::CToleranceTypes::E_AbsoluteTolerance, 1e-5); + TEqual equal(maths::CToleranceTypes::E_AbsoluteTolerance, 1e-4); CPPUNIT_ASSERT(filter1.equalTolerance(filter2, equal)); } @@ -124,7 +124,7 @@ void CNormalMeanPrecConjugateTest::testPropagation() { // Test that propagation doesn't affect the expected values // of likelihood mean and precision. - const double eps = 1e-12; + const double eps = 1e-7; test::CRandomNumbers rng; diff --git a/lib/maths/unittest/COneOfNPriorTest.cc b/lib/maths/unittest/COneOfNPriorTest.cc index d48bc418d0..642001adf9 100644 --- a/lib/maths/unittest/COneOfNPriorTest.cc +++ b/lib/maths/unittest/COneOfNPriorTest.cc @@ -169,7 +169,7 @@ void COneOfNPriorTest::testMultipleUpdate() { LOG_DEBUG(<< filter1.print()); LOG_DEBUG(<< "vs"); LOG_DEBUG(<< filter2.print()); - TEqual equal(maths::CToleranceTypes::E_AbsoluteTolerance, 1e-6); + TEqual equal(maths::CToleranceTypes::E_AbsoluteTolerance, 1e-3); TDoubleVec weights1 = filter1.weights(); TDoubleVec weights2 = filter2.weights(); diff --git a/lib/maths/unittest/CPoissonMeanConjugateTest.cc b/lib/maths/unittest/CPoissonMeanConjugateTest.cc index 76919cc8f7..77a4af4e3a 100644 --- a/lib/maths/unittest/CPoissonMeanConjugateTest.cc +++ b/lib/maths/unittest/CPoissonMeanConjugateTest.cc @@ -118,7 +118,7 @@ void CPoissonMeanConjugateTest::testPropagation() { // Test that propagation doesn't affect the expected values // of likelihood mean. - const double eps = 1e-12; + const double eps = 1e-7; test::CRandomNumbers rng; diff --git a/lib/maths/unittest/CPriorTest.cc b/lib/maths/unittest/CPriorTest.cc index 360ca62af3..3bd49e7c68 100644 --- a/lib/maths/unittest/CPriorTest.cc +++ b/lib/maths/unittest/CPriorTest.cc @@ -96,7 +96,7 @@ void CPriorTest::testExpectation() { CPPUNIT_ASSERT(prior.expectation(CX(), n, mean)); LOG_DEBUG(<< "n = " << n << ", mean = " << mean << ", error = " << std::fabs(mean - trueMean)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(trueMean, mean, 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(trueMean, mean, 1e-7); } double varianceErrors[] = {1.4, 0.1, 0.05, 0.01, 0.005, diff --git a/lib/maths/unittest/CXMeansOnline1dTest.cc b/lib/maths/unittest/CXMeansOnline1dTest.cc index 87b471c3d0..a0b1bbb4ee 100644 --- a/lib/maths/unittest/CXMeansOnline1dTest.cc +++ b/lib/maths/unittest/CXMeansOnline1dTest.cc @@ -82,7 +82,7 @@ void CXMeansOnline1dTest::testCluster() { LOG_DEBUG(<< "expected centre = " << expectedCentre); LOG_DEBUG(<< "expected spread = " << expectedSpread); CPPUNIT_ASSERT_EQUAL(expectedCount, cluster.count()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedCentre, cluster.centre(), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedCentre, cluster.centre(), 5e-7); CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedSpread, cluster.spread(), 0.05 * expectedSpread); CPPUNIT_ASSERT_EQUAL(1.0, cluster.weight(maths_t::E_ClustersEqualWeight)); CPPUNIT_ASSERT_EQUAL(expectedCount, cluster.weight(maths_t::E_ClustersFractionWeight)); @@ -93,7 +93,7 @@ void CXMeansOnline1dTest::testCluster() { LOG_DEBUG(<< "count = " << cluster.count()); LOG_DEBUG(<< "weight = " << cluster.weight(maths_t::E_ClustersFractionWeight)); CPPUNIT_ASSERT(cluster.count() < expectedCount); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedCentre, cluster.centre(), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedCentre, cluster.centre(), 5e-7); CPPUNIT_ASSERT(cluster.spread() > expectedSpread); CPPUNIT_ASSERT_EQUAL(1.0, cluster.weight(maths_t::E_ClustersEqualWeight)); CPPUNIT_ASSERT(cluster.weight(maths_t::E_ClustersFractionWeight) < expectedCount); diff --git a/lib/model/unittest/CMetricModelTest.cc b/lib/model/unittest/CMetricModelTest.cc index 5ecb3fbcd4..85a50fe212 100644 --- a/lib/model/unittest/CMetricModelTest.cc +++ b/lib/model/unittest/CMetricModelTest.cc @@ -1218,7 +1218,7 @@ void CMetricModelTest::testInfluence() { {core::make_triple(std::string{"i1"}, 0.9, 1.0), core::make_triple(std::string{"i2"}, 0.9, 1.0)}, {}, - {core::make_triple(std::string{"i1"}, 1.0, 1.0)}, + {core::make_triple(std::string{"i1"}, 0.9, 1.0)}, {}, {core::make_triple(std::string{"i2"}, 1.0, 1.0)}}; testFeature(model_t::E_IndividualSumByBucketAndPerson, values, influencers, influences);