开发者

Javascript equivalent functions to Matlab Functions: Polyfit/Polyval?

Desperately need a Javascript equivalent to polyval and polyfit functions that exist in Matlab. Essentially those functions in matlab do a curve fit based on two equally sized arrays depending on a specified polynomial. I need to do some calculations that involve curve fitting in javascript and can't for the life of me find an equivalent function.

This is MatLab's explanation of the function polyfit

"P = POLYFIT(X,Y,N) finds the coefficients of a polynomial P(X) of degree N that fits the data Y best in a least-squares sense. P is a row vector of length N+1 containing the polynomial coefficients in descending powers, 开发者_运维知识库P(1)*X^N + P(2)*X^(N-1) +...+ P(N)*X + P(N+1)."

This is MatLab's explanation of polyval.

"POLYVAL Evaluate polynomial. Y = POLYVAL(P,X) returns the value of a polynomial P evaluated at X. P is a vector of length N+1 whose elements are the coefficients of the polynomial in descending powers.

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

Any help would be super.

Regards,


numericjs may help you get started.


POLYFIT performs a least-square polynomial fitting which comes down to solving a system of linear equations. I did a quick search, but I couldn't find a basic linear algebra Javascript library that solves such systems... The easiest method would be to implement the Gaussian elimination algorithm yourself.

POLYVAL is simply evaluating the polynomial at the points X by substituting the coefficients in the equation.


perhaps this code might help someone

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)


Give this gist a try, it uses 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

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