Skip to content

Instantly share code, notes, and snippets.

@KvanTTT
Last active July 28, 2020 07:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KvanTTT/3849678 to your computer and use it in GitHub Desktop.
Save KvanTTT/3849678 to your computer and use it in GitHub Desktop.
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;
}
}
@vgchl
Copy link

vgchl commented Jun 17, 2013

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
Copy link
Author

KvanTTT commented Oct 31, 2013

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

@remixie
Copy link

remixie commented Oct 11, 2017

@KvanTTT Is this code free for commercial use?

@KvanTTT
Copy link
Author

KvanTTT commented Nov 2, 2017

@remixie, sure, it's free for commercial use :)
Sorry for the delay. I'm afraid notifications does not work for gists :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment