반응형
Recent Posts
Recent Comments
Link
관리 메뉴

공머씨의 블로그

내가 공부한 옥타브2 20. 익명함수(Anonymous function) 본문

내가 공부한 옥타브(매틀랩)/내가 공부한 옥타브 시리즈2 (공업수학1)

내가 공부한 옥타브2 20. 익명함수(Anonymous function)

공머씨 2020. 5. 4. 12:55
반응형

먼저 익명 함수란, (Anonymous function)

현재의 작업공간안에서 함수를 정의하는 방법입니다. 

m파일에 따로 사용자 함수를 저장하지 않고 함수를 만드는 방법 이라고 생각하면 될 것 같습니다. (??)

익명 함수의 정의 방법은 아래 그림과 같습니다. 

먼저 @ 표시가 익명 함수라는 뜻이고

@ 다음 () 안에 콤마로 연결한 문자가 인자들입니다. (함수에 쓰이는 변수들)

함수의 핸들은 함수의 이름이 되는 것입니다. (정의한 함수를 다룰 때 함수의 이름을 입력해서 사용할 수 있으므로 함수의 이름=함수의 핸들이라고 생각하면 될 것 같습니다.)

'그 함수는 어떤 계산을 하는 함수냐' 에 대한  함수의 정의가 오른쪽에 나옵니다. 

이 명령을 사용하고나면 myf라는 함수를 사용할 수 있게 됩니다.

 

간단한 익명 함수를 아래 코드를 보고 만들어 보길 바랍니다. 

 workspace에 class가 function handle로 저장되어있음을 볼 수 있습니다. 

workspace에 function handle가 저장된 모습

 

 

아래와 같이 사용해주면 됩니다. 

 

 

인자를 한 개로 하여 사용해도 됩니다. 

다음과 같이 사용할 수 있습니다. 

 

예를 들면 아래와 같이 사용할 수 있습니다. 

보다시피 똑같은 기능을 하는 함수인데 inline함수로 사용할 때 함수를 정의하기가 좀 더 귀찮은 형태입니다. 

이 포스팅에서는 익명 함수를 사용하겠습니다. 

 

inline도 알아두면 옛날에 만들었던 코드들을 이해하는데 도움이 되겠습니다. 

익명 함수나 inline함수나 함수를 호출할 때 함수 이름(인자 목록)으로 부릅니다. 

인자 목록은 순서대로 작성해주면 됩니다.

 

 

익명 함수에 작성법을 알게 되었으므로  아래와 같은 예제를 작성해보겠습니다.

 

전체 코드와 Figure 창입니다.

%익명함수와 inline함수를 작성해보고 둘 다 같은 그래프가 그려지는지 확인하는 코드

x=[-3:0.001:3];
myfunc1=@(x) x.^3+x+2; %벡터인자에 대해서도 계산할 수 있도록 . 을 찍는다. 
myfunc2=inline('x.^3+x+2','x');

y=myfunc1(x);
subplot(1,2,1);plot(x,y)

%y를 정의하지 않고 plot에 바로 myfunc2(x)를 사용해 보았습니다 
subplot(1,2,2);plot(x,myfunc2(x)) %Y대신에 이렇게 작성해도 되는구나

gtext('Hi','FontSize',100)

 

 

 

 

 

 

 

힌트

 

결과 화면입니다.

 

 

 

매트랩 스타일로 조건을 나눠준 코드입니다. 

%ex16b 매트랩 스타일 코드

x=[-2 : 0.01 : 2];
func1=@(x)(x.^2).*exp(-abs(x));
subplot(2,1,1);plot(x,func1(x));

func2=@(x)(x>-1.5 & x<1.5).*(x.^2).*(exp(-abs(x))) + (x<-1.5 & x>1.5).*0;
subplot(2,1,2);plot(x,func2(x));

func2라는 익명함수에서 x의 범위가 -2와 2사이에서 

-1.5보다 작고 1.5보다 큰 x에서 0이 곱해지므로

아래와 같은 조건을 작성하지않고 위에 나온대로 작성해주면 됩니다.

func2=@(x) ((x.^2).*exp(-abs(x))).*(-1.5<x&x<1.5)+0.*((x<-1.5&x>-2)&(x>1.5&x<2));

 

또 다른 방식으로 해결한 코드입니다.

 

%ex 16b에 대한 코드입니다. 
%% INIT
x= -2:0.001:2 ;
y = zeros( size(x) ); % x와 같은 사이즈 y

%% 식
func1=@(x) (x.^2).*exp(-abs(x));

