Matlab函数的Javascript等效函数:Polyfit/Polyval

Javascript equivalent functions to Matlab Functions: Polyfit/Polyval?

本文关键字:函数 Polyfit Polyval Javascript Matlab      更新时间:2023-09-26

迫切需要一个相当于Matlab中存在的polyval和polyfit函数的Javascript。本质上,matlab中的这些函数基于两个相同大小的数组根据指定的多项式进行曲线拟合。我需要在javascript中做一些涉及曲线拟合的计算,但我找不到等效的函数。

这是MatLab对polyfit函数的解释

" p = POLYFIT(X,Y,N)求多项式p (X)的系数在最小二乘意义上最适合数据Y的N度。P是一个包含多项式系数的长度为N+1的行向量降幂,P(1)*X^N + P(2)*X^(N-1) +…+ p (n)* x + p (n +1)"

这是MatLab对polyval的解释。

"POLYVAL求值多项式。Y = POLYVAL(P,X)返回多项式P的值x P是一个长度为N+1的向量,其元素是的降幂多项式

    Y = P(1)*X^N + P(2)*X^(N-1) + ... + P(N)*X + P(N+1)"

任何帮助都太好了。

认为,

numericjs可以帮助你开始。

POLYFIT执行最小二乘多项式拟合,可归结为求解线性方程组。我做了一个快速搜索,但我找不到一个基本的线性代数Javascript库来解决这样的系统…最简单的方法是自己实现高斯消去算法。

POLYVAL只是通过代入方程中的系数来求多项式在X点处的值。

也许这段代码可以帮助到某人

function _prepare(_mat) {
_mat=[[]].concat(_mat)
for(i=0;i<_mat.length;++i)
    _mat[i]=[0].concat(_mat[i])
return _mat
}
function linear(_mat){
_mat=_prepare(_mat)
return _solve(_mat)
}

function _solve(_mat){
var c=new Array(),d=new Array()
var n=_mat.length-1
for(i=0;i<=n+1;i++) {
    d[i]=new Array();
    c[i]=0
    for(j=0;j<=n+1;++j)
        d[i][j]=0
}
// mission impossible
// calculate all the determinants of the system
for(m=2; m<=n ; ++m) {
    for(i=m;i<=n;++i)
        for(j = m-1;j<=n+1;++j)
            d[i][j] = [_mat[i][j] * _mat[m-1][m-1] , _mat[i][m-1]]
        for(i=m;i<=n;++i)
            for(j=m-1;j<=n+1;++j) {
                _mat[i][j] = d[i][j][0]-d[i][j][1]*_mat[m-1][j] 
                if(Math.abs(_mat[i][j])<1e-25) _mat[i][j]=0  // i have to add this line
            }
}
// now the coefficients of equation (not exactly)
for(i=n;i>=1;--i) {
    c[i-1] = _mat[i][n+1]
    if (i!=n)
    for(j=n; j>=i+1;--j)
        c[i-1] = c[i-1] -_mat[i][j] * c[j-1]
    if(_mat[i][i]!=0)
        c[i-1]=c[i-1] / _mat[i][i]
    else
        c[i-1]=0
    if(Math.abs(c[i-1])<1e-25)
        c[i-1]=0
}
c.length=n
return c
}
function fitpoly(e,b){
var a=new Array()
var n = 1+b,e=[[0,0]].concat(e),ns=e.length-1
for(i=0;i<=n+1;i++) {
    a[i]=new Array();
    for(j=0;j<=n+1;++j)
        a[i][j]=0
}
for(m=1;m <= n;m++)
    for(i=1;i<= m;i++) {
        j = m - i + 1; 
        for(ii=1;ii <= ns;ii++)
            a[i][j] = a[i][j] + Math.pow(e[ii][0], m-1)
    }  
for(i=1;i<= n;++i)
    for(ii=1;ii<=ns;++ii)
        a[i][n+1] = a[i][n+1] +e[ii][1]*Math.pow(e[ii][0],i-1) 
for(m = n+2 ; m <= 2*n ; ++m)
    for(i = m-n; i<= n;++i) {
        j= m -i 
        for(ii=1; ii<=ns;++ii)
            a[i][j] = a[i][j] + Math.pow(e[ii][0],m-2) // coefficients of system
    }
a.length=a.length-1  
return _solve(a)
}

//and then
poly_degree = 6
points= [[2,2],[2,4],[4,6],[6,4],[8,2]]
// coefficients of polynome 
console.log(fitpoly(points, poly_degree))
// or solve a linear system. Here with six variables
solution = linear([[1,2,3,-2,-3,-26,52],[3,2,5,-2,4,30,-60],[6,1,-4,-1,5,94,-188],[-1,2,4,3,4,30,-60],[-1,4,2,-1,2,26,-52],[3,-3,11,-7,-2,-1,-95]])
console.log(solution)

试一下这个要点,它使用了numeric.js:

function polyfit(xArray, yArray, order) {
  if (xArray.length <= order) console.warn("Warning: Polyfit may be poorly conditioned.")
  let xMatrix = []
  let yMatrix = numeric.transpose([yArray])
  for (let i = 0; i < xArray.length; i++) {
    let temp = []
    for (let j = 0; j <= order; j++) {
      temp.push(Math.pow(xArray[i], j))
    }
    xMatrix.push(temp)
  }
  let xMatrixT = numeric.transpose(xMatrix)
  let dot1 = numeric.dot(xMatrixT, xMatrix)
  let dot2 = numeric.dot(xMatrixT, yMatrix)
  let dotInv = numeric.inv(dot1)
  let coefficients = numeric.dot(dotInv, dot2)
  return coefficients
}