diff --git a/lib/maths/CTrendComponent.cc b/lib/maths/CTrendComponent.cc index 2ca1ccba67..8b603c8d8e 100644 --- a/lib/maths/CTrendComponent.cc +++ b/lib/maths/CTrendComponent.cc @@ -59,6 +59,7 @@ const std::string RESIDUAL_MOMENTS_TAG{"c"}; const double TIME_SCALES[]{144.0, 72.0, 36.0, 12.0, 4.0, 1.0, 0.25, 0.05}; const std::size_t NUMBER_MODELS{boost::size(TIME_SCALES)}; const double MAX_CONDITION{1e12}; +const double MINIMUM_WEIGHT_TO_USE_MODEL_FOR_PREDICTION{0.01}; const core_t::TTime UNSET_TIME{0}; } @@ -210,11 +211,16 @@ CTrendComponent::TDoubleDoublePr CTrendComponent::value(core_t::TTime time, double scaledTime{scaleTime(time, m_RegressionOrigin)}; TMeanAccumulator prediction_; - { - TDoubleVec factors(this->factors(std::abs(time - m_LastUpdate))); - for (std::size_t i = 0u; i < NUMBER_MODELS; ++i) { - prediction_.add(m_Models[i].s_Regression.predict(scaledTime, MAX_CONDITION), - factors[i] * CBasicStatistics::mean(m_Models[i].s_Weight)); + + TDoubleVec weights(this->factors(std::abs(time - m_LastUpdate))); + double Z{0.0}; + for (std::size_t i = 0u; i < NUMBER_MODELS; ++i) { + weights[i] *= CBasicStatistics::mean(m_Models[i].s_Weight); + Z += weights[i]; + } + for (std::size_t i = 0u; i < NUMBER_MODELS; ++i) { + if (weights[i] > MINIMUM_WEIGHT_TO_USE_MODEL_FOR_PREDICTION * Z) { + prediction_.add(m_Models[i].s_Regression.predict(scaledTime, MAX_CONDITION), weights[i]); } } diff --git a/lib/maths/unittest/CForecastTest.cc b/lib/maths/unittest/CForecastTest.cc index 6dc01fb764..819a488bdb 100644 --- a/lib/maths/unittest/CForecastTest.cc +++ b/lib/maths/unittest/CForecastTest.cc @@ -90,7 +90,7 @@ void CForecastTest::testDailyNoLongTermTrend() { return 40.0 + alpha * y[i / 6] + beta * y[(i / 6 + 1) % y.size()] + noise; }; - this->test(trend, bucketLength, 60, 64.0, 4.0, 0.13); + this->test(trend, bucketLength, 60, 64.0, 5.0, 0.14); } void CForecastTest::testDailyConstantLongTermTrend() { @@ -163,7 +163,7 @@ void CForecastTest::testComplexConstantLongTermTrend() { scale[d] * (20.0 + y[h] + noise); }; - this->test(trend, bucketLength, 60, 24.0, 17.0, 0.04); + this->test(trend, bucketLength, 60, 24.0, 13.0, 0.01); } void CForecastTest::testComplexVaryingLongTermTrend() { @@ -193,7 +193,7 @@ void CForecastTest::testComplexVaryingLongTermTrend() { return trend_.value(time_) + scale[d] * (20.0 + y[h] + noise); }; - this->test(trend, bucketLength, 60, 4.0, 23.0, 0.05); + this->test(trend, bucketLength, 60, 4.0, 24.0, 0.051); } void CForecastTest::testNonNegative() { @@ -363,7 +363,7 @@ void CForecastTest::testFinancialIndex() { //file << "my = " << core::CContainerPrinter::print(my) << ";\n"; //file << "uy = " << core::CContainerPrinter::print(uy) << ";\n"; - CPPUNIT_ASSERT(percentageOutOfBounds < 53.0); + CPPUNIT_ASSERT(percentageOutOfBounds < 52.0); CPPUNIT_ASSERT(maths::CBasicStatistics::mean(error) < 0.1); }