搜索
bottom↓
回复: 13

C语言实现最小二乘法抛物线拟合

[复制链接]

出0入0汤圆

发表于 2011-9-13 16:29:04 | 显示全部楼层 |阅读模式
如题~求大虾们指点~

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2013-5-19 12:36:01 | 显示全部楼层
主要是你想拟合成什么样的?用直线拟合曲线的话 是使得误差最小的直线  曲线拟合直线的话 一般二阶就可以了

出10入23汤圆

发表于 2013-5-19 17:51:29 | 显示全部楼层
matlab 实现,再转C
或者直接推导公式实现吧

出10入23汤圆

发表于 2013-5-19 18:10:01 | 显示全部楼层
y = a * x^2 + b * x + c
Error = (a * x^2 + b * x + c - y)^2
Error = a^2 * x^4 +b^2 * x^2 + C^2 + y^2 + 2 * (a * b * x^3 + a * c * x^2 - a * y * x^2 + b * c * x - b * y * y - c * y)

Error(a) = 2 * x^4 * a + 2 * b * x^3 + 2 * c * x^2 - 2 * y * x^2
Error(b) = 2 * x^2 * b + 2 * a * x^3 + 2 * c * x - 2 * y * x
Error(c) = 2 * c + 2 * a * x^2 + 2 * b * x - 2 * y

出10入23汤圆

发表于 2013-5-19 18:16:40 | 显示全部楼层
a * x^4 + b * x^3 + c * x^2 = y * x^2
a * x^3 + b * x^2 + c * x = y * x
a * x^2 + b * x + c = y

出0入0汤圆

发表于 2013-5-19 19:41:31 | 显示全部楼层
算法运算量注定很大,用在电脑上就可以,如果是在MSP上的话。。。。。

出10入23汤圆

发表于 2013-5-19 20:35:03 | 显示全部楼层
C语言实现,已通过matlab对比验证:
/***********************************************************************************
从txt文件里读取double型XY数据
***********************************************************************************/
int GetXY(const char* FileName, double* X, double* Y, int* Amount)
{
        FILE* File = fopen(FileName, "r");
        if (!File)
                return -1;
        for (*Amount = 0; !feof(File); X++, Y++, (*Amount)++)
                if (2 != fscanf(File, (const char*)"%lf %lf", X, Y))
                        break;
        fclose(File);
        return 0;
}

/***********************************************************************************
从double型XY数据中获取系数矩阵
***********************************************************************************/
int GetK(double* K, const double* X, const double* Y, int Amount)
{
        *(K + 10) = Amount;
        *K = 0;
        *(K + 1) = 0;
        *(K + 2) = 0;
        *(K + 3) = 0;
        *(K + 6) = 0;
        *(K + 7) = 0;
        *(K + 11) = 0;
        for ( ; Amount; Amount--, X++, Y++)
        {
                *K += (*X) * (*X) * (*X) * (*X);
                *(K + 1) += (*X) * (*X) * (*X);
                *(K + 2) += (*X) * (*X);
                *(K + 3) += (*X) * (*X) * (*Y);
                *(K + 6) += (*X);
                *(K + 7) += (*X) * (*Y);
                *(K + 11) += (*Y);
        }
        *(K + 4) = *(K + 1);
        *(K + 5) = *(K + 2);
        *(K + 8) = *(K + 2);
        *(K + 9) = *(K + 6);
        return 0;
}

/***********************************************************************************
系数矩阵变换,解矩阵方程
***********************************************************************************/
int TransK(double* K)
{
        //
        *(K + 5) = (*(K + 5)) * (*K) - (*(K + 4)) * (*(K + 1));
        *(K + 6) = (*(K + 6)) * (*K) - (*(K + 4)) * (*(K + 2));
        *(K + 7) = (*(K + 7)) * (*K) - (*(K + 4)) * (*(K + 3));
        *(K + 4) = 0;
        *(K + 9) = (*(K + 9)) * (*K) - (*(K + 8)) * (*(K + 1));
        *(K + 10) = (*(K + 10)) * (*K) - (*(K + 8)) * (*(K + 2));
        *(K + 11) = (*(K + 11)) * (*K) - (*(K + 8)) * (*(K + 3));
        *(K + 8) = 0;
        //
        //
        *(K + 10) = (*(K + 10)) * (*(K + 5)) - (*(K + 9)) * (*(K + 6));
        *(K + 11) = (*(K + 11)) * (*(K + 5)) - (*(K + 9)) * (*(K + 7));
        *(K + 9) = 0;
        //
        //
        *(K + 5) = (*(K + 5)) * (*(K + 10));
        *(K + 7) = (*(K + 7)) * (*(K + 10)) - (*(K + 6)) * (*(K + 11));
        *(K + 6) = 0;
        //
        //
        *K = (*K) * (*(K + 5));
        *(K + 2) = (*(K + 2)) * (*(K + 5));
        *(K + 3) = (*(K + 3)) * (*(K + 5)) - (*(K + 1)) * (*(K + 7));
        *(K + 1) = 0;
        //
        //
        *K = (*K) * (*(K + 10));
        *(K + 3) = (*(K + 3)) * (*(K + 10)) - (*(K + 2)) * (*(K + 11));
        *(K + 2) = 0;
        //
        //
        if (0 != *(K + 00))
        {
                *(K + 3) /= *(K + 00);
                *K = 1.0;
        }
        if (0 != *(K + 5))
        {
                *(K + 7) /= *(K + 5);
                *(K + 5) = 1.0;
        }
        if (0 != *(K + 10))
        {
                *(K + 11) /= *(K + 10);
                *(K + 10) = 1.0;
        }
        //
        return 0;
}

/***********************************************************************************
***********************************************************************************/
int Cal(const char* FileName, double* ParaA, double* ParaB, double* ParaC)
{
        double ParaK[12], BufferX[1024], BufferY[1024];
        int Amount;
        GetXY(FileName, (double*)BufferX, (double*)BufferY, &Amount);
        GetK((double*)ParaK, (const double*)BufferX, (const double*)BufferY, Amount);
        TransK((double*)ParaK);
        *ParaA = ParaK[3];
        *ParaB = ParaK[7];
        *ParaC = ParaK[11];
        return 0;
}

int main(int argc, char* argv[])
{
        double ParaA, ParaB, ParaC;
        Cal((const char*)"test.txt", &ParaA, &ParaB, &ParaC);
        printf("ParaA = %lf\r\nParaB = %lf\r\nParaC = %lf\r\n", ParaA, ParaB, ParaC);
        return 0;
}

出10入23汤圆

发表于 2013-5-19 20:37:34 | 显示全部楼层
使用了大量浮点乘法运算(也可以换成整型运算,但是精度下降),尽量避免了使用除法运算,运算量还算不大

出0入0汤圆

发表于 2013-5-20 21:09:37 | 显示全部楼层
路过学习一下

出0入0汤圆

 楼主| 发表于 2013-10-11 14:47:03 | 显示全部楼层
zouzhichao 发表于 2013-5-19 20:35
C语言实现,已通过matlab对比验证:
/***************************************************************** ...

人才啊, 多谢啦

出0入0汤圆

发表于 2013-10-23 21:45:04 | 显示全部楼层
学习学习啊

出0入0汤圆

发表于 2014-4-11 19:26:34 | 显示全部楼层
早点有就好了 !当初也是要做个曲线拟合 ,但不知道怎么搞..多谢了!

出0入0汤圆

发表于 2014-4-12 14:52:32 | 显示全部楼层
是呀,求解

出0入0汤圆

发表于 2014-9-4 17:51:30 | 显示全部楼层
曲线拟合
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 16:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表