go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/matrix/polynomial_regression.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package matrix
     9  
    10  import "errors"
    11  
    12  var (
    13  	// ErrPolynomialRegressionArraysNotSameLength is a (hopefully) uncommon error.
    14  	ErrPolynomialRegressionArraysNotSameLength = errors.New("polynomial array inputs must be the same length")
    15  )
    16  
    17  // PolynomialRegression returns the polynomial regression of a given degree over the given values.
    18  func PolynomialRegression(xvalues, yvalues []float64, degree int) ([]float64, error) {
    19  	if len(xvalues) != len(yvalues) {
    20  		return nil, ErrPolynomialRegressionArraysNotSameLength
    21  	}
    22  
    23  	m := len(yvalues)
    24  	n := degree + 1
    25  	y := New(m, 1, yvalues...)
    26  	x := Zero(m, n)
    27  
    28  	for i := 0; i < m; i++ {
    29  		ip := float64(1)
    30  		for j := 0; j < n; j++ {
    31  			x.Set(i, j, ip)
    32  			ip *= xvalues[i]
    33  		}
    34  	}
    35  
    36  	q, r := x.QR()
    37  	qty, err := q.Transpose().Times(y)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	c := make([]float64, n)
    43  	for i := n - 1; i >= 0; i-- {
    44  		c[i] = qty.Get(i, 0)
    45  		for j := i + 1; j < n; j++ {
    46  			c[i] -= c[j] * r.Get(i, j)
    47  		}
    48  		c[i] /= r.Get(i, i)
    49  	}
    50  
    51  	return c, nil
    52  }