diff options
author | Laurent Balland-Poirier <laurent.balland-poirier@laposte.net> | 2015-04-16 22:32:07 +0200 |
---|---|---|
committer | Philippe Jung <phil.jung@free.fr> | 2015-06-22 09:57:49 +0000 |
commit | 35fd66e8648c6d82396486a9469dcb061c832b91 (patch) | |
tree | 964896be8feecb3203eada29bc2a9bc77d0c1588 /chart2 | |
parent | tdf#70673 Exponential trendline: enable negative Y values (diff) | |
download | core-35fd66e8648c6d82396486a9469dcb061c832b91.tar.gz core-35fd66e8648c6d82396486a9469dcb061c832b91.zip |
tdf#70673 Power trendline: enable negative Y values
With a negative intercept, Y values can be negative
Change-Id: I9c23cc89b74498f7e7c7bcee00057627768f48aa
Reviewed-on: https://gerrit.libreoffice.org/15357
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Philippe Jung <phil.jung@free.fr>
Diffstat (limited to 'chart2')
3 files changed, 32 insertions, 9 deletions
diff --git a/chart2/source/inc/PotentialRegressionCurveCalculator.hxx b/chart2/source/inc/PotentialRegressionCurveCalculator.hxx index dba739e214cc..d9ad473fc116 100644 --- a/chart2/source/inc/PotentialRegressionCurveCalculator.hxx +++ b/chart2/source/inc/PotentialRegressionCurveCalculator.hxx @@ -57,9 +57,10 @@ private: throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE; - // formula is: f(x) = x ^ m_fSlope * m_fIntercept + // formula is: f(x) = x ^ m_fSlope * m_fSign * m_fIntercept double m_fSlope; double m_fIntercept; + double m_fSign; }; } // namespace chart diff --git a/chart2/source/inc/RegressionCalculationHelper.hxx b/chart2/source/inc/RegressionCalculationHelper.hxx index 2e0e3a4adc53..7f0a69368467 100644 --- a/chart2/source/inc/RegressionCalculationHelper.hxx +++ b/chart2/source/inc/RegressionCalculationHelper.hxx @@ -127,6 +127,19 @@ public: } }; +class isValidAndXPositiveAndYNegative : 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 ) || + x <= 0.0 || + y >= 0.0 ); + } +}; + } // namespace RegressionCalculationHelper } // namespace chart diff --git a/chart2/source/tools/PotentialRegressionCurveCalculator.cxx b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx index 7495c912b6ea..0e4f4cd204cd 100644 --- a/chart2/source/tools/PotentialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx @@ -50,14 +50,23 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValidAndBothPositive())); + m_fSign = 1.0; - const size_t nMax = aValues.first.size(); + size_t nMax = aValues.first.size(); if( nMax == 0 ) { - ::rtl::math::setNan( & m_fSlope ); - ::rtl::math::setNan( & m_fIntercept ); - ::rtl::math::setNan( & m_fCorrelationCoeffitient ); - return; + aValues = RegressionCalculationHelper::cleanup( + aXValues, aYValues, + RegressionCalculationHelper::isValidAndXPositiveAndYNegative()); + nMax = aValues.first.size(); + if( nMax == 0 ) + { + ::rtl::math::setNan( & m_fSlope ); + ::rtl::math::setNan( & m_fIntercept ); + ::rtl::math::setNan( & m_fCorrelationCoeffitient ); + return; + } + m_fSign = -1.0; } double fAverageX = 0.0, fAverageY = 0.0; @@ -65,7 +74,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( for( i = 0; i < nMax; ++i ) { fAverageX += log( aValues.first[i] ); - fAverageY += log( aValues.second[i] ); + fAverageY += log( m_fSign * aValues.second[i] ); } const double fN = static_cast< double >( nMax ); @@ -76,7 +85,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( for( i = 0; i < nMax; ++i ) { double fDeltaX = log( aValues.first[i] ) - fAverageX; - double fDeltaY = log( aValues.second[i] ) - fAverageY; + double fDeltaY = log( m_fSign * aValues.second[i] ) - fAverageY; fQx += fDeltaX * fDeltaX; fQy += fDeltaY * fDeltaY; @@ -87,7 +96,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( m_fIntercept = fAverageY - m_fSlope * fAverageX; m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy ); - m_fIntercept = exp( m_fIntercept ); + m_fIntercept = m_fSign * exp( m_fIntercept ); } double SAL_CALL PotentialRegressionCurveCalculator::getCurveValue( double x ) |