summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Balland-Poirier <laurent.balland-poirier@laposte.net>2015-04-16 21:45:58 +0200
committerPhilippe Jung <phil.jung@free.fr>2015-06-22 09:57:14 +0000
commitcad19fa8414b419f2e0f9ee88139e9b7a2dd4ff4 (patch)
tree75be9cc3f2048d7e6181d0343529a9d990366dc4
parent733f5887af46d1d5e2fbea6be93cabb2a1749752 (diff)
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.jung@free.fr> Tested-by: Philippe Jung <phil.jung@free.fr>
-rw-r--r--chart2/source/inc/ExponentialRegressionCurveCalculator.hxx3
-rw-r--r--chart2/source/inc/RegressionCalculationHelper.hxx12
-rw-r--r--chart2/source/tools/ExponentialRegressionCurveCalculator.cxx27
3 files changed, 32 insertions, 10 deletions
diff --git a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx
index 1247d41d6517..782fb57aaca6 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 32456cf8dbb4..2e0e3a4adc53 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 3738d686f683..2e1deddb20a8 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 );