%% 
reg_idx = -1.5<x & x<1.5 ;
y( reg_idx ) = func1( x (reg_idx) );
% 다른 부분은 이미 0으로 초기화했으므로 처리하지 않아도 결과적으로 완성됨

subplot(2,1,1);plot(x,func1(x));
subplot(2,1,2);plot(x,y);

 

 

 

 

 

 

 


17절에서는 익명 함수를 전달받아서 사용하는 함수 'fuction fuction'에 대해 알아보겠습니다. 

(함수의 함수라고도 합니다. )

'fuction fuction'이라는 것은 인자로 함수의 핸들을 전달받는 함수를 말합니다. 

어려워 보이는 것 같지만 예제를 통해 익히면 됩니다! 

 

매트랩 내장 함수 중에서 plot와 비슷한 기능을 가진 fplot()이라는 함수가 있는데

이 함수는 괄호 안의 인자가 함수의 핸들, 범위입니다. 

fplot(handle of function, lims);

 

그냥 사용하는 거랑 뭐가 다른지 모르겠다. 

func=@(x) 3*x.^2;
lims=[-2 2];
subplot(2,1,1);fplot(func,lims)

func1=@(x) 3*x.^2;
x=[-2:0.01: 2]
subplot(2,1,2);plot(x,func1(x))

범위를 저장하는 변수로 lims가 아닌 다른 변수를 사용해도 됩니다.

 

 

시작과 끝을 알리는 두 개의 범위를 알려주면 인자로 받은 함수의 그래프를 주어진 그래프의 범위 내에서 그리는 함수입니다. 

예를 들면 우리가 함수의 그래프를 그릴 때 3x^2이라는 함수를 그리고 싶으면  익명 함수를 정의합니다.

func=@(x) 3*x.^2;

 

그다음에 이 범위를 전체의 값을 다 주는 게 아니라 시작 값과 끝값만 준 다음에 fplot라는 함수를 작성하면 됩니다. 

시작값과 끝 값은 x의 범위를 이야기합니다. 

 

첫 번째 인자로 함수의 핸들, 두 번째 인자로 시작 값과 끝 값을 주면 

아래와 같이 함수의 그래프를 그려줍니다. 

 

 

 

전체 코드와 Figure창입니다. 

% fuction fuction사용법예시 입니다. 

func=@(x) 3*x.^2;
lims=[-2,2]; %시작값과 끝값만 정의 
fplot(func,lims)
gtext('OH','FontSize',99);

 

 

 

우리가 직접 함숫값을 계산할 필요가 없이 fplot라는 내장 함수가 함숫값까지 계산해서 그래프를 그려주는 역할을 하게 됩니다. 

 

이런 function function을 사용하려면 익명 함수를 이용해서 함수의 핸들을 만들어 주어야 합니다.

 

 

에디터를 열어서 위 문제에서 시키는 대로 하나씩 코드를 작성해보면 됩니다. 

 

 

전체 코드와 Figure입니다.

 

%예제 17a 코드입니다. 
g=9.81;
cd=0.25;
m=6.81;

v=@(t)  sqrt((g*m)/cd)*tanh(sqrt((g*cd*t)/m));
lims=[0,12]
fplot(v,lims); %인자 목록에 함수의 핸들, 시작값과 끝값을 저장하는 벡터를 순서대로 작성하면 된다.
%바로 위 3줄을 아래와 같이 한줄로 작성할 수 있습니다.
%fplot(@(t)  sqrt((g*m)/cd)*tanh(sqrt((g*cd*t)/m)),[0,12]);

gtext('wow','FontSize',50);

 

 

 

 

 

 

 

 

똑같은 형식의 문제입니다. 

함수를 계산하는 익명 함수를 만들고 그래프를 그린 다음에

fminbnd를 사용해서 최솟값을 찾는 문제입니다.

fminbnd()의 기능에 대해서는 '참고'를 읽어보길 바랍니다. 

 

 

 

전체 코드와 Figure입니다.

%예제 17번b코드 입니다. 

x=[0:0.1:6*pi];
myf1=@(x) 8*exp(-0.25*x).*sin(x);

plot(x,myf1(x));


[xval,fval]=fminbnd(myf1,2,7);
text(xval,fval,['minimum=' num2str(fval) 'at x=' num2str(xval)])

 

 

 

fplot를 사용하면 다음과 같습니다.

lims=[0 6*pi];
myf1=@(x) 8*exp(-0.25.*x).*sin(x);
fplot(myf1,lims)

