[Libreoffice-commits] core.git: chart2/source

Laurent Balland-Poirier laurent.balland-poirier at laposte.net
Mon Jun 22 02:57:37 PDT 2015


 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-poirier at 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.jung at free.fr>
    Tested-by: Philippe Jung <phil.jung at 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 );


More information about the Libreoffice-commits mailing list