Kaydet (Commit) e0e28557 authored tarafından Philippe Jung's avatar Philippe Jung

tdf#92231 Potential regression curve calculation is wrong

Fixes potential regression curve class.

For potential regression curve algorithm, we try to get y = C * D^x
Switching to neperian logs:
   ln(y) = ln(C) + x ln(D)
So we make a linear regression and get
   slope = ln(D) => D = exp(slope)
   intercept = ln(C) => C = exp(intercept)

The current code computes the linear regression between log(y) and
log(x)
It should be between ln(y) and x.
Moreover, the slope is ln(D) so exp(slope) should be returned.
Finally, in getCurveValue, the return value is y = C x^D which is wrong

Change-Id: If8c952001229d3436be48abfef87c8302cf0544f
Reviewed-on: https://gerrit.libreoffice.org/16400Reviewed-by: 's avatarPhilippe Jung <phil.jung@free.fr>
Tested-by: 's avatarPhilippe Jung <phil.jung@free.fr>
üst bc265079
......@@ -51,6 +51,14 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
aXValues, aYValues,
RegressionCalculationHelper::isValidAndBothPositive()));
// We try to get y =C * D^x
// switching to neperian logs:
// ln(y) = ln(C) + x ln(D)
// So we make a linear regression and get
// slope = ln(D) => D = exp(slope)
// intercept = ln(C) => C = exp(intercept)
// Warning: the linear regression is between
// ln(y) and x. Not between ln(y) and ln(x)
const size_t nMax = aValues.first.size();
if( nMax == 0 )
{
......@@ -64,7 +72,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
size_t i = 0;
for( i = 0; i < nMax; ++i )
{
fAverageX += log( aValues.first[i] );
fAverageX += aValues.first[i] ;
fAverageY += log( aValues.second[i] );
}
......@@ -75,7 +83,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
double fQx = 0.0, fQy = 0.0, fQxy = 0.0;
for( i = 0; i < nMax; ++i )
{
double fDeltaX = log( aValues.first[i] ) - fAverageX;
double fDeltaX = aValues.first[i] - fAverageX;
double fDeltaY = log( aValues.second[i] ) - fAverageY;
fQx += fDeltaX * fDeltaX;
......@@ -87,6 +95,7 @@ void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
m_fIntercept = fAverageY - m_fSlope * fAverageX;
m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy );
m_fSlope = exp( m_fSlope );
m_fIntercept = exp( m_fIntercept );
}
......@@ -100,7 +109,7 @@ double SAL_CALL PotentialRegressionCurveCalculator::getCurveValue( double x )
if( ! ( ::rtl::math::isNan( m_fSlope ) ||
::rtl::math::isNan( m_fIntercept )))
{
fResult = m_fIntercept * pow( x, m_fSlope );
fResult = m_fIntercept * pow( m_fSlope, x );
}
return fResult;
......
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