多项式正反算解算源码 自己写的 C++

一次,二次、三次多项式系数解算是工程项目里最常用到的方法,就是常用的数学公式,如果从头写还是比较费劲,涉及到高斯解方程等,这里将源码分享给大家,已经经过大量的测试,解算算法是完全正确的。直接复制即可使用,如果能帮到大家,希望能点赞。

//solve one order polynomial

void PolynCal1(double *x1, double *y1, double *x2, 
    double *y2, int n, double *cofx, double *cofy)
{
    for(int i=0; i<n; i++)
    {
        x1[i]=(cofx[0]+cofx[1]*x2[i]+cofx[2]*y2[i]);
        y1[i]=(cofy[0]+cofy[1]*x2[i]+cofy[2]*y2[i]);
    }
}


void PolynCoff3(double *x1, double *y1, double *x2, 
    double *y2, int n, double *cofx, double *cofy, 
    double *rmsx, double *rmsy)
{
    double a[10],aa[100],al[10];
    int    i;

    //x 
    memset(aa,0,sizeof(double)*100);
    memset(al,0,sizeof(double)*10);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];        a[2] = y2[i]; 
        a[3] = x2[i]*x2[i];    a[4] = x2[i]*y2[i];    a[5] = y2[i]*y2[i];
        a[6] = x2[i]*x2[i]*x2[i]; a[7] = x2[i]*x2[i]*y2[i];
        a[8] = x2[i]*y2[i]*y2[i]; a[9] = y2[i]*y2[i]*y2[i];
        EquationNorm(a,10,x1[i],aa,al,1.0);
    }
    Agaus(aa, al, 10);
    memcpy(cofx, al, sizeof(double)*10);

    //y
    memset(aa,0,sizeof(double)*100);
    memset(al,0,sizeof(double)*10);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];        a[2] = y2[i]; 
        a[3] = x2[i]*x2[i];    a[4] = x2[i]*y2[i];    a[5] = y2[i]*y2[i];
        a[6] = x2[i]*x2[i]*x2[i]; a[7] = x2[i]*x2[i]*y2[i];
        a[8] = x2[i]*y2[i]*y2[i]; a[9] = y2[i]*y2[i]*y2[i];
        EquationNorm(a,10,y1[i],aa,al,1.0);
    }
    Agaus(aa, al, 10);
    memcpy(cofy, al, sizeof(double)*10);

    if(rmsx)
    {
        for(i=0; i<n; i++)
        {
            rmsx[i]=(cofx[0]+ 
                cofx[1]*x2[i]+cofx[2]*y2[i]+ 
                cofx[3]*x2[i]*x2[i]+cofx[4]*x2[i]*y2[i]+
                cofx[5]*y2[i]*y2[i] + cofx[6]*x2[i]*x2[i]*x2[i] + cofx[7]*x2[i]*x2[i]*y2[i]+
                cofx[8]*x2[i]*y2[i]*y2[i] + cofx[9]*y2[i]*y2[i]*y2[i])-x1[i];
        }
    }

    if(rmsy)
    {
        for(i=0; i<n; i++)
        {
            rmsy[i]=(cofy[0]+ 
                cofy[1]*x2[i]+cofy[2]*y2[i]+ 
                cofy[3]*x2[i]*x2[i]+cofy[4]*x2[i]*y2[i]+
                cofy[5]*y2[i]*y2[i] + cofy[6]*x2[i]*x2[i]*x2[i] + cofy[7]*x2[i]*x2[i]*y2[i]+
                cofy[8]*x2[i]*y2[i]*y2[i] + cofy[9]*y2[i]*y2[i]*y2[i])-y1[i];
        }
    }

}

