牛顿差值多项式
實驗題目:Newton插值多項式相關知識:
通過n+1個節點的次數不超過n的Newton插值多項式為:
?
| x | 0 | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100 | 110 | 120 |
| y | 5 | 1 | 7.5 | 3 | 4.5 | 8.8 | 15.5 | 6.5 | -5 | -10 | -2 | 4.5 | 7 |
?
?
?
?
?
試驗要求:利用Newton插值多項式求被插值函數f(x)在點x=65處的近似值。建議:畫出Newton插值多項式的曲線。
下面的算法我借鑒的機械工業出版社的一本數值計算的書《數值分析》/.(美) David Kincaid,(美)Ward Cheney著/.王國榮, 俞耀明, 徐兆亮譯
?
WIN32代碼
?
// application. //#include <windows.h> #include <iostream> #include <vector>LRESULT CALLBACK MainWndProc(HWND hwnd ,UINT message, WPARAM wParam,LPARAM lParam);//---------------------------------------------------------------------------using namespace std;//用來保存多項式系數 vector<double> vc; // 牛頓差值多項式 數據double data[][2] = {0,5,10,1,20,7.5,30,3,40,4.5,50,8.8,60,15.5,70,6.5,80,-5,90,-10,100,-2,110,4.5,120,7};//計算出差值函數 void BuildNewtonFunc(double data[][2],const int count) {//計算出每個 基函數 的系數 下面用 小寫字母 c+數字 來注釋表示vc.push_back(data[0][1]); //第一個基函數的系數 為y0 ,同時基函數也是常指函數double c0 = vc[0];int k ,i;double d;double u;for(k=1;k< count;k++){d = data[k][0]-data[k-1][0]; //利用 u = vc[k-1];for(i=k-2;i>= 0;i--) //這個for循環利用的是嵌套乘法 或者 霍納算法 進行分解{ // 目的是用已知的c(i)來推算出 未知的 c(i+i)u = u *(data[k][0]-data[i][0])+vc[i];d = d *(data[k][0]-data[i][0]);}vc.push_back((data[k][1]-u)/d);}} void NewtonFunc(vector<double> vc ,const double x,double &y) {y = 0;int i;int j;double temp;for(i=0;i<vc.size();++i){temp = vc[i];for(j=0;j<i;j++){temp *= x - data[j][0]; }y += temp;} }//---------------------------------------------------------------------------int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {char szClassName[] = "MainWClass"; WNDCLASSEX wndclass;// 用描述主窗口的參數填充WNDCLASSEX結構wndclass.cbSize = sizeof(wndclass); // 結構的大小wndclass.style = CS_HREDRAW|CS_VREDRAW;//指定如果大小改變就重畫wndclass.lpfnWndProc = MainWndProc; // 窗口函數指針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 = szClassName;//窗口類的名稱 wndclass.hIconSm = NULL;//沒有類的小圖標 //注冊窗口類::RegisterClassEx(&wndclass);HWND hwnd = ::CreateWindowEx(0,//擴展樣式szClassName,//類名"My First Window",//標題 WS_OVERLAPPEDWINDOW,//窗口風格 overlapped windowCW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,//父窗口句柄NULL,// 菜單句柄hInstance , // 程序實例句柄 NULL);if (hwnd == NULL){ ::MessageBox(NULL,"ERror","error",MB_OK);return -1;}//顯示窗口,刷新客戶區::ShowWindow(hwnd,nCmdShow);::UpdateWindow(hwnd);MSG msg ;while(::GetMessage(&msg,NULL,0,0)){::TranslateMessage(&msg);::DispatchMessage(&msg);}return msg.wParam; } void DrawLine(HDC hdc,int ax,int ay,int bx,int by) {::MoveToEx(hdc, ax, ay, NULL);::LineTo(hdc, bx ,by); } LRESULT CALLBACK MainWndProc(HWND hwnd ,UINT message, WPARAM wParam,LPARAM lParam) {char szText[] = "最簡單的窗口";int cx,cy;double i,y,y2;switch(message){case WM_PAINT:{HDC hdc;PAINTSTRUCT ps;hdc = ::BeginPaint(hwnd ,&ps);RECT rt;::GetClientRect(hwnd,&rt);cx = rt.right;cy = rt.bottom;//::TextOut(hdc ,10,10,szText,strlen(szText));BuildNewtonFunc(data,sizeof(data)/sizeof(data[0]));/*double y;NewtonFunc(vc,65,y);*/::SetMapMode(hdc,MM_ANISOTROPIC); //設置坐標模式::SetWindowExtEx(hdc,600,200,NULL);//設置邏輯單位的大小為1000*1000;::SetViewportExtEx(hdc,cx,-cy,NULL);::SetViewportOrgEx(hdc,cx/2,cy/2,NULL);//設置坐標原點::TextOut(hdc,0,0,"o",1);//畫X軸DrawLine(hdc,-cx,0,cy,0);DrawLine(hdc,0,cx,0,-cy);MoveToEx(hdc,0,0,NULL);for(i=0;i<100;i++){NewtonFunc(vc,i,y);NewtonFunc(vc,i+1,y2);DrawLine(hdc,i,y,i+1,y2);}::EndPaint(hwnd ,&ps);return 0 ;}case WM_DESTROY:{::PostQuitMessage(0);return 0 ;}}return ::DefWindowProc(hwnd ,message,wParam ,lParam ); }
效果圖:
?
總結
- 上一篇: MFC中如何给对话框添加背景图片
- 下一篇: simulink学习仿真(微分模块、传递