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

tdf#70673 Exponential trendline: enable negative Y values

With a negative intercept, Y values can be negative

Rebase with forced intercept fec037e6

Conflicts:
	chart2/source/tools/ExponentialRegressionCurveCalculator.cxx

Change-Id: Ie351c006fb1688ef3e657da7ce0789a9da1317f0
Reviewed-on: https://gerrit.libreoffice.org/15353Reviewed-by: 's avatarPhilippe Jung <phil.jung@free.fr>
Tested-by: 's avatarPhilippe Jung <phil.jung@free.fr>
üst 733f5887
......@@ -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
......
......@@ -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:
......
......@@ -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 );
......
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