//solve one order polynomial
void PolynCoff2(double *x1, double *y1, double *x2, 
    double *y2, int n, double *cofx, double *cofy, 
    double *rmsx, double *rmsy)
{
    double a[6],aa[36],al[6];
    int    i;

    //x 
    memset(aa,0,sizeof(double)*36);
    memset(al,0,sizeof(double)*6);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];        a[2] = y2[i]; 
        a[3] = x2[i]*x2[i];    a[4] = x2[i]*y2[i];    a[5] = y2[i]*y2[i];
        EquationNorm(a,6,x1[i],aa,al,1.0);
    }
    Agaus(aa, al, 6);
    memcpy(cofx, al, sizeof(double)*6);

    //y
    memset(aa,0,sizeof(double)*36);
    memset(al,0,sizeof(double)*6);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];        a[2] = y2[i]; 
        a[3] = x2[i]*x2[i];    a[4] = x2[i]*y2[i];    a[5] = y2[i]*y2[i];
        EquationNorm(a,6,y1[i],aa,al,1.0);
    }
    Agaus(aa, al, 6);
    memcpy(cofy, al, sizeof(double)*6);

    if(rmsx)
    {
        for(i=0; i<n; i++)
        {
            rmsx[i]=(cofx[0]+ 
                cofx[1]*x2[i]+cofx[2]*y2[i]+ 
                cofx[3]*x2[i]*x2[i]+cofx[4]*x2[i]*y2[i]+
                cofx[5]*y2[i]*y2[i])-x1[i];
        }
    }

    if(rmsy)
    {
        for(i=0; i<n; i++)
        {
            rmsy[i]=(cofy[0]+ 
                cofy[1]*x2[i]+cofy[2]*y2[i]+ 
                cofy[3]*x2[i]*x2[i]+cofy[4]*x2[i]*y2[i]+
                cofy[5]*y2[i]*y2[i])-y1[i];
        }
    }

}

void PolynCal2(double *x1, double *y1, double *x2, 
    double *y2, int n, const double *cofx, const double *cofy)
{
    for(int i=0; i<n; i++)
    {
        x1[i]=(cofx[0]+ 
            cofx[1]*x2[i]+cofx[2]*y2[i]+ 
            cofx[3]*x2[i]*x2[i]+cofx[4]*x2[i]*y2[i]+cofx[5]*y2[i]*y2[i]);
        y1[i]=(cofy[0]+ 
            cofy[1]*x2[i]+cofy[2]*y2[i]+ 
            cofy[3]*x2[i]*x2[i]+cofy[4]*x2[i]*y2[i]+cofy[5]*y2[i]*y2[i]);
    }
}

void PolynCal3(double *x1, double *y1, double *x2, 
    double *y2, int n, const double *cofx, const double *cofy)
{
    for(int i=0; i<n; i++)
    {
        x1[i]=(cofx[0]+ 
            cofx[1]*x2[i]+cofx[2]*y2[i]+ 
            cofx[3]*x2[i]*x2[i]+cofx[4]*x2[i]*y2[i]+
            cofx[5]*y2[i]*y2[i] + cofx[6]*x2[i]*x2[i]*x2[i] + cofx[7]*x2[i]*x2[i]*y2[i]+
            cofx[8]*x2[i]*y2[i]*y2[i] + cofx[9]*y2[i]*y2[i]*y2[i]);
        y1[i]=(cofy[0]+ 
            cofy[1]*x2[i]+cofy[2]*y2[i]+ 
            cofy[3]*x2[i]*x2[i]+cofy[4]*x2[i]*y2[i]+
            cofy[5]*y2[i]*y2[i] + cofy[6]*x2[i]*x2[i]*x2[i] + cofy[7]*x2[i]*x2[i]*y2[i]+
            cofy[8]*x2[i]*y2[i]*y2[i] + cofy[9]*y2[i]*y2[i]*y2[i]);
    }
}

