From 9a94e06a36596a9f71419b660ed2aec4d1ebca3c Mon Sep 17 00:00:00 2001 From: Laurent Balland-Poirier Date: Wed, 30 Sep 2015 16:33:30 +0200 Subject: tdf#70673 Improve exponential trend line equation Use negative Y if there is only 1 positive Y Skip some 0 or 1 in some corner case. Add minus sign if intercept is missing Simplify writing of equation Change-Id: I4b164568c87c54934a38ff2d0cd72133f7fece26 Reviewed-on: https://gerrit.libreoffice.org/19033 Tested-by: Jenkins Reviewed-by: Noel Grandin --- .../tools/ExponentialRegressionCurveCalculator.cxx | 61 +++++++++------------- 1 file changed, 25 insertions(+), 36 deletions(-) (limited to 'chart2/source/tools/ExponentialRegressionCurveCalculator.cxx') diff --git a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx index a5cf10491ad5..d5c8ed0656af 100644 --- a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx @@ -54,13 +54,13 @@ void SAL_CALL ExponentialRegressionCurveCalculator::recalculateRegression( m_fSign = 1.0; size_t nMax = aValues.first.size(); - if( nMax == 0 ) + if( nMax <= 1 ) // at least 2 points { aValues = RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValidAndYNegative()); nMax = aValues.first.size(); - if( nMax == 0 ) + if( nMax <= 1 ) { ::rtl::math::setNan( & m_fLogSlope ); ::rtl::math::setNan( & m_fLogIntercept ); @@ -157,48 +157,37 @@ OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation( ::sal_Int32 nNumberFormatKey ) const { 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 ); + bool bHasSlope = !rtl::math::approxEqual( exp(m_fLogSlope), 1.0 ); + bool bHasLogSlope = !rtl::math::approxEqual( fabs(m_fLogSlope), 1.0 ); + bool bHasIntercept = !rtl::math::approxEqual( m_fSign*fIntercept, 1.0 ) && fIntercept != 0.0; - OUStringBuffer aBuf( "f(x) = "); + OUStringBuffer aBuf( "f(x) = " ); - if ( fIntercept == 0.0) + if ( bHasIntercept ) { - // underflow, a true zero is impossible - aBuf.append( "exp( "); - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fLogIntercept) ); - aBuf.append( (m_fLogSlope < 0.0) ? " - " : " + "); - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fabs(m_fLogSlope)) ); - aBuf.append( " x )"); + aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fIntercept) ); + aBuf.append( " exp( " ); } else { - if (bHasIntercept) - { - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fIntercept) ); - aBuf.append( " exp( "); - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fLogSlope) ); - aBuf.append( " x )"); - } - else - { - // show logarithmic output, if intercept and slope both are near one - // otherwise drop output of intercept, which is 1 here - aBuf.append( " exp( "); - if (!bHasSlope) - { - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fLogIntercept) ); - aBuf.append( (m_fLogSlope < 0.0) ? " - " : " + "); - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fabs(m_fLogSlope)) ); - } - else - { - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fLogSlope) ); - } - aBuf.append( " x )"); + if ( m_fSign < 0.0 ) + aBuf.append( "- " ); + aBuf.append( "exp( " ); + if ( fIntercept == 0.0 || // underflow, a true zero is impossible + ( !bHasSlope && m_fLogIntercept != 0.0 ) ) // show logarithmic output, if intercept and slope both are near one + { // otherwise drop output of intercept, which is 1 here + aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fLogIntercept) ); + aBuf.append( (m_fLogSlope < 0.0) ? " " : " + "); } } + if ( m_fLogSlope < 0.0 ) + aBuf.append( "- "); + if ( bHasLogSlope ) + { + aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fabs(m_fLogSlope)) ); + aBuf.append( ' ' ); + } + aBuf.append( "x )"); return aBuf.makeStringAndClear(); } -- cgit