c语言曲线拟合
‘壹’ 曲线拟合 最小二乘法 c语言程序
去翻一下,计算方法或者数值分析的书吧。有公式,你按那公式求就可以了。
一楼用的是列主元消去法(跟高斯消去法差不多,就多了一个选主元(绝对值最大))
对于解AX=b,平方根法要求A是对称且正定矩阵
由于平方根法里面要计算根号,计算量就比较大,而且工程中的A不一定都是正定的。所以在工程中采用改进的平方根法(它解出来的解与真解有一点误差,但是相当相近),也就是说A只要对称就行了。
‘贰’ C语言曲线拟合原理
虽然我知道什么是曲线拟合,怎么做,但是我不清楚你问题的具体内容,
从chuaike24的回答
“请高手 说实话 我是菜鸟 但你的程序感觉好凌乱 好多地方可以精简说最明显的问题 power函数返回值无论怎样都返回0 ”来看,我可能是没看到你的程序,所以信息不全。
我只回答什么是曲线拟合
曲线拟合,简单来说,是指以近似的方法用一条曲线逼近一组数据点。
逼近的方法最常用的事最小二乘法,当然也有其他方法。
逼近的曲线可以是直线,也可以是多项式曲线,二次,三次,多次,也可以是分段多项式曲线,也可以是B样条曲线。在这里,如果不需要深入研究,你只要把B样条曲线理解为一种近似于分段多项式曲线即可。
你问的不多,这些对你的回答已经足够,需要深入了解再问
不建议使用C语言来实现曲线拟合。
这种数学问题用matlab很容易就可以解决,c语言写要麻烦的多的多。比如你采用最小二乘法的话,
你需要自己用c语言写很多矩阵运算。
必须做的话,参考一下这个吧:http://wenku..com/link?url=-
‘肆’ 急~~~~~~!!!求解!用C语言编写最小二乘法求数据的拟合曲线~并做出图显示拟合效果!高分悬赏!
#include<stdio.h>
#include<math.h>
void Guass(int n,float Array[][10])
{
float s,u;
int i,j,k,a,x,y;
for(i=0;i<n-1;i++)
{
s=Array[i][i];
k=i;
for(a=i+1;a<n;a++)
{
if(fabs(s) < fabs(Array[a][i]))
{
s=Array[a][i];
k=a;
}
}
if(k!=i)
{
for(j=i;j<n+1;j++)
{
u=Array[i][j];Array[i][j]=Array[k][j];Array[k][j]=u;
}
}
for(x=i+1;x<n;x++)
{
u=Array[x][i]/s;
for(y=i;y<n+1;y++)
{
Array[x][y]=Array[x][y]-u*Array[i][y];
}
}
}
for(x=n-1;x>=0;x--)
{
s=0;
for(y=x+1;y<n;y++)
s=s+Array[x][y]*Array[y][n];
Array[x][n]=(Array[x][n]-s)/(Array[x][x]);//得到结果
}
for(i=0;i<n;i++)printf("%f ",Array[i][n]);printf("\n");
}
int main()
{
int n,i,j;
float Array[10][10];
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<n+1;j++)
scanf("%f",&Array[i][j]);
}
Guass(n,Array);
return 0;
}
你的串号我已经记下,采纳后我会帮你制作
‘伍’ 用VC++编一个曲线拟合程序
在windows环境下编程序,最传统的方法是Win32 API,历史极其悠久,核心内容自从windows诞生至今几乎没变化。他很庞大,包括界面部分(即GDI),还有消息处理部分(要让鼠标拖动就要使用鼠标消息),还有文件,打印,网络等等功能,他作为Windows最直接的编程方法,至今都很重要。Win32 API是使用C语言的,为了发挥C++的优势,微软基于Win32 API,开发了MFC,他就是Visual C++的主要功能之一。我比较懒,也不高兴学MFC,毕竟做的程序简单,体现不出MFC的优势,如果程序中控件(例如按钮,文本)比较多,窗口较多,那么用MFC就方便很多。
楼主要求的程序,不是很复杂,用纯粹的C语言,使用Win32API,就可以了,楼主要学的话看一下WIN32 API的书,当然你也可以学MFC,前提要对C++比较熟悉,类,继承,多态一定要搞清楚。
我写了一下,代码如下:
#include <windows.h>
#include <math.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int cxClient, cyClient ,cByteWidth;
POINT apt[5] ;
bool requestRedraw;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
//入口点,就是main函数
static TCHAR szAppName[] = TEXT ("Bezier") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
//创建一个窗口
hwnd = CreateWindow (szAppName, TEXT ("Bezier Splines"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
//建立消息循环,来接受鼠标动作,窗口缩放,移动等动作
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void DrawBezier (HDC hdc,HDC hdcMem)
{
//这里是画曲线,通过打点的方式画到位图中,然后显示,当然算法有待改进
static char bits [259200];
if(requestRedraw)
{
memset(bits,0xFF,259200);
float tDelat = 0.025/max(cxClient,cyClient);
for(float t = 0 ; t < 1 + tDelat ; t += tDelat)
{
float mt = 1 - t;
float t2 = t * t,t3 = t2 * t,t4 = t3 * t;
float mt2 = mt * mt,mt3 = mt2 * mt,mt4 = mt3 * mt;
int fX = apt[0].x * t4 + 4 * apt[1].x * t3 * mt + 6 * apt[2].x * t2 * mt2
+ 4 * apt[3].x * t * mt3 + apt[4].x * mt4 + 0.5f;
int fY = apt[0].y * t4 + 4 * apt[1].y * t3 * mt + 6 * apt[2].y * t2 * mt2
+ 4 * apt[3].y * t * mt3 + apt[4].y * mt4 + 0.5f;
bits[( fX + ((fY * cByteWidth) << 3)) >> 3] &= (0xFF ^ ( 0x80 >> ( fX & 0x07 ))) ;
}
requestRedraw = false;
}
HBITMAP hBitmap ;
BITMAP bitmap = { 0, cxClient, cyClient, cByteWidth, 1, 1 } ;
bitmap.bmBits = bits ;
hBitmap = CreateBitmapIndirect (&bitmap) ;
SelectObject(hdcMem,hBitmap);
BitBlt (hdc, 0, 0, cxClient, cyClient,
hdcMem, 0, 0, SRCCOPY) ;
DeleteObject(hBitmap);
//把点用直线连起来
static HPEN hRedPen = CreatePen (PS_SOLID, 1, RGB (255, 0, 0)) ;
SelectObject(hdc,hRedPen);
MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;
LineTo (hdc, apt[1].x, apt[1].y) ;
LineTo (hdc, apt[2].x, apt[2].y) ;
LineTo (hdc, apt[3].x, apt[3].y) ;
LineTo (hdc, apt[4].x, apt[4].y) ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//消息循环处理函数
static HDC hdc,hdcMem;
static PAINTSTRUCT ps ;
static int chosen = -1,minDistance = 1e3 ;
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd) ;
hdcMem = CreateCompatibleDC (hdc) ;
ReleaseDC(hwnd,hdc);
return 0 ;
//当窗口大小改变,要重新画曲线
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
cByteWidth = int(ceil(cxClient / 8.0f))%2 == 0 ? ceil(cxClient / 8.0f) : ceil(cxClient / 8.0f)+1;
apt[0].x = 1 * cxClient / 6 ; apt[0].y = 1 * cyClient / 2 ;
apt[1].x = 1 * cxClient / 2 ; apt[1].y = 1 * cyClient / 6 ;
apt[2].x = 1 * cxClient / 2 ; apt[2].y = 4 * cyClient / 5 ;
apt[3].x = 2 * cxClient / 3 ; apt[3].y = 4 * cyClient / 5 ;
apt[4].x = 4 * cxClient / 5 ; apt[4].y = 1 * cyClient / 3 ;
chosen = -1;
requestRedraw = true;
return 0 ;
//鼠标点击,计算出选择哪一个要移动的点
case WM_LBUTTONDOWN:
minDistance = 1e3; chosen = -1;
for(int i = 0 ; i <5 ; i++ )
{
int dx = LOWORD (lParam) - apt[i].x ; int dy = HIWORD (lParam) - apt[i].y ;
int currentDist = dx*dx + dy*dy;
if(currentDist < minDistance)
{
minDistance = currentDist;
chosen = i;
}
}
return 0;
//鼠标移动,让点跟随鼠标
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON && chosen >= 0)
{
apt[chosen].x = LOWORD (lParam) ;
apt[chosen].y = HIWORD (lParam) ;
requestRedraw = true;
PostMessage(hwnd,WM_PAINT,NULL,NULL);
}
return 0;
//这个是windows传给程序的绘图命令
case WM_PAINT:
InvalidateRect (hwnd, NULL, FALSE) ;
hdc = BeginPaint (hwnd, &ps) ;
DrawBezier (hdc,hdcMem) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
不懂的话,可以Hi我
‘陆’ c语言曲线拟合问题。已经有源代码, 求高手修改符合要求!!!!
以你列举的数据为例,一次运算是哪些数据?
输入拟合多项式的次数:
5
输入给定点的个数n及坐标(x,y):
5
?,?
?,?
?,?
?,?
?,?
你给出了10行数据?能做几次运算?
结果为什么是4个文件?那些数据写第一个文件里去?
我看你的描述,反正得不到这些信息。
‘柒’ C语言线性曲线拟合
可以直接在线进行拟合,下面是地址(已验证)
http://3.14159.biz/math/Fit.html
建议你直接对数据用Matlab的cftool拟合(可以自由的自定义拟合函数形式)