[xval,fval]=fminbnd(myf1,2,7)
text(xval,fval,['minimum=' num2str(fval) 'at x=' num2str(xval)])

 

 

 

 

코드를 설명해보겠습니다. 

 

주어진 함수를 계산하는 익명 함수를  정의합니다. 

그런 다음에 x의 범위를 주고 그다음 다른 익명 함수를 사요 해서 y를 계산하고 

plot 해서 그것을 보고

최솟값을 찾기 위해 함수의 핸들을 사용하고 범위를 2에서 7까지 주었습니다. 

(x의 범위가 0에서 6*pi까지 인데 범위를 2에서 7로 준 이유)

그런 다음 계산을 하면

xval이라는 변수에는 함숫값이 최솟값일 때의 x값이 들어갑니다.

최솟값의 좌표에   문자열을(최솟값임을 나타내는) 찍는 프로그램입니다. 

 

교수님의 답변입니다.

수학적으로 함수의 최솟값이 여러개인 경우에, 함수의 최소값은 이 여러 극소값들 중에서 제일 작은 값입니다.

극소값이 하나 뿐인 함수라면, 범위를 어떻게 주던 항상 최소값을 찾습니다. 

 

하지만, 극소값이 여러개인 경우에 fminbnd 함수는 진짜 최소값을 찾지 못하고 다른 극소값을 찾고 거기에서 멈추는 경우가 았습니다. 

이것은 알고리즘이 처음 초기치를 주면, 그 근처에서 극소값을 찾기 때문이지요. 

알고리즘이 우연히 진짜 최소값 근처에서 시작하면 진짜 최소값을 찾지만, 

초기치가 진짜 최소값이 아닌 다른 극소값 근처로 주어지면, 그 초기치 근처의 극소값을 찾습니다. 

이건 알고리즘의 한계입니다. 그래서 일단 전체 범위의 그래프를 그려서 눈으로 살펴 보고, 그 다음에 최소값이 있는 부분의 범위를 지정하여 진짜 최소값을 찾습니다.   

 

직접만들어본 코드입니다.

 

%직접만든 코드
fun = @cos;
lims=[0 pi];
fplot(fun,lims);
[xval,fval]= fminbnd(fun,x1,x2)

text(xval,fval,['minimun' num2str(fval) 'at x is' num2str(xval)])

%fminbnd>최솟값을 함숫값으로 가지는 x의 값을 찾는다.

 

 

 

 

그다음 예제 17c는 똑같은 형식이긴 한데 익명 함수를 사용하지 말고 m파일에 따로 저장되어있는 매트랩 종료 함수를 하나 만들고, 그때는 어떻게 핸들을 사용할 수 있는지 '그 차이를 느껴보라'에 대한 프로그램입니다. 

 

  1. 먼저 함수를 계산하는 m파일 함수를 작성해서 저장하고 

  2. 새로운 파일을 하나 연 다음에 

  3. 그래프를 그리고

  4. 최솟값을 찾아보라는 문제입니다. 

 

※익명 함수일 때는 핸들 이름이 그냥 붙어있었는데 m파일일 때는 함수 앞에 @를 붙여야 핸들이 됩니다 ,

 

 

 

 

 

 사용자 함수가 정의된 m파일입니다. 

하나의 파일을 열어서 주어진 식을 저장하는 파일을 저장해놓습니다.  (m파일 사용자 함수입니다. )

% ex17c에 사용되는 사용자 정의 함수 myf2입니다 

function y=myf2(x)
         y=exp(4*x).*sin(1./x); %나눗셈에도 어레이 연산자 적용
endfunction

 

 

함수를 호출하고 그래프를 그리는 코드입니다.

% ex17c에 대한 코드 입니다. 

lims=[0.01 0.2];
fplot(@myf2,lims);

[xval,fval]=fminbnd(@myf2,lims(1),lims(2));

text(xval,fval,['minimum=' num2str(fval) 'at t=' num2str(xval)]);

lims(1)은 lims에 저장된 첫번째 요소

lims(2)는 lims에 저장된 두번째 요소 입니다.

 

저는 처음에 아래와 같이 작성했습니다.

%ex17c번 입니다.
x=[0.01:.1:0.2];

fplot(@myfunc,x);
[xval,fval]=fminbnd(@myfunc,0.01,0.2);
text(xval,fval,['minimum is',num2str(fval),'at x is',num2str(xval)])

 

 

 

 

 

 

원리를 이해하기까지 보다 

사용할 줄 아는 정도의 숙달만 되면 된다고 합니다. (대학교 2학년 수준에서는)

 

 

 

반응형
Comments