25#include <rtl/math.hxx>
26#include <rtl/ustrbuf.hxx>
38 assert(aVec1.size() == aVec2.size());
39 for (
size_t i = 0;
i < aVec1.size(); ++
i)
40 fResult += aVec1[
i] * aVec2[
i];
52 const sal_Int32 aNoValues,
55 double aSumError = 0.0;
56 double aSumTotal = 0.0;
57 double aSumYpred2 = 0.0;
59 for( sal_Int32
i = 0;
i < aNoValues;
i++ )
61 double xValue = rValues.first[
i];
62 double yActual = rValues.second[
i];
64 aSumTotal += (yActual - yAverage) * (yActual - yAverage);
65 aSumError += (yActual - yPredicted) * (yActual - yPredicted);
70 double aRSquared = 0.0;
73 if (
auto const div = aSumError + aSumYpred2)
75 aRSquared = aSumYpred2 /
div;
78 else if (aSumTotal != 0.0)
80 aRSquared = 1.0 - (aSumError / aSumTotal);
99 const sal_Int32 aNoValues = aValues.first.size();
106 double yAverage = 0.0;
108 std::vector<double> yVector;
109 yVector.resize(aNoValues, 0.0);
111 for(sal_Int32
i = 0;
i < aNoValues;
i++)
113 double yValue = aValues.second[
i];
121 yAverage /= aNoValues;
128 std::vector<double> xVector;
129 xVector.resize(aNoValues, 0.0);
130 double xAverage = 0.0;
132 for(sal_Int32
i = 0;
i < aNoValues; ++
i)
134 double xValue = aValues.first[
i];
140 xAverage /= aNoValues;
145 for (sal_Int32
i = 0;
i < aNoValues; ++
i)
147 xVector[
i] -= xAverage;
148 yVector[
i] -= yAverage;
154 double fSlope = fSumXY / fSumX2;
172 std::vector<double> aQRTransposed;
173 aQRTransposed.resize(aNoValues * aNoPowers, 0.0);
175 for(sal_Int32 j = 0; j < aNoPowers; j++)
178 sal_Int32 aColumnIndex = j * aNoValues;
179 for(sal_Int32
i = 0;
i < aNoValues;
i++)
181 double xValue = aValues.first[
i];
182 aQRTransposed[
i + aColumnIndex] = std::pow(xValue,
static_cast<int>(aPower));
187 sal_Int32 aMinorSize = std::min(aNoValues, aNoPowers);
189 std::vector<double> aDiagonal;
190 aDiagonal.resize(aMinorSize, 0.0);
193 for (sal_Int32 aMinor = 0; aMinor < aMinorSize; aMinor++)
195 double aNormSqr = 0.0;
196 for (sal_Int32
x = aMinor;
x < aNoValues;
x++)
198 double c = aQRTransposed[
x + aMinor * aNoValues];
204 if (aQRTransposed[aMinor + aMinor * aNoValues] > 0.0)
205 a = -std::sqrt(aNormSqr);
207 a = std::sqrt(aNormSqr);
209 aDiagonal[aMinor] =
a;
213 aQRTransposed[aMinor + aMinor * aNoValues] -=
a;
215 for (sal_Int32 aColumn = aMinor + 1; aColumn < aNoPowers; aColumn++)
218 for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
220 alpha -= aQRTransposed[aRow + aColumn * aNoValues] * aQRTransposed[aRow + aMinor * aNoValues];
222 alpha /=
a * aQRTransposed[aMinor + aMinor * aNoValues];
224 for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
226 aQRTransposed[aRow + aColumn * aNoValues] -=
alpha * aQRTransposed[aRow + aMinor * aNoValues];
233 for (sal_Int32 aMinor = 0; aMinor < aMinorSize; aMinor++)
235 double aDotProduct = 0;
237 for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
239 aDotProduct += yVector[aRow] * aQRTransposed[aRow + aMinor * aNoValues];
241 aDotProduct /= aDiagonal[aMinor] * aQRTransposed[aMinor + aMinor * aNoValues];
243 for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
245 yVector[aRow] += aDotProduct * aQRTransposed[aRow + aMinor * aNoValues];
250 for (sal_Int32 aRow = aDiagonal.size() - 1; aRow >= 0; aRow--)
252 yVector[aRow] /= aDiagonal[aRow];
253 double yRow = yVector[aRow];
256 for (sal_Int32
i = 0;
i < aRow;
i++)
258 yVector[
i] -= yRow * aQRTransposed[
i + aRow * aNoValues];
274 return std::numeric_limits<double>::quiet_NaN();
276 sal_Int32 aNoCoefficients =
static_cast<sal_Int32
>(
mCoefficients.size());
279 double fResult = 0.0;
280 for (sal_Int32
i = aNoCoefficients - 1;
i >= 0;
i--)
289 sal_Int32 nNumberFormatKey, sal_Int32* pFormulaMaxWidth )
const
293 sal_Int32 nValueLength=0;
296 if ( pFormulaMaxWidth && *pFormulaMaxWidth > 0 )
298 sal_Int32 nCharMin =
aBuf.getLength();
299 double nCoefficients = aLastIndex + 1.0;
300 for (sal_Int32
i = aLastIndex;
i >= 0;
i--)
308 if ( rtl::math::approxEqual( fabs( aValue ) , 1.0 ) )
314 if (
i != aLastIndex )
318 nCharMin +=
mXName.getLength() + 1;
325 nValueLength = ( *pFormulaMaxWidth - nCharMin ) / nCoefficients;
326 if ( nValueLength <= 0 )
330 bool bFindValue =
false;
331 sal_Int32 nLineLength =
aBuf.getLength();
332 for (sal_Int32
i = aLastIndex;
i >= 0;
i--)
335 OUStringBuffer aTmpBuf(
"");
340 else if (aValue < 0.0)
343 aTmpBuf.append(
" " );
344 aTmpBuf.append( OUStringChar(
aMinusSign) +
" ");
350 aTmpBuf.append(
" + " );
355 sal_Int32* pValueLength = nValueLength ? &nValueLength :
nullptr;
356 OUString aValueString =
getFormattedString( xNumFormatter, nNumberFormatKey, aValue, pValueLength );
357 if (
i == 0 || aValueString !=
"1" )
359 aTmpBuf.append( aValueString );
361 aTmpBuf.append(
" " );
373 OUString aValueOfi = OUString::number(
i );
374 for ( sal_Int32
n = 0;
n < aValueOfi.getLength() ;
n++ )
376 sal_Int32
nIndex = aValueOfi[
n] -
u'0';
384 if ( std::u16string_view(
aBuf) == Concat2View(
mYName +
" = ") )
387 return aBuf.makeStringAndClear();
const sal_Unicode aSuperscriptFigures[10]
const sal_Unicode aMinusSign
PolynomialRegressionCurveCalculator()
virtual OUString ImplGetRepresentation(const css::uno::Reference< css::util::XNumberFormatter > &xNumFormatter, sal_Int32 nNumberFormatKey, sal_Int32 *pFormulaMaxWidth=nullptr) const override
std::vector< double > mCoefficients
virtual ~PolynomialRegressionCurveCalculator() override
void computeCorrelationCoefficient(RegressionCalculationHelper::tDoubleVectorPair &rValues, const sal_Int32 aNoValues, double yAverage)
virtual double SAL_CALL getCurveValue(double x) override
virtual void SAL_CALL recalculateRegression(const css::uno::Sequence< double > &aXValues, const css::uno::Sequence< double > &aYValues) override
static void addStringToEquation(OUStringBuffer &aStrEquation, sal_Int32 &nLineLength, OUStringBuffer const &aAddString, const sal_Int32 *pMaxLength)
static OUString getFormattedString(const css::uno::Reference< css::util::XNumberFormatter > &xNumFormatter, sal_Int32 nNumberFormatKey, double fNumber, const sal_Int32 *pStringLength)
double m_fCorrelationCoefficient
std::pair< std::vector< double >, std::vector< double > > tDoubleVectorPair
tDoubleVectorPair cleanup(const css::uno::Sequence< double > &rXValues, const css::uno::Sequence< double > &rYValues, Pred aPred)
takes the given x- and y-values and copies them into the resulting pair, which contains x-values in t...
static double lcl_GetDotProduct(std::vector< double > &aVec1, std::vector< double > &aVec2)
constexpr double alpha[nDetails]
double div(const double &fNumerator, const double &fDenominator)