commited PolynomialRegressionCurveCalculator2 by accident
Change-Id: Icd41c465a96e357dca4e50993c899f9365239d8b
This commit is contained in:
@@ -1,264 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/*
|
|
||||||
* This file is part of the LibreOffice project.
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* This file incorporates work covered by the following license notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed
|
|
||||||
* with this work for additional information regarding copyright
|
|
||||||
* ownership. The ASF licenses this file to you under the Apache
|
|
||||||
* License, Version 2.0 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PolynomialRegressionCurveCalculator.hxx"
|
|
||||||
#include "macros.hxx"
|
|
||||||
#include "RegressionCalculationHelper.hxx"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <rtl/math.hxx>
|
|
||||||
#include <rtl/ustrbuf.hxx>
|
|
||||||
|
|
||||||
using namespace com::sun::star;
|
|
||||||
|
|
||||||
namespace chart
|
|
||||||
{
|
|
||||||
|
|
||||||
PolynomialRegressionCurveCalculator::PolynomialRegressionCurveCalculator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
PolynomialRegressionCurveCalculator::~PolynomialRegressionCurveCalculator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
// ____ XRegressionCurveCalculator ____
|
|
||||||
void SAL_CALL PolynomialRegressionCurveCalculator::recalculateRegression(
|
|
||||||
const uno::Sequence< double >& aXValues,
|
|
||||||
const uno::Sequence< double >& aYValues )
|
|
||||||
throw (uno::RuntimeException)
|
|
||||||
{
|
|
||||||
rtl::math::setNan(&m_fCorrelationCoeffitient);
|
|
||||||
|
|
||||||
RegressionCalculationHelper::tDoubleVectorPair aValues(
|
|
||||||
RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValid()));
|
|
||||||
|
|
||||||
const size_t aNoValues = aValues.first.size();
|
|
||||||
|
|
||||||
std::vector<sal_Int32> aDegrees;
|
|
||||||
|
|
||||||
printf("%d\n", mDegree);
|
|
||||||
|
|
||||||
for( sal_Int32 i = 0; i < mDegree+1; i++ )
|
|
||||||
{
|
|
||||||
aDegrees.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
float_50 yAverage = 0.0;
|
|
||||||
|
|
||||||
std::vector<float_50> aTransposedMatrix;
|
|
||||||
aTransposedMatrix.resize(aNoValues * aDegrees.size(), 0.0);
|
|
||||||
|
|
||||||
std::vector<float_50> yVector;
|
|
||||||
yVector.resize(aNoValues, 0.0);
|
|
||||||
|
|
||||||
for( size_t i = 0; i < aNoValues; i++ )
|
|
||||||
{
|
|
||||||
float_50 x = aValues.first[i];
|
|
||||||
float_50 y = aValues.second[i];
|
|
||||||
yVector[i] = y;
|
|
||||||
yAverage += y;
|
|
||||||
|
|
||||||
for( size_t j = 0; j < aDegrees.size(); j++ )
|
|
||||||
{
|
|
||||||
aTransposedMatrix[i + j * aNoValues] = boost::multiprecision::pow((float_50)x, aDegrees[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yAverage /= aNoValues;
|
|
||||||
|
|
||||||
sal_Int32 m = aNoValues;
|
|
||||||
sal_Int32 n = aDegrees.size();
|
|
||||||
|
|
||||||
sal_Int32 minorSize = std::min(m, n);
|
|
||||||
|
|
||||||
std::vector<float_50> rDiag;
|
|
||||||
rDiag.resize(minorSize, 0.0);
|
|
||||||
|
|
||||||
for (sal_Int32 minor = 0; minor < minorSize; minor++)
|
|
||||||
{
|
|
||||||
float_50 xNormSqr = 0.0;
|
|
||||||
for (sal_Int32 row = minor; row < m; row++)
|
|
||||||
{
|
|
||||||
float_50 c = aTransposedMatrix[row + minor * aNoValues];
|
|
||||||
xNormSqr += c * c;
|
|
||||||
}
|
|
||||||
|
|
||||||
float_50 a = 0.0;
|
|
||||||
if (aTransposedMatrix[minor + minor * aNoValues] > 0.0)
|
|
||||||
a = -boost::multiprecision::sqrt(xNormSqr);
|
|
||||||
else
|
|
||||||
a = boost::multiprecision::sqrt(xNormSqr);
|
|
||||||
rDiag[minor] = a;
|
|
||||||
|
|
||||||
if (a != 0.0)
|
|
||||||
{
|
|
||||||
aTransposedMatrix[minor + minor * aNoValues] -= a;
|
|
||||||
|
|
||||||
for (sal_Int32 col = minor + 1; col < n; col++)
|
|
||||||
{
|
|
||||||
float_50 alpha = 0;
|
|
||||||
for (sal_Int32 row = minor; row < m; row++)
|
|
||||||
{
|
|
||||||
alpha -= aTransposedMatrix[row + col * aNoValues] * aTransposedMatrix[row + minor * aNoValues];
|
|
||||||
}
|
|
||||||
alpha /= a * aTransposedMatrix[minor + minor * aNoValues];
|
|
||||||
|
|
||||||
for (sal_Int32 row = minor; row < m; row++) {
|
|
||||||
aTransposedMatrix[row + col * aNoValues] -= alpha * aTransposedMatrix[row + minor * aNoValues];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply Householder transforms to solve Q.y = b
|
|
||||||
for (sal_Int32 minor = 0; minor < minorSize; minor++)
|
|
||||||
{
|
|
||||||
float_50 dotProduct = 0;
|
|
||||||
|
|
||||||
for (sal_Int32 row = minor; row < m; row++)
|
|
||||||
{
|
|
||||||
dotProduct += yVector[row] * aTransposedMatrix[row + minor * aNoValues];
|
|
||||||
}
|
|
||||||
dotProduct /= rDiag[minor] * aTransposedMatrix[minor + minor * aNoValues];
|
|
||||||
|
|
||||||
for (sal_Int32 row = minor; row < m; row++)
|
|
||||||
{
|
|
||||||
yVector[row] += dotProduct * aTransposedMatrix[row + minor * aNoValues];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mResult.clear();
|
|
||||||
mResult.resize(n, (float_50) 0.0);
|
|
||||||
|
|
||||||
// solve triangular system R.x = y
|
|
||||||
for (sal_Int32 row = rDiag.size() - 1; row >= 0; --row)
|
|
||||||
{
|
|
||||||
yVector[row] /= rDiag[row];
|
|
||||||
float_50 yRow = yVector[row];
|
|
||||||
mResult[row] = yRow;
|
|
||||||
|
|
||||||
for (sal_Int32 i = 0; i < row; i++)
|
|
||||||
{
|
|
||||||
yVector[i] -= yRow * aTransposedMatrix[i + row * aNoValues];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate correlation coeffitient
|
|
||||||
float_50 aSumError = 0.0;
|
|
||||||
float_50 aSumTotal = 0.0;
|
|
||||||
|
|
||||||
for( size_t i = 0; i < aNoValues; ++i )
|
|
||||||
{
|
|
||||||
float_50 x = aValues.first[i];
|
|
||||||
float_50 yActual = aValues.second[i];
|
|
||||||
float_50 yPredicted = getCurveValue( (double) x );
|
|
||||||
aSumTotal += (yActual - yAverage) * (yActual - yAverage);
|
|
||||||
aSumError += (yActual - yPredicted) * (yActual - yPredicted);
|
|
||||||
}
|
|
||||||
|
|
||||||
float_50 aRSquared = 1.0 - (aSumError / aSumTotal);
|
|
||||||
|
|
||||||
if (aRSquared > 0.0)
|
|
||||||
aRSquared = boost::multiprecision::sqrt(aRSquared);
|
|
||||||
else
|
|
||||||
aRSquared = 0.0;
|
|
||||||
m_fCorrelationCoeffitient = (double) aRSquared;
|
|
||||||
}
|
|
||||||
|
|
||||||
double SAL_CALL PolynomialRegressionCurveCalculator::getCurveValue( double x )
|
|
||||||
throw (lang::IllegalArgumentException,
|
|
||||||
uno::RuntimeException)
|
|
||||||
{
|
|
||||||
double fResult;
|
|
||||||
rtl::math::setNan(&fResult);
|
|
||||||
|
|
||||||
if (mResult.empty())
|
|
||||||
{
|
|
||||||
return fResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
float_50 m = 0.0;
|
|
||||||
float_50 aa;
|
|
||||||
for (size_t i = 0; i<mResult.size(); i++)
|
|
||||||
{
|
|
||||||
aa = boost::multiprecision::pow((float_50)x, i);
|
|
||||||
aa = aa * mResult[i];
|
|
||||||
m += aa;
|
|
||||||
}
|
|
||||||
fResult = (double) m;
|
|
||||||
return fResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
uno::Sequence< geometry::RealPoint2D > SAL_CALL PolynomialRegressionCurveCalculator::getCurveValues(
|
|
||||||
double min, double max, sal_Int32 nPointCount,
|
|
||||||
const uno::Reference< chart2::XScaling >& xScalingX,
|
|
||||||
const uno::Reference< chart2::XScaling >& xScalingY,
|
|
||||||
sal_Bool bMaySkipPointsInCalculation )
|
|
||||||
throw (lang::IllegalArgumentException,
|
|
||||||
uno::RuntimeException)
|
|
||||||
{
|
|
||||||
|
|
||||||
return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
|
|
||||||
}
|
|
||||||
|
|
||||||
OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation(
|
|
||||||
const uno::Reference< util::XNumberFormatter >& xNumFormatter,
|
|
||||||
sal_Int32 nNumberFormatKey ) const
|
|
||||||
{
|
|
||||||
OUStringBuffer aBuf( "f(x) = ");
|
|
||||||
|
|
||||||
sal_Int32 aLastIndex = mResult.size() - 1;
|
|
||||||
for (sal_Int32 i = aLastIndex; i >= 0; i--)
|
|
||||||
{
|
|
||||||
double aValue = (double) mResult[i];
|
|
||||||
if (aValue == 0.0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (aValue < 0.0)
|
|
||||||
{
|
|
||||||
aBuf.appendAscii( " - " );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i != aLastIndex)
|
|
||||||
aBuf.appendAscii( " + " );
|
|
||||||
}
|
|
||||||
|
|
||||||
aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, std::abs( aValue ) ) );
|
|
||||||
|
|
||||||
if(i > 0)
|
|
||||||
{
|
|
||||||
if (i == 1)
|
|
||||||
{
|
|
||||||
aBuf.appendAscii( "x" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aBuf.appendAscii( "x^" );
|
|
||||||
aBuf.append(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return aBuf.makeStringAndClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace chart
|
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
Reference in New Issue
Block a user