Skip to content

@KvanTTT /PolynominalRegression.cs
Last active

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Implementation of Polynomial regression (http://en.wikipedia.org/wiki/Polynomial_regression) with Math.NET library (http://www.mathdotnet.com/)
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Generic;
public class PolynomialRegression
{
private int _order;
private Vector<double> _coefs;
/// <summary>
/// Calculates polynom regression for xData = [x1, x2, ... , xn] and yData = [y1, y2, ... , yn].
/// </summary>
/// <param name="order">Order of output polynom.</param>
public PolynomialRegression(DenseVector xData, DenseVector yData, int order)
{
_order = order;
var vandMatrix = new DenseMatrix(xData.Count, order + 1);
for (int i = 0; i < xData.Count; i++)
{
double mult = 1;
for (int j = 0; j < order + 1; j++)
{
vandMatrix[i, j] = mult;
mult *= xData[i];
}
}
// var vandMatrixT = vandMatrix.Transpose();
// 1 variant:
//_coefs = (vandMatrixT * vandMatrix).Inverse() * vandMatrixT * yData;
// 2 variant:
//_coefs = (vandMatrixT * vandMatrix).LU().Solve(vandMatrixT * yData);
// 3 variant (most fast I think. Possible LU decomposion also can be replaced with one triangular matrix):
_coefs = vandMatrix.TransposeThisAndMultiply(vandMatrix).LU().Solve(TransposeAndMult(vandMatrix, yData));
}
/// <summary>
/// Calculates polynom regression for xData = [0, 1, ... , n] and yData = [y1, y2, ... , yn].
/// </summary>
/// <param name="order">Order of output polynom.</param>
public PolynominalRegression(DenseVector yData, int order)
{
_order = order;
var vandMatrix = new DenseMatrix(yData.Count, order + 1);
for (int i = 0; i < yData.Count; i++)
{
double mult = 1;
for (int j = 0; j < order + 1; j++)
{
vandMatrix[i, j] = mult;
mult *= i;
}
}
_coefs = vandMatrix.TransposeThisAndMultiply(vandMatrix).LU().Solve(TransposeAndMult(vandMatrix, yData));
}
private Vector<double> VandermondeRow(double x)
{
double[] result = new double[_order + 1];
double mult = 1;
for (int i = 0; i <= _order; i++)
{
result[i] = mult;
mult *= x;
}
return new DenseVector(result);
}
private static DenseVector TransposeAndMult(Matrix m, Vector v)
{
var result = new DenseVector(m.ColumnCount);
for (int j = 0; j < m.RowCount; j++)
for (int i = 0; i < m.ColumnCount; i++)
result[i] += m[j, i] * v[j];
return result;
}
public double Calculate(double x)
{
return VandermondeRow(x) * _coefs;
}
}
@teunvanvegchel

Hi! I can't seem to get this working, I'm getting NaN's only. What value should I provide for the order parameter?

Fixed: Used DenseVector.OfEnumerable(IEnumerable) to create the vectors :)

@KvanTTT
Owner

Order parameter should be greater or equal to 0. If you will use 0 for order parameter, you'll get parallel to abscissa line. Parameter of 1 will give you custom line, 2 will give you parabola etc. Example of this code using you can explore here: https://github.com/KvanTTT/MathExpressions.NET/tree/master/MathExpressions.NET.Benchmarks.GUI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.