//solve one order polynomial
void PolynCoff1(double *x1, double *y1, double *x2, 
    double *y2, int n, double *cofx, double *cofy, 
    double *rmsx, double *rmsy)
{
    double a[3],aa[9],al[3];
    int    i;

    //x 
    memset(aa,0,sizeof(double)*9);
    memset(al,0,sizeof(double)*3);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];    a[2] = y2[i];  
        EquationNorm(a,3,x1[i],aa,al,1.0);
    }
    Agaus(aa, al, 3);
    memcpy(cofx, al, sizeof(double)*3);

    //y
    memset(aa,0,sizeof(double)*9);
    memset(al,0,sizeof(double)*3);    
    for(i=0; i<n; i++)
    {
        a[0] = 1.0;
        a[1] = x2[i];    a[2] = y2[i];  
        EquationNorm(a,3,y1[i],aa,al,1.0);
    }
    Agaus(aa, al, 3);
    memcpy(cofy, al, sizeof(double)*3);

    //rmsx
    if(rmsx)
    {
        for(i=0; i<n; i++)
            rmsx[i]=(cofx[0]+cofx[1]*x2[i]+cofx[2]*y2[i])-x1[i];
    }
    //rmsy
    if(rmsy)
    {
        for(i=0; i<n; i++)
            rmsy[i]=(cofy[0]+cofy[1]*x2[i]+cofy[2]*y2[i])-y1[i];
    }
}

void EquationNorm(double *a, int n, double b, 
    double *aa, double *ab, double p)
{
    int  i,j;
    for (i=0; i<n; i++) 
    {
        for (j=0; j<n; j++) 
            *aa++ += p* a[i] * a[j];
        *ab++ += p* a[i] * b;
    }
}

int Agaus(double *a, double *b, int n)
{
    int l = 1, k, i, j, is = 0, p, q;
    boost::scoped_array<int> js(new int[n]);
    double d,t;
    for (k=0; k<=n-2; k++) {
        d=0.0;
        for (i=k; i<=n-1; i++) {
            for (j=k; j<=n-1; j++) {
                t = std::fabs(a[i*n+j]);
                if (t>d) {
                    d     = t;
                    js[k] = j;
                    is    = i;
                }
            }
        }

        if (d+1.0 == 1.0)
            l = 0;
        else {
            if (js[k] != k)
                for (i=0; i<=n-1; i++) {
                    p    = i*n+k;
                    q    = i*n+js[k];
                    t    = a[p];
                    a[p] = a[q];
                    a[q] = t;
                }
            
            if (is != k) {
                for (j=k; j<=n-1; j++) {
                    p    = k*n+j;
                    q    = is*n+j;
                    t    = a[p];
                    a[p] = a[q]; 
                    a[q] = t;
                }
                t     = b[k];
                b[k]  = b[is];
                b[is] = t;
            }
        }

        if (l == 0)
            return 0;

        d = a[k*n+k];
        for (j=k+1; j<=n-1; j++) {
            p    = k*n+j;
            a[p] = a[p]/d;
        }
        
        b[k] = b[k]/d;
        for (i=k+1; i<=n-1; i++) {
            for (j=k+1; j<=n-1; j++) {
                p    = i*n+j;
                a[p] = a[p]-a[i*n+k]*a[k*n+j];
            }
            b[i] = b[i]-a[i*n+k]*b[k];
        }
    }

    d = a[(n-1)*n+n-1];
    if (std::fabs(d)+1.0 == 1.0)
        return 0;
    
    b[n-1] = b[n-1]/d;
    for (i=n-2; i>=0; i--) {
        t = 0.0;
        for (j=i+1; j<=n-1; j++)
            t = t+a[i*n+j]*b[j];
        b[i] = b[i]-t;
    }

    js[n-1] = n-1;
    for (k=n-1; k>=0; k--) {
        if (js[k] != k) {
            t        = b[k];
            b[k]     = b[js[k]];
            b[js[k]] = t;
        }
    }
    return 1;
}

猜你喜欢

转载自blog.csdn.net/yangguang3ming/article/details/87911509