Kaydet (Commit) 35fd66e8 authored tarafından Laurent Balland-Poirier's avatar Laurent Balland-Poirier Kaydeden (comit) Philippe Jung

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/15357Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarPhilippe Jung <phil.jung@free.fr>
üst cad19fa8
...@@ -57,9 +57,10 @@ private: ...@@ -57,9 +57,10 @@ private:
throw (css::lang::IllegalArgumentException, throw (css::lang::IllegalArgumentException,
css::uno::RuntimeException, std::exception) SAL_OVERRIDE; 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_fSlope;
double m_fIntercept; double m_fIntercept;
double m_fSign;
}; };
} // namespace chart } // namespace chart
......
...@@ -127,6 +127,19 @@ public: ...@@ -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 RegressionCalculationHelper
} // namespace chart } // namespace chart
......
...@@ -50,14 +50,23 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( ...@@ -50,14 +50,23 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
RegressionCalculationHelper::cleanup( RegressionCalculationHelper::cleanup(
aXValues, aYValues, aXValues, aYValues,
RegressionCalculationHelper::isValidAndBothPositive())); RegressionCalculationHelper::isValidAndBothPositive()));
m_fSign = 1.0;
const size_t nMax = aValues.first.size(); size_t nMax = aValues.first.size();
if( nMax == 0 ) if( nMax == 0 )
{ {
::rtl::math::setNan( & m_fSlope ); aValues = RegressionCalculationHelper::cleanup(
::rtl::math::setNan( & m_fIntercept ); aXValues, aYValues,
::rtl::math::setNan( & m_fCorrelationCoeffitient ); RegressionCalculationHelper::isValidAndXPositiveAndYNegative());
return; 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; double fAverageX = 0.0, fAverageY = 0.0;
...@@ -65,7 +74,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( ...@@ -65,7 +74,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
for( i = 0; i < nMax; ++i ) for( i = 0; i < nMax; ++i )
{ {
fAverageX += log( aValues.first[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 ); const double fN = static_cast< double >( nMax );
...@@ -76,7 +85,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( ...@@ -76,7 +85,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
for( i = 0; i < nMax; ++i ) for( i = 0; i < nMax; ++i )
{ {
double fDeltaX = log( aValues.first[i] ) - fAverageX; 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; fQx += fDeltaX * fDeltaX;
fQy += fDeltaY * fDeltaY; fQy += fDeltaY * fDeltaY;
...@@ -87,7 +96,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression( ...@@ -87,7 +96,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
m_fIntercept = fAverageY - m_fSlope * fAverageX; m_fIntercept = fAverageY - m_fSlope * fAverageX;
m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy ); 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 ) double SAL_CALL PotentialRegressionCurveCalculator::getCurveValue( double x )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment