1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<math.h> 4 #include<float.h> 5 #include<time.h> 6 7 #define PI 3.14159265358979323846 /* pi */ 8 #define ε 1.0e-12 9 int main() 10 { 11 double x0 = PI;//取的初始值 12 double x1 = 0.0;//有x0算出的x1,初始值先給定0 13 double fx = 0.0;//f(x) 14 double fxp = 0.0;//f(x)的導數 15 double faix = 0.0;//計算結果,牛頓迭代格式 faix =x-(fx/fxp) 16 int i = 0;//迭代計算次數 17 while (fabs((x0 - x1) / x1) > ε)//判斷兩次迭代變量之間相對誤差與精度比較 18 { 19 x1 = x0;//用x1存放上次的x0 20 fx = sin(x0) - x0 / 2; 21 fxp = cos(x0) - 0.5; 22 faix = x0 - fx / fxp; 23 x0 = faix;//將迭代后的結果賦給上次代入值變量,供下一次代入使用 24 i++;//計算次數 25 printf("第%d次迭代,迭代結果為:,%+.12e \n", i, x1); 26 } 27 }
題目:計算sinx=x/2的根。
分析:newton法在大范圍的收斂定理:
函數f(x)在區間[a,b]上存在二階連續導數,且滿足4個條件:
1. f(a)*f(b)<0
2. 當x屬於[a,b]時,函數的導數值不等於零。
3. 當x屬於[a,b]時,函數的二階導數值保號。
4. a-f(a)/f'(a)<=b,且b-f(b)/f'(b)<=a
計算結果:
matlab求解非線性方程:
,x=[pi/2,pi] 。
1 clc; 2 clear all; 3 close all; 4 %% 繪圖 5 ezplot('sin(x)-x/2') 6 hold on; 7 ezplot('sin(x)') 8 hold on; 9 ezplot('x/2') 10 hold on; 11 ezplot('y=0*x') 12 legend('f(x)=sin(x)-x/2','sin(x)','x/2') 13 title('求解非線性方程') 14 %% 牛頓迭代法 15 fx=@(x)sin(x)-x/2.0;%定義 f(x)=sin(x)-x/2 匿名函數 16 DfxDx=@(x) cos(x)-1/2.0;% 定義f'(x) 17 epsilonT=1e-12;%收斂判斷標准:相對誤差 18 x0=pi;%給初值 19 n=0;%迭代次數 20 while 1 21 x1=x0-fx(x0)/DfxDx(x0); 22 epsilon=abs((x1-x0)/x1); 23 x0=x1; 24 n=n+1; 25 disp(['第' num2str(n) '次迭代,x=', num2str(x1,15)]); 26 if epsilon<epsilonT 27 break;%跳出while循環 28 end 29 end 30 disp('end')
第1次迭代,x=2.0943951023932
第2次迭代,x=1.91322295498104
第3次迭代,x=1.89567175194481
第4次迭代,x=1.89549428525543
第5次迭代,x=1.89549426703398
第6次迭代,x=1.89549426703398
end
1stopt解非線性方程:
,x=[pi/2,pi] 。
1 NewCodeBlock"求解非線性方程"; 2 // 3 AlgorithmOption =[1,0,1.00E-30,1000,20,30,50,20,0,0.15,1]; 4 Parameter x=[pi/2,pi]; 5 Function sin(x)=x/2;
求解非線性方程
====== 結果 ======
迭代數: 21
計算用時(時:分:秒:微秒): 00:00:00:119
計算結束原因: 達到收斂判斷標准
優化算法: 通用全局優化算法(UGO1)
函數表達式 sin(x)-(x/2) = 0
目標函數值(最小): 0
x: 1.89549426703398
====== 計算結束 ======
准牛頓方法解非線性方程:sin(x)=x/2,x=[pi/2,pi]
https://zhuanlan.zhihu.com/p/101077902
1 %% qusi-newton 准牛頓(割線法,不用求導數,用割線斜率代替切線) 2 clc; 3 clear all; 4 close all; 5 f=@(x)sin(x)-x/2.0;%定義 f(x)=sin(x)-x/2 匿名函數 6 epsilonT=1e-12;%收斂判斷標准:相對誤差 7 x0=pi/2;%給初值 8 x1=pi/2+0.1; 9 n=0;%迭代次數 10 while 1 11 % x2=x0-f(x0)*(x1-x0)/(f(x1)-f(x0)); 12 x2=x1-f(x1)*(x1-x0)/(f(x1)-f(x0));%等同於上句,都行 13 epsilon=abs((x1-x0)/x1); 14 x0=x1; 15 x1=x2; 16 n=n+1; 17 disp(['第' num2str(n) '次迭代,x=', num2str(x1,15)]); 18 if epsilon<epsilonT 19 break;%跳出while循環 20 end 21 end 22 disp('qusi-newton end')
第1次迭代,x=1.96101103612234
第2次迭代,x=1.88595391153747
第3次迭代,x=1.89514618938836
第4次迭代,x=1.89549620158427
第5次迭代,x=1.89549426664428
第6次迭代,x=1.89549426703398
第7次迭代,x=1.89549426703398
第8次迭代,x=1.89549426703398
qusi-newton end
非線性多元方程組用牛頓法求解:
1 % https://zhuanlan.zhihu.com/p/146371408 2 % https://zhuanlan.zhihu.com/p/63103354 知乎代碼 3 clc; 4 clear all; 5 close all; 6 x0=[1 2]; 7 eps=1e-12; 8 [allx,ally,r,n]=mulNewton(fun,x0,eps); 9 10 disp(['迭代' num2str(n) '次,' 'x1=' num2str(eval(r(1)),100) ',x2=' num2str(eval(r(2)),100) ])% 0.19808577588668504464406945200284 11 % disp(r) 12 disp('newton end') 13 %% 子函數區域 14 function [allx,ally,r,n]=mulNewton(F,x0,eps) 15 if nargin==2 16 eps=1.0e-4; 17 end 18 x0 = transpose(x0); 19 Fx = subs(F,transpose(symvar(F)),x0);%將初始點代入方程組 20 var = transpose(symvar(F)); 21 dF = jacobian(F,var);%求雅克比矩陣 22 dFx = subs(dF,transpose(symvar(F)),x0);%將當前解帶入雅克比矩陣 23 r=x0-inv(dFx)*Fx';%迭代 24 n=1; 25 tol=1; 26 N=100; 27 symx=length(x0); 28 ally=zeros(symx,N); 29 allx=zeros(symx,N); 30 31 while tol>eps 32 x0=r; 33 Fx = subs(F,transpose(symvar(F)),x0); 34 dFx = subs(dF,transpose(symvar(F)),x0); 35 r=vpa(x0-inv(dFx)*Fx'); 36 tol=norm(r-x0) 37 if(n>N) 38 disp('迭代步數太多,可能不收斂!'); 39 break; 40 end 41 allx(:,n)=x0; 42 ally(:,n)=Fx; 43 n=n+1; 44 end 45 end 46 47 48 function f = fun(x) 49 k=2; 50 for i=1:k 51 x(i)=sym (['x',num2str(i)]); 52 end 53 54 f(1)=0.5*sin(x(1))+0.1*cos(x(1)*x(2))-x(1); 55 f(2)=0.5*cos(x(1))-0.1*cos(x(2))-x(2); 56 end
1stopt求解非線性方程組:
1 NewCodeBlock"求解非線性方程組"; 2 //https://zhuanlan.zhihu.com/p/63103354 3 //https://zhuanlan.zhihu.com/p/146371408 4 AlgorithmOption =[1,0,1.00E-30,1000,20,30,50,20,0,0.15,1]; 5 Parameter x(2); 6 Function 0.5*sin(x1)+0.1*cos(x1*x2)-x1=0; 7 0.5*cos(x1)-0.1*cos(x2)-x2=0;
求解非線性方程組
====== 結果 ======
迭代數: 21
計算用時(時:分:秒:微秒): 00:00:00:429
計算結束原因: 達到收斂判斷標准
優化算法: 通用全局優化算法(UGO1)
函數表達式 1: 0.5*sin(x1)+0.1*cos(x1*x2)-x1-0 = 0
2: 0.5*cos(x1)-0.1*cos(x2)-x2-0 = 0
目標函數值(最小): 0
x1: 0.198085775886685
x2: 0.398040303134032====== 計算結束 ======
多元線性方程組求解:https://zhuanlan.zhihu.com/p/128577559
高斯列主元消去法:
1 % 高斯列主元消去法 https://zhuanlan.zhihu.com/p/128577559 2 % 先選擇每列元素絕對值最大值放通過行變換放在主對角線上,之后將矩陣A化為上三角矩陣,然后回代求解線性方程組Ax=b。 3 clc; 4 clear all; 5 close all; 6 % A=[2 8 2; 7 % 1 6 -1; 8 % 2 1 2];%https://wenku.baidu.com/view/99bf58cf050876323112120c.html 9 % b=[14 13 5]'; 10 A=[0.001 2 3; 11 -1 3.712 4.623; 12 -2 1.072 5.643];%https://wenku.baidu.com/view/99bf58cf050876323112120c.html 13 b=[1 14 2 15 3 ]; 16 x = gaussPivotScale(A, b) 17 disp('end'); 18 19 function x = gaussPivotScale(A, b) 20 21 %GAUSSPIVOTSCALE It uses Gauss elimination with partial pivoting 22 % and row scaling to solve the linear system Ax = b. 23 % A : It is the n-by-n coefficient matrix. 24 % b : It is the n-by-1 result vector. 25 % x : It is the n-by-1 solution vector. 26 27 tic 28 format long 29 30 % judge wether there is a solution or not from the linear system 31 r_A = rank(A); 32 r_Ab = rank([A, b]); 33 34 if r_A ~= r_Ab 35 disp('This linear system is no solution'); 36 end 37 38 % Elimination 39 40 [row, ~] = size(A); 41 C = [A, b]; 42 43 for k = 1 : row-1 44 45 % style of table 46 fprintf('This is%2dth transformation \n [A | b] = \n', k); 47 48 M = max(abs(C(k:end, k:end-1)), [], 2); % find maximum in kth row,A所有行每行元素絕對值最大值 49 a = abs(C(k:end, k)); % each value is absoluted value in kth column,所有行第k列絕對值 50 [~, id] = max(a ./ M); % find row with maximum 51 52 if id > k 53 C([k, id], :) = C([id, k], :); % pivot rows 54 end 55 56 mult = C(k+1:row, k) / C(k, k); % construct multipliers 57 58 % creat mesh, and improve speed 59 [C_k, mult] = meshgrid(C(k, :), mult); 60 C(k+1:row, :) = C(k+1:row, :) - C_k .* mult; 61 62 disp(C) 63 end 64 65 % Back Substitution 66 [row, ~] = size(C); 67 68 for k = row : -1 : 1 69 C(k, :) = C(k, :) ./ C(k, k); 70 C(1:k-1, row+1) = C(1:k-1, row+1) - C(1:k-1, k) * C(k, row+1); 71 end 72 73 x = C(:, end); 74 75 toc 76 77 end