diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 7637fcc359..98470dd5e3 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -25,6 +25,9 @@ Reduce model memory by storing state for periodicity testing in a compressed for Forecasting of Machine Learning job time series is now supported for large jobs by temporarily storing model state on disk ({pull}89[#89]) +Fix a bug causing us to under estimate the memory used by shared pointers and reduce the memory consumed +by unnecessary reference counting ({pull}108[#108]) + === Bug Fixes Age seasonal components in proportion to the fraction of values with which they're updated ({pull}88[#88]) diff --git a/include/api/CForecastRunner.h b/include/api/CForecastRunner.h index f678592dd5..ff54659b8c 100644 --- a/include/api/CForecastRunner.h +++ b/include/api/CForecastRunner.h @@ -115,7 +115,7 @@ class API_EXPORT CForecastRunner final : private core::CNonCopyable { using TForecastModelWrapper = model::CForecastDataSink::SForecastModelWrapper; using TForecastResultSeries = model::CForecastDataSink::SForecastResultSeries; using TForecastResultSeriesVec = std::vector; - using TMathsModelPtr = std::shared_ptr; + using TMathsModelPtr = std::unique_ptr; using TStrUSet = boost::unordered_set; diff --git a/include/core/CMemory.h b/include/core/CMemory.h index 4c8cb022b6..6d6f839c2f 100644 --- a/include/core/CMemory.h +++ b/include/core/CMemory.h @@ -287,21 +287,25 @@ class CORE_EXPORT CMemory : private CNonInstantiatable { static std::size_t dynamicSize(const T& t, typename boost::enable_if>::type* = nullptr) { - if (t == nullptr) { - return 0; - } - return staticSize(*t) + dynamicSize(*t); + return t == nullptr ? 0 : staticSize(*t) + dynamicSize(*t); } //! Overload for std::shared_ptr. template static std::size_t dynamicSize(const std::shared_ptr& t) { - if (!t) { + if (t == nullptr) { return 0; } long uc = t.use_count(); - // Round up - return (staticSize(*t) + dynamicSize(*t) + std::size_t(uc - 1)) / uc; + // Note we add on sizeof(long) here to account for the memory + // used by the shared reference count. Also, round up. + return (sizeof(long) + staticSize(*t) + dynamicSize(*t) + std::size_t(uc - 1)) / uc; + } + + //! Overload for std::unique_ptr. + template + static std::size_t dynamicSize(const std::unique_ptr& t) { + return t == nullptr ? 0 : staticSize(*t) + dynamicSize(*t); } //! Overload for boost::array. @@ -703,25 +707,40 @@ class CORE_EXPORT CMemoryDebug : private CNonInstantiatable { static void dynamicSize(const char* name, const std::shared_ptr& t, CMemoryUsage::TMemoryUsagePtr mem) { - if (t) { + if (t != nullptr) { long uc = t.use_count(); // If the pointer is shared by multiple users, each one // might count it, so divide by the number of users. // However, if only 1 user has it, do a full debug. if (uc == 1) { - mem->addItem("shared_ptr", CMemory::staticSize(*t)); + // Note we add on sizeof(long) here to account for + // the memory used by the shared reference count. + mem->addItem("shared_ptr", sizeof(long) + CMemory::staticSize(*t)); dynamicSize(name, *t, mem); } else { std::ostringstream ss; ss << "shared_ptr (x" << uc << ')'; - // Round up - mem->addItem(ss.str(), (CMemory::staticSize(*t) + + // Note we add on sizeof(long) here to account for + // the memory used by the shared reference count. + // Also, round up. + mem->addItem(ss.str(), (sizeof(long) + CMemory::staticSize(*t) + CMemory::dynamicSize(*t) + std::size_t(uc - 1)) / uc); } } } + //! Overload for std::unique_ptr. + template + static void dynamicSize(const char* name, + const std::unique_ptr& t, + CMemoryUsage::TMemoryUsagePtr mem) { + if (t != nullptr) { + mem->addItem("ptr", CMemory::staticSize(*t)); + memory_detail::SDebugMemoryDynamicSize::dispatch(name, *t, mem); + } + } + //! Overload for boost::array. template static void dynamicSize(const char* name, diff --git a/include/maths/CChecksum.h b/include/maths/CChecksum.h index f8da99d94d..55125dd255 100644 --- a/include/maths/CChecksum.h +++ b/include/maths/CChecksum.h @@ -158,13 +158,20 @@ class CChecksumImpl { : CChecksumImpl::value>::dispatch(seed, *target); } - //! Checksum a pointer. + //! Checksum a shared pointer. template static uint64_t dispatch(uint64_t seed, const std::shared_ptr& target) { return !target ? seed : CChecksumImpl::value>::dispatch(seed, *target); } + //! Checksum a unique pointer. + template + static uint64_t dispatch(uint64_t seed, const std::unique_ptr& target) { + return !target ? seed + : CChecksumImpl::value>::dispatch(seed, *target); + } + //! Checksum a pair. template static uint64_t dispatch(uint64_t seed, const std::pair& target) { diff --git a/include/maths/CClusterer.h b/include/maths/CClusterer.h index 8f1b5b2e79..70c7375bef 100644 --- a/include/maths/CClusterer.h +++ b/include/maths/CClusterer.h @@ -125,7 +125,6 @@ class MATHS_EXPORT CClustererTypes { template class CClusterer : public CClustererTypes { public: - using TClustererPtr = std::shared_ptr; using TPointVec = std::vector; using TPointPrecise = typename SPromoted::Type; using TPointPreciseVec = std::vector; diff --git a/include/maths/CClustererStateSerialiser.h b/include/maths/CClustererStateSerialiser.h index faee50eaf2..c2e38867f8 100644 --- a/include/maths/CClustererStateSerialiser.h +++ b/include/maths/CClustererStateSerialiser.h @@ -43,7 +43,7 @@ struct SDistributionRestoreParams; //! to potential competitors. class MATHS_EXPORT CClustererStateSerialiser { public: - using TClusterer1dPtr = std::shared_ptr; + using TClusterer1dPtr = std::unique_ptr; public: //! Construct the appropriate CClusterer sub-class from its state @@ -73,7 +73,7 @@ class MATHS_EXPORT CClustererStateSerialiser { //! \note Sets \p ptr to NULL on failure. template bool operator()(const SDistributionRestoreParams& params, - std::shared_ptr>>& ptr, + std::unique_ptr>>& ptr, core::CStateRestoreTraverser& traverser) { return this->operator()(params, CClustererTypes::CDoNothing(), CClustererTypes::CDoNothing(), ptr, traverser); @@ -87,7 +87,7 @@ class MATHS_EXPORT CClustererStateSerialiser { bool operator()(const SDistributionRestoreParams& params, const CClustererTypes::TSplitFunc& splitFunc, const CClustererTypes::TMergeFunc& mergeFunc, - std::shared_ptr>>& ptr, + std::unique_ptr>>& ptr, core::CStateRestoreTraverser& traverser) { std::size_t numResults(0); diff --git a/include/maths/CModelStateSerialiser.h b/include/maths/CModelStateSerialiser.h index 0d2ef51b64..1c4fdd6233 100644 --- a/include/maths/CModelStateSerialiser.h +++ b/include/maths/CModelStateSerialiser.h @@ -34,7 +34,7 @@ struct SModelRestoreParams; //! compatibility in the future as the classes evolve. class MATHS_EXPORT CModelStateSerialiser { public: - using TModelPtr = std::shared_ptr; + using TModelPtr = std::unique_ptr; public: //! Construct the appropriate CPrior sub-class from its state diff --git a/include/maths/CMultimodalPrior.h b/include/maths/CMultimodalPrior.h index b34d4e7096..9156d7fa3b 100644 --- a/include/maths/CMultimodalPrior.h +++ b/include/maths/CMultimodalPrior.h @@ -49,11 +49,9 @@ namespace maths { //! point of view this is the composite pattern. class MATHS_EXPORT CMultimodalPrior : public CPrior { public: - using TClustererPtr = std::shared_ptr; - using TPriorPtr = std::shared_ptr; + using TClustererPtr = std::unique_ptr; + using TPriorPtr = std::unique_ptr; using TPriorPtrVec = std::vector; - using TPriorPtrVecItr = TPriorPtrVec::iterator; - using TPriorPtrVecCItr = TPriorPtrVec::const_iterator; using TMeanVarAccumulator = CBasicStatistics::SSampleMeanVar::TAccumulator; using TMeanVarAccumulatorVec = std::vector; @@ -80,6 +78,9 @@ class MATHS_EXPORT CMultimodalPrior : public CPrior { double decayRate = 0.0); //! Create from a collection of weights and priors. + //! + //! \note The priors are moved into place clearing the values in \p priors. + //! \note This constructor doesn't support subsequent update of the prior. CMultimodalPrior(maths_t::EDataType dataType, double decayRate, TPriorPtrVec& priors); //! Construct from part of a state document. @@ -320,7 +321,7 @@ class MATHS_EXPORT CMultimodalPrior : public CPrior { CMultimodalPrior* m_Prior; }; - using TMode = SMultimodalPriorMode>; + using TMode = SMultimodalPriorMode; using TModeVec = std::vector; private: diff --git a/include/maths/CMultimodalPriorMode.h b/include/maths/CMultimodalPriorMode.h index ace923875d..7d875286ed 100644 --- a/include/maths/CMultimodalPriorMode.h +++ b/include/maths/CMultimodalPriorMode.h @@ -36,6 +36,8 @@ struct SMultimodalPriorMode { SMultimodalPriorMode() : s_Index(0), s_Prior() {} SMultimodalPriorMode(std::size_t index, const PRIOR_PTR& prior) : s_Index(index), s_Prior(prior->clone()) {} + SMultimodalPriorMode(std::size_t index, PRIOR_PTR&& prior) + : s_Index(index), s_Prior(std::move(prior)) {} //! Get the weight of this sample. double weight() const { return s_Prior->numberSamples(); } diff --git a/include/maths/CMultivariateMultimodalPrior.h b/include/maths/CMultivariateMultimodalPrior.h index af509bbab3..3b720b5f1c 100644 --- a/include/maths/CMultivariateMultimodalPrior.h +++ b/include/maths/CMultivariateMultimodalPrior.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -50,10 +51,10 @@ namespace multivariate_multimodal_prior_detail { using TSizeDoublePr = std::pair; using TSizeDoublePr3Vec = core::CSmallVector; -using TPriorPtr = std::shared_ptr; using TDouble10Vec1Vec = CMultivariatePrior::TDouble10Vec1Vec; using TDouble10VecWeightsAry1Vec = CMultivariatePrior::TDouble10VecWeightsAry1Vec; -using TMode = SMultimodalPriorMode>; +using TPriorPtr = std::unique_ptr; +using TMode = SMultimodalPriorMode; using TModeVec = std::vector; //! Implementation of a sample joint log marginal likelihood calculation. @@ -134,7 +135,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { using TMatrix = CSymmetricMatrixNxN; using TMatrixVec = std::vector; using TClusterer = CClusterer; - using TClustererPtr = std::shared_ptr; + using TClustererPtr = std::unique_ptr; using TPriorPtrVec = std::vector; // Lift all overloads of into scope. @@ -162,13 +163,13 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { //! Create from a collection of priors. //! - //! \note The priors are shallow copied. + //! \note The priors are moved into place clearing the values in \p priors. //! \note This constructor doesn't support subsequent update of the prior. CMultivariateMultimodalPrior(maths_t::EDataType dataType, TPriorPtrVec& priors) : CMultivariatePrior(dataType, 0.0) { m_Modes.reserve(priors.size()); for (std::size_t i = 0u; i < priors.size(); ++i) { - m_Modes.emplace_back(i, priors[i]); + m_Modes.emplace_back(i, std::move(priors[i])); } } @@ -425,12 +426,12 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { for (const auto& mode : m_Modes) { TUnivariatePriorPtrDoublePr prior(mode.s_Prior->univariate(marginalize, condition)); if (prior.first == nullptr) { - return TUnivariatePriorPtrDoublePr(); + return {}; } if (prior.first->isNonInformative()) { continue; } - modes.push_back(prior.first); + modes.push_back(std::move(prior.first)); weights.push_back(prior.second); maxWeight.add(weights.back()); } @@ -444,8 +445,8 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { modes[i]->numberSamples(weights[i] / Z * modes[i]->numberSamples()); } - return {TUnivariatePriorPtr(new CMultimodalPrior(this->dataType(), - this->decayRate(), modes)), + return {boost::make_unique(this->dataType(), + this->decayRate(), modes), Z > 0.0 ? maxWeight[0] + std::log(Z) : 0.0}; } @@ -465,7 +466,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { const TSizeDoublePr10Vec& condition) const { if (N == 2) { - return TPriorPtrDoublePr(TPriorPtr(this->clone()), 0.0); + return {TPriorPtr(this->clone()), 0.0}; } std::size_t n = m_Modes.size(); @@ -484,7 +485,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { if (prior.first->isNonInformative()) { continue; } - modes.push_back(prior.first); + modes.push_back(std::move(prior.first)); weights.push_back(prior.second); maxWeight.add(weights.back()); } @@ -498,7 +499,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { modes[i]->numberSamples(weights[i] / Z * modes[i]->numberSamples()); } - return {TPriorPtr(new CMultivariateMultimodalPrior<2>(this->dataType(), modes)), + return {boost::make_unique>(this->dataType(), modes), Z > 0.0 ? maxWeight[0] + std::log(Z) : 0.0}; } @@ -905,7 +906,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { // Create the child modes. LOG_TRACE(<< "Creating mode with index " << leftSplitIndex); - modes.emplace_back(leftSplitIndex, m_Prior->m_SeedPrior); + modes.emplace_back(leftSplitIndex, TPriorPtr(m_Prior->m_SeedPrior->clone())); { TPointVec samples; if (!m_Prior->m_Clusterer->sample( @@ -935,7 +936,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { } LOG_TRACE(<< "Creating mode with index " << rightSplitIndex); - modes.emplace_back(rightSplitIndex, m_Prior->m_SeedPrior); + modes.emplace_back(rightSplitIndex, TPriorPtr(m_Prior->m_SeedPrior->clone())); { TPointVec samples; if (!m_Prior->m_Clusterer->sample( @@ -1025,7 +1026,7 @@ class CMultivariateMultimodalPrior : public CMultivariatePrior { MODE_TAG, TMode mode, traverser.traverseSubLevel(boost::bind( &TMode::acceptRestoreTraverser, &mode, boost::cref(params), _1)), - m_Modes.push_back(mode)) + m_Modes.push_back(std::move(mode))) RESTORE_SETUP_TEARDOWN( NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), diff --git a/include/maths/CMultivariateMultimodalPriorFactory.h b/include/maths/CMultivariateMultimodalPriorFactory.h index e9e03d51ea..28ea037362 100644 --- a/include/maths/CMultivariateMultimodalPriorFactory.h +++ b/include/maths/CMultivariateMultimodalPriorFactory.h @@ -25,7 +25,7 @@ struct SDistributionRestoreParams; //! \brief Factory for multivariate multimodal priors. class MATHS_EXPORT CMultivariateMultimodalPriorFactory { public: - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; public: //! Create a new non-informative multivariate normal prior. diff --git a/include/maths/CMultivariateNormalConjugate.h b/include/maths/CMultivariateNormalConjugate.h index e85ad90ff6..6c28b77d48 100644 --- a/include/maths/CMultivariateNormalConjugate.h +++ b/include/maths/CMultivariateNormalConjugate.h @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -348,7 +349,7 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { univariate(const TSize10Vec& marginalize, const TSizeDoublePr10Vec& condition) const { if (!this->check(marginalize, condition)) { - return TUnivariatePriorPtrDoublePr(); + return {}; } TSize10Vec i1; @@ -358,7 +359,7 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { << "marginalize '" << core::CContainerPrinter::print(marginalize) << "'" << ", condition '" << core::CContainerPrinter::print(condition) << "'"); - return TUnivariatePriorPtrDoublePr(); + return {}; } maths_t::EDataType dataType = this->dataType(); @@ -378,8 +379,8 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { double m1 = m(i1[0]); double c11 = c(i1[0], i1[0]); if (condition.empty()) { - return {TUnivariatePriorPtr(new CNormalMeanPrecConjugate( - dataType, m1, p, s, c11 * v / 2.0, decayRate)), + return {boost::make_unique( + dataType, m1, p, s, c11 * v / 2.0, decayRate), 0.0}; } @@ -408,14 +409,14 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { LOG_TRACE(<< "mean = " << mean << ", variance = " << variance << ", weight = " << weight); - return {TUnivariatePriorPtr(new CNormalMeanPrecConjugate( - dataType, mean, p, s, variance * v / 2.0, decayRate)), + return {boost::make_unique( + dataType, mean, p, s, variance * v / 2.0, decayRate), weight}; } catch (const std::exception& e) { LOG_ERROR(<< "Failed to get univariate prior: " << e.what()); } - return TUnivariatePriorPtrDoublePr(); + return {}; } //! Compute the bivariate prior marginalizing over the variables @@ -433,16 +434,16 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { virtual TPriorPtrDoublePr bivariate(const TSize10Vec& marginalize, const TSizeDoublePr10Vec& condition) const { if (N == 2) { - return TPriorPtrDoublePr(std::shared_ptr(this->clone()), 0.0); + return {TPriorPtr(this->clone()), 0.0}; } if (!this->check(marginalize, condition)) { - return TPriorPtrDoublePr(); + return {}; } TSize10Vec i1; this->remainingVariables(marginalize, condition, i1); if (i1.size() != 2) { - return TPriorPtrDoublePr(); + return {}; } maths_t::EDataType dataType = this->dataType(); @@ -472,8 +473,8 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { } } if (condition.empty()) { - return {TPriorPtr(new CMultivariateNormalConjugate<2>( - dataType, m1, p, f, c11, decayRate)), + return {boost::make_unique>( + dataType, m1, p, f, c11, decayRate), 0.0}; } @@ -505,14 +506,14 @@ class CMultivariateNormalConjugate : public CMultivariatePrior { weight -= 0.5 * (xc - m2).transpose() * c22SolvexcMinusm2; LOG_TRACE(<< "mean = " << mean << ", covariance = " << covariance); - return {TPriorPtr(new CMultivariateNormalConjugate<2>( - dataType, mean, p, f, covariance, decayRate)), + return {boost::make_unique>( + dataType, mean, p, f, covariance, decayRate), weight}; } catch (const std::exception& e) { LOG_ERROR(<< "Failed to get univariate prior: " << e.what()); } - return TPriorPtrDoublePr(); + return {}; } //! Get the support for the marginal likelihood function. diff --git a/include/maths/CMultivariateNormalConjugateFactory.h b/include/maths/CMultivariateNormalConjugateFactory.h index fcae08d5cc..fef5886833 100644 --- a/include/maths/CMultivariateNormalConjugateFactory.h +++ b/include/maths/CMultivariateNormalConjugateFactory.h @@ -25,7 +25,7 @@ struct SDistributionRestoreParams; //! \brief Factory for multivariate normal conjugate priors. class MATHS_EXPORT CMultivariateNormalConjugateFactory { public: - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; public: //! Create a new non-informative multivariate normal prior. diff --git a/include/maths/CMultivariateOneOfNPriorFactory.h b/include/maths/CMultivariateOneOfNPriorFactory.h index eeeff3eb2c..9c8cf3f1ef 100644 --- a/include/maths/CMultivariateOneOfNPriorFactory.h +++ b/include/maths/CMultivariateOneOfNPriorFactory.h @@ -25,7 +25,7 @@ struct SDistributionRestoreParams; //! \brief Factory for multivariate 1-of-n priors. class MATHS_EXPORT CMultivariateOneOfNPriorFactory { public: - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; using TPriorPtrVec = std::vector; public: diff --git a/include/maths/CMultivariatePrior.h b/include/maths/CMultivariatePrior.h index 96c51fc04e..e1dd62009b 100644 --- a/include/maths/CMultivariatePrior.h +++ b/include/maths/CMultivariatePrior.h @@ -46,9 +46,9 @@ class MATHS_EXPORT CMultivariatePrior { using TTail10Vec = core::CSmallVector; using TDouble10VecWeightsAry = maths_t::TDouble10VecWeightsAry; using TDouble10VecWeightsAry1Vec = maths_t::TDouble10VecWeightsAry1Vec; - using TUnivariatePriorPtr = std::shared_ptr; + using TUnivariatePriorPtr = std::unique_ptr; using TUnivariatePriorPtrDoublePr = std::pair; - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; using TPriorPtrDoublePr = std::pair; using TWeights = maths_t::CUnitWeights; diff --git a/include/maths/CNaiveBayes.h b/include/maths/CNaiveBayes.h index 5fda126d09..e98834407d 100644 --- a/include/maths/CNaiveBayes.h +++ b/include/maths/CNaiveBayes.h @@ -129,7 +129,7 @@ class MATHS_EXPORT CNaiveBayesFeatureDensityFromPrior final : public CNaiveBayes virtual std::string print() const; private: - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; private: //! The density model. @@ -151,10 +151,14 @@ class MATHS_EXPORT CNaiveBayes { TOptionalDouble minMaxLogLikelihoodToUseFeature = TOptionalDouble()); CNaiveBayes(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser); + CNaiveBayes(const CNaiveBayes& other); //! Persist state by passing information to \p inserter. void acceptPersistInserter(core::CStatePersistInserter& inserter) const; + //! Copy by assign operator. + CNaiveBayes& operator=(const CNaiveBayes& other); + //! Efficiently swap the contents of this and \p other. void swap(CNaiveBayes& other); @@ -222,33 +226,47 @@ class MATHS_EXPORT CNaiveBayes { std::string print() const; private: - using TFeatureDensityPtr = std::shared_ptr; + using TFeatureDensityPtr = std::unique_ptr; using TFeatureDensityPtrVec = std::vector; //! \brief The data associated with a class. - struct SClass { - SClass() = default; - SClass(double count, const TFeatureDensityPtrVec& conditionalDensities); + class CClass { + public: + CClass() = default; + explicit CClass(double count); + CClass(const CClass& other); //! Initialize by reading state from \p traverser. bool acceptRestoreTraverser(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser); //! Persist state by passing information to \p inserter. void acceptPersistInserter(core::CStatePersistInserter& inserter) const; + + //! Get the number of examples in this class. + double count() const; + //! Get a writable reference of the number of examples in this class. + double& count(); + //! Get the class conditional densities. + const TFeatureDensityPtrVec& conditionalDensities() const; + //! Get a writable reference of the class conditional densities. + TFeatureDensityPtrVec& conditionalDensities(); + //! Debug the memory used by this object. void debugMemoryUsage(core::CMemoryUsage::TMemoryUsagePtr mem) const; //! Get the memory used by this object. std::size_t memoryUsage() const; + //! Get a checksum for this object. uint64_t checksum(uint64_t seed = 0) const; + private: //! The number of examples in this class. - double s_Count = 0.0; + double m_Count = 0.0; //! The feature conditional densities for this class. - TFeatureDensityPtrVec s_ConditionalDensities; + TFeatureDensityPtrVec m_ConditionalDensities; }; - using TSizeClassUMap = boost::unordered_map; + using TSizeClassUMap = boost::unordered_map; private: //! Initialize by reading state from \p traverser. diff --git a/include/maths/COneOfNPrior.h b/include/maths/COneOfNPrior.h index f04e54ebe0..6df0d101d8 100644 --- a/include/maths/COneOfNPrior.h +++ b/include/maths/COneOfNPrior.h @@ -46,7 +46,7 @@ struct SDistributionRestoreParams; //! value semantics and manage the heap. class MATHS_EXPORT COneOfNPrior : public CPrior { public: - using TPriorPtr = std::shared_ptr; + using TPriorPtr = std::unique_ptr; using TPriorPtrVec = std::vector; using TPriorCPtrVec = std::vector; using TDoublePriorPtrPr = std::pair; diff --git a/include/maths/COrderings.h b/include/maths/COrderings.h index eae1edccb9..99e7df26ee 100644 --- a/include/maths/COrderings.h +++ b/include/maths/COrderings.h @@ -331,6 +331,11 @@ class COrderings : private core::CNonInstantiatable { return SPtrLess::less(lhs.get(), rhs.get()); } + template + bool operator()(const std::unique_ptr& lhs, const std::unique_ptr& rhs) { + return SPtrLess::less(lhs.get(), rhs.get()); + } + template bool operator()(const std::pair& lhs, const std::pair& rhs) const { return lexicographical_compare(lhs.first, lhs.second, rhs.first, @@ -372,6 +377,11 @@ class COrderings : private core::CNonInstantiatable { return SPtrGreater::greater(lhs.get(), rhs.get()); } + template + bool operator()(const std::unique_ptr& lhs, const std::unique_ptr& rhs) { + return SPtrLess::less(lhs.get(), rhs.get()); + } + template bool operator()(const std::pair& lhs, const std::pair& rhs) const { return lexicographical_compare(lhs.first, lhs.second, rhs.first, diff --git a/include/maths/CPriorStateSerialiser.h b/include/maths/CPriorStateSerialiser.h index ddf0977cf0..1b532bc688 100644 --- a/include/maths/CPriorStateSerialiser.h +++ b/include/maths/CPriorStateSerialiser.h @@ -38,14 +38,21 @@ struct SDistributionRestoreParams; //! compatibility in the future as the classes evolve. class MATHS_EXPORT CPriorStateSerialiser { public: - using TPriorPtr = std::shared_ptr; - using TMultivariatePriorPtr = std::shared_ptr; + using TPriorUPtr = std::unique_ptr; + using TPriorSPtr = std::shared_ptr; + using TMultivariatePriorPtr = std::unique_ptr; public: //! Construct the appropriate CPrior sub-class from its state //! document representation. Sets \p ptr to NULL on failure. bool operator()(const SDistributionRestoreParams& params, - TPriorPtr& ptr, + TPriorUPtr& ptr, + core::CStateRestoreTraverser& traverser) const; + + //! Construct the appropriate CPrior sub-class from its state + //! document representation. Sets \p ptr to NULL on failure. + bool operator()(const SDistributionRestoreParams& params, + TPriorSPtr& ptr, core::CStateRestoreTraverser& traverser) const; //! Persist state by passing information to the supplied inserter diff --git a/include/maths/CSeasonalComponentAdaptiveBucketing.h b/include/maths/CSeasonalComponentAdaptiveBucketing.h index cfc4ddaf84..1d4a23aaa4 100644 --- a/include/maths/CSeasonalComponentAdaptiveBucketing.h +++ b/include/maths/CSeasonalComponentAdaptiveBucketing.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,6 @@ class CStatePersistInserter; class CStateRestoreTraverser; } namespace maths { -class CSeasonalTime; //! \brief An adaptive bucketing of the value of a periodic function. //! @@ -181,7 +181,7 @@ class MATHS_EXPORT CSeasonalComponentAdaptiveBucketing : private CAdaptiveBucket //@} private: - using TSeasonalTimePtr = std::shared_ptr; + using TSeasonalTimePtr = std::unique_ptr; //! \brief The state maintained for each bucket. struct SBucket { diff --git a/include/maths/CSeasonalTime.h b/include/maths/CSeasonalTime.h index 3cdd22d208..2a6212e08e 100644 --- a/include/maths/CSeasonalTime.h +++ b/include/maths/CSeasonalTime.h @@ -246,7 +246,7 @@ class MATHS_EXPORT CSeasonalTimeStateSerializer { public: //! Shared pointer to the CTimeSeriesDecompositionInterface abstract //! base class. - using TSeasonalTimePtr = std::shared_ptr; + using TSeasonalTimePtr = std::unique_ptr; public: //! Construct the appropriate CSeasonalTime sub-class from its state diff --git a/include/maths/CTimeSeriesDecompositionDetail.h b/include/maths/CTimeSeriesDecompositionDetail.h index 34aac7e1c6..81a7bdb50b 100644 --- a/include/maths/CTimeSeriesDecompositionDetail.h +++ b/include/maths/CTimeSeriesDecompositionDetail.h @@ -12,8 +12,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -50,7 +52,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { }; //! \brief The message passed to add a point. - struct MATHS_EXPORT SAddValue : public SMessage, private core::CNonCopyable { + struct MATHS_EXPORT SAddValue : public SMessage { SAddValue(core_t::TTime time, core_t::TTime lastTime, double value, @@ -60,6 +62,8 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { double calendar, const TPredictor& predictor, const CPeriodicityHypothesisTestsConfig& periodicityTestConfig); + SAddValue(const SAddValue&) = delete; + SAddValue& operator=(const SAddValue&) = delete; //! The value to add. double s_Value; @@ -120,10 +124,12 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { //! \brief The basic interface for one aspect of the modeling of a time //! series decomposition. - class MATHS_EXPORT CHandler : core::CNonCopyable { + class MATHS_EXPORT CHandler { public: CHandler(); - virtual ~CHandler(); + virtual ~CHandler() = default; + CHandler(const CHandler&) = delete; + CHandler& operator=(const CHandler&) = delete; //! Add a value. virtual void handle(const SAddValue& message); @@ -149,8 +155,12 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { }; //! \brief Manages communication between handlers. - class MATHS_EXPORT CMediator : core::CNonCopyable { + class MATHS_EXPORT CMediator { public: + CMediator() = default; + CMediator(const CMediator&) = delete; + CMediator& operator=(const CMediator&) = delete; + //! Forward \p message to all registered models. template void forward(const M& message) const; @@ -183,6 +193,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { public: CPeriodicityTest(double decayRate, core_t::TTime bucketLength); CPeriodicityTest(const CPeriodicityTest& other, bool isForForecast = false); + CPeriodicityTest& operator=(const CPeriodicityTest&) = delete; //! Initialize by reading state from \p traverser. bool acceptRestoreTraverser(core::CStateRestoreTraverser& traverser); @@ -228,7 +239,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { private: using TTimeAry = boost::array; - using TExpandingWindowPtr = std::shared_ptr; + using TExpandingWindowPtr = std::unique_ptr; using TExpandingWindowPtrAry = boost::array; private: @@ -272,6 +283,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { public: CCalendarTest(double decayRate, core_t::TTime bucketLength); CCalendarTest(const CCalendarTest& other, bool isForForecast = false); + CCalendarTest& operator=(const CCalendarTest&) = delete; //! Initialize by reading state from \p traverser. bool acceptRestoreTraverser(core::CStateRestoreTraverser& traverser); @@ -305,7 +317,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { std::size_t memoryUsage() const; private: - using TCalendarCyclicTestPtr = std::shared_ptr; + using TCalendarCyclicTestPtr = std::unique_ptr; private: //! Handle \p symbol. @@ -342,10 +354,12 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { CComponents(const CComponents& other); //! \brief Watches to see if the seasonal components state changes. - class MATHS_EXPORT CScopeNotifyOnStateChange : core::CNonCopyable { + class MATHS_EXPORT CScopeNotifyOnStateChange { public: CScopeNotifyOnStateChange(CComponents& components); ~CScopeNotifyOnStateChange(); + CScopeNotifyOnStateChange(const CScopeNotifyOnStateChange&) = delete; + CScopeNotifyOnStateChange& operator=(const CScopeNotifyOnStateChange&) = delete; //! Check if the seasonal component's state changed. bool changed() const; @@ -663,7 +677,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { TComponentErrorsVec m_PredictionErrors; }; - using TSeasonalPtr = std::shared_ptr; + using TSeasonalPtr = std::unique_ptr; //! \brief Calendar periodic components of the decomposition. class MATHS_EXPORT CCalendar { @@ -738,7 +752,7 @@ class MATHS_EXPORT CTimeSeriesDecompositionDetail { TComponentErrorsVec m_PredictionErrors; }; - using TCalendarPtr = std::shared_ptr; + using TCalendarPtr = std::unique_ptr; private: //! Get the total size of the components. diff --git a/include/maths/CTimeSeriesDecompositionStateSerialiser.h b/include/maths/CTimeSeriesDecompositionStateSerialiser.h index 732f09474a..380345aa30 100644 --- a/include/maths/CTimeSeriesDecompositionStateSerialiser.h +++ b/include/maths/CTimeSeriesDecompositionStateSerialiser.h @@ -39,16 +39,22 @@ struct STimeSeriesDecompositionRestoreParams; //! compatibility in the future as the classes evolve. class MATHS_EXPORT CTimeSeriesDecompositionStateSerialiser { public: - //! Shared pointer to the CTimeSeriesDecompositionInterface abstract - //! base class. - using TDecompositionPtr = std::shared_ptr; + using TDecompositionUPtr = std::unique_ptr; + using TDecompositionSPtr = std::shared_ptr; public: //! Construct the appropriate CTimeSeriesDecompositionInterface //! sub-class from its state document representation. Sets \p result //! to NULL on failure. bool operator()(const STimeSeriesDecompositionRestoreParams& params, - TDecompositionPtr& result, + TDecompositionUPtr& result, + core::CStateRestoreTraverser& traverser) const; + + //! Construct the appropriate CTimeSeriesDecompositionInterface + //! sub-class from its state document representation. Sets \p result + //! to NULL on failure. + bool operator()(const STimeSeriesDecompositionRestoreParams& params, + TDecompositionSPtr& result, core::CStateRestoreTraverser& traverser) const; //! Persist state by passing information to the supplied inserter. diff --git a/include/maths/CTimeSeriesModel.h b/include/maths/CTimeSeriesModel.h index 8574c1df5e..72e5a34b88 100644 --- a/include/maths/CTimeSeriesModel.h +++ b/include/maths/CTimeSeriesModel.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -21,7 +22,6 @@ namespace ml { namespace maths { class CDecayRateController; -class CMultivariatePrior; class CPrior; class CTimeSeriesDecompositionInterface; class CTimeSeriesAnomalyModel; @@ -74,6 +74,8 @@ class MATHS_EXPORT CUnivariateTimeSeriesModel : public CModel { core::CStateRestoreTraverser& traverser); ~CUnivariateTimeSeriesModel(); + const CUnivariateTimeSeriesModel& operator=(const CUnivariateTimeSeriesModel&) = delete; + //! Get the model identifier. virtual std::size_t identifier() const; @@ -211,14 +213,14 @@ class MATHS_EXPORT CUnivariateTimeSeriesModel : public CModel { using TDouble2VecWeightsAryVec = std::vector; using TVector = CVectorNx1; using TVectorMeanAccumulator = CBasicStatistics::SSampleMean::TAccumulator; - using TDecayRateController2AryPtr = std::shared_ptr; + using TDecayRateController2AryPtr = std::unique_ptr; using TPriorPtr = std::shared_ptr; - using TAnomalyModelPtr = std::shared_ptr; + using TAnomalyModelPtr = std::unique_ptr; using TMultivariatePriorCPtrSizePr = std::pair; using TMultivariatePriorCPtrSizePr1Vec = core::CSmallVector; using TModelCPtr1Vec = core::CSmallVector; - using TChangeDetectorPtr = std::shared_ptr; + using TChangeDetectorPtr = std::unique_ptr; private: CUnivariateTimeSeriesModel(const CUnivariateTimeSeriesModel& other, @@ -269,9 +271,13 @@ class MATHS_EXPORT CUnivariateTimeSeriesModel : public CModel { TDecayRateController2AryPtr m_Controllers; //! The time series trend decomposition. + //! + //! \note This can be temporarily be shared with the change detector. TDecompositionPtr m_TrendModel; //! The time series' residual model. + //! + //! \note This can be temporarily be shared with the change detector. TPriorPtr m_ResidualModel; //! A model for time periods when the basic model can't predict the @@ -299,7 +305,7 @@ class MATHS_EXPORT CUnivariateTimeSeriesModel : public CModel { //! \brief Manages the creation correlate models. class MATHS_EXPORT CTimeSeriesCorrelateModelAllocator { public: - using TMultivariatePriorPtr = std::shared_ptr; + using TMultivariatePriorPtr = std::unique_ptr; public: virtual ~CTimeSeriesCorrelateModelAllocator() = default; @@ -346,7 +352,7 @@ class MATHS_EXPORT CTimeSeriesCorrelations { using TSize2Vec = core::CSmallVector; using TSize2Vec1Vec = core::CSmallVector; using TSizeSizePr = std::pair; - using TMultivariatePriorPtr = std::shared_ptr; + using TMultivariatePriorPtr = std::unique_ptr; using TMultivariatePriorPtrDoublePr = std::pair; using TSizeSizePrMultivariatePriorPtrDoublePrUMap = boost::unordered_map; @@ -421,6 +427,8 @@ class MATHS_EXPORT CTimeSeriesCorrelations { using TModelCPtr1Vec = core::CSmallVector; using TSizeSizePrMultivariatePriorPtrDoublePrPr = std::pair; + using TConstSizeSizePrMultivariatePriorPtrDoublePrPr = + std::pair; private: CTimeSeriesCorrelations(const CTimeSeriesCorrelations& other, @@ -441,7 +449,7 @@ class MATHS_EXPORT CTimeSeriesCorrelations { core::CStateRestoreTraverser& traverser); //! Persist the \p model passing information to \p inserter. - static void persist(const TSizeSizePrMultivariatePriorPtrDoublePrPr& model, + static void persist(const TConstSizeSizePrMultivariatePriorPtrDoublePrPr& model, core::CStatePersistInserter& inserter); //! Add the time series identified by \p id. @@ -523,6 +531,9 @@ class MATHS_EXPORT CMultivariateTimeSeriesModel : public CModel { CMultivariateTimeSeriesModel(const CMultivariateTimeSeriesModel& other); CMultivariateTimeSeriesModel(const SModelRestoreParams& params, core::CStateRestoreTraverser& traverser); + ~CMultivariateTimeSeriesModel(); + + const CMultivariateTimeSeriesModel& operator=(const CMultivariateTimeSeriesModel&) = delete; //! Returns 0 since these models don't need a unique identifier. virtual std::size_t identifier() const; @@ -657,9 +668,9 @@ class MATHS_EXPORT CMultivariateTimeSeriesModel : public CModel { using TDouble2VecWeightsAryVec = std::vector; using TVector = CVectorNx1; using TVectorMeanAccumulator = CBasicStatistics::SSampleMean::TAccumulator; - using TDecayRateController2AryPtr = std::shared_ptr; - using TMultivariatePriorPtr = std::shared_ptr; - using TAnomalyModelPtr = std::shared_ptr; + using TDecayRateController2AryPtr = std::unique_ptr; + using TMultivariatePriorPtr = std::unique_ptr; + using TAnomalyModelPtr = std::unique_ptr; private: //! Update the trend with \p samples. diff --git a/include/model/CAnomalyDetector.h b/include/model/CAnomalyDetector.h index 71c40ce92a..e1b6639f50 100644 --- a/include/model/CAnomalyDetector.h +++ b/include/model/CAnomalyDetector.h @@ -73,7 +73,7 @@ class MODEL_EXPORT CAnomalyDetector : private core::CNonCopyable { using TDataGathererPtr = std::shared_ptr; using TModelFactoryCPtr = std::shared_ptr; - using TModelPtr = std::shared_ptr; + using TModelPtr = std::unique_ptr; //! A shared pointer to an instance of this class using TAnomalyDetectorPtr = std::shared_ptr; diff --git a/include/model/CAnomalyDetectorModel.h b/include/model/CAnomalyDetectorModel.h index 695f277f26..e2e5fa0813 100644 --- a/include/model/CAnomalyDetectorModel.h +++ b/include/model/CAnomalyDetectorModel.h @@ -8,7 +8,6 @@ #define INCLUDED_ml_model_CAnomalyDetectorModel_h #include -#include #include #include #include @@ -121,7 +120,7 @@ struct SAttributeProbability; //! //! The hierarchy is non-copyable because we don't currently need to be //! able to copy models and the "correct" copy semantics are not obvious. -class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { +class MODEL_EXPORT CAnomalyDetectorModel { friend class CModelDetailsView; public: @@ -152,16 +151,20 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { using TFeatureInfluenceCalculatorCPtrPrVec = std::vector; using TFeatureInfluenceCalculatorCPtrPrVecVec = std::vector; - using TMultivariatePriorPtr = std::shared_ptr; - using TFeatureMultivariatePriorPtrPr = std::pair; - using TFeatureMultivariatePriorPtrPrVec = std::vector; - using TMathsModelPtr = std::shared_ptr; - using TMathsModelPtrVec = std::vector; + using TMathsModelSPtr = std::shared_ptr; + using TFeatureMathsModelSPtrPr = std::pair; + using TFeatureMathsModelSPtrPrVec = std::vector; + using TMathsModelUPtr = std::unique_ptr; + using TMathsModelUPtrVec = std::vector; + using TMultivariatePriorSPtr = std::shared_ptr; + using TFeatureMultivariatePriorSPtrPr = std::pair; + using TFeatureMultivariatePriorSPtrPrVec = std::vector; + using TCorrelationsPtr = std::unique_ptr; + using TFeatureCorrelationsPtrPr = std::pair; + using TFeatureCorrelationsPtrPrVec = std::vector; using TDataGathererPtr = std::shared_ptr; - using TModelPtr = std::shared_ptr; - using TModelCPtr = std::shared_ptr; - using TCorrelationsPtr = std::shared_ptr; using CModelDetailsViewPtr = std::auto_ptr; + using TModelPtr = std::unique_ptr; public: //! A value used to indicate a time variable is unset @@ -186,6 +189,7 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { CAnomalyDetectorModel(bool isForPersistence, const CAnomalyDetectorModel& other); virtual ~CAnomalyDetectorModel() = default; + CAnomalyDetectorModel& operator=(const CAnomalyDetectorModel&) = delete; //@} //! Get a human understandable description of the model for debugging. @@ -497,7 +501,11 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { //! \brief The feature models. struct MODEL_EXPORT SFeatureModels { - SFeatureModels(model_t::EFeature feature, TMathsModelPtr newModel); + SFeatureModels(model_t::EFeature feature, TMathsModelSPtr newModel); + SFeatureModels(const SFeatureModels&) = delete; + SFeatureModels& operator=(const SFeatureModels&) = delete; + SFeatureModels(SFeatureModels&&) = default; + SFeatureModels& operator=(SFeatureModels&&) = default; //! Restore the models reading state from \p traverser. bool acceptRestoreTraverser(const SModelParams& params, @@ -513,17 +521,21 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { //! The feature. model_t::EFeature s_Feature; //! A prototype model. - TMathsModelPtr s_NewModel; + TMathsModelSPtr s_NewModel; //! The person models. - TMathsModelPtrVec s_Models; + TMathsModelUPtrVec s_Models; }; using TFeatureModelsVec = std::vector; //! \brief The feature correlate models. struct MODEL_EXPORT SFeatureCorrelateModels { SFeatureCorrelateModels(model_t::EFeature feature, - TMultivariatePriorPtr modelPrior, - TCorrelationsPtr model); + const TMultivariatePriorSPtr& modelPrior, + TCorrelationsPtr&& model); + SFeatureCorrelateModels(const SFeatureCorrelateModels&) = delete; + SFeatureCorrelateModels& operator=(const SFeatureCorrelateModels&) = delete; + SFeatureCorrelateModels(SFeatureCorrelateModels&&) = default; + SFeatureCorrelateModels& operator=(SFeatureCorrelateModels&&) = default; //! Restore the models reading state from \p traverser. bool acceptRestoreTraverser(const SModelParams& params, @@ -539,7 +551,7 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { //! The feature. model_t::EFeature s_Feature; //! The prototype prior for a correlate model. - TMultivariatePriorPtr s_ModelPrior; + TMultivariatePriorSPtr s_ModelPrior; //! The correlate models. TCorrelationsPtr s_Models; }; @@ -549,6 +561,7 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { class CTimeSeriesCorrelateModelAllocator : public maths::CTimeSeriesCorrelateModelAllocator { public: using TMemoryUsage = std::function; + using TMultivariatePriorUPtr = TMultivariatePriorPtr; public: CTimeSeriesCorrelateModelAllocator(CResourceMonitor& resourceMonitor, @@ -569,10 +582,10 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { virtual std::size_t chunkSize() const; //! Create a new prior for a correlation model. - virtual TMultivariatePriorPtr newPrior() const; + virtual TMultivariatePriorUPtr newPrior() const; //! Set the prototype prior. - void prototypePrior(const TMultivariatePriorPtr& prior); + void prototypePrior(const TMultivariatePriorSPtr& prior); private: //! The global resource monitor. @@ -584,7 +597,7 @@ class MODEL_EXPORT CAnomalyDetectorModel : private core::CNonCopyable { //! The maximum permitted number of correlations which can be modeled. std::size_t m_MaxNumberCorrelations; //! The prototype correlate prior. - TMultivariatePriorPtr m_PrototypePrior; + TMultivariatePriorSPtr m_PrototypePrior; }; protected: diff --git a/include/model/CCountingModelFactory.h b/include/model/CCountingModelFactory.h index 56b4a7580c..820459881d 100644 --- a/include/model/CCountingModelFactory.h +++ b/include/model/CCountingModelFactory.h @@ -79,12 +79,12 @@ class MODEL_EXPORT CCountingModelFactory : public CModelFactory { virtual TPriorPtr defaultPrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for \p feature which is a stub. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for pairs of correlated time series //! of \p feature which is a stub. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const; //@} diff --git a/include/model/CEventRateModel.h b/include/model/CEventRateModel.h index b9eb787ef8..7d80d524d0 100644 --- a/include/model/CEventRateModel.h +++ b/include/model/CEventRateModel.h @@ -97,9 +97,9 @@ class MODEL_EXPORT CEventRateModel : public CIndividualModel { //! buckets. CEventRateModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const maths::CMultinomialConjugate& probabilityPrior, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector); @@ -110,9 +110,9 @@ class MODEL_EXPORT CEventRateModel : public CIndividualModel { //! and so must be sampled for before this model can be used. CEventRateModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser); diff --git a/include/model/CEventRateModelFactory.h b/include/model/CEventRateModelFactory.h index f1b9dcff9e..34b72e38b0 100644 --- a/include/model/CEventRateModelFactory.h +++ b/include/model/CEventRateModelFactory.h @@ -86,7 +86,7 @@ class MODEL_EXPORT CEventRateModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for pairs of correlated time series @@ -94,7 +94,7 @@ class MODEL_EXPORT CEventRateModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const; //@} diff --git a/include/model/CEventRatePopulationModel.h b/include/model/CEventRatePopulationModel.h index a8f19fa2f7..3d28b9d326 100644 --- a/include/model/CEventRatePopulationModel.h +++ b/include/model/CEventRatePopulationModel.h @@ -74,12 +74,6 @@ namespace model { //! state can be maintained. class MODEL_EXPORT CEventRatePopulationModel : public CPopulationModel { public: - using TFeatureMathsModelPtrPr = std::pair; - using TFeatureMathsModelPtrPrVec = std::vector; - using TFeatureMathsModelPtrVecPr = std::pair; - using TFeatureMathsModelPtrVecPrVec = std::vector; - using TFeatureCorrelationsPtrPr = std::pair; - using TFeatureCorrelationsPtrPrVec = std::vector; using TSizeSizePrUInt64Pr = std::pair; using TSizeSizePrUInt64PrVec = std::vector; using TFeatureData = SEventRateFeatureData; @@ -133,9 +127,9 @@ class MODEL_EXPORT CEventRatePopulationModel : public CPopulationModel { //! and so must be sampled for before this model can be used. CEventRatePopulationModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector); @@ -145,9 +139,9 @@ class MODEL_EXPORT CEventRatePopulationModel : public CPopulationModel { //! and so must be sampled for before this model can be used. CEventRatePopulationModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser); @@ -158,6 +152,8 @@ class MODEL_EXPORT CEventRatePopulationModel : public CPopulationModel { //! redundant except to create a signature that will not be mistaken //! for a general purpose copy constructor. CEventRatePopulationModel(bool isForPersistence, const CEventRatePopulationModel& other); + CEventRatePopulationModel(const CEventRatePopulationModel&) = delete; + CEventRatePopulationModel& operator=(const CEventRatePopulationModel&) = delete; //@} //! \name Persistence @@ -309,9 +305,9 @@ class MODEL_EXPORT CEventRatePopulationModel : public CPopulationModel { private: //! Initialize the feature models. - void initialize(const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels); + void initialize(const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels); //! Get the start time of the current bucket. virtual core_t::TTime currentBucketStartTime() const; diff --git a/include/model/CEventRatePopulationModelFactory.h b/include/model/CEventRatePopulationModelFactory.h index 887ee60ec2..bec5da8575 100644 --- a/include/model/CEventRatePopulationModelFactory.h +++ b/include/model/CEventRatePopulationModelFactory.h @@ -87,7 +87,7 @@ class MODEL_EXPORT CEventRatePopulationModelFactory final : public CModelFactory //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for pairs of correlated time series @@ -95,7 +95,7 @@ class MODEL_EXPORT CEventRatePopulationModelFactory final : public CModelFactory //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const; //@} diff --git a/include/model/CForecastModelPersist.h b/include/model/CForecastModelPersist.h index 079f42ad6e..49450c09ef 100644 --- a/include/model/CForecastModelPersist.h +++ b/include/model/CForecastModelPersist.h @@ -39,7 +39,7 @@ namespace model { //! locally never leaving process/io boundaries. class MODEL_EXPORT CForecastModelPersist final { public: - using TMathsModelPtr = std::shared_ptr; + using TMathsModelPtr = std::unique_ptr; public: class MODEL_EXPORT CPersist final { diff --git a/include/model/CIndividualModel.h b/include/model/CIndividualModel.h index 0d3f380bc0..b2ed9e62fc 100644 --- a/include/model/CIndividualModel.h +++ b/include/model/CIndividualModel.h @@ -53,12 +53,6 @@ class MODEL_EXPORT CIndividualModel : public CAnomalyDetectorModel { using TFeatureSizeSizeTriple = core::CTriple; using TFeatureSizeSizeTripleDouble1VecUMap = boost::unordered_map; - using TFeatureMathsModelPtrPr = std::pair; - using TFeatureMathsModelPtrPrVec = std::vector; - using TFeatureMathsModelPtrVecPr = std::pair; - using TFeatureMathsModelPtrVecPrVec = std::vector; - using TFeatureCorrelationsPtrPr = std::pair; - using TFeatureCorrelationsPtrPrVec = std::vector; public: //! \name Life-cycle @@ -76,9 +70,9 @@ class MODEL_EXPORT CIndividualModel : public CAnomalyDetectorModel { //! and so must be sampled for before this model can be used. CIndividualModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators); //! Create a copy that will result in the same persisted state as the @@ -87,6 +81,8 @@ class MODEL_EXPORT CIndividualModel : public CAnomalyDetectorModel { //! redundant except to create a signature that will not be mistaken //! for a general purpose copy constructor. CIndividualModel(bool isForPersistence, const CIndividualModel& other); + CIndividualModel(const CIndividualModel&) = delete; + CIndividualModel& operator=(const CIndividualModel&) = delete; //@} //! Returns false. diff --git a/include/model/CMetricModel.h b/include/model/CMetricModel.h index 7946249bd2..a7eca11e4e 100644 --- a/include/model/CMetricModel.h +++ b/include/model/CMetricModel.h @@ -91,9 +91,9 @@ class MODEL_EXPORT CMetricModel : public CIndividualModel { //! buckets. CMetricModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector); @@ -103,9 +103,9 @@ class MODEL_EXPORT CMetricModel : public CIndividualModel { //! and so must be sampled for before this model can be used. CMetricModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser); diff --git a/include/model/CMetricModelFactory.h b/include/model/CMetricModelFactory.h index 267bcf34d8..8b77d304ed 100644 --- a/include/model/CMetricModelFactory.h +++ b/include/model/CMetricModelFactory.h @@ -86,7 +86,7 @@ class MODEL_EXPORT CMetricModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for pairs of correlated time series @@ -94,7 +94,7 @@ class MODEL_EXPORT CMetricModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const; //@} diff --git a/include/model/CMetricPopulationModel.h b/include/model/CMetricPopulationModel.h index a851ce1c48..601f3d7622 100644 --- a/include/model/CMetricPopulationModel.h +++ b/include/model/CMetricPopulationModel.h @@ -53,12 +53,6 @@ namespace model { //! state can be maintained. class MODEL_EXPORT CMetricPopulationModel : public CPopulationModel { public: - using TFeatureMathsModelPtrPr = std::pair; - using TFeatureMathsModelPtrPrVec = std::vector; - using TFeatureMathsModelPtrVecPr = std::pair; - using TFeatureMathsModelPtrVecPrVec = std::vector; - using TFeatureCorrelationsPtrPr = std::pair; - using TFeatureCorrelationsPtrPrVec = std::vector; using TFeatureData = SMetricFeatureData; using TSizeSizePrFeatureDataPr = std::pair; using TSizeSizePrFeatureDataPrVec = std::vector; @@ -109,9 +103,9 @@ class MODEL_EXPORT CMetricPopulationModel : public CPopulationModel { //! and so must be sampled for before this model can be used. CMetricPopulationModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector); @@ -121,9 +115,9 @@ class MODEL_EXPORT CMetricPopulationModel : public CPopulationModel { //! and so must be sampled for before this model can be used. CMetricPopulationModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser); @@ -134,6 +128,8 @@ class MODEL_EXPORT CMetricPopulationModel : public CPopulationModel { //! redundant except to create a signature that will not be mistaken //! for a general purpose copy constructor. CMetricPopulationModel(bool isForPersistence, const CMetricPopulationModel& other); + CMetricPopulationModel(const CMetricPopulationModel&) = delete; + CMetricPopulationModel& operator=(const CMetricPopulationModel&) = delete; //@} //! Returns false. @@ -285,9 +281,9 @@ class MODEL_EXPORT CMetricPopulationModel : public CPopulationModel { private: //! Initialize the feature models. - void initialize(const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels); + void initialize(const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels); //! Get the start time of the current bucket. virtual core_t::TTime currentBucketStartTime() const; diff --git a/include/model/CMetricPopulationModelFactory.h b/include/model/CMetricPopulationModelFactory.h index cd65ec1795..9ba356514b 100644 --- a/include/model/CMetricPopulationModelFactory.h +++ b/include/model/CMetricPopulationModelFactory.h @@ -87,7 +87,7 @@ class MODEL_EXPORT CMetricPopulationModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const; //! Get the default prior for pairs of correlated time series @@ -95,7 +95,7 @@ class MODEL_EXPORT CMetricPopulationModelFactory final : public CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const; //@} diff --git a/include/model/CModelFactory.h b/include/model/CModelFactory.h index dfc0884ee4..4e4b9a69b0 100644 --- a/include/model/CModelFactory.h +++ b/include/model/CModelFactory.h @@ -73,17 +73,18 @@ class MODEL_EXPORT CModelFactory { using TStrCRef = boost::reference_wrapper; using TStrCRefVec = std::vector; using TDataGathererPtr = std::shared_ptr; - using TPriorPtr = std::shared_ptr; - using TMultivariatePriorPtr = std::shared_ptr; - using TFeatureMultivariatePriorPtrPr = std::pair; - using TFeatureMultivariatePriorPtrPrVec = std::vector; + using TPriorPtr = std::unique_ptr; + using TMultivariatePriorSPtr = std::shared_ptr; + using TMultivariatePriorUPtr = std::unique_ptr; + using TFeatureMultivariatePriorSPtrPr = std::pair; + using TFeatureMultivariatePriorSPtrPrVec = std::vector; using TDecompositionCPtr = std::shared_ptr; using TMathsModelPtr = std::shared_ptr; - using TCorrelationsPtr = std::shared_ptr; - using TFeatureCorrelationsPtrPr = std::pair; - using TFeatureCorrelationsPtrPrVec = std::vector; using TFeatureMathsModelPtrPr = std::pair; using TFeatureMathsModelPtrPrVec = std::vector; + using TCorrelationsPtr = std::unique_ptr; + using TFeatureCorrelationsPtrPr = std::pair; + using TFeatureCorrelationsPtrPrVec = std::vector; using TModelPtr = std::shared_ptr; using TModelCPtr = std::shared_ptr; using TInfluenceCalculatorCPtr = std::shared_ptr; @@ -198,21 +199,21 @@ class MODEL_EXPORT CModelFactory { //! Get the default correlate priors to use for correlated pairs of time //! series of \p features. - const TFeatureMultivariatePriorPtrPrVec& + const TFeatureMultivariatePriorSPtrPrVec& defaultCorrelatePriors(const TFeatureVec& features) const; //! Get the default models for correlations of \p features. - const TFeatureCorrelationsPtrPrVec& defaultCorrelates(const TFeatureVec& features) const; + TFeatureCorrelationsPtrPrVec defaultCorrelates(const TFeatureVec& features) const; //! Get the default prior to use for \p feature. TPriorPtr defaultPrior(model_t::EFeature feature) const; //! Get the default prior to use for multivariate \p feature. - TMultivariatePriorPtr defaultMultivariatePrior(model_t::EFeature feature) const; + TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature) const; //! Get the default prior to use for correlared pairs of time //! series for univariate \p feature. - TMultivariatePriorPtr defaultCorrelatePrior(model_t::EFeature feature) const; + TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature) const; //! Get the default prior for \p feature. //! @@ -225,7 +226,7 @@ class MODEL_EXPORT CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const = 0; //! Get the default prior for pairs of correlated time series @@ -233,7 +234,7 @@ class MODEL_EXPORT CModelFactory { //! //! \param[in] feature The feature for which to get the prior. //! \param[in] params The model parameters. - virtual TMultivariatePriorPtr + virtual TMultivariatePriorUPtr defaultCorrelatePrior(model_t::EFeature feature, const SModelParams& params) const = 0; //! Get the default prior to use for categorical data. @@ -364,7 +365,7 @@ class MODEL_EXPORT CModelFactory { virtual double minimumSeasonalVarianceScale() const = 0; protected: - using TMultivariatePriorPtrVec = std::vector; + using TMultivariatePriorUPtrVec = std::vector; using TOptionalSearchKey = boost::optional; protected: @@ -381,15 +382,15 @@ class MODEL_EXPORT CModelFactory { //! \param[in] dimension The dimension. //! \param[in] params The model parameters. //! \warning Up to ten dimensions are supported. - TMultivariatePriorPtr multivariateNormalPrior(std::size_t dimension, - const SModelParams& params) const; + TMultivariatePriorUPtr multivariateNormalPrior(std::size_t dimension, + const SModelParams& params) const; //! Get a multivariate multimodal prior with dimension \p dimension. //! //! \param[in] dimension The dimension. //! \param[in] params The model parameters. //! \warning Up to ten dimensions are supported. - TMultivariatePriorPtr + TMultivariatePriorUPtr multivariateMultimodalPrior(std::size_t dimension, const SModelParams& params, const maths::CMultivariatePrior& modePrior) const; @@ -399,9 +400,9 @@ class MODEL_EXPORT CModelFactory { //! \param[in] dimension The dimension. //! \param[in] params The model parameters. //! \param[in] models The component models to select between. - TMultivariatePriorPtr multivariateOneOfNPrior(std::size_t dimension, - const SModelParams& params, - const TMultivariatePriorPtrVec& models) const; + TMultivariatePriorUPtr multivariateOneOfNPrior(std::size_t dimension, + const SModelParams& params, + const TMultivariatePriorUPtrVec& models) const; //! Get the default prior for time-of-day and time-of-week modeling. //! This is just a mixture of normals which allows more modes than @@ -415,13 +416,12 @@ class MODEL_EXPORT CModelFactory { //! modes than we typically do. //! //! \param[in] params The model parameters. - TMultivariatePriorPtr latLongPrior(const SModelParams& params) const; + TMultivariatePriorUPtr latLongPrior(const SModelParams& params) const; private: using TFeatureVecMathsModelMap = std::map; using TFeatureVecMultivariatePriorMap = - std::map; - using TFeatureVecCorrelationsMap = std::map; + std::map; using TStrFeatureVecPr = std::pair; using TStrFeatureVecPrInfluenceCalculatorCPtrMap = std::map; @@ -449,9 +449,6 @@ class MODEL_EXPORT CModelFactory { //! A cache of priors for correlate pairs of collections of features. mutable TFeatureVecMultivariatePriorMap m_CorrelatePriorCache; - //! A cache of models of the correlations of collections of features. - mutable TFeatureVecCorrelationsMap m_CorrelationsCache; - //! A cache of influence calculators for collections of features. mutable TStrFeatureVecPrInfluenceCalculatorCPtrMap m_InfluenceCalculatorCache; }; diff --git a/lib/core/unittest/CMemoryUsageTest.cc b/lib/core/unittest/CMemoryUsageTest.cc index da49785758..17f9c9b6f7 100644 --- a/lib/core/unittest/CMemoryUsageTest.cc +++ b/lib/core/unittest/CMemoryUsageTest.cc @@ -508,7 +508,8 @@ void CMemoryUsageTest::testUsage() { LOG_DEBUG(<< "expected dynamic size = " << sizeof(SBar) + sizeof(SFoo) * value.s_State.capacity()); CPPUNIT_ASSERT_EQUAL(core::CMemory::dynamicSize(pointer), - sizeof(SBar) + sizeof(SFoo) * value.s_State.capacity()); + sizeof(long) + sizeof(SBar) + + sizeof(SFoo) * value.s_State.capacity()); } { @@ -625,7 +626,7 @@ void CMemoryUsageTest::testUsage() { core::CMemory::dynamicSize(basederivedPtr)); TBasePtr sPtr(new CDerived(6)); - CPPUNIT_ASSERT_EQUAL(sPtr->memoryUsage() + sizeof(CDerived), + CPPUNIT_ASSERT_EQUAL(sPtr->memoryUsage() + sizeof(long) + sizeof(CDerived), core::CMemory::dynamicSize(sPtr)); } { @@ -657,9 +658,11 @@ void CMemoryUsageTest::testUsage() { std::size_t total = core::CMemory::dynamicSize(vec); std::size_t calc = vec.capacity() * sizeof(TBasePtr); for (std::size_t i = 0; i < 6; ++i) { + calc += sizeof(long); calc += static_cast(vec[i].get())->memoryUsage(); calc += sizeof(CBase); } + calc += sizeof(long); calc += static_cast(vec[6].get())->memoryUsage(); calc += sizeof(CDerived); CPPUNIT_ASSERT_EQUAL(calc, total); @@ -1113,8 +1116,8 @@ void CMemoryUsageTest::testSharedPointer() { // = 688 std::size_t expectedSize = - vec1.capacity() * sizeof(TIntVecPtr) + - vec2.capacity() * sizeof(TIntVecPtr) + 3 * sizeof(TIntVec) + + vec1.capacity() * sizeof(TIntVecPtr) + vec2.capacity() * sizeof(TIntVecPtr) + + 3 * (sizeof(long) + sizeof(TIntVec)) + (vec1[0]->capacity() + vec1[1]->capacity() + vec1[3]->capacity()) * sizeof(int); LOG_DEBUG(<< "Expected: " << expectedSize << ", actual: " diff --git a/lib/maths/CClustererStateSerialiser.cc b/lib/maths/CClustererStateSerialiser.cc index 124d4b2191..5bec0134b0 100644 --- a/lib/maths/CClustererStateSerialiser.cc +++ b/lib/maths/CClustererStateSerialiser.cc @@ -11,6 +11,8 @@ #include #include +#include + namespace ml { namespace maths { @@ -31,10 +33,10 @@ bool CClustererStateSerialiser::operator()(const SDistributionRestoreParams& par do { const std::string& name = traverser.name(); if (name == CClustererTypes::X_MEANS_ONLINE_1D_TAG) { - ptr.reset(new CXMeansOnline1d(params, splitFunc, mergeFunc, traverser)); + ptr = boost::make_unique(params, splitFunc, mergeFunc, traverser); ++numResults; } else if (name == CClustererTypes::K_MEANS_ONLINE_1D_TAG) { - ptr.reset(new CKMeansOnline1d(params, traverser)); + ptr = boost::make_unique(params, traverser); ++numResults; } else { LOG_ERROR(<< "No clusterer corresponds to node name " << traverser.name()); diff --git a/lib/maths/CModelStateSerialiser.cc b/lib/maths/CModelStateSerialiser.cc index adbde792d3..ebe0d14b71 100644 --- a/lib/maths/CModelStateSerialiser.cc +++ b/lib/maths/CModelStateSerialiser.cc @@ -9,6 +9,7 @@ #include #include +#include namespace ml { namespace maths { @@ -26,13 +27,13 @@ bool CModelStateSerialiser::operator()(const SModelRestoreParams& params, do { const std::string& name = traverser.name(); if (name == UNIVARIATE_TIME_SERIES_TAG) { - result.reset(new CUnivariateTimeSeriesModel(params, traverser)); + result = boost::make_unique(params, traverser); ++numResults; } else if (name == MULTIVARIATE_TIME_SERIES_TAG) { - result.reset(new CMultivariateTimeSeriesModel(params, traverser)); + result = boost::make_unique(params, traverser); ++numResults; } else if (name == MODEL_STUB_TAG) { - result.reset(new CModelStub()); + result = boost::make_unique(); ++numResults; } else { LOG_ERROR(<< "No model corresponds to name " << traverser.name()); diff --git a/lib/maths/CMultimodalPrior.cc b/lib/maths/CMultimodalPrior.cc index 3a5cc55c4f..50e507d487 100644 --- a/lib/maths/CMultimodalPrior.cc +++ b/lib/maths/CMultimodalPrior.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -92,7 +93,7 @@ CMultimodalPrior::CMultimodalPrior(maths_t::EDataType dataType, normals.emplace_back(dataType, moments_, decayRate); } - m_Clusterer.reset(new CKMeansOnline1d(normals)); + m_Clusterer = boost::make_unique(normals); m_Modes.reserve(normals.size()); for (std::size_t i = 0u; i < normals.size(); ++i) { @@ -104,7 +105,7 @@ CMultimodalPrior::CMultimodalPrior(maths_t::EDataType dataType, double decayRate : CPrior(dataType, decayRate) { m_Modes.reserve(priors.size()); for (std::size_t i = 0u; i < priors.size(); ++i) { - m_Modes.emplace_back(i, priors[i]); + m_Modes.emplace_back(i, std::move(priors[i])); } } @@ -132,7 +133,7 @@ bool CMultimodalPrior::acceptRestoreTraverser(const SDistributionRestoreParams& MODE_TAG, TMode mode, traverser.traverseSubLevel(boost::bind(&TMode::acceptRestoreTraverser, &mode, boost::cref(params), _1)), - m_Modes.push_back(mode)) + m_Modes.push_back(std::move(mode))) RESTORE_SETUP_TEARDOWN(NUMBER_SAMPLES_TAG, double numberSamples, core::CStringUtils::stringToType(traverser.value(), numberSamples), this->numberSamples(numberSamples)) @@ -637,7 +638,7 @@ void CMultimodalPrior::CModeSplitCallback::operator()(std::size_t sourceIndex, // Create the child modes. LOG_TRACE(<< "Creating mode with index " << leftSplitIndex); - modes.emplace_back(leftSplitIndex, m_Prior->m_SeedPrior); + modes.emplace_back(leftSplitIndex, TPriorPtr(m_Prior->m_SeedPrior->clone())); { TDoubleVec samples; if (!m_Prior->m_Clusterer->sample(leftSplitIndex, MODE_SPLIT_NUMBER_SAMPLES, samples)) { @@ -661,7 +662,7 @@ void CMultimodalPrior::CModeSplitCallback::operator()(std::size_t sourceIndex, } LOG_TRACE(<< "Creating mode with index " << rightSplitIndex); - modes.emplace_back(rightSplitIndex, m_Prior->m_SeedPrior); + modes.emplace_back(rightSplitIndex, TPriorPtr(m_Prior->m_SeedPrior->clone())); { TDoubleVec samples; if (!m_Prior->m_Clusterer->sample(rightSplitIndex, MODE_SPLIT_NUMBER_SAMPLES, samples)) { @@ -707,7 +708,7 @@ void CMultimodalPrior::CModeMergeCallback::operator()(std::size_t leftMergeIndex TModeVec& modes = m_Prior->m_Modes; // Create the new mode. - TMode newMode(targetIndex, m_Prior->m_SeedPrior); + TMode newMode(targetIndex, TPriorPtr(m_Prior->m_SeedPrior->clone())); double wl = 0.0; double wr = 0.0; @@ -778,7 +779,7 @@ void CMultimodalPrior::CModeMergeCallback::operator()(std::size_t leftMergeIndex // Add the new mode. LOG_TRACE(<< "Creating mode with index " << targetIndex); - modes.push_back(newMode); + modes.push_back(std::move(newMode)); m_Prior->checkInvariants("MERGE: "); diff --git a/lib/maths/CMultivariateConstantPrior.cc b/lib/maths/CMultivariateConstantPrior.cc index 73ad2ea920..300c1c57ca 100644 --- a/lib/maths/CMultivariateConstantPrior.cc +++ b/lib/maths/CMultivariateConstantPrior.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -116,7 +117,7 @@ CMultivariateConstantPrior::TUnivariatePriorPtrDoublePr CMultivariateConstantPrior::univariate(const TSize10Vec& marginalize, const TSizeDoublePr10Vec& condition) const { if (!this->check(marginalize, condition)) { - return TUnivariatePriorPtrDoublePr(); + return {}; } TSize10Vec i1; @@ -125,24 +126,24 @@ CMultivariateConstantPrior::univariate(const TSize10Vec& marginalize, LOG_ERROR(<< "Invalid variables for computing univariate distribution: " << "marginalize '" << core::CContainerPrinter::print(marginalize) << "'" << ", condition '" << core::CContainerPrinter::print(condition) << "'"); - return TUnivariatePriorPtrDoublePr(); + return {}; } return this->isNonInformative() - ? TUnivariatePriorPtrDoublePr(TUnivariatePriorPtr(new CConstantPrior), 0.0) + ? TUnivariatePriorPtrDoublePr(boost::make_unique(), 0.0) : TUnivariatePriorPtrDoublePr( - TUnivariatePriorPtr(new CConstantPrior((*m_Constant)[i1[0]])), 0.0); + boost::make_unique((*m_Constant)[i1[0]]), 0.0); } CMultivariateConstantPrior::TPriorPtrDoublePr CMultivariateConstantPrior::bivariate(const TSize10Vec& marginalize, const TSizeDoublePr10Vec& condition) const { if (m_Dimension == 2) { - return TPriorPtrDoublePr(TPriorPtr(this->clone()), 0.0); + return {TPriorPtr(this->clone()), 0.0}; } if (!this->check(marginalize, condition)) { - return TPriorPtrDoublePr(); + return {}; } TSize10Vec i1; @@ -151,16 +152,16 @@ CMultivariateConstantPrior::bivariate(const TSize10Vec& marginalize, LOG_ERROR(<< "Invalid variables for computing univariate distribution: " << "marginalize '" << core::CContainerPrinter::print(marginalize) << "'" << ", condition '" << core::CContainerPrinter::print(condition) << "'"); - return TPriorPtrDoublePr(); + return {}; } if (!this->isNonInformative()) { TDouble10Vec constant; constant[0] = (*m_Constant)[i1[0]]; constant[1] = (*m_Constant)[i1[1]]; - return TPriorPtrDoublePr(TPriorPtr(new CMultivariateConstantPrior(2, constant)), 0.0); + return {boost::make_unique(2, constant), 0.0}; } - return TPriorPtrDoublePr(TPriorPtr(new CMultivariateConstantPrior(2)), 0.0); + return {boost::make_unique(2), 0.0}; } CMultivariateConstantPrior::TDouble10VecDouble10VecPr @@ -171,7 +172,7 @@ CMultivariateConstantPrior::marginalLikelihoodSupport() const { lowest[i] = boost::numeric::bounds::lowest(); highest[i] = boost::numeric::bounds::highest(); } - return std::make_pair(lowest, highest); + return {lowest, highest}; } CMultivariateConstantPrior::TDouble10Vec diff --git a/lib/maths/CMultivariateMultimodalPrior.cc b/lib/maths/CMultivariateMultimodalPrior.cc index 0e2bd96e0d..1d4f237b2a 100644 --- a/lib/maths/CMultivariateMultimodalPrior.cc +++ b/lib/maths/CMultivariateMultimodalPrior.cc @@ -178,7 +178,7 @@ void modeMergeCallback(std::size_t dimension, using TSizeSet = std::set; // Create the new mode. - TMode newMode(targetIndex, seedPrior); + TMode newMode(targetIndex, TPriorPtr(seedPrior->clone())); double wl = 0.0; double wr = 0.0; @@ -253,7 +253,7 @@ void modeMergeCallback(std::size_t dimension, // Add the new mode. LOG_TRACE(<< "Creating mode with index " << targetIndex); - modes.push_back(newMode); + modes.push_back(std::move(newMode)); LOG_TRACE(<< "Merged modes"); } diff --git a/lib/maths/CMultivariateOneOfNPrior.cc b/lib/maths/CMultivariateOneOfNPrior.cc index e45cfcb5af..e38fae3a93 100644 --- a/lib/maths/CMultivariateOneOfNPrior.cc +++ b/lib/maths/CMultivariateOneOfNPrior.cc @@ -136,7 +136,7 @@ bool modelAcceptRestoreTraverser(const SDistributionRestoreParams& params, return false; } - models.emplace_back(weight, model); + models.emplace_back(weight, std::move(model)); return true; } @@ -191,7 +191,7 @@ CMultivariateOneOfNPrior::CMultivariateOneOfNPrior(std::size_t dimension, m_Models.reserve(models.size()); CModelWeight weight(1.0); for (const auto& model : models) { - m_Models.emplace_back(weight, model); + m_Models.emplace_back(weight, TPriorPtr(model->clone())); } } @@ -210,7 +210,7 @@ CMultivariateOneOfNPrior::CMultivariateOneOfNPrior(std::size_t dimension, // Create a new model vector using the specified models and their associated weights. m_Models.reserve(models.size()); for (const auto& model : models) { - m_Models.emplace_back(CModelWeight(model.first), model.second); + m_Models.emplace_back(CModelWeight(model.first), TPriorPtr(model.second->clone())); } } @@ -425,9 +425,9 @@ CMultivariateOneOfNPrior::univariate(const TSize10Vec& marginalize, if (model.second->participatesInModelSelection()) { TUnivariatePriorPtrDoublePr prior(model.second->univariate(marginalize, condition)); if (prior.first == nullptr) { - return TUnivariatePriorPtrDoublePr(); + return {}; } - models.emplace_back(1.0, prior.first); + models.emplace_back(1.0, std::move(prior.first)); weights.push_back(prior.second + model.first.logWeight()); maxWeight.add(weights.back()); Z += std::exp(model.first.logWeight()); @@ -446,7 +446,7 @@ CMultivariateOneOfNPrior::TPriorPtrDoublePr CMultivariateOneOfNPrior::bivariate(const TSize10Vec& marginalize, const TSizeDoublePr10Vec& condition) const { if (m_Dimension == 2) { - return TPriorPtrDoublePr(TPriorPtr(this->clone()), 0.0); + return {TPriorPtr(this->clone()), 0.0}; } TDoublePriorPtrPrVec models; @@ -458,9 +458,9 @@ CMultivariateOneOfNPrior::bivariate(const TSize10Vec& marginalize, if (model.second->participatesInModelSelection()) { TPriorPtrDoublePr prior(model.second->bivariate(marginalize, condition)); if (prior.first == nullptr) { - return TPriorPtrDoublePr(); + return {}; } - models.emplace_back(1.0, prior.first); + models.emplace_back(1.0, std::move(prior.first)); weights.push_back(prior.second + model.first.logWeight()); maxWeight.add(weights.back()); Z += std::exp(model.first.logWeight()); diff --git a/lib/maths/CMultivariateOneOfNPriorFactory.cc b/lib/maths/CMultivariateOneOfNPriorFactory.cc index 0652879b54..25bb7bbbed 100644 --- a/lib/maths/CMultivariateOneOfNPriorFactory.cc +++ b/lib/maths/CMultivariateOneOfNPriorFactory.cc @@ -8,6 +8,8 @@ #include +#include + namespace ml { namespace maths { @@ -16,14 +18,14 @@ CMultivariateOneOfNPriorFactory::nonInformative(std::size_t dimension, maths_t::EDataType dataType, double decayRate, const TPriorPtrVec& models) { - return TPriorPtr(new CMultivariateOneOfNPrior(dimension, models, dataType, decayRate)); + return boost::make_unique(dimension, models, dataType, decayRate); } bool CMultivariateOneOfNPriorFactory::restore(std::size_t dimension, const SDistributionRestoreParams& params, TPriorPtr& ptr, core::CStateRestoreTraverser& traverser) { - ptr.reset(new CMultivariateOneOfNPrior(dimension, params, traverser)); + ptr = boost::make_unique(dimension, params, traverser); return true; } } diff --git a/lib/maths/CNaiveBayes.cc b/lib/maths/CNaiveBayes.cc index 38b351eec3..c546a3d000 100644 --- a/lib/maths/CNaiveBayes.cc +++ b/lib/maths/CNaiveBayes.cc @@ -35,6 +35,7 @@ const std::string CLASS_MODEL_TAG{"c"}; const std::string MIN_MAX_LOG_LIKELIHOOD_TO_USE_FEATURE_TAG{"d"}; const std::string COUNT_TAG{"e"}; const std::string CONDITIONAL_DENSITY_FROM_PRIOR_TAG{"f"}; +const std::string EXEMPLAR_FROM_PRIOR_TAG{"g"}; } CNaiveBayesFeatureDensityFromPrior::CNaiveBayesFeatureDensityFromPrior(const CPrior& prior) @@ -132,17 +133,33 @@ CNaiveBayes::CNaiveBayes(const SDistributionRestoreParams& params, this, boost::cref(params), _1)); } +CNaiveBayes::CNaiveBayes(const CNaiveBayes& other) + : m_MinMaxLogLikelihoodToUseFeature{other.m_MinMaxLogLikelihoodToUseFeature}, + m_DecayRate{other.m_DecayRate}, m_Exemplar{other.m_Exemplar->clone()} { + for (const auto& class_ : m_ClassConditionalDensities) { + m_ClassConditionalDensities.emplace(class_.first, class_.second); + } +} + bool CNaiveBayes::acceptRestoreTraverser(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser) { std::size_t label; do { const std::string& name{traverser.name()}; RESTORE_BUILT_IN(CLASS_LABEL_TAG, label) - RESTORE_SETUP_TEARDOWN(CLASS_MODEL_TAG, SClass class_, - traverser.traverseSubLevel(boost::bind( - &SClass::acceptRestoreTraverser, - boost::ref(class_), boost::cref(params), _1)), - m_ClassConditionalDensities.emplace(label, class_)) + RESTORE_SETUP_TEARDOWN( + EXEMPLAR_FROM_PRIOR_TAG, CNaiveBayesFeatureDensityFromPrior density, + traverser.traverseSubLevel( + boost::bind(&CNaiveBayesFeatureDensityFromPrior::acceptRestoreTraverser, + boost::ref(density), boost::cref(params), _1)), + m_Exemplar.reset(density.clone())) + // Add other implementations' restore code here. + RESTORE_SETUP_TEARDOWN( + CLASS_MODEL_TAG, CClass class_, + traverser.traverseSubLevel(boost::bind(&CClass::acceptRestoreTraverser, + boost::ref(class_), + boost::cref(params), _1)), + m_ClassConditionalDensities.emplace(label, std::move(class_))) RESTORE_SETUP_TEARDOWN(MIN_MAX_LOG_LIKELIHOOD_TO_USE_FEATURE_TAG, double value, core::CStringUtils::stringToType(traverser.value(), value), m_MinMaxLogLikelihoodToUseFeature.reset(value)) @@ -153,6 +170,14 @@ bool CNaiveBayes::acceptRestoreTraverser(const SDistributionRestoreParams& param void CNaiveBayes::acceptPersistInserter(core::CStatePersistInserter& inserter) const { using TSizeClassUMapCItr = TSizeClassUMap::const_iterator; using TSizeClassUMapCItrVec = std::vector; + + if (dynamic_cast(m_Exemplar.get())) { + inserter.insertLevel(EXEMPLAR_FROM_PRIOR_TAG, + boost::bind(&CNaiveBayesFeatureDensity::acceptPersistInserter, + m_Exemplar.get(), _1)); + } + // Add other implementations' persist code here. + TSizeClassUMapCItrVec classes; classes.reserve(m_ClassConditionalDensities.size()); for (auto i = m_ClassConditionalDensities.begin(); @@ -164,9 +189,10 @@ void CNaiveBayes::acceptPersistInserter(core::CStatePersistInserter& inserter) c for (const auto& class_ : classes) { inserter.insertValue(CLASS_LABEL_TAG, class_->first); inserter.insertLevel(CLASS_MODEL_TAG, - boost::bind(&SClass::acceptPersistInserter, + boost::bind(&CClass::acceptPersistInserter, boost::ref(class_->second), _1)); } + if (m_MinMaxLogLikelihoodToUseFeature) { inserter.insertValue(MIN_MAX_LOG_LIKELIHOOD_TO_USE_FEATURE_TAG, *m_MinMaxLogLikelihoodToUseFeature, @@ -174,6 +200,14 @@ void CNaiveBayes::acceptPersistInserter(core::CStatePersistInserter& inserter) c } } +CNaiveBayes& CNaiveBayes::operator=(const CNaiveBayes& other) { + if (this != &other) { + CNaiveBayes copy{other}; + this->swap(copy); + } + return *this; +} + void CNaiveBayes::swap(CNaiveBayes& other) { std::swap(m_DecayRate, other.m_DecayRate); m_Exemplar.swap(other.m_Exemplar); @@ -187,8 +221,7 @@ bool CNaiveBayes::initialized() const { void CNaiveBayes::initialClassCounts(const TDoubleSizePrVec& counts) { for (const auto& count : counts) { - m_ClassConditionalDensities[count.second] = - SClass{count.first, TFeatureDensityPtrVec{}}; + m_ClassConditionalDensities.emplace(count.second, CClass{count.first}); } } @@ -199,23 +232,23 @@ void CNaiveBayes::addTrainingDataPoint(std::size_t label, const TDouble1VecVec& auto& class_ = m_ClassConditionalDensities[label]; - if (class_.s_ConditionalDensities.empty()) { - class_.s_ConditionalDensities.reserve(x.size()); + if (class_.conditionalDensities().empty()) { + class_.conditionalDensities().reserve(x.size()); std::generate_n( - std::back_inserter(class_.s_ConditionalDensities), x.size(), + std::back_inserter(class_.conditionalDensities()), x.size(), [this]() { return TFeatureDensityPtr{m_Exemplar->clone()}; }); } bool updateCount{false}; for (std::size_t i = 0u; i < x.size(); ++i) { if (x[i].size() > 0) { - class_.s_ConditionalDensities[i]->add(x[i]); + class_.conditionalDensities()[i]->add(x[i]); updateCount = true; } } if (updateCount) { - class_.s_Count += 1.0; + class_.count() += 1.0; } else { LOG_TRACE("Ignoring empty feature vector"); } @@ -223,7 +256,7 @@ void CNaiveBayes::addTrainingDataPoint(std::size_t label, const TDouble1VecVec& void CNaiveBayes::dataType(maths_t::EDataType dataType) { for (auto& class_ : m_ClassConditionalDensities) { - for (auto& density : class_.second.s_ConditionalDensities) { + for (auto& density : class_.second.conditionalDensities()) { density->dataType(dataType); } } @@ -232,8 +265,8 @@ void CNaiveBayes::dataType(maths_t::EDataType dataType) { void CNaiveBayes::propagateForwardsByTime(double time) { double factor{std::exp(-m_DecayRate * time)}; for (auto& class_ : m_ClassConditionalDensities) { - class_.second.s_Count *= factor; - for (auto& density : class_.second.s_ConditionalDensities) { + class_.second.count() *= factor; + for (auto& density : class_.second.conditionalDensities()) { density->propagateForwardsByTime(time); } } @@ -270,7 +303,7 @@ CNaiveBayes::TDoubleSizePrVec CNaiveBayes::classProbabilities(const TDouble1VecV TDoubleSizePrVec p; p.reserve(m_ClassConditionalDensities.size()); for (const auto& class_ : m_ClassConditionalDensities) { - p.emplace_back(CTools::fastLog(class_.second.s_Count), class_.first); + p.emplace_back(CTools::fastLog(class_.second.count()), class_.first); } TDoubleVec logLikelihoods; @@ -279,7 +312,7 @@ CNaiveBayes::TDoubleSizePrVec CNaiveBayes::classProbabilities(const TDouble1VecV TMaxAccumulator maxLogLikelihood; logLikelihoods.clear(); for (const auto& class_ : m_ClassConditionalDensities) { - const auto& density = class_.second.s_ConditionalDensities[i]; + const auto& density = class_.second.conditionalDensities()[i]; double logLikelihood{density->logValue(x[i])}; double logMaximumLikelihood{density->logMaximumValue()}; maxLogLikelihood.add(logLikelihood - logMaximumLikelihood); @@ -323,6 +356,9 @@ std::size_t CNaiveBayes::memoryUsage() const { } uint64_t CNaiveBayes::checksum(uint64_t seed) const { + CChecksum::calculate(seed, m_MinMaxLogLikelihoodToUseFeature); + CChecksum::calculate(seed, m_DecayRate); + CChecksum::calculate(seed, m_Exemplar); return CChecksum::calculate(seed, m_ClassConditionalDensities); } @@ -331,7 +367,7 @@ std::string CNaiveBayes::print() const { result << "\n"; for (const auto& class_ : m_ClassConditionalDensities) { result << "CLASS(" << class_.first << ")\n"; - for (const auto& density : class_.second.s_ConditionalDensities) { + for (const auto& density : class_.second.conditionalDensities()) { result << "---"; result << density->print() << "\n"; } @@ -342,37 +378,43 @@ std::string CNaiveBayes::print() const { bool CNaiveBayes::validate(const TDouble1VecVec& x) const { auto class_ = m_ClassConditionalDensities.begin(); if (class_ != m_ClassConditionalDensities.end() && - class_->second.s_ConditionalDensities.size() > 0 && - class_->second.s_ConditionalDensities.size() != x.size()) { + class_->second.conditionalDensities().size() > 0 && + class_->second.conditionalDensities().size() != x.size()) { LOG_ERROR("Unexpected feature vector: " << core::CContainerPrinter::print(x)); return false; } return true; } -CNaiveBayes::SClass::SClass(double count, const TFeatureDensityPtrVec& conditionalDensities) - : s_Count{count}, s_ConditionalDensities(conditionalDensities) { +CNaiveBayes::CClass::CClass(double count) : m_Count{count} { +} + +CNaiveBayes::CClass::CClass(const CClass& other) : m_Count{other.m_Count} { + m_ConditionalDensities.reserve(other.m_ConditionalDensities.size()); + for (const auto& density : other.m_ConditionalDensities) { + m_ConditionalDensities.emplace_back(density->clone()); + } } -bool CNaiveBayes::SClass::acceptRestoreTraverser(const SDistributionRestoreParams& params, +bool CNaiveBayes::CClass::acceptRestoreTraverser(const SDistributionRestoreParams& params, core::CStateRestoreTraverser& traverser) { do { const std::string& name{traverser.name()}; - RESTORE_BUILT_IN(COUNT_TAG, s_Count) + RESTORE_BUILT_IN(COUNT_TAG, m_Count) RESTORE_SETUP_TEARDOWN(CONDITIONAL_DENSITY_FROM_PRIOR_TAG, - CNaiveBayesFeatureDensityFromPrior tmp, + CNaiveBayesFeatureDensityFromPrior density, traverser.traverseSubLevel(boost::bind( &CNaiveBayesFeatureDensityFromPrior::acceptRestoreTraverser, - boost::ref(tmp), boost::cref(params), _1)), - s_ConditionalDensities.emplace_back(tmp.clone())) + boost::ref(density), boost::cref(params), _1)), + m_ConditionalDensities.emplace_back(density.clone())) // Add other implementations' restore code here. } while (traverser.next()); return true; } -void CNaiveBayes::SClass::acceptPersistInserter(core::CStatePersistInserter& inserter) const { - inserter.insertValue(COUNT_TAG, s_Count, core::CIEEE754::E_SinglePrecision); - for (const auto& density : s_ConditionalDensities) { +void CNaiveBayes::CClass::acceptPersistInserter(core::CStatePersistInserter& inserter) const { + inserter.insertValue(COUNT_TAG, m_Count, core::CIEEE754::E_SinglePrecision); + for (const auto& density : m_ConditionalDensities) { if (dynamic_cast(density.get())) { inserter.insertLevel(CONDITIONAL_DENSITY_FROM_PRIOR_TAG, boost::bind(&CNaiveBayesFeatureDensity::acceptPersistInserter, @@ -383,17 +425,33 @@ void CNaiveBayes::SClass::acceptPersistInserter(core::CStatePersistInserter& ins } } -void CNaiveBayes::SClass::debugMemoryUsage(core::CMemoryUsage::TMemoryUsagePtr mem) const { - core::CMemoryDebug::dynamicSize("s_ConditionalDensities", s_ConditionalDensities, mem); +double CNaiveBayes::CClass::count() const { + return m_Count; +} + +double& CNaiveBayes::CClass::count() { + return m_Count; +} + +const CNaiveBayes::TFeatureDensityPtrVec& CNaiveBayes::CClass::conditionalDensities() const { + return m_ConditionalDensities; +} + +CNaiveBayes::TFeatureDensityPtrVec& CNaiveBayes::CClass::conditionalDensities() { + return m_ConditionalDensities; +} + +void CNaiveBayes::CClass::debugMemoryUsage(core::CMemoryUsage::TMemoryUsagePtr mem) const { + core::CMemoryDebug::dynamicSize("s_ConditionalDensities", m_ConditionalDensities, mem); } -std::size_t CNaiveBayes::SClass::memoryUsage() const { - return core::CMemory::dynamicSize(s_ConditionalDensities); +std::size_t CNaiveBayes::CClass::memoryUsage() const { + return core::CMemory::dynamicSize(m_ConditionalDensities); } -uint64_t CNaiveBayes::SClass::checksum(uint64_t seed) const { - seed = CChecksum::calculate(seed, s_Count); - return CChecksum::calculate(seed, s_ConditionalDensities); +uint64_t CNaiveBayes::CClass::checksum(uint64_t seed) const { + seed = CChecksum::calculate(seed, m_Count); + return CChecksum::calculate(seed, m_ConditionalDensities); } } } diff --git a/lib/maths/COneOfNPrior.cc b/lib/maths/COneOfNPrior.cc index ca1906ce06..7e38123780 100644 --- a/lib/maths/COneOfNPrior.cc +++ b/lib/maths/COneOfNPrior.cc @@ -95,7 +95,7 @@ COneOfNPrior::COneOfNPrior(const TPriorPtrVec& models, maths_t::EDataType dataTy m_Models.reserve(models.size()); CModelWeight weight(1.0); for (const auto& model : models) { - m_Models.emplace_back(weight, model); + m_Models.emplace_back(weight, TPriorPtr(model->clone())); } } @@ -113,7 +113,7 @@ COneOfNPrior::COneOfNPrior(const TDoublePriorPtrPrVec& models, // Create a new model vector using the specified models and their associated weights. m_Models.reserve(models.size()); for (const auto& model : models) { - m_Models.emplace_back(CModelWeight(model.first), model.second); + m_Models.emplace_back(CModelWeight(model.first), TPriorPtr(model.second->clone())); } } @@ -1032,7 +1032,7 @@ bool COneOfNPrior::modelAcceptRestoreTraverser(const SDistributionRestoreParams& return false; } - m_Models.emplace_back(weight, model); + m_Models.emplace_back(weight, std::move(model)); return true; } diff --git a/lib/maths/CPriorStateSerialiser.cc b/lib/maths/CPriorStateSerialiser.cc index 18b1d9883e..e3983c35ed 100644 --- a/lib/maths/CPriorStateSerialiser.cc +++ b/lib/maths/CPriorStateSerialiser.cc @@ -25,7 +25,9 @@ #include #include +#include +#include #include #include @@ -43,40 +45,68 @@ const std::string ONE_OF_N_TAG("e"); const std::string POISSON_TAG("f"); const std::string MULTINOMIAL_TAG("g"); const std::string CONSTANT_TAG("h"); - const std::string EMPTY_STRING; + +//! Implements restore for std::shared_ptr. +template +void doRestore(std::shared_ptr& ptr, core::CStateRestoreTraverser& traverser) { + ptr = std::make_shared(traverser); } -bool CPriorStateSerialiser::operator()(const SDistributionRestoreParams& params, - TPriorPtr& ptr, - core::CStateRestoreTraverser& traverser) const { - size_t numResults(0); +//! Implements restore for std::unique_ptr. +template +void doRestore(std::unique_ptr& ptr, core::CStateRestoreTraverser& traverser) { + ptr = boost::make_unique(traverser); +} + +//! Implements restore for std::shared_ptr. +template +void doRestore(const SDistributionRestoreParams& params, + std::shared_ptr& ptr, + core::CStateRestoreTraverser& traverser) { + ptr = std::make_shared(params, traverser); +} + +//! Implements restore for std::unique_ptr. +template +void doRestore(const SDistributionRestoreParams& params, + std::unique_ptr& ptr, + core::CStateRestoreTraverser& traverser) { + ptr = boost::make_unique(params, traverser); +} + +//! Implements restore into the supplied pointer. +template +bool restore(const SDistributionRestoreParams& params, + PTR& ptr, + core::CStateRestoreTraverser& traverser) { + std::size_t numResults{0}; do { const std::string& name = traverser.name(); if (name == CONSTANT_TAG) { - ptr.reset(new CConstantPrior(traverser)); + doRestore(ptr, traverser); ++numResults; } else if (name == GAMMA_TAG) { - ptr.reset(new CGammaRateConjugate(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == LOG_NORMAL_TAG) { - ptr.reset(new CLogNormalMeanPrecConjugate(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == MULTIMODAL_TAG) { - ptr.reset(new CMultimodalPrior(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == MULTINOMIAL_TAG) { - ptr.reset(new CMultinomialConjugate(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == NORMAL_TAG) { - ptr.reset(new CNormalMeanPrecConjugate(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == ONE_OF_N_TAG) { - ptr.reset(new COneOfNPrior(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == POISSON_TAG) { - ptr.reset(new CPoissonMeanConjugate(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else { // Due to the way we divide large state into multiple chunks @@ -95,6 +125,19 @@ bool CPriorStateSerialiser::operator()(const SDistributionRestoreParams& params, return true; } +} + +bool CPriorStateSerialiser::operator()(const SDistributionRestoreParams& params, + TPriorUPtr& ptr, + core::CStateRestoreTraverser& traverser) const { + return restore(params, ptr, traverser); +} + +bool CPriorStateSerialiser::operator()(const SDistributionRestoreParams& params, + TPriorSPtr& ptr, + core::CStateRestoreTraverser& traverser) const { + return restore(params, ptr, traverser); +} void CPriorStateSerialiser::operator()(const CPrior& prior, core::CStatePersistInserter& inserter) const { diff --git a/lib/maths/CSeasonalComponentAdaptiveBucketing.cc b/lib/maths/CSeasonalComponentAdaptiveBucketing.cc index 99ea15b1ea..4bbbfae67c 100644 --- a/lib/maths/CSeasonalComponentAdaptiveBucketing.cc +++ b/lib/maths/CSeasonalComponentAdaptiveBucketing.cc @@ -136,7 +136,7 @@ bool CSeasonalComponentAdaptiveBucketing::initialize(std::size_t n) { if (this->CAdaptiveBucketing::initialize(a, b, n)) { n = this->size(); - m_Buckets.assign(n, SBucket()); + m_Buckets.assign(n, {}); return true; } return false; diff --git a/lib/maths/CSeasonalTime.cc b/lib/maths/CSeasonalTime.cc index 662e2afa8a..31d79fb6f6 100644 --- a/lib/maths/CSeasonalTime.cc +++ b/lib/maths/CSeasonalTime.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -252,11 +253,11 @@ bool CSeasonalTimeStateSerializer::acceptRestoreTraverser(TSeasonalTimePtr& resu do { const std::string& name = traverser.name(); if (name == DIURNAL_TIME_TAG) { - result.reset(new CDiurnalTime); + result = boost::make_unique(); result->fromString(traverser.value()); ++numResults; } else if (name == ARBITRARY_PERIOD_TIME_TAG) { - result.reset(new CGeneralPeriodTime); + result = boost::make_unique(); result->fromString(traverser.value()); ++numResults; } else { diff --git a/lib/maths/CTimeSeriesDecomposition.cc b/lib/maths/CTimeSeriesDecomposition.cc index 77b93b5558..a0f247b406 100644 --- a/lib/maths/CTimeSeriesDecomposition.cc +++ b/lib/maths/CTimeSeriesDecomposition.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/maths/CTimeSeriesDecompositionDetail.cc b/lib/maths/CTimeSeriesDecompositionDetail.cc index 03eee8b95c..f2d9b93d8c 100644 --- a/lib/maths/CTimeSeriesDecompositionDetail.cc +++ b/lib/maths/CTimeSeriesDecompositionDetail.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -415,8 +416,6 @@ CTimeSeriesDecompositionDetail::SNewComponents::SNewComponents(core_t::TTime tim CTimeSeriesDecompositionDetail::CHandler::CHandler() : m_Mediator{nullptr} { } -CTimeSeriesDecompositionDetail::CHandler::~CHandler() { -} void CTimeSeriesDecompositionDetail::CHandler::handle(const SAddValue& /*message*/) { } @@ -481,7 +480,7 @@ CTimeSeriesDecompositionDetail::CPeriodicityTest::CPeriodicityTest(const CPeriod // Note that m_Windows is an array. for (std::size_t i = 0u; !isForForecast && i < other.m_Windows.size(); ++i) { if (other.m_Windows[i]) { - m_Windows[i] = std::make_shared(*other.m_Windows[i]); + m_Windows[i] = boost::make_unique(*other.m_Windows[i]); } } } @@ -782,7 +781,7 @@ CTimeSeriesDecompositionDetail::CCalendarTest::CCalendarTest(const CCalendarTest bool isForForecast) : m_Machine{other.m_Machine}, m_DecayRate{other.m_DecayRate}, m_LastMonth{other.m_LastMonth}, m_Test{!isForForecast && other.m_Test - ? std::make_shared( + ? boost::make_unique( *other.m_Test) : nullptr} { } @@ -796,7 +795,7 @@ bool CTimeSeriesDecompositionDetail::CCalendarTest::acceptRestoreTraverser(core: RESTORE_BUILT_IN(LAST_MONTH_6_3_TAG, m_LastMonth); RESTORE_SETUP_TEARDOWN( CALENDAR_TEST_6_3_TAG, - m_Test = std::make_shared(m_DecayRate), + m_Test = boost::make_unique(m_DecayRate), traverser.traverseSubLevel(boost::bind( &CCalendarCyclicTest::acceptRestoreTraverser, m_Test.get(), _1)), /**/) @@ -914,7 +913,7 @@ std::size_t CTimeSeriesDecompositionDetail::CCalendarTest::memoryUsage() const { std::size_t CTimeSeriesDecompositionDetail::CCalendarTest::extraMemoryOnInitialization() const { static std::size_t result{0}; if (result == 0) { - TCalendarCyclicTestPtr test(new CCalendarCyclicTest(m_DecayRate)); + TCalendarCyclicTestPtr test = boost::make_unique(m_DecayRate); result = core::CMemory::dynamicSize(test); } return result; @@ -934,8 +933,8 @@ void CTimeSeriesDecompositionDetail::CCalendarTest::apply(std::size_t symbol, switch (state) { case CC_TEST: - if (!m_Test) { - m_Test = std::make_shared(m_DecayRate); + if (m_Test == nullptr) { + m_Test = boost::make_unique(m_DecayRate); m_LastMonth = this->month(time) + 2; } break; @@ -983,8 +982,8 @@ CTimeSeriesDecompositionDetail::CComponents::CComponents(const CComponents& othe m_BucketLength{other.m_BucketLength}, m_GainController{other.m_GainController}, m_SeasonalComponentSize{other.m_SeasonalComponentSize}, m_CalendarComponentSize{other.m_CalendarComponentSize}, m_Trend{other.m_Trend}, - m_Seasonal{other.m_Seasonal ? new CSeasonal{*other.m_Seasonal} : nullptr}, - m_Calendar{other.m_Calendar ? new CCalendar{*other.m_Calendar} : nullptr}, + m_Seasonal{other.m_Seasonal ? boost::make_unique(*other.m_Seasonal) : nullptr}, + m_Calendar{other.m_Calendar ? boost::make_unique(*other.m_Calendar) : nullptr}, m_MeanVarianceScale{other.m_MeanVarianceScale}, m_PredictionErrorWithoutTrend{other.m_PredictionErrorWithoutTrend}, m_PredictionErrorWithTrend{other.m_PredictionErrorWithTrend}, @@ -1008,13 +1007,13 @@ bool CTimeSeriesDecompositionDetail::CComponents::acceptRestoreTraverser( &CTrendComponent::acceptRestoreTraverser, &m_Trend, boost::cref(params), _1))) RESTORE_SETUP_TEARDOWN( - SEASONAL_6_3_TAG, m_Seasonal.reset(new CSeasonal), + SEASONAL_6_3_TAG, m_Seasonal = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CSeasonal::acceptRestoreTraverser, m_Seasonal.get(), m_DecayRate, m_BucketLength, _1)), /**/) RESTORE_SETUP_TEARDOWN( - CALENDAR_6_3_TAG, m_Calendar.reset(new CCalendar), + CALENDAR_6_3_TAG, m_Calendar = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CCalendar::acceptRestoreTraverser, m_Calendar.get(), m_DecayRate, m_BucketLength, _1)), @@ -1043,13 +1042,13 @@ bool CTimeSeriesDecompositionDetail::CComponents::acceptRestoreTraverser( m_BucketLength, boost::ref(m_Trend), _1)), m_UsingTrendForPrediction = true) RESTORE_SETUP_TEARDOWN( - SEASONAL_OLD_TAG, m_Seasonal.reset(new CSeasonal), + SEASONAL_OLD_TAG, m_Seasonal = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CSeasonal::acceptRestoreTraverser, m_Seasonal.get(), m_DecayRate, m_BucketLength, _1)), /**/) RESTORE_SETUP_TEARDOWN( - CALENDAR_OLD_TAG, m_Calendar.reset(new CCalendar), + CALENDAR_OLD_TAG, m_Calendar = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CCalendar::acceptRestoreTraverser, m_Calendar.get(), m_DecayRate, m_BucketLength, _1)), @@ -1206,7 +1205,7 @@ void CTimeSeriesDecompositionDetail::CComponents::handle(const SDetectedSeasonal case SC_NORMAL: case SC_NEW_COMPONENTS: { if (!m_Seasonal) { - m_Seasonal.reset(new CSeasonal); + m_Seasonal = boost::make_unique(); } core_t::TTime time{message.s_Time}; @@ -1248,7 +1247,7 @@ void CTimeSeriesDecompositionDetail::CComponents::handle(const SDetectedCalendar case SC_NORMAL: case SC_NEW_COMPONENTS: { if (!m_Calendar) { - m_Calendar.reset(new CCalendar); + m_Calendar = boost::make_unique(); } core_t::TTime time{message.s_Time}; diff --git a/lib/maths/CTimeSeriesDecompositionStateSerialiser.cc b/lib/maths/CTimeSeriesDecompositionStateSerialiser.cc index 8bfe1a0c64..76f9f50877 100644 --- a/lib/maths/CTimeSeriesDecompositionStateSerialiser.cc +++ b/lib/maths/CTimeSeriesDecompositionStateSerialiser.cc @@ -15,7 +15,9 @@ #include #include +#include +#include #include #include @@ -30,23 +32,49 @@ namespace { // DO NOT change the existing tags if new sub-classes are added. const std::string TIME_SERIES_DECOMPOSITION_TAG("a"); const std::string TIME_SERIES_DECOMPOSITION_STUB_TAG("b"); - const std::string EMPTY_STRING; + +//! Implements restore for std::shared_ptr. +template +void doRestore(std::shared_ptr& ptr) { + ptr = std::make_shared(); } -bool CTimeSeriesDecompositionStateSerialiser:: -operator()(const STimeSeriesDecompositionRestoreParams& params, - TDecompositionPtr& result, - core::CStateRestoreTraverser& traverser) const { - std::size_t numResults = 0; +//! Implements restore for std::unique_ptr. +template +void doRestore(std::unique_ptr& ptr) { + ptr = boost::make_unique(); +} +//! Implements restore for std::shared_ptr. +template +void doRestore(const STimeSeriesDecompositionRestoreParams& params, + std::shared_ptr& ptr, + core::CStateRestoreTraverser& traverser) { + ptr = std::make_shared(params, traverser); +} + +//! Implements restore for std::unique_ptr. +template +void doRestore(const STimeSeriesDecompositionRestoreParams& params, + std::unique_ptr& ptr, + core::CStateRestoreTraverser& traverser) { + ptr = boost::make_unique(params, traverser); +} + +//! Implements restore into the supplied pointer. +template +bool restore(const STimeSeriesDecompositionRestoreParams& params, + PTR& ptr, + core::CStateRestoreTraverser& traverser) { + std::size_t numResults{0}; do { const std::string& name = traverser.name(); if (name == TIME_SERIES_DECOMPOSITION_TAG) { - result.reset(new CTimeSeriesDecomposition(params, traverser)); + doRestore(params, ptr, traverser); ++numResults; } else if (name == TIME_SERIES_DECOMPOSITION_STUB_TAG) { - result.reset(new CTimeSeriesDecompositionStub()); + doRestore(ptr); ++numResults; } else { LOG_ERROR(<< "No decomposition corresponds to name " << traverser.name()); @@ -56,12 +84,27 @@ operator()(const STimeSeriesDecompositionRestoreParams& params, if (numResults != 1) { LOG_ERROR(<< "Expected 1 (got " << numResults << ") decomposition tags"); - result.reset(); + ptr.reset(); return false; } return true; } +} + +bool CTimeSeriesDecompositionStateSerialiser:: +operator()(const STimeSeriesDecompositionRestoreParams& params, + TDecompositionUPtr& ptr, + core::CStateRestoreTraverser& traverser) const { + return restore(params, ptr, traverser); +} + +bool CTimeSeriesDecompositionStateSerialiser:: +operator()(const STimeSeriesDecompositionRestoreParams& params, + TDecompositionSPtr& ptr, + core::CStateRestoreTraverser& traverser) const { + return restore(params, ptr, traverser); +} void CTimeSeriesDecompositionStateSerialiser:: operator()(const CTimeSeriesDecompositionInterface& decomposition, diff --git a/lib/maths/CTimeSeriesDecompositionStub.cc b/lib/maths/CTimeSeriesDecompositionStub.cc index e7249eccaa..be17b61d6c 100644 --- a/lib/maths/CTimeSeriesDecompositionStub.cc +++ b/lib/maths/CTimeSeriesDecompositionStub.cc @@ -7,6 +7,7 @@ #include #include +#include namespace ml { namespace maths { diff --git a/lib/maths/CTimeSeriesModel.cc b/lib/maths/CTimeSeriesModel.cc index 8bde49c498..cbb9b01ab9 100644 --- a/lib/maths/CTimeSeriesModel.cc +++ b/lib/maths/CTimeSeriesModel.cc @@ -26,6 +26,8 @@ #include #include +#include + #include #include #include @@ -53,7 +55,7 @@ using TSizeDoublePr10Vec = core::CSmallVector; using TTail10Vec = core::CSmallVector; using TOptionalSize = boost::optional; using TMeanAccumulator = CBasicStatistics::SSampleMean::TAccumulator; -using TChangeDetectorPtr = std::shared_ptr; +using TChangeDetectorPtr = std::unique_ptr; using TMultivariatePriorCPtrSizePr1Vec = CTimeSeriesCorrelations::TMultivariatePriorCPtrSizePr1Vec; //! The decay rate controllers we maintain. @@ -594,14 +596,14 @@ CUnivariateTimeSeriesModel::CUnivariateTimeSeriesModel(const CModelParams& param bool modelAnomalies) : CModel(params), m_Id(id), m_IsNonNegative(false), m_IsForecastable(true), m_TrendModel(trendModel.clone()), m_ResidualModel(residualModel.clone()), - m_AnomalyModel(modelAnomalies ? std::make_shared( + m_AnomalyModel(modelAnomalies ? boost::make_unique( params.bucketLength(), params.decayRate()) - : TAnomalyModelPtr()), + : nullptr), m_CurrentChangeInterval(0), m_SlidingWindow(SLIDING_WINDOW_SIZE), m_Correlations(nullptr) { if (controllers) { - m_Controllers = std::make_shared(*controllers); + m_Controllers = boost::make_unique(*controllers); } } @@ -1174,7 +1176,7 @@ bool CUnivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestoreParam RESTORE(RNG_6_3_TAG, m_Rng.fromString(traverser.value())) RESTORE_SETUP_TEARDOWN( CONTROLLER_6_3_TAG, - m_Controllers = std::make_shared(), + m_Controllers = boost::make_unique(), core::CPersistUtils::restore(CONTROLLER_6_3_TAG, *m_Controllers, traverser), /**/) RESTORE(TREND_MODEL_6_3_TAG, traverser.traverseSubLevel(boost::bind( @@ -1187,7 +1189,7 @@ bool CUnivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestoreParam boost::ref(m_ResidualModel), _1))) RESTORE_SETUP_TEARDOWN( ANOMALY_MODEL_6_3_TAG, - m_AnomalyModel = std::make_shared(), + m_AnomalyModel = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CTimeSeriesAnomalyModel::acceptRestoreTraverser, m_AnomalyModel.get(), boost::cref(params), _1)), @@ -1197,7 +1199,7 @@ bool CUnivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestoreParam RESTORE_BUILT_IN(CURRENT_CHANGE_INTERVAL_6_3_TAG, m_CurrentChangeInterval) RESTORE_SETUP_TEARDOWN( CHANGE_DETECTOR_6_3_TAG, - m_ChangeDetector = std::make_shared( + m_ChangeDetector = boost::make_unique( m_TrendModel, m_ResidualModel), traverser.traverseSubLevel(boost::bind( &CUnivariateTimeSeriesChangeDetector::acceptRestoreTraverser, @@ -1216,7 +1218,7 @@ bool CUnivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestoreParam RESTORE_BOOL(IS_FORECASTABLE_OLD_TAG, m_IsForecastable) RESTORE_SETUP_TEARDOWN( CONTROLLER_OLD_TAG, - m_Controllers = std::make_shared(), + m_Controllers = boost::make_unique(), core::CPersistUtils::restore(CONTROLLER_OLD_TAG, *m_Controllers, traverser), /**/) RESTORE(TREND_OLD_TAG, traverser.traverseSubLevel(boost::bind( @@ -1229,7 +1231,7 @@ bool CUnivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestoreParam boost::ref(m_ResidualModel), _1))) RESTORE_SETUP_TEARDOWN( ANOMALY_MODEL_OLD_TAG, - m_AnomalyModel = std::make_shared(), + m_AnomalyModel = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CTimeSeriesAnomalyModel::acceptRestoreTraverser, m_AnomalyModel.get(), boost::cref(params), _1)), @@ -1321,19 +1323,19 @@ CUnivariateTimeSeriesModel::CUnivariateTimeSeriesModel(const CUnivariateTimeSeri m_IsForecastable(other.m_IsForecastable), m_Rng(other.m_Rng), m_TrendModel(other.m_TrendModel->clone()), m_ResidualModel(other.m_ResidualModel->clone()), - m_AnomalyModel(!isForForecast && other.m_AnomalyModel - ? std::make_shared(*other.m_AnomalyModel) - : TAnomalyModelPtr()), + m_AnomalyModel(!isForForecast && other.m_AnomalyModel != nullptr + ? boost::make_unique(*other.m_AnomalyModel) + : nullptr), m_CandidateChangePoint(other.m_CandidateChangePoint), m_CurrentChangeInterval(other.m_CurrentChangeInterval), - m_ChangeDetector(!isForForecast && other.m_ChangeDetector - ? std::make_shared( - *other.m_ChangeDetector) - : TChangeDetectorPtr()), + m_ChangeDetector( + !isForForecast && other.m_ChangeDetector != nullptr + ? boost::make_unique(*other.m_ChangeDetector) + : nullptr), m_SlidingWindow(!isForForecast ? other.m_SlidingWindow : TTimeDoublePrCBuf{}), m_Correlations(nullptr) { if (!isForForecast && other.m_Controllers != nullptr) { - m_Controllers = std::make_shared(*other.m_Controllers); + m_Controllers = boost::make_unique(*other.m_Controllers); } } @@ -1354,7 +1356,7 @@ CUnivariateTimeSeriesModel::testAndApplyChange(const CModelAddSamplesParams& par m_CurrentChangeInterval += this->params().bucketLength(); if (this->params().testForChange(m_CurrentChangeInterval)) { LOG_TRACE(<< "Starting to test for change at " << time); - m_ChangeDetector = std::make_shared( + m_ChangeDetector = boost::make_unique( m_TrendModel, m_ResidualModel, minimumTimeToDetect, maximumTimeToTest); m_CurrentChangeInterval = 0; } @@ -1716,9 +1718,10 @@ void CTimeSeriesCorrelations::refresh(const CTimeSeriesCorrelateModelAllocator& for (/**/; i < missing.size() && m_CorrelationDistributionModels.size() < nextChunk; ++i) { - m_CorrelationDistributionModels.insert( - {missing[i], - {allocator.newPrior(), correlationCoeffs[missingRank[i]]}}); + m_CorrelationDistributionModels.emplace( + missing[i], TMultivariatePriorPtrDoublePr{ + allocator.newPrior(), + correlationCoeffs[missingRank[i]]}); } } } @@ -1786,7 +1789,7 @@ bool CTimeSeriesCorrelations::restoreCorrelationModels(const SDistributionRestor CORRELATION_MODEL_TAG, TSizeSizePrMultivariatePriorPtrDoublePrPr prior, traverser.traverseSubLevel(boost::bind(&restore, boost::cref(params), boost::ref(prior), _1)), - m_CorrelationDistributionModels.insert(prior)) + m_CorrelationDistributionModels.insert(std::move(prior))) } while (traverser.next()); return true; } @@ -1824,7 +1827,7 @@ bool CTimeSeriesCorrelations::restore(const SDistributionRestoreParams& params, return true; } -void CTimeSeriesCorrelations::persist(const TSizeSizePrMultivariatePriorPtrDoublePrPr& model, +void CTimeSeriesCorrelations::persist(const TConstSizeSizePrMultivariatePriorPtrDoublePrPr& model, core::CStatePersistInserter& inserter) { inserter.insertValue(FIRST_CORRELATE_ID_TAG, model.first.first); inserter.insertValue(SECOND_CORRELATE_ID_TAG, model.first.second); @@ -1954,13 +1957,13 @@ CMultivariateTimeSeriesModel::CMultivariateTimeSeriesModel( const TDecayRateController2Ary* controllers, bool modelAnomalies) : CModel(params), m_IsNonNegative(false), m_ResidualModel(residualModel.clone()), - m_AnomalyModel(modelAnomalies ? std::make_shared( + m_AnomalyModel(modelAnomalies ? boost::make_unique( params.bucketLength(), params.decayRate()) - : TAnomalyModelPtr()), + : nullptr), m_SlidingWindow(SLIDING_WINDOW_SIZE) { if (controllers) { - m_Controllers = std::make_shared(*controllers); + m_Controllers = boost::make_unique(*controllers); } for (std::size_t d = 0u; d < this->dimension(); ++d) { m_TrendModel.emplace_back(trend.clone()); @@ -1970,12 +1973,12 @@ CMultivariateTimeSeriesModel::CMultivariateTimeSeriesModel( CMultivariateTimeSeriesModel::CMultivariateTimeSeriesModel(const CMultivariateTimeSeriesModel& other) : CModel(other.params()), m_IsNonNegative(other.m_IsNonNegative), m_ResidualModel(other.m_ResidualModel->clone()), - m_AnomalyModel(other.m_AnomalyModel - ? std::make_shared(*other.m_AnomalyModel) - : TAnomalyModelPtr()), + m_AnomalyModel(other.m_AnomalyModel != nullptr + ? boost::make_unique(*other.m_AnomalyModel) + : nullptr), m_SlidingWindow(other.m_SlidingWindow) { if (other.m_Controllers) { - m_Controllers = std::make_shared(*other.m_Controllers); + m_Controllers = boost::make_unique(*other.m_Controllers); } m_TrendModel.reserve(other.m_TrendModel.size()); for (const auto& trend : other.m_TrendModel) { @@ -1990,6 +1993,9 @@ CMultivariateTimeSeriesModel::CMultivariateTimeSeriesModel(const SModelRestorePa this, boost::cref(params), _1)); } +CMultivariateTimeSeriesModel::~CMultivariateTimeSeriesModel() { +} + std::size_t CMultivariateTimeSeriesModel::identifier() const { return 0; } @@ -2016,7 +2022,7 @@ void CMultivariateTimeSeriesModel::modelCorrelations(CTimeSeriesCorrelations& /* } TSize2Vec1Vec CMultivariateTimeSeriesModel::correlates() const { - return TSize2Vec1Vec(); + return {}; } void CMultivariateTimeSeriesModel::addBucketValue(const TTimeDouble2VecSizeTrVec& /*value*/) { @@ -2433,7 +2439,7 @@ bool CMultivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestorePar RESTORE(RNG_6_3_TAG, m_Rng.fromString(traverser.value())) RESTORE_SETUP_TEARDOWN( CONTROLLER_6_3_TAG, - m_Controllers = std::make_shared(), + m_Controllers = boost::make_unique(), core::CPersistUtils::restore(CONTROLLER_6_3_TAG, *m_Controllers, traverser), /**/) RESTORE_SETUP_TEARDOWN( @@ -2449,7 +2455,7 @@ bool CMultivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestorePar boost::ref(m_ResidualModel), _1))) RESTORE_SETUP_TEARDOWN( ANOMALY_MODEL_6_3_TAG, - m_AnomalyModel = std::make_shared(), + m_AnomalyModel = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CTimeSeriesAnomalyModel::acceptRestoreTraverser, m_AnomalyModel.get(), boost::cref(params), _1)), @@ -2464,7 +2470,7 @@ bool CMultivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestorePar RESTORE_BOOL(IS_NON_NEGATIVE_OLD_TAG, m_IsNonNegative) RESTORE_SETUP_TEARDOWN( CONTROLLER_OLD_TAG, - m_Controllers = std::make_shared(), + m_Controllers = boost::make_unique(), core::CPersistUtils::restore(CONTROLLER_6_3_TAG, *m_Controllers, traverser), /**/) RESTORE_SETUP_TEARDOWN( @@ -2480,7 +2486,7 @@ bool CMultivariateTimeSeriesModel::acceptRestoreTraverser(const SModelRestorePar boost::ref(m_ResidualModel), _1))) RESTORE_SETUP_TEARDOWN( ANOMALY_MODEL_OLD_TAG, - m_AnomalyModel = std::make_shared(), + m_AnomalyModel = boost::make_unique(), traverser.traverseSubLevel( boost::bind(&CTimeSeriesAnomalyModel::acceptRestoreTraverser, m_AnomalyModel.get(), boost::cref(params), _1)), diff --git a/lib/maths/unittest/CMultimodalPriorTest.cc b/lib/maths/unittest/CMultimodalPriorTest.cc index 8fb8d7d651..dbfa7921b8 100644 --- a/lib/maths/unittest/CMultimodalPriorTest.cc +++ b/lib/maths/unittest/CMultimodalPriorTest.cc @@ -43,7 +43,7 @@ namespace { using TDoubleVec = std::vector; using TDoubleDoublePr = std::pair; using TDoubleDoublePrVec = std::vector; -using TPriorPtr = std::shared_ptr; +using TPriorPtr = std::unique_ptr; using CGammaRateConjugate = CPriorTestInterfaceMixin; using CLogNormalMeanPrecConjugate = CPriorTestInterfaceMixin; using CNormalMeanPrecConjugate = CPriorTestInterfaceMixin; diff --git a/lib/maths/unittest/CNaiveBayesTest.cc b/lib/maths/unittest/CNaiveBayesTest.cc index b0de6d00d0..9547b476d4 100644 --- a/lib/maths/unittest/CNaiveBayesTest.cc +++ b/lib/maths/unittest/CNaiveBayesTest.cc @@ -234,7 +234,7 @@ void CNaiveBayesTest::testMemoryUsage() { // Check invariants. using TMemoryUsagePtr = std::unique_ptr; - using TNaiveBayesPtr = std::shared_ptr; + using TNaiveBayesPtr = std::unique_ptr; test::CRandomNumbers rng; diff --git a/lib/maths/unittest/COneOfNPriorTest.cc b/lib/maths/unittest/COneOfNPriorTest.cc index 7f2bb5fe64..d48bc418d0 100644 --- a/lib/maths/unittest/COneOfNPriorTest.cc +++ b/lib/maths/unittest/COneOfNPriorTest.cc @@ -48,7 +48,7 @@ using TDoubleVec = std::vector; using TDoubleDoublePr = std::pair; using TDoubleDoublePrVec = std::vector; using TMeanAccumulator = maths::CBasicStatistics::SSampleMean::TAccumulator; -using TPriorPtr = std::shared_ptr; +using TPriorPtr = std::unique_ptr; using TPriorPtrVec = std::vector; using TOptionalDouble = boost::optional; using CGammaRateConjugate = CPriorTestInterfaceMixin; @@ -64,7 +64,7 @@ COneOfNPrior::TPriorPtrVec clone(const TPriorPtrVec& models, COneOfNPrior::TPriorPtrVec result; result.reserve(models.size()); for (std::size_t i = 0u; i < models.size(); ++i) { - result.push_back(COneOfNPrior::TPriorPtr(models[i]->clone())); + result.push_back(TPriorPtr(models[i]->clone())); if (decayRate) { result.back()->decayRate(*decayRate); } @@ -505,7 +505,7 @@ void COneOfNPriorTest::testModelSelection() { maths::CNormalMeanPrecConjugate normal = maths::CNormalMeanPrecConjugate::nonInformativePrior(maths_t::E_ContinuousData); maths::COneOfNPrior::TPriorPtrVec mode; - mode.push_back(COneOfNPrior::TPriorPtr(normal.clone())); + mode.push_back(TPriorPtr(normal.clone())); models.push_back(TPriorPtr(new maths::CMultimodalPrior( maths_t::E_ContinuousData, clusterer, maths::COneOfNPrior(mode, maths_t::E_ContinuousData)))); diff --git a/lib/maths/unittest/CTimeSeriesChangeDetectorTest.cc b/lib/maths/unittest/CTimeSeriesChangeDetectorTest.cc index 27871b0f7c..5db53fdeb8 100644 --- a/lib/maths/unittest/CTimeSeriesChangeDetectorTest.cc +++ b/lib/maths/unittest/CTimeSeriesChangeDetectorTest.cc @@ -41,7 +41,6 @@ using TTimeDoublePr = std::pair; using TTimeDoublePrCBuf = boost::circular_buffer; using TDecompositionPtr = std::shared_ptr; using TPriorPtr = std::shared_ptr; -using TPriorPtrVec = std::vector; core_t::TTime BUCKET_LENGTH{1800}; const double DECAY_RATE{0.0002}; @@ -54,7 +53,7 @@ TPriorPtr makeResidualModel() { maths::CNormalMeanPrecConjugate normal{maths::CNormalMeanPrecConjugate::nonInformativePrior( maths_t::E_ContinuousData, DECAY_RATE)}; - TPriorPtrVec mode; + maths::COneOfNPrior::TPriorPtrVec mode; mode.reserve(3u); mode.emplace_back(gamma.clone()); mode.emplace_back(lognormal.clone()); @@ -70,7 +69,7 @@ TPriorPtr makeResidualModel() { maths::CMultimodalPrior multimodal{maths_t::E_ContinuousData, clusterer, modePrior, DECAY_RATE}; - TPriorPtrVec models; + maths::COneOfNPrior::TPriorPtrVec models; mode.emplace_back(gamma.clone()); mode.emplace_back(lognormal.clone()); mode.emplace_back(normal.clone()); diff --git a/lib/maths/unittest/CTimeSeriesModelTest.cc b/lib/maths/unittest/CTimeSeriesModelTest.cc index dabedade13..fce3067ebb 100644 --- a/lib/maths/unittest/CTimeSeriesModelTest.cc +++ b/lib/maths/unittest/CTimeSeriesModelTest.cc @@ -1101,14 +1101,16 @@ void CTimeSeriesModelTest::testProbability() { LOG_DEBUG(<< "Univariate"); { - maths::CUnivariateTimeSeriesModel models[]{ - maths::CUnivariateTimeSeriesModel{modelParams(bucketLength), 1, - maths::CTimeSeriesDecompositionStub{}, - univariateNormal(), 0, false}, - maths::CUnivariateTimeSeriesModel{ - modelParams(bucketLength), 1, - maths::CTimeSeriesDecomposition{24.0 * DECAY_RATE, bucketLength}, - univariateNormal(), nullptr, false}}; + maths::CUnivariateTimeSeriesModel model0{ + modelParams(bucketLength), 1, maths::CTimeSeriesDecompositionStub{}, + univariateNormal(), 0, false}; + maths::CUnivariateTimeSeriesModel model1{ + modelParams(bucketLength), + 1, + maths::CTimeSeriesDecomposition{24.0 * DECAY_RATE, bucketLength}, + univariateNormal(), + nullptr, + false}; TDoubleVec samples; rng.generateNormalSamples(10.0, 4.0, 1000, samples); @@ -1120,9 +1122,9 @@ void CTimeSeriesModelTest::testProbability() { for (auto sample : samples) { double trend{5.0 + 5.0 * std::sin(boost::math::double_constants::two_pi * static_cast(time) / 86400.0)}; - models[0].addSamples(addSampleParams(weight), - {core::make_triple(time, TDouble2Vec{sample}, TAG)}); - models[1].addSamples( + model0.addSamples(addSampleParams(weight), + {core::make_triple(time, TDouble2Vec{sample}, TAG)}); + model1.addSamples( addSampleParams(weight), {core::make_triple(time, TDouble2Vec{trend + sample}, TAG)}); time += bucketLength; @@ -1158,12 +1160,12 @@ void CTimeSeriesModelTest::testProbability() { weight_[i] = weight[i][0]; } double lb[2], ub[2]; - models[0].residualModel().probabilityOfLessLikelySamples( + model0.residualModel().probabilityOfLessLikelySamples( calculation, sample, {weight_}, lb[0], ub[0], expectedTail[0]); - models[1].residualModel().probabilityOfLessLikelySamples( + model1.residualModel().probabilityOfLessLikelySamples( calculation, - {models[1].trendModel().detrend(time, sample[0], confidence)}, + {model1.trendModel().detrend(time, sample[0], confidence)}, {weight_}, lb[1], ub[1], expectedTail[1]); expectedProbability[0] = (lb[0] + ub[0]) / 2.0; expectedProbability[1] = (lb[1] + ub[1]) / 2.0; @@ -1179,12 +1181,12 @@ void CTimeSeriesModelTest::testProbability() { .addWeights(weight); bool conditional; TSize1Vec mostAnomalousCorrelate; - models[0].probability(params, time_, {sample}, - probability[0], tail[0], conditional, - mostAnomalousCorrelate); - models[1].probability(params, time_, {sample}, - probability[1], tail[1], conditional, - mostAnomalousCorrelate); + model0.probability(params, time_, {sample}, + probability[0], tail[0], conditional, + mostAnomalousCorrelate); + model1.probability(params, time_, {sample}, + probability[1], tail[1], conditional, + mostAnomalousCorrelate); } CPPUNIT_ASSERT_EQUAL(expectedProbability[0], probability[0]); @@ -1199,14 +1201,13 @@ void CTimeSeriesModelTest::testProbability() { LOG_DEBUG(<< "Multivariate"); { - maths::CMultivariateTimeSeriesModel models[]{ - maths::CMultivariateTimeSeriesModel{modelParams(bucketLength), - maths::CTimeSeriesDecompositionStub{}, - multivariateNormal(), 0, false}, - maths::CMultivariateTimeSeriesModel{ - modelParams(bucketLength), - maths::CTimeSeriesDecomposition{24.0 * DECAY_RATE, bucketLength}, - multivariateNormal(), nullptr, false}}; + maths::CMultivariateTimeSeriesModel model0{ + modelParams(bucketLength), maths::CTimeSeriesDecompositionStub{}, + multivariateNormal(), 0, false}; + maths::CMultivariateTimeSeriesModel model1{ + modelParams(bucketLength), + maths::CTimeSeriesDecomposition{24.0 * DECAY_RATE, bucketLength}, + multivariateNormal(), nullptr, false}; TDoubleVecVec samples; rng.generateMultivariateNormalSamples( @@ -1218,15 +1219,15 @@ void CTimeSeriesModelTest::testProbability() { TDouble2VecWeightsAryVec weight{maths_t::CUnitWeights::unit(3)}; for (auto& sample : samples) { TDouble2Vec sample_(sample); - models[0].addSamples(addSampleParams(weight), - {core::make_triple(time, sample_, TAG)}); + model0.addSamples(addSampleParams(weight), + {core::make_triple(time, sample_, TAG)}); double trend{5.0 + 5.0 * std::sin(boost::math::double_constants::two_pi * static_cast(time) / 86400.0)}; for (auto& component : sample_) { component += trend; } - models[1].addSamples(addSampleParams(weight), - {core::make_triple(time, sample_, TAG)}); + model1.addSamples(addSampleParams(weight), + {core::make_triple(time, sample_, TAG)}); time += bucketLength; } } @@ -1261,15 +1262,15 @@ void CTimeSeriesModelTest::testProbability() { weight_[i] = weight[i]; } double lb[2], ub[2]; - models[0].residualModel().probabilityOfLessLikelySamples( + model0.residualModel().probabilityOfLessLikelySamples( calculation, {TDouble10Vec(sample)}, {weight_}, lb[0], ub[0], expectedTail[0]); TDouble10Vec detrended; for (std::size_t j = 0u; j < sample.size(); ++j) { - detrended.push_back(models[1].trendModel()[j]->detrend( + detrended.push_back(model1.trendModel()[j]->detrend( time, sample[j], confidence)); } - models[1].residualModel().probabilityOfLessLikelySamples( + model1.residualModel().probabilityOfLessLikelySamples( calculation, {detrended}, {weight_}, lb[1], ub[1], expectedTail[1]); expectedProbability[0] = (lb[0] + ub[0]) / 2.0; @@ -1286,12 +1287,12 @@ void CTimeSeriesModelTest::testProbability() { .addWeights(weight); bool conditional; TSize1Vec mostAnomalousCorrelate; - models[0].probability(params, time_, {sample}, - probability[0], tail[0], conditional, - mostAnomalousCorrelate); - models[1].probability(params, time_, {sample}, - probability[1], tail[1], conditional, - mostAnomalousCorrelate); + model0.probability(params, time_, {sample}, + probability[0], tail[0], conditional, + mostAnomalousCorrelate); + model1.probability(params, time_, {sample}, + probability[1], tail[1], conditional, + mostAnomalousCorrelate); } CPPUNIT_ASSERT_EQUAL(expectedProbability[0], probability[0]); @@ -1788,21 +1789,22 @@ void CTimeSeriesModelTest::testAddSamplesWithCorrelations() { maths::CTimeSeriesDecomposition trend{DECAY_RATE, bucketLength}; maths::CTimeSeriesCorrelations correlations{MINIMUM_SIGNIFICANT_CORRELATION, DECAY_RATE}; maths::CNormalMeanPrecConjugate prior{univariateNormal()}; - maths::CUnivariateTimeSeriesModel models[]{ - {modelParams(bucketLength), 0, trend, prior, nullptr}, - {modelParams(bucketLength), 1, trend, prior, nullptr}}; - models[0].modelCorrelations(correlations); - models[1].modelCorrelations(correlations); + maths::CUnivariateTimeSeriesModel model0{modelParams(bucketLength), 0, + trend, prior, nullptr}; + maths::CUnivariateTimeSeriesModel model1{modelParams(bucketLength), 1, + trend, prior, nullptr}; + model0.modelCorrelations(correlations); + model1.modelCorrelations(correlations); CTimeSeriesCorrelateModelAllocator allocator; TDouble2VecWeightsAryVec weights{maths_t::CUnitWeights::unit(1)}; core_t::TTime time{0}; for (auto sample : samples) { correlations.refresh(allocator); - models[0].addSamples(addSampleParams(weights), - {core::make_triple(time, TDouble2Vec{sample[0]}, TAG)}); - models[1].addSamples(addSampleParams(weights), - {core::make_triple(time, TDouble2Vec{sample[1]}, TAG)}); + model0.addSamples(addSampleParams(weights), + {core::make_triple(time, TDouble2Vec{sample[0]}, TAG)}); + model1.addSamples(addSampleParams(weights), + {core::make_triple(time, TDouble2Vec{sample[1]}, TAG)}); correlations.processSamples(); time += bucketLength; } diff --git a/lib/model/CAnomalyDetectorModel.cc b/lib/model/CAnomalyDetectorModel.cc index 8c44800c62..628adb6041 100644 --- a/lib/model/CAnomalyDetectorModel.cc +++ b/lib/model/CAnomalyDetectorModel.cc @@ -478,7 +478,7 @@ const core_t::TTime CAnomalyDetectorModel::TIME_UNSET(-1); const std::string CAnomalyDetectorModel::EMPTY_STRING; CAnomalyDetectorModel::SFeatureModels::SFeatureModels(model_t::EFeature feature, - TMathsModelPtr newModel) + TMathsModelSPtr newModel) : s_Feature(feature), s_NewModel(newModel) { } @@ -490,13 +490,13 @@ bool CAnomalyDetectorModel::SFeatureModels::acceptRestoreTraverser(const SModelP params_.distributionRestoreParams(dataType)}; do { if (traverser.name() == MODEL_TAG) { - TMathsModelPtr prior; + TMathsModelUPtr model; if (!traverser.traverseSubLevel( boost::bind(maths::CModelStateSerialiser(), - boost::cref(params), boost::ref(prior), _1))) { + boost::cref(params), boost::ref(model), _1))) { return false; } - s_Models.push_back(prior); + s_Models.push_back(std::move(model)); } } while (traverser.next()); return true; @@ -519,10 +519,11 @@ std::size_t CAnomalyDetectorModel::SFeatureModels::memoryUsage() const { return core::CMemory::dynamicSize(s_NewModel) + core::CMemory::dynamicSize(s_Models); } -CAnomalyDetectorModel::SFeatureCorrelateModels::SFeatureCorrelateModels(model_t::EFeature feature, - TMultivariatePriorPtr modelPrior, - TCorrelationsPtr model) - : s_Feature(feature), s_ModelPrior(modelPrior), s_Models(model->clone()) { +CAnomalyDetectorModel::SFeatureCorrelateModels::SFeatureCorrelateModels( + model_t::EFeature feature, + const TMultivariatePriorSPtr& modelPrior, + TCorrelationsPtr&& model) + : s_Feature(feature), s_ModelPrior(modelPrior), s_Models(std::move(model)) { } bool CAnomalyDetectorModel::SFeatureCorrelateModels::acceptRestoreTraverser( @@ -586,13 +587,13 @@ std::size_t CAnomalyDetectorModel::CTimeSeriesCorrelateModelAllocator::chunkSize return 500; } -CAnomalyDetectorModel::TMultivariatePriorPtr +CAnomalyDetectorModel::CTimeSeriesCorrelateModelAllocator::TMultivariatePriorUPtr CAnomalyDetectorModel::CTimeSeriesCorrelateModelAllocator::newPrior() const { - return TMultivariatePriorPtr(m_PrototypePrior->clone()); + return TMultivariatePriorUPtr(m_PrototypePrior->clone()); } void CAnomalyDetectorModel::CTimeSeriesCorrelateModelAllocator::prototypePrior( - const TMultivariatePriorPtr& prior) { + const TMultivariatePriorSPtr& prior) { m_PrototypePrior = prior; } } diff --git a/lib/model/CAnomalyDetectorModelConfig.cc b/lib/model/CAnomalyDetectorModelConfig.cc index 38128f5617..27aa6e17e9 100644 --- a/lib/model/CAnomalyDetectorModelConfig.cc +++ b/lib/model/CAnomalyDetectorModelConfig.cc @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include diff --git a/lib/model/CCountingModelFactory.cc b/lib/model/CCountingModelFactory.cc index f1ce47f69f..3a48ccbeb9 100644 --- a/lib/model/CCountingModelFactory.cc +++ b/lib/model/CCountingModelFactory.cc @@ -10,11 +10,14 @@ #include #include +#include #include #include #include +#include + #include namespace ml { @@ -78,27 +81,26 @@ CCountingModelFactory::makeDataGatherer(const std::string& partitionFieldValue, CCountingModelFactory::TPriorPtr CCountingModelFactory::defaultPrior(model_t::EFeature /*feature*/, const SModelParams& /*params*/) const { - return std::make_shared(); + return boost::make_unique(); } -CCountingModelFactory::TMultivariatePriorPtr +CCountingModelFactory::TMultivariatePriorUPtr CCountingModelFactory::defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& /*params*/) const { - return std::make_shared(model_t::dimension(feature)); + return boost::make_unique(model_t::dimension(feature)); } -CCountingModelFactory::TMultivariatePriorPtr +CCountingModelFactory::TMultivariatePriorUPtr CCountingModelFactory::defaultCorrelatePrior(model_t::EFeature /*feature*/, const SModelParams& /*params*/) const { - return std::make_shared(2); + return boost::make_unique(2); } const CSearchKey& CCountingModelFactory::searchKey() const { if (!m_SearchKeyCache) { - m_SearchKeyCache.reset( - CSearchKey(m_Identifier, function_t::function(m_Features), - m_UseNull, this->modelParams().s_ExcludeFrequent, "", - m_PersonFieldName, "", m_PartitionFieldName)); + m_SearchKeyCache.emplace(m_Identifier, function_t::function(m_Features), + m_UseNull, this->modelParams().s_ExcludeFrequent, + "", m_PersonFieldName, "", m_PartitionFieldName); } return *m_SearchKeyCache; } diff --git a/lib/model/CEventRateModel.cc b/lib/model/CEventRateModel.cc index 352bf4ef4d..ad679dce7e 100644 --- a/lib/model/CEventRateModel.cc +++ b/lib/model/CEventRateModel.cc @@ -59,9 +59,9 @@ const std::string PROBABILITY_PRIOR_TAG("b"); CEventRateModel::CEventRateModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const maths::CMultinomialConjugate& probabilityPrior, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector) @@ -69,7 +69,7 @@ CEventRateModel::CEventRateModel(const SModelParams& params, dataGatherer, newFeatureModels, newFeatureCorrelateModelPriors, - featureCorrelatesModels, + std::move(featureCorrelatesModels), influenceCalculators), m_CurrentBucketStats(CAnomalyDetectorModel::TIME_UNSET), m_ProbabilityPrior(probabilityPrior), @@ -78,9 +78,9 @@ CEventRateModel::CEventRateModel(const SModelParams& params, CEventRateModel::CEventRateModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser) @@ -88,7 +88,7 @@ CEventRateModel::CEventRateModel(const SModelParams& params, dataGatherer, newFeatureModels, newFeatureCorrelateModelPriors, - featureCorrelatesModels, + std::move(featureCorrelatesModels), influenceCalculators), m_CurrentBucketStats(CAnomalyDetectorModel::TIME_UNSET), m_InterimBucketCorrector(interimBucketCorrector) { diff --git a/lib/model/CEventRateModelFactory.cc b/lib/model/CEventRateModelFactory.cc index a06898b9a4..cccf21f5ab 100644 --- a/lib/model/CEventRateModelFactory.cc +++ b/lib/model/CEventRateModelFactory.cc @@ -23,6 +23,8 @@ #include #include +#include + #include namespace ml { @@ -114,13 +116,13 @@ CEventRateModelFactory::defaultPrior(model_t::EFeature feature, // Categorical data all use the multinomial prior. The creation // of these priors is managed by defaultCategoricalPrior. if (model_t::isCategorical(feature)) { - return TPriorPtr(); + return nullptr; } // If the feature data only ever takes a single value we use a // special lightweight prior. if (model_t::isConstant(feature)) { - return std::make_shared(); + return boost::make_unique(); } // Gaussian mixture for modeling time-of-day and time-of-week. @@ -128,8 +130,6 @@ CEventRateModelFactory::defaultPrior(model_t::EFeature feature, return this->timeOfDayPrior(params); } - using TPriorPtrVec = std::vector; - // The data will be counts for the number of events in a specified // interval. As such we expect counts to be greater than or equal // to zero. We use a small non-zero offset, for the log-normal prior @@ -153,7 +153,7 @@ CEventRateModelFactory::defaultPrior(model_t::EFeature feature, maths::CPoissonMeanConjugate::nonInformativePrior(0.0, params.s_DecayRate); // Create the component priors. - TPriorPtrVec priors; + maths::COneOfNPrior::TPriorPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 5u : 4u); priors.emplace_back(gammaPrior.clone()); priors.emplace_back(logNormalPrior.clone()); @@ -161,7 +161,7 @@ CEventRateModelFactory::defaultPrior(model_t::EFeature feature, priors.emplace_back(poissonPrior.clone()); if (params.s_MinimumModeFraction <= 0.5) { // Create the multimode prior. - TPriorPtrVec modePriors; + maths::COneOfNPrior::TPriorPtrVec modePriors; modePriors.reserve(3u); modePriors.emplace_back(gammaPrior.clone()); modePriors.emplace_back(logNormalPrior.clone()); @@ -176,44 +176,45 @@ CEventRateModelFactory::defaultPrior(model_t::EFeature feature, priors.emplace_back(multimodalPrior.clone()); } - return std::make_shared(priors, dataType, params.s_DecayRate); + return boost::make_unique(priors, dataType, params.s_DecayRate); } -CEventRateModelFactory::TMultivariatePriorPtr +CEventRateModelFactory::TMultivariatePriorUPtr CEventRateModelFactory::defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const { std::size_t dimension = model_t::dimension(feature); - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal(this->multivariateNormalPrior(dimension, params)); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(dimension, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(dimension, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(dimension, params, + *priors.back())); } return this->multivariateOneOfNPrior(dimension, params, priors); } -CEventRateModelFactory::TMultivariatePriorPtr +CEventRateModelFactory::TMultivariatePriorUPtr CEventRateModelFactory::defaultCorrelatePrior(model_t::EFeature /*feature*/, const SModelParams& params) const { - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = this->multivariateNormalPrior(2, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(2, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(2, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(2, params, *priors.back())); } return this->multivariateOneOfNPrior(2, params, priors); } const CSearchKey& CEventRateModelFactory::searchKey() const { if (!m_SearchKeyCache) { - m_SearchKeyCache.reset(CSearchKey( - m_Identifier, function_t::function(m_Features), m_UseNull, - this->modelParams().s_ExcludeFrequent, m_ValueFieldName, - m_PersonFieldName, "", m_PartitionFieldName, m_InfluenceFieldNames)); + m_SearchKeyCache.emplace(m_Identifier, function_t::function(m_Features), + m_UseNull, this->modelParams().s_ExcludeFrequent, + m_ValueFieldName, m_PersonFieldName, "", + m_PartitionFieldName, m_InfluenceFieldNames); } return *m_SearchKeyCache; } diff --git a/lib/model/CEventRatePopulationModel.cc b/lib/model/CEventRatePopulationModel.cc index 5517803254..98906c7053 100644 --- a/lib/model/CEventRatePopulationModel.cc +++ b/lib/model/CEventRatePopulationModel.cc @@ -70,9 +70,9 @@ const std::string EMPTY_STRING(""); CEventRatePopulationModel::CEventRatePopulationModel( const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector) : CPopulationModel(params, dataGatherer, influenceCalculators), @@ -85,15 +85,16 @@ CEventRatePopulationModel::CEventRatePopulationModel( boost::numeric::bounds::highest(), params.s_DecayRate)), m_InterimBucketCorrector(interimBucketCorrector), m_Probabilities(0.05) { - this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, featureCorrelatesModels); + this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, + std::move(featureCorrelatesModels)); } CEventRatePopulationModel::CEventRatePopulationModel( const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser) @@ -101,15 +102,16 @@ CEventRatePopulationModel::CEventRatePopulationModel( m_CurrentBucketStats(dataGatherer->currentBucketStartTime() - dataGatherer->bucketLength()), m_InterimBucketCorrector(interimBucketCorrector), m_Probabilities(0.05) { - this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, featureCorrelatesModels); + this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, + std::move(featureCorrelatesModels)); traverser.traverseSubLevel( boost::bind(&CEventRatePopulationModel::acceptRestoreTraverser, this, _1)); } void CEventRatePopulationModel::initialize( - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels) { + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels) { m_FeatureModels.reserve(newFeatureModels.size()); for (const auto& model : newFeatureModels) { m_FeatureModels.emplace_back(model.first, model.second); @@ -125,7 +127,7 @@ void CEventRatePopulationModel::initialize( m_FeatureCorrelatesModels.emplace_back( featureCorrelatesModels[i].first, newFeatureCorrelateModelPriors[i].second, - featureCorrelatesModels[i].second); + std::move(featureCorrelatesModels[i].second)); } std::sort(m_FeatureCorrelatesModels.begin(), m_FeatureCorrelatesModels.end(), [](const SFeatureCorrelateModels& lhs, const SFeatureCorrelateModels& rhs) { diff --git a/lib/model/CEventRatePopulationModelFactory.cc b/lib/model/CEventRatePopulationModelFactory.cc index 1d89c69fb0..4d719ea462 100644 --- a/lib/model/CEventRatePopulationModelFactory.cc +++ b/lib/model/CEventRatePopulationModelFactory.cc @@ -23,6 +23,8 @@ #include #include +#include + #include namespace ml { @@ -113,21 +115,19 @@ CEventRatePopulationModelFactory::defaultPrior(model_t::EFeature feature, // Categorical data all use the multinomial prior. The creation // of these priors is managed by defaultCategoricalPrior. if (model_t::isCategorical(feature)) { - return TPriorPtr(); + return nullptr; } // If the feature data only ever takes a single value we use a // special lightweight prior. if (model_t::isConstant(feature)) { - return std::make_shared(); + return boost::make_unique(); } if (model_t::isDiurnal(feature)) { return this->timeOfDayPrior(params); } - using TPriorPtrVec = std::vector; - // The feature data will be counts for the number of events in a // specified interval. As such we expect counts to be greater than // or equal to zero. We use a small non-zero offset, for the log- @@ -151,7 +151,7 @@ CEventRatePopulationModelFactory::defaultPrior(model_t::EFeature feature, maths::CPoissonMeanConjugate::nonInformativePrior(0.0, params.s_DecayRate); // Create the component priors. - TPriorPtrVec priors; + maths::COneOfNPrior::TPriorPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 5u : 4u); priors.emplace_back(gammaPrior.clone()); priors.emplace_back(logNormalPrior.clone()); @@ -159,7 +159,7 @@ CEventRatePopulationModelFactory::defaultPrior(model_t::EFeature feature, priors.emplace_back(poissonPrior.clone()); if (params.s_MinimumModeFraction <= 0.5) { // Create the multimode prior. - TPriorPtrVec modePriors; + maths::COneOfNPrior::TPriorPtrVec modePriors; modePriors.reserve(3u); modePriors.emplace_back(gammaPrior.clone()); modePriors.emplace_back(logNormalPrior.clone()); @@ -174,45 +174,45 @@ CEventRatePopulationModelFactory::defaultPrior(model_t::EFeature feature, priors.emplace_back(multimodalPrior.clone()); } - return std::make_shared(priors, dataType, params.s_DecayRate); + return boost::make_unique(priors, dataType, params.s_DecayRate); } -CEventRatePopulationModelFactory::TMultivariatePriorPtr +CEventRatePopulationModelFactory::TMultivariatePriorUPtr CEventRatePopulationModelFactory::defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const { std::size_t dimension = model_t::dimension(feature); - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = - this->multivariateNormalPrior(dimension, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(dimension, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(dimension, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(dimension, params, + *priors.back())); } return this->multivariateOneOfNPrior(dimension, params, priors); } -CEventRatePopulationModelFactory::TMultivariatePriorPtr +CEventRatePopulationModelFactory::TMultivariatePriorUPtr CEventRatePopulationModelFactory::defaultCorrelatePrior(model_t::EFeature /*feature*/, const SModelParams& params) const { - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = this->multivariateNormalPrior(2, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(2, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(2, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(2, params, *priors.back())); } return this->multivariateOneOfNPrior(2, params, priors); } const CSearchKey& CEventRatePopulationModelFactory::searchKey() const { if (!m_SearchKeyCache) { - m_SearchKeyCache.reset(CSearchKey( - m_Identifier, function_t::function(m_Features), m_UseNull, - this->modelParams().s_ExcludeFrequent, m_ValueFieldName, m_AttributeFieldName, - m_PersonFieldName, m_PartitionFieldName, m_InfluenceFieldNames)); + m_SearchKeyCache.emplace(m_Identifier, function_t::function(m_Features), + m_UseNull, this->modelParams().s_ExcludeFrequent, + m_ValueFieldName, m_AttributeFieldName, m_PersonFieldName, + m_PartitionFieldName, m_InfluenceFieldNames); } return *m_SearchKeyCache; } diff --git a/lib/model/CForecastModelPersist.cc b/lib/model/CForecastModelPersist.cc index 5cdeeede50..1077d93f5b 100644 --- a/lib/model/CForecastModelPersist.cc +++ b/lib/model/CForecastModelPersist.cc @@ -118,7 +118,7 @@ bool CForecastModelPersist::CRestore::restoreOneModel(core::CStateRestoreTravers bool restoredFeature = false; bool restoredDataType = false; byFieldValue.clear(); - maths_t::EDataType dataType; + maths_t::EDataType dataType{}; do { const std::string& name = traverser.name(); diff --git a/lib/model/CIndividualModel.cc b/lib/model/CIndividualModel.cc index 1213c05534..55945b6ff8 100644 --- a/lib/model/CIndividualModel.cc +++ b/lib/model/CIndividualModel.cc @@ -72,9 +72,9 @@ const std::string MEMORY_ESTIMATOR_TAG("i"); CIndividualModel::CIndividualModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators) : CAnomalyDetectorModel(params, dataGatherer, influenceCalculators) { m_FeatureModels.reserve(newFeatureModels.size()); @@ -92,7 +92,7 @@ CIndividualModel::CIndividualModel(const SModelParams& params, m_FeatureCorrelatesModels.emplace_back( featureCorrelatesModels[i].first, newFeatureCorrelateModelPriors[i].second, - featureCorrelatesModels[i].second); + std::move(featureCorrelatesModels[i].second)); } std::sort(m_FeatureCorrelatesModels.begin(), m_FeatureCorrelatesModels.end(), [](const SFeatureCorrelateModels& lhs, const SFeatureCorrelateModels& rhs) { diff --git a/lib/model/CMetricModel.cc b/lib/model/CMetricModel.cc index cf41cb12bb..f0212dc1bb 100644 --- a/lib/model/CMetricModel.cc +++ b/lib/model/CMetricModel.cc @@ -58,16 +58,16 @@ const std::string INDIVIDUAL_STATE_TAG("a"); CMetricModel::CMetricModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector) : CIndividualModel(params, dataGatherer, newFeatureModels, newFeatureCorrelateModelPriors, - featureCorrelatesModels, + std::move(featureCorrelatesModels), influenceCalculators), m_CurrentBucketStats(CAnomalyDetectorModel::TIME_UNSET), m_InterimBucketCorrector(interimBucketCorrector) { @@ -75,9 +75,9 @@ CMetricModel::CMetricModel(const SModelParams& params, CMetricModel::CMetricModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser) @@ -85,7 +85,7 @@ CMetricModel::CMetricModel(const SModelParams& params, dataGatherer, newFeatureModels, newFeatureCorrelateModelPriors, - featureCorrelatesModels, + std::move(featureCorrelatesModels), influenceCalculators), m_CurrentBucketStats(CAnomalyDetectorModel::TIME_UNSET), m_InterimBucketCorrector(interimBucketCorrector) { diff --git a/lib/model/CMetricModelFactory.cc b/lib/model/CMetricModelFactory.cc index a3d264695c..e608babad5 100644 --- a/lib/model/CMetricModelFactory.cc +++ b/lib/model/CMetricModelFactory.cc @@ -21,6 +21,8 @@ #include #include +#include + #include namespace ml { @@ -111,17 +113,15 @@ CMetricModelFactory::defaultPrior(model_t::EFeature feature, const SModelParams& // Categorical data all use the multinomial prior. The creation // of these priors is managed by defaultCategoricalPrior. if (model_t::isCategorical(feature)) { - return TPriorPtr(); + return nullptr; } // If the feature data only ever takes a single value we use a // special lightweight prior. if (model_t::isConstant(feature)) { - return std::make_shared(); + return boost::make_unique(); } - using TPriorPtrVec = std::vector; - // The data will be arbitrary metric values. Metrics with negative values // will be handled by adjusting offsets in the gamma and log-normal priors // on the fly. We start off with a small non-zero offset for the log-normal @@ -144,14 +144,14 @@ CMetricModelFactory::defaultPrior(model_t::EFeature feature, const SModelParams& maths::CNormalMeanPrecConjugate::nonInformativePrior(dataType, params.s_DecayRate); // Create the component priors. - TPriorPtrVec priors; + maths::COneOfNPrior::TPriorPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 4u : 3u); priors.emplace_back(gammaPrior.clone()); priors.emplace_back(logNormalPrior.clone()); priors.emplace_back(normalPrior.clone()); if (params.s_MinimumModeFraction <= 0.5) { // Create the multimode prior. - TPriorPtrVec modePriors; + maths::COneOfNPrior::TPriorPtrVec modePriors; modePriors.reserve(3u); modePriors.emplace_back(gammaPrior.clone()); modePriors.emplace_back(logNormalPrior.clone()); @@ -166,10 +166,10 @@ CMetricModelFactory::defaultPrior(model_t::EFeature feature, const SModelParams& priors.emplace_back(multimodalPrior.clone()); } - return std::make_shared(priors, dataType, params.s_DecayRate); + return boost::make_unique(priors, dataType, params.s_DecayRate); } -CMetricModelFactory::TMultivariatePriorPtr +CMetricModelFactory::TMultivariatePriorUPtr CMetricModelFactory::defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const { std::size_t dimension = model_t::dimension(feature); @@ -179,37 +179,37 @@ CMetricModelFactory::defaultMultivariatePrior(model_t::EFeature feature, return this->latLongPrior(params); } - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = - this->multivariateNormalPrior(dimension, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(dimension, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(dimension, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(dimension, params, + *priors.back())); } return this->multivariateOneOfNPrior(dimension, params, priors); } -CMetricModelFactory::TMultivariatePriorPtr +CMetricModelFactory::TMultivariatePriorUPtr CMetricModelFactory::defaultCorrelatePrior(model_t::EFeature /*feature*/, const SModelParams& params) const { - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = this->multivariateNormalPrior(2, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(2, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(2, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(2, params, *priors.back())); } return this->multivariateOneOfNPrior(2, params, priors); } const CSearchKey& CMetricModelFactory::searchKey() const { if (!m_SearchKeyCache) { - m_SearchKeyCache.reset(CSearchKey( - m_Identifier, function_t::function(m_Features), m_UseNull, - this->modelParams().s_ExcludeFrequent, m_ValueFieldName, - m_PersonFieldName, "", m_PartitionFieldName, m_InfluenceFieldNames)); + m_SearchKeyCache.emplace(m_Identifier, function_t::function(m_Features), + m_UseNull, this->modelParams().s_ExcludeFrequent, + m_ValueFieldName, m_PersonFieldName, "", + m_PartitionFieldName, m_InfluenceFieldNames); } return *m_SearchKeyCache; } diff --git a/lib/model/CMetricPopulationModel.cc b/lib/model/CMetricPopulationModel.cc index 701bb39623..269b2cdfe5 100644 --- a/lib/model/CMetricPopulationModel.cc +++ b/lib/model/CMetricPopulationModel.cc @@ -76,24 +76,25 @@ const std::string MEMORY_ESTIMATOR_TAG("d"); CMetricPopulationModel::CMetricPopulationModel( const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector) : CPopulationModel(params, dataGatherer, influenceCalculators), m_CurrentBucketStats(dataGatherer->currentBucketStartTime() - dataGatherer->bucketLength()), m_InterimBucketCorrector(interimBucketCorrector), m_Probabilities(0.05) { - this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, featureCorrelatesModels); + this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, + std::move(featureCorrelatesModels)); } CMetricPopulationModel::CMetricPopulationModel( const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, const TInterimBucketCorrectorCPtr& interimBucketCorrector, core::CStateRestoreTraverser& traverser) @@ -101,14 +102,15 @@ CMetricPopulationModel::CMetricPopulationModel( m_CurrentBucketStats(dataGatherer->currentBucketStartTime() - dataGatherer->bucketLength()), m_InterimBucketCorrector(interimBucketCorrector), m_Probabilities(0.05) { - this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, featureCorrelatesModels); + this->initialize(newFeatureModels, newFeatureCorrelateModelPriors, + std::move(featureCorrelatesModels)); traverser.traverseSubLevel( boost::bind(&CMetricPopulationModel::acceptRestoreTraverser, this, _1)); } -void CMetricPopulationModel::initialize(const TFeatureMathsModelPtrPrVec& newFeatureModels, - const TFeatureMultivariatePriorPtrPrVec& newFeatureCorrelateModelPriors, - const TFeatureCorrelationsPtrPrVec& featureCorrelatesModels) { +void CMetricPopulationModel::initialize(const TFeatureMathsModelSPtrPrVec& newFeatureModels, + const TFeatureMultivariatePriorSPtrPrVec& newFeatureCorrelateModelPriors, + TFeatureCorrelationsPtrPrVec&& featureCorrelatesModels) { m_FeatureModels.reserve(newFeatureModels.size()); for (const auto& model : newFeatureModels) { m_FeatureModels.emplace_back(model.first, model.second); @@ -124,7 +126,7 @@ void CMetricPopulationModel::initialize(const TFeatureMathsModelPtrPrVec& newFea m_FeatureCorrelatesModels.emplace_back( featureCorrelatesModels[i].first, newFeatureCorrelateModelPriors[i].second, - featureCorrelatesModels[i].second); + std::move(featureCorrelatesModels[i].second)); } std::sort(m_FeatureCorrelatesModels.begin(), m_FeatureCorrelatesModels.end(), [](const SFeatureCorrelateModels& lhs, const SFeatureCorrelateModels& rhs) { diff --git a/lib/model/CMetricPopulationModelFactory.cc b/lib/model/CMetricPopulationModelFactory.cc index c360d87eae..28e49a5058 100644 --- a/lib/model/CMetricPopulationModelFactory.cc +++ b/lib/model/CMetricPopulationModelFactory.cc @@ -21,6 +21,8 @@ #include #include +#include + #include namespace ml { @@ -111,17 +113,15 @@ CMetricPopulationModelFactory::defaultPrior(model_t::EFeature feature, // Categorical data all use the multinomial prior. The creation // of these priors is managed by defaultCategoricalPrior. if (model_t::isCategorical(feature)) { - return TPriorPtr(); + return nullptr; } // If the feature data only ever takes a single value we use a // special lightweight prior. if (model_t::isConstant(feature)) { - return std::make_shared(); + return boost::make_unique(); } - using TPriorPtrVec = std::vector; - // The data will be arbitrary metric values. Metrics with negative values // will be handled by adjusting offsets in the gamma and log-normal priors // on the fly. We start off with a small non-zero offset for the log-normal @@ -144,14 +144,14 @@ CMetricPopulationModelFactory::defaultPrior(model_t::EFeature feature, maths::CNormalMeanPrecConjugate::nonInformativePrior(dataType, params.s_DecayRate); // Create the component priors. - TPriorPtrVec priors; + maths::COneOfNPrior::TPriorPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 4u : 3u); priors.emplace_back(gammaPrior.clone()); priors.emplace_back(logNormalPrior.clone()); priors.emplace_back(normalPrior.clone()); if (params.s_MinimumModeFraction <= 0.5) { // Create the multimode prior. - TPriorPtrVec modePriors; + maths::COneOfNPrior::TPriorPtrVec modePriors; modePriors.reserve(3u); modePriors.emplace_back(gammaPrior.clone()); modePriors.emplace_back(logNormalPrior.clone()); @@ -166,10 +166,10 @@ CMetricPopulationModelFactory::defaultPrior(model_t::EFeature feature, priors.emplace_back(multimodalPrior.clone()); } - return std::make_shared(priors, dataType, params.s_DecayRate); + return boost::make_unique(priors, dataType, params.s_DecayRate); } -CMetricPopulationModelFactory::TMultivariatePriorPtr +CMetricPopulationModelFactory::TMultivariatePriorUPtr CMetricPopulationModelFactory::defaultMultivariatePrior(model_t::EFeature feature, const SModelParams& params) const { std::size_t dimension = model_t::dimension(feature); @@ -179,37 +179,37 @@ CMetricPopulationModelFactory::defaultMultivariatePrior(model_t::EFeature featur return this->latLongPrior(params); } - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = - this->multivariateNormalPrior(dimension, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(dimension, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(dimension, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(dimension, params, + *priors.back())); } return this->multivariateOneOfNPrior(dimension, params, priors); } -CMetricPopulationModelFactory::TMultivariatePriorPtr +CMetricPopulationModelFactory::TMultivariatePriorUPtr CMetricPopulationModelFactory::defaultCorrelatePrior(model_t::EFeature /*feature*/, const SModelParams& params) const { - TMultivariatePriorPtrVec priors; + TMultivariatePriorUPtrVec priors; priors.reserve(params.s_MinimumModeFraction <= 0.5 ? 2u : 1u); - TMultivariatePriorPtr multivariateNormal = this->multivariateNormalPrior(2, params); - priors.push_back(multivariateNormal); + TMultivariatePriorUPtr normal{this->multivariateNormalPrior(2, params)}; + priors.push_back(std::move(normal)); if (params.s_MinimumModeFraction <= 0.5) { - priors.push_back(this->multivariateMultimodalPrior(2, params, *multivariateNormal)); + priors.push_back(this->multivariateMultimodalPrior(2, params, *priors.back())); } return this->multivariateOneOfNPrior(2, params, priors); } const CSearchKey& CMetricPopulationModelFactory::searchKey() const { if (!m_SearchKeyCache) { - m_SearchKeyCache.reset(CSearchKey( - m_Identifier, function_t::function(m_Features), m_UseNull, - this->modelParams().s_ExcludeFrequent, m_ValueFieldName, m_AttributeFieldName, - m_PersonFieldName, m_PartitionFieldName, m_InfluenceFieldNames)); + m_SearchKeyCache.emplace(m_Identifier, function_t::function(m_Features), + m_UseNull, this->modelParams().s_ExcludeFrequent, + m_ValueFieldName, m_AttributeFieldName, m_PersonFieldName, + m_PartitionFieldName, m_InfluenceFieldNames); } return *m_SearchKeyCache; } diff --git a/lib/model/CModelFactory.cc b/lib/model/CModelFactory.cc index aeefab4bfa..fcf5cee33a 100644 --- a/lib/model/CModelFactory.cc +++ b/lib/model/CModelFactory.cc @@ -30,6 +30,7 @@ #include #include +#include namespace ml { namespace model { @@ -101,16 +102,15 @@ CModelFactory::defaultFeatureModel(model_t::EFeature feature, modelAnomalies && !model_t::isConstant(feature)); } - TMultivariatePriorPtr prior{this->defaultMultivariatePrior(feature)}; + TMultivariatePriorUPtr prior{this->defaultMultivariatePrior(feature)}; return std::make_shared( params, *trend, *prior, controlDecayRate ? &controllers : nullptr, modelAnomalies && !model_t::isConstant(feature)); } -const CModelFactory::TFeatureMultivariatePriorPtrPrVec& +const CModelFactory::TFeatureMultivariatePriorSPtrPrVec& CModelFactory::defaultCorrelatePriors(const TFeatureVec& features) const { - auto result = m_CorrelatePriorCache.insert( - {features, TFeatureMultivariatePriorPtrPrVec()}); + auto result = m_CorrelatePriorCache.emplace(features, TFeatureMultivariatePriorSPtrPrVec{}); if (result.second) { result.first->second.reserve(features.size()); for (auto feature : features) { @@ -123,33 +123,30 @@ CModelFactory::defaultCorrelatePriors(const TFeatureVec& features) const { return result.first->second; } -const CModelFactory::TFeatureCorrelationsPtrPrVec& +CModelFactory::TFeatureCorrelationsPtrPrVec CModelFactory::defaultCorrelates(const TFeatureVec& features) const { - auto result = m_CorrelationsCache.insert({features, TFeatureCorrelationsPtrPrVec()}); - if (result.second) { - result.first->second.reserve(features.size()); - for (auto feature : features) { - if (!model_t::isCategorical(feature) && model_t::dimension(feature) == 1) { - result.first->second.emplace_back( - feature, TCorrelationsPtr(new maths::CTimeSeriesCorrelations( - m_ModelParams.s_MinimumSignificantCorrelation, - m_ModelParams.s_DecayRate))); - } + TFeatureCorrelationsPtrPrVec result; + result.reserve(features.size()); + for (auto feature : features) { + if (!model_t::isCategorical(feature) && model_t::dimension(feature) == 1) { + result.emplace_back(feature, boost::make_unique( + m_ModelParams.s_MinimumSignificantCorrelation, + m_ModelParams.s_DecayRate)); } } - return result.first->second; + return result; } CModelFactory::TPriorPtr CModelFactory::defaultPrior(model_t::EFeature feature) const { return this->defaultPrior(feature, m_ModelParams); } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::defaultMultivariatePrior(model_t::EFeature feature) const { return this->defaultMultivariatePrior(feature, m_ModelParams); } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::defaultCorrelatePrior(model_t::EFeature feature) const { return this->defaultCorrelatePrior(feature, m_ModelParams); } @@ -297,13 +294,13 @@ CModelFactory::TInterimBucketCorrectorPtr CModelFactory::interimBucketCorrector( return result; } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::multivariateNormalPrior(std::size_t dimension, const SModelParams& params) const { return maths::CMultivariateNormalConjugateFactory::nonInformative( dimension, this->dataType(), params.s_DecayRate); } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::multivariateMultimodalPrior(std::size_t dimension, const SModelParams& params, const maths::CMultivariatePrior& modePrior) const { @@ -313,17 +310,15 @@ CModelFactory::multivariateMultimodalPrior(std::size_t dimension, params.s_MinimumModeCount, params.minimumCategoryCount(), modePrior); } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::multivariateOneOfNPrior(std::size_t dimension, const SModelParams& params, - const TMultivariatePriorPtrVec& models) const { + const TMultivariatePriorUPtrVec& models) const { return maths::CMultivariateOneOfNPriorFactory::nonInformative( dimension, this->dataType(), params.s_DecayRate, models); } CModelFactory::TPriorPtr CModelFactory::timeOfDayPrior(const SModelParams& params) const { - using TPriorPtrVec = std::vector; - maths_t::EDataType dataType = this->dataType(); maths::CNormalMeanPrecConjugate normalPrior = maths::CNormalMeanPrecConjugate::nonInformativePrior(dataType, params.s_DecayRate); @@ -331,7 +326,7 @@ CModelFactory::TPriorPtr CModelFactory::timeOfDayPrior(const SModelParams& param // Create a multimodal prior with purely normal distributions // - don't bother with long-tail distributions - TPriorPtrVec modePriors; + maths::COneOfNPrior::TPriorPtrVec modePriors; modePriors.reserve(1u); modePriors.emplace_back(normalPrior.clone()); maths::COneOfNPrior modePrior(modePriors, dataType, params.s_DecayRate); @@ -342,14 +337,14 @@ CModelFactory::TPriorPtr CModelFactory::timeOfDayPrior(const SModelParams& param 4, // minimumClusterCount CAnomalyDetectorModelConfig::DEFAULT_CATEGORY_DELETE_FRACTION); - return std::make_shared(dataType, clusterer, modePrior, - params.s_DecayRate); + return boost::make_unique(dataType, clusterer, modePrior, + params.s_DecayRate); } -CModelFactory::TMultivariatePriorPtr +CModelFactory::TMultivariatePriorUPtr CModelFactory::latLongPrior(const SModelParams& params) const { maths_t::EDataType dataType = this->dataType(); - TMultivariatePriorPtr modePrior = maths::CMultivariateNormalConjugateFactory::nonInformative( + TMultivariatePriorUPtr modePrior = maths::CMultivariateNormalConjugateFactory::nonInformative( 2, dataType, params.s_DecayRate); return maths::CMultivariateMultimodalPriorFactory::nonInformative( 2, // dimension diff --git a/lib/model/CResourceMonitor.cc b/lib/model/CResourceMonitor.cc index 6e1fd65a25..3f2dc8c308 100644 --- a/lib/model/CResourceMonitor.cc +++ b/lib/model/CResourceMonitor.cc @@ -42,7 +42,7 @@ void CResourceMonitor::memoryUsageReporter(const TMemoryUsageReporterFunc& repor } void CResourceMonitor::registerComponent(CAnomalyDetector& detector) { - LOG_TRACE(<< "Registering component: " << detector.model()); + LOG_TRACE(<< "Registering component: " << detector.model().get()); m_Models.insert({detector.model().get(), std::size_t(0)}); } @@ -50,11 +50,11 @@ void CResourceMonitor::unRegisterComponent(CAnomalyDetector& detector) { auto iter = m_Models.find(detector.model().get()); if (iter == m_Models.end()) { LOG_ERROR(<< "Inconsistency - component has not been registered: " - << detector.model()); + << detector.model().get()); return; } - LOG_TRACE(<< "Unregistering component: " << detector.model()); + LOG_TRACE(<< "Unregistering component: " << detector.model().get()); m_Models.erase(iter); } diff --git a/lib/model/unittest/CModelDetailsViewTest.cc b/lib/model/unittest/CModelDetailsViewTest.cc index 1714acc287..c2f5080948 100644 --- a/lib/model/unittest/CModelDetailsViewTest.cc +++ b/lib/model/unittest/CModelDetailsViewTest.cc @@ -67,11 +67,12 @@ void CModelDetailsViewTest::testModelPlot() { bucketLength, 1.0, 0.001, 0.2, 6 * core::constants::HOUR, 24 * core::constants::HOUR}; maths::CUnivariateTimeSeriesModel timeSeriesModel{timeSeriesModelParams, 0, trend, prior}; - model->mockTimeSeriesModels( - {model::CMockModel::TMathsModelPtr(timeSeriesModel.clone(0)), - model::CMockModel::TMathsModelPtr(timeSeriesModel.clone(1)), - model::CMockModel::TMathsModelPtr(timeSeriesModel.clone(2)), - model::CMockModel::TMathsModelPtr(timeSeriesModel.clone(3))}); + model::CMockModel::TMathsModelUPtrVec models; + models.emplace_back(timeSeriesModel.clone(0)); + models.emplace_back(timeSeriesModel.clone(1)); + models.emplace_back(timeSeriesModel.clone(2)); + models.emplace_back(timeSeriesModel.clone(3)); + model->mockTimeSeriesModels(std::move(models)); }; LOG_DEBUG(<< "Individual sum"); diff --git a/lib/model/unittest/CResourceLimitTest.cc b/lib/model/unittest/CResourceLimitTest.cc index d549808cfd..a7aeb75e0b 100644 --- a/lib/model/unittest/CResourceLimitTest.cc +++ b/lib/model/unittest/CResourceLimitTest.cc @@ -240,14 +240,14 @@ class CMockEventRateModel : public ml::model::CEventRateModel { public: CMockEventRateModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, const maths::CMultinomialConjugate& personProbabilityPrior, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, CResourceMonitor& resourceMonitor) : CEventRateModel(params, dataGatherer, newFeatureModels, - TFeatureMultivariatePriorPtrPrVec(), + TFeatureMultivariatePriorSPtrPrVec(), TFeatureCorrelationsPtrPrVec(), personProbabilityPrior, influenceCalculators, @@ -284,13 +284,13 @@ class CMockMetricModel : public ml::model::CMetricModel { public: CMockMetricModel(const SModelParams& params, const TDataGathererPtr& dataGatherer, - const TFeatureMathsModelPtrPrVec& newFeatureModels, + const TFeatureMathsModelSPtrPrVec& newFeatureModels, const TFeatureInfluenceCalculatorCPtrPrVecVec& influenceCalculators, CResourceMonitor& resourceMonitor) : CMetricModel(params, dataGatherer, newFeatureModels, - TFeatureMultivariatePriorPtrPrVec(), + TFeatureMultivariatePriorSPtrPrVec(), TFeatureCorrelationsPtrPrVec(), influenceCalculators, std::make_shared(params.s_BucketLength)), diff --git a/lib/model/unittest/Mocks.cc b/lib/model/unittest/Mocks.cc index 345c2dd06c..7fddaadb53 100644 --- a/lib/model/unittest/Mocks.cc +++ b/lib/model/unittest/Mocks.cc @@ -190,8 +190,8 @@ void CMockModel::mockAddBucketBaselineMean(model_t::EFeature feature, m_BucketBaselineMeans[{feature, core::make_triple(pid, cid, time)}] = value; } -void CMockModel::mockTimeSeriesModels(const TMathsModelPtrVec& models) { - m_Models = models; +void CMockModel::mockTimeSeriesModels(TMathsModelUPtrVec&& models) { + m_Models = std::move(models); } CMemoryUsageEstimator* CMockModel::memoryUsageEstimator() const { diff --git a/lib/model/unittest/Mocks.h b/lib/model/unittest/Mocks.h index 74064d9833..2801c97573 100644 --- a/lib/model/unittest/Mocks.h +++ b/lib/model/unittest/Mocks.h @@ -118,7 +118,7 @@ class CMockModel : public CAnomalyDetectorModel { core_t::TTime time, const TDouble1Vec& value); - void mockTimeSeriesModels(const TMathsModelPtrVec& model); + void mockTimeSeriesModels(TMathsModelUPtrVec&& model); private: using TDouble1Vec = CAnomalyDetectorModel::TDouble1Vec; @@ -141,7 +141,7 @@ class CMockModel : public CAnomalyDetectorModel { bool m_IsPopulation; TFeatureSizeSizeTimeTriplePrDouble1VecUMap m_BucketValues; TFeatureSizeSizeTimeTriplePrDouble1VecUMap m_BucketBaselineMeans; - TMathsModelPtrVec m_Models; + TMathsModelUPtrVec m_Models; model::CInterimBucketCorrector m_InterimBucketCorrector; };