chart2/source/inc/ExponentialRegressionCurveCalculator.hxx | 3 - chart2/source/inc/RegressionCalculationHelper.hxx | 12 ++++ chart2/source/tools/ExponentialRegressionCurveCalculator.cxx | 27 +++++++---- 3 files changed, 32 insertions(+), 10 deletions(-)
New commits: commit cad19fa8414b419f2e0f9ee88139e9b7a2dd4ff4 Author: Laurent Balland-Poirier <laurent.balland-poir...@laposte.net> Date: Thu Apr 16 21:45:58 2015 +0200 tdf#70673 Exponential trendline: enable negative Y values With a negative intercept, Y values can be negative Rebase with forced intercept fec037e68f0dea164915fbfe1db4699a3861adf4 Conflicts: chart2/source/tools/ExponentialRegressionCurveCalculator.cxx Change-Id: Ie351c006fb1688ef3e657da7ce0789a9da1317f0 Reviewed-on: https://gerrit.libreoffice.org/15353 Reviewed-by: Philippe Jung <phil.j...@free.fr> Tested-by: Philippe Jung <phil.j...@free.fr> diff --git a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx index 1247d41..782fb57 100644 --- a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx +++ b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx @@ -56,10 +56,11 @@ private: throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE; - // formula is: f(x) = exp(m_fLogIntercept) * exp( m_fLogSlope * x ) + // formula is: f(x) = m_fSign * exp(m_fLogIntercept) * exp( m_fLogSlope * x ) // mathematical model f(x) = Intercept * Slope^x double m_fLogSlope; double m_fLogIntercept; + double m_fSign; }; } // namespace chart diff --git a/chart2/source/inc/RegressionCalculationHelper.hxx b/chart2/source/inc/RegressionCalculationHelper.hxx index 32456cf..2e0e3a4 100644 --- a/chart2/source/inc/RegressionCalculationHelper.hxx +++ b/chart2/source/inc/RegressionCalculationHelper.hxx @@ -102,6 +102,18 @@ public: } }; +class isValidAndYNegative : public ::std::binary_function< double, double, bool > +{ +public: + inline bool operator()( double x, double y ) + { return ! ( ::rtl::math::isNan( x ) || + ::rtl::math::isNan( y ) || + ::rtl::math::isInf( x ) || + ::rtl::math::isInf( y ) || + y >= 0.0 ); + } +}; + class isValidAndBothPositive : public ::std::binary_function< double, double, bool > { public: diff --git a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx index 3738d68..2e1dedd 100644 --- a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx @@ -50,25 +50,34 @@ void SAL_CALL ExponentialRegressionCurveCalculator::recalculateRegression( RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValidAndYPositive())); + m_fSign = 1.0; - const size_t nMax = aValues.first.size(); + size_t nMax = aValues.first.size(); if( nMax == 0 ) { - ::rtl::math::setNan( & m_fLogSlope ); - ::rtl::math::setNan( & m_fLogIntercept ); - ::rtl::math::setNan( & m_fCorrelationCoeffitient );// actual it is coefficient of determination - return; + aValues = RegressionCalculationHelper::cleanup( + aXValues, aYValues, + RegressionCalculationHelper::isValidAndYNegative()); + nMax = aValues.first.size(); + if( nMax == 0 ) + { + ::rtl::math::setNan( & m_fLogSlope ); + ::rtl::math::setNan( & m_fLogIntercept ); + ::rtl::math::setNan( & m_fCorrelationCoeffitient );// actual it is coefficient of determination + return; + } + m_fSign = -1.0; } double fAverageX = 0.0, fAverageY = 0.0; - double fLogIntercept = mForceIntercept ? log(mInterceptValue) : 0.0; + double fLogIntercept = ( mForceIntercept && (m_fSign * mInterceptValue)>0 ) ? log(m_fSign * mInterceptValue) : 0.0; std::vector<double> yVector; yVector.resize(nMax, 0.0); size_t i = 0; for( i = 0; i < nMax; ++i ) { - double yValue = log(aValues.second[i]); + double yValue = log( m_fSign *aValues.second[i] ); if (mForceIntercept) { yValue -= fLogIntercept; @@ -111,7 +120,7 @@ double SAL_CALL ExponentialRegressionCurveCalculator::getCurveValue( double x ) if( ! ( ::rtl::math::isNan( m_fLogSlope ) || ::rtl::math::isNan( m_fLogIntercept ))) { - fResult = exp(m_fLogIntercept + x * m_fLogSlope); + fResult = m_fSign * exp(m_fLogIntercept + x * m_fLogSlope); } return fResult; @@ -146,7 +155,7 @@ OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, ::sal_Int32 nNumberFormatKey ) const { - double fIntercept = exp(m_fLogIntercept); + double fIntercept = m_fSign * exp(m_fLogIntercept); double fSlope = exp(m_fLogSlope); bool bHasSlope = !rtl::math::approxEqual( fSlope, 1.0 ); bool bHasIntercept = !rtl::math::approxEqual( fIntercept, 1.0 ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits