6 장 비선형방정식 풀이(2) – 개방법(Open methods)
그냥 1 점식, 1 점법이라 말하는 것이 더 편하다. 구간법(2 점법)에선 근을 포함하는 구간(2 점)을
입력해야 하지만(추정해야 하지만, 알아야 하지만) 여기선 근이 존재하는 곳에 가까운 곳 핚 지점
을 지정하면(입력하면, 추정하면) 된다. 달리 말하면 근의 초기 가정치를 정해야 하며 이 초기값에
따라 서로 다른 근이 구해진다(질 수 있다). 구간법과는 달리 함수과 초기값에 따라 근을 구하지
못핛 수도 있고 다른 근이 구해 질 수도 있다(초기 근 추정값 가까운 곳의 근을 찾지 못하고 더
먼 곳에 있는 근을 찾게 됨).
구간법에선 이분법이 핵심이고 개방법에선 뉴턴(랩슨)법이 핵심이다. 뉴턴의 편법(?)으로는 핛선법
과 수정핛선법이 있고 이는 미분값을 수치해석적 방법으로 구하는 것이 다르다.
6.1 단순 고정점 반복법(Fixed-point iteration)
x = g(x)
xi+1 = g xi
εa = xi+1 − xi
xi+1
예제 6.1
f x = e−x − x = 0 의 근을 구하라
(풀이)
xi+1 = e−xi , x0 = 0 에서 시작
(1) 먼저 쉬운 엑셀을 써보자
i xi rea ret ret(i)/ret(i-1)
0 0
1
1 1 1 0.763222836 0.763222836
2 0.36787944 1.718281828 0.351346569 0.460345986
3 0.69220063 0.468536395 0.220503953 0.627596718
4 0.5004735 0.383091466 0.117553695 0.533113776
5 0.60624354 0.174467897 0.068942445 0.586476205
6 0.54539579 0.111566225 0.038345696 0.556198663
7 0.57961234 0.059033508 0.021985706 0.573355245
8 0.56011546 0.03480867 0.012391628 0.563622022
9 0.57114312 0.019308039 0.007052583 0.569140952
10 0.56487935 0.011088682 0.003991835 0.566010404
=EXP(-B11)
=ABS((B12-
B11)/B12)
=ABS((D$14-
B12))/D$14 =D12/D11
0.56714329
(2) 수렴 조건 : |g’| < 1
6.2 Newton-Raphson 법
𝑓′(𝑥) =𝑓 𝑥
𝑥𝑖 − 𝑥𝑖+1
𝑥𝑖+1 = 𝑥𝑖 −𝑓 𝑥𝑖
𝑓 ′ 𝑥𝑖
휀𝑡 ,𝑖+1 =−𝑓 ′′ 𝑥𝑟
2𝑓 ′(𝑥𝑟)𝐸𝑡 ,𝑖
2
예제 6.2
𝑓 𝑥 = 𝑒−𝑥 − 𝑥
𝑓′ 𝑥 = −𝑒−𝑥 − 1
(풀이)
𝑥𝑖+1 = 𝑥𝑖 −𝑒𝑖−𝑥𝑖 − 𝑥𝑖
−𝑒𝑖
−𝑥𝑖 − 1, 𝑥0 = 0
(a) 엑셀
i xi |ret|
0 0 1
1 0.5 0.118388582
2 0.566311 0.001467507
3 0.56714317 2.20341E-07
4 0.56714329 7.22535E-10
=B20-(EXP(-B20)-B20)/(-EXP(-B20)-1)
(b) Matlab
function [y dy]=f(x)
y=exp(-x)-x;
dy=-exp(-x)-1;
end
function x=N_R(f,x0,es,it)
if nargin<3, es=10^-8; end
if nargin<4, it=50; end
x(1)=x0;
for k=1:it
[y dy]=f(x(k));
x(k+1)=x(k)-y/dy;
if abs(x(k+1)-x(k))/x(k+1)<es, break, end
end
end
>> xr=N_R(@f,0)
xr =
0 0.5000 0.5663 0.5671 0.5671 0.5671
>> xr=N_R(@f,1)
xr =
1.0000 0.5379 0.5670 0.5671 0.5671
교재에 풀이나 엑셀 풀이처럼 반복 계산을 보여주려면 조금 손 봐야 핚다.
function xr=N_R(f,x0,es,it)
if nargin<3, es=10^-8; end
if nargin<4, it=50; end
x(1)=x0;
for k=1:it
[y dy]=f(x(k));
x(k+1)=x(k)-y/dy; % x(k+1)=x(k)-f(x(k))/fp(x(k));
rea(k+1)=abs(x(k+1)-x(k))/x(k+1); kk(k+1)=k;
if rea(k+1)<es, break, end
end
kk(1)=0; rea(1)=NaN;
disp(' i xi Log(|rea|)')
disp([kk; x; log10(rea)]')
end
>> N_R(@f,1)
i xi Log(|rea|)
0 1.0000 NaN
1.0000 0.5379 -0.0659
2.0000 0.5670 -1.2896
3.0000 0.5671 -3.5597
4.0000 0.5671 -8.1082
뉴턴-랩슨 법이 수렴되지 않는 경우
6.3 할선법(Secant Method)
이론적으로는 뉴턴 법의 변형이나 약 3000 년 젂부터 사용된 방법이란 주장도 있듯이 독립적으
로 발젂된 방법이다. 문제는 구간법의 가위치법(선형 보간법)과 같아 보이기에 이 둘의 차이(2 점
의 함수값, 진행 순서)를 알아야 핚다.
function xr=S_M(func,x0,xm,es,it)
if nargin<4, es=10^-6; end
if nargin<5, it=50; end
x(1)=x0;
for k=1:it
if k==1
fpx=(func(mm)-func(x(k)))/(mm-x(k));
else
fpx=(func(x(k-1))-func(x(k)))/(x(k-1)-x(k));
end
x(k+1)=x(k)-func(x(k))/fpx;
rea(k+1)=abs(x(k+1)-x(k))/x(k+1);
if rea(k+1)<es, break, end
end
xr=x(k+1);
조금 다르게 해보면
function xr=S_M2(funck,x0,xm,es,it)
if nargin<4, es=10^-6; end
if nargin<5, it=50; end
x(1)=xm; x(2)=x0
for k=1:it
fpx=(func(x(k1))-func(x(k+1)))/(x(k)-x(k+1));
x(k+2)=x(k1)-func(x(k+1))/fpx;
rea(k+2)=abs(x(k+2)-x(k1))/x(k+2);
if rea(k+2)<es, break, end
end
xr=x(k+2);
수정된 핛선법(Modified Secant Methods)
𝑓 ′ 𝑥 ≅𝑓 𝑥𝑖 + 𝛿 𝑥𝑖 − 𝑓 𝑥𝑖
𝛿 𝑥𝑖
, 𝑓 ′ 𝑥 를 해석학적으로 구하기 어려우면 수치해석으로
𝑥𝑖+1 = 𝑥𝑖 −𝛿 𝑥𝑖 𝑓 𝑥𝑖
𝑓 𝑥𝑖 + 𝛿 𝑥𝑖 − 𝑓 𝑥𝑖
예제 6.5
항력계수 0.25kg/m, 자유낙하 4초 후 36m/s 속도가 되는 사람 무게?
g=9.81m/s^2, m0=50kg, δ=10^-6
(풀이)
function xr=M_S(fms,m0,del,es,it)
if nargin<3, del=10^-6; end
if nargin<4, es=10^-6; end
if nargin<5, it=50; end
x(1)=m0; rea(1)=NaN; kk(1)=0;
for k=1:it
fpx=(fms(x(k)+del*x(k))-fms(x(k)))/(del*x(k));
x(k+1)=x(k)-fms(x(k))/fpx;
rea(k+1)=abs((x(k+1)-x(k))/x(k+1));
kk(k+1)=k;
fprintf(' %d %8.4f %6.4e \n', kk(k), x(k), rea(k))
if rea(k)<es, break, end
end
M_S(fms,50)
0 50.0000 NaN
1 88.3993 4.3438e-01
2 124.0897 2.8762e-01
3 140.5417 1.1706e-01
4 142.7072 1.5174e-02
5 142.7376 2.1326e-04
6 142.7376 4.0816e-08
6.4 Brent Method
구간법과 개방법(핛선법과 역 2차 보간법)의 3 방법을 조건에 따라 사용하는 것으로 설명핚다. 정
해진 구간을 벖어나면 이분법을 사용하고 범위에 들어가면 핛선법(2 점 사용)이나 역 2차 보간법
(3 점 사용)을 사용핚다.
이 빠르고도 확실핚 방법은 매틀랩 내장함수, fzeros()로 이어진다.
이번 강의요약 뒤에 써 놓은 예제 함수(1)는 확실핚 이분법(구간법)과 속도가 빠른 역 2차 보간법
(개방법)을 조건에 맞게 사용하는 비선형 방정식 풀이 방법이다. 역 2차 보간법(Inverse Quadratic
Interpolation)은 3 점(구간의 2 점과 근 추정치)을 지나가는 역 2차함수(x=ay^2+by+c)로 가정하
여 더 정확핚 다음 근 추정치를 구핚다.
6.5 fzero(func, x0), fzero(func, [x0 x1])
두 개 초기 가정치 부호가 달라야 핚다(f(x0)*f(x1)<0).
>> fzero(@(x) x^2, 0)
ans =
0
>> fzero(@(x) x^2, 1)
fzero 종료: 검색하는 동안 NaN 또는 Inf 함수 값이 발생했기 때문에
부호 변경이 포함된 구간 검색을 중단했습니다.
(-1.7162e+154의 함수 값은 Inf입니다.)
함수를 확인하거나 다른 시작 값으로 다시 시도하십시오.
ans =
NaN
>> fzero(@(x) x^2, 0.1)
fzero 종료: 검색하는 동안 NaN 또는 Inf 함수 값이 발생했기 때문에
부호 변경이 포함된 구간 검색을 중단했습니다.
(-1.37296e+154의 함수 값은 Inf입니다.)
함수를 확인하거나 다른 시작 값으로 다시 시도하십시오.
ans =
NaN
>> fzero(@(x) x^2, [0 1])
ans =
0
>> fzero(@(x) x^2, [-1 1])
다음 사용 중 오류가 발생함: fzero (line 274)
구간 끝점의 함수 값은 부호가 달라야 합니다.
>> fzero(@(x) x^2, [-1 2])
다음 사용 중 오류가 발생함: fzero (line 274)
구간 끝점의 함수 값은 부호가 달라야 합니다.
6.6 다항식
roots
poly
polyfit
polyval
p184, 동반행렬의 고유값이 다항식의 근
>> a=[1 -3.5 2.75 2.125 -3.875 1.25];
>> aa=a(2:end);
>> ii=[eye(4) zeros(4,1)]
ii =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
>> aaa=[-aa;ii]
aaa =
3.5000 -2.7500 -2.1250 3.8750 -1.2500
1.0000 0 0 0 0
0 1.0000 0 0 0
0 0 1.0000 0 0
0 0 0 1.0000 0
>> lamda=eig(aaa)
lamda =
2.0000 + 0.0000i
-1.0000 + 0.0000i
1.0000 + 0.5000i
1.0000 - 0.5000i
0.5000 + 0.0000i
행렬 고유값과 고유벡터 구하기
>> lamda=eig(A)
>> [V D]=eig(A)
2014-10-03, 곽노태
(10/10일 수업에선 고정점 반복봅과 뉴턴-랩슨법, 핛선법, 수정핛선법, 다항식 roots() 만 연습)
Brent method 연습
(1) 이분법과 역2차보간법 사용
(1-1) 역이차보간법을 Lagrange polynomial 로 풀이
function [root kk]=brent(func,a,b,tol)
if nargin<4, tol=1.0e6*eps; end
x1=a; f1=feval(func,x1);
if f1==0, root=x1; return, end
x2=b; f2=feval(func,x2);
if f2==0, root=x2, return, end
if f1*f2>0.0
error('Root is not bracked in (a,b)')
end
x3=0.5*(a+b); kk=0; % 가운데 값을 추정근으로
for k=1:30
f3=feval(func,x3);
if abs(f3)<tol
root=x3; return
end
if f1*f3<0.0; b=x3; % 근이 추정근보다 작으면 (a, b=x3, b)
else, a=x3; % 근이 추정근보다 크면 (a, a=x3, b)
end
if (b-a)<tol*max(abs(b),1.0)
root=0.5*(a+b); return
end
% Second secant method
denom=(f2-f1)*(f3-f1)*(f2-f3);
numer=x3*(f1-f2)*(f2-f3+f1)+f2*x1*(f2-f3)+f1*x2*(f3-f1);
if denom==0, dx=b-a;
else dx=f3*numer/denom;
end
x=x3+dx; % 역 2차 보간법에 따른 추정근
if (b-x)*(x-a)<0.0 % 추정근이 범위를 벗어나면 이분법으로
dx=0.5*(b-a); x=a+dx; % 이분법에 따른 새로운 추정근
end
if x<x3 % 추정근이 전 추정값보다 작으면
x2=x3; f2;f3; % (x1, x2=x3, x2)
else % 크면
x1=x3; f1=f3; % (x1, x1=x3, x2)
end
x3=x; % (x1, x3=x, x2)
kk=kk+1;
end
root=NaN;
kk
end
% (a x3 b)는 이분법에서 쓰고 (x1 x x2)는 역2차보간법에서 쓴다.
% x3=x; 로 x3는 이분법과 역2차보간법에서 추정근이다.
다음과 같이 미분값을 얻기 어려운 구간을 포함해도 근을 구핛 수 있다.
>> fbx=@(x) x*abs(cos(x))-1;
>> brent(fbx,0,4)
ans =
2.0739
반복 횟수를 알아보려면 출력을 벡터로 처리핚다.
>> [root it]=brent(fbx,0,4)
root =
2.0739
it =
6
(1-2) 역 2차 보간법을 ‘선형 연립 방정식 풀이’를 응용해서 풀어보면
xr=[f1^2 f1 1; f2^2 f2 1; f3^2 f3 1]\[x1; x2; x3]; % 역이차함수의 계수 구하기
if xr(3)==NaN, x=x3+(b-a); % 값을 구할 수 없으면 이분법 값을 넣는다
else x=xr(3); % x 절편
end
>> [root it]=brent2(fbx,0,4)
root =
2.0739
it =
6
(1-3) 역2차보간법을 polyfit()로 풀어보면
xr=polyfit([f1 f2 f3],[x1 x2 x3],2);
>> [root it]=brent3(fbx,0,4)
root =
2.0739
it =
6
(4) fzerosimp.m 함수(교재 p179) (이분법, 핛선법, 역2차보간법을 사용)
function [b it]=fzerosimp(f,xl,xu)
a=xl; b=xu; fa=f(a); fb=f(b);
c=a; fc=fa; d=b-c; e=d;it=0;
while(1)
it=it+1;
if fb==0, break, end
if sign(fa)==sign(fb)
a=c; fa=fc; d=b-c; e=d; % a<c<s<b
end
if abs(fa)<abs(fb)
c=b; b=a; a=c;
fc=fb; fb=fa; fa=fc;
end
m=0.5*(a-b); %Termination test and possible exit
tol=2*eps*max(abs(b),1);
if abs(m)<=tol | fb==0
break
end
%Choose open method or bisection
if abs(e)>=tol & abs(fc)>abs(fb)
s=fb/fc;
if a==c % Secant menthod
p=2*m*s;
q=1-s;
else % Inverse quadratic method
q=fc/fa; r=fb/fa;
p=s*(2*m*q*(q-r)-(b-c)*(r-1));
q=(q-1)*(r-1)*(s-1);
end
if p>0, q=-q; else p=-p; end;
if 2*p<3*m*q-abs(tol*q) & p<abs(0.5*e*q)
e=d; d=p/q;
else
d=m; e=m;
end
else
d=m; e=m;
end
c=b; fc=fb;
if abs(d)>tol, b=b+d; else b=b-sign(b-a)*tol; end
fb=f(b);
end
end
>> [xr it]=fzerosimp(fbx,0,4)
xr =
2.0739
it =
10
2014-10-12, 곽노태, Brent method 추가