저는 MATLAB을 비롯하여 다양한 컴퓨터 언어들을 사용하는 것을 좋아하는데 ~ 최근에는 회사에서 실험 데이터를 다루는 과정에서 파이썬을 많이 사용하고 있고 그 중에서 많은 분들이 아실 만한 pandas 라이브러리를 사용하고 있습니다 . 파이썬은 공짜이기도 하지만 pandas 를 비롯한 정말 좋은 라이브러리들이 많아서 앞으로도 꾸준히 사용하게 될 것 같습니다.

실험 데이터들은 많은 경우 엑셀이나 csv 파일 형태로 저장을 하게 되는데, MATLAB에서 xlsread, csvread 와 같은 함수를 통해 이런 데이터들을 불러오게 되고 MATLAB cell 타입에 대해서 다루어야 되는 경우가 종종 있습니다.

셀 타입으로 된 데이터 중 중복되는 내용을 제거하거나~ 유일한 데이터만 추려해야 되는 경우가 종종 발생하게 되는데 오늘은 이에 대해서 소개를 해 보려 합니다.

셀 데이터 중에서 유일한 데이터만 선택하는 것은 정말 간단한데 ~ 아래 포스팅에서도 소개했던 unique() 함수를 사용하시면 되겠습니다.

https://iamaman.tistory.com/269

그리고 위 포스팅에서 사용한 unique, setdiff 함수를 사용하면 ~ 중복되는 내용 역시도 추려 낼 수가 있습니다.

아래와 같이 A 라고 하는 중복되는 내용을 가지고 있는 셀을 준비하고 uniqueDup 함수에 넣어보면~ 유니크한 값이 들어있는 uniqueCell 와 중복된 값이 들어있는 dups 변수를 얻을 수 있습니다.



  1. 오리입니다 2019.11.08 14:07

    매트랩 과제하다가 코드를 잘짠거같은데 움직이질않네요
    한번봐주실수잇아요??
    답을알려드리라는게아니라.. 어떤게잘못됫다라고 짚어주는쪽으로요..가능할까요??
    되신다면. xodls1125-_-@nate.com 메일한번만주세요!!

MATLAB 을 사용하여 압축을 하고 싶으면 zip() 이라는 함수를 사용 합니다.

 

현재 폴더의 하위 내용들을 압축하고 싶은 경우 보통은 현재 폴더를 압축하곤 하는데 이렇게 하려면 현재 폴더가 아닌곳에 zip 파일을 저장해야 합니다.

 

오늘은 현재 폴더 하위의 내용들을 압축하는 방법에 대해 소개하려 합니다.

 

현재 폴더의 내용을 검색하는 방법은 dir() 이라는 함수를 사용합니다. dir() 함수는 recursive 한 파일 검색은 되지 않습니다.

 

recursive 한 파일 검색을 하고 싶다면 아래 포스팅을 참조하시면 됩니다.

 

http://iamaman.tistory.com/757

 

아무튼 오늘은 그냥 현재 폴더에 대해서만 검색 할것이므로 dir() 함수를 사용합니다.

 

그런데 dir() 함수를 사용하여 현재 폴더를 검색하면 '.', '..' 라는 폴더가 검색 됩니다.

 

바로 현재와 상위 폴더 입니다.

 

현재 폴더의 하위 내용들을 압축하고 싶기 때문에 그래서 이 부분들을 제외하고 압축을 해야 합니다.

 

위 소개한 부분들을 제외하고 압축을 하는 방법은 아래 코드와 같습니다.

 

a= dir('.');

fileAll=cell(length(a),1);

 

for n=1:length(a)

    if ~(strcmp(a(n).name,'.') || strcmp(a(n).name,'..'))

        fileAll{n}=a(n).name;

    end

end

 

AllFile=fileAll(~cellfun('isempty',fileAll));

zip('CurrentFolder.zip',AllFile);

 


파이썬을 사용하다 보면 string 처리가 굉장히 편하다는 생각이 많이 했습니다.

 

배열의 각 인자들로 구성된 string 들을 하나로 합치거나 특정 delimiter 로 나누는 등의 일들이 너무나 간단하게 처리 되어서 좋다는 생각이 많이 했습니다.

 

오늘은 MATLAB 에서 string 을 붙이는 방법에 대해 알아보려 합니다.

 

MATLAB 에서는 다음과 같은 경우 그냥 그냉 배열로 구성 하면 string 을 붙일 수 있습니다.

 

a='abc'

b='def'

c=[a b]

 

다음과 같이 c 값은 a, b 값이 붙어서 나옵니다.

 

c =

 

abcdef

 

하지만 중간에 delimiter 를 넣고 싶은 경우에는 얘기가 좀 달라잡니다.

 

중간에 쉼표를 넣고 싶다면 다음과 같이 쉼표를 넣어 줘야 겠죠~

 

c=[a ', ' b]

 

c =

abc, def

 

그런데 이렇게 붙여야 할 문자들이 2~3개라면 이렇게 해도 되겠지만 몇 십개 몇 백개라면 문제가 되겠죠~

 

이럴 때 사용 할 수 있는 함수로 strjoin() 함수가 있습니다.

 

Strjoin 함수는 cell 타입으로 구성된 string 에 대해 delimiter 를 넣어서 문자를 붙일 수 있습니다.

 

aa= {'abc', 'def', 'ghi'}

c = strjoin(aa,', ')

 

c =

abc, def, ghi

 

위 예와 같이 사용 방법은 굉장히 간단 합니다.

 

첫 번재 인자로 string cell 을 넣어주고 두 번재 인자로 delimiter 를 넣어 주면 됩니다.

MATLAB 의 Stateflow 는 Stateflow API 를 활용하여 m 파일 명령어로 구성 및 조정이 가능 합니다. 

 

때에 따라서는 일일이 사람이 Stateflow 를 그리는것 보다는 Stateflow API 를 활용하는것이 효율 적인 경우가 많이 있습니다.

 

Stateflow API 를 활용하면 Python 과 같은 스크립트 언어등을 활용하여 Stateflow 를 그리는 Code generation 등도 가능 합니다.

 

오늘은 Stateflow 에서 사용중인 Data 를 다 찾는 방법에 대해 알아보려 합니다. 

 

Stateflow 에서 Data 를 다루기 위해서는 Stateflow.Data Object 를 다 찾으면 됩니다. 

 

Stateflow 에서 data 를 다 찾는 스크립트는 다음과 같습니다.

 

 

위 코드에서 sfroot 는 stateflow 의 root 즉, 최상위 stateflow 를 의미 합니다.

 

다음으로 아래 코드 부분이 Stateflow.Data 를 다 찾는 코드 입니다.

 

datav = m.find('-isa','Stateflow.Data');

 

그 이하 부분은 찾아진 데이터의 Name 필드를 vall 이라는 Cell 객체에 넣고~ vall(:) 명령을 통해 Command 창에 data 들을 나열 합니다.

 


MATLAB 에서와 마찬가지로 Scilab 에서도 cell 타입을 지원 합니다.

 

cell 타입은 특이하게도 모든 데이터 타입들을 다 저장 할 수 있는 데이터 타입입니다.

 

MATLAB 에서는 아래 포스팅에서 소개한 적이 있습니다.

 

Scilab 에서는 cell() 은 아래와 같이 m1,m2,….mn 의 다차원으로 정의 할 수 있습니다.


 

c = cell(m1, m2, ..., mn)

 

c = cell(3) 이라고 정의 하면 3 행 3열의 cell 을 정의합니다. 3 행 1열의 cell 을 정의하고 싶다면 c = cell(3,1) 이라고 정의 해야 합니다.

 

cell 의 차원을 알기 위해서는 아래와 같이 dims를 사용하거나 size() 함수를 사용하는 방법이 있습니다.

 

c.dims or size(c)

 

dims 로 차원을 확인해 보면 그 리턴 타입이 int32 입니다. 이런 경우 index 로는 사용 할 수 없다고 합니다.

 

size() 함수로 차원을 알아보면 동일한 결과가 나오지만 그 type 을 확인해 보면 double 인 것을 확인 할 수 있습니다. (type 의 결과가 1 인 것은 double 을 의미 합니다.) 따라서 인덱스로 사용할 수 있겠죠.

 

다음으로 cell 의 각 element 에 접근 하기 위해서는 괄호() 를 사용하는데 그냥 () 만 사용해서 나온 결과는 cell 입니다.

 

따라서 각 index의 값에 접근 하고 싶을 때는 entries 라는 키워드를 사용해야 합니다.


 

괄호는 sub cell 에 접근 할 때 사용합니다. 위 그림은 X 라는 3행 2열 cell 의 모든 행 1열에 b 라는 셀을 넣는 예입니다.


오늘의 포스팅에서는 function handle 사용법의 추가 적인 내용들에 대하여 정리하겠습니다.

 

여러 함수에 대해 똑 같은 값을 적용할 때에는 function handle 을 struct classcell class 의 형태로 만들어서 이용할 수가 있습니다.



다음 수식에 대하여 struct 의 형태로 function handle 을 구성하고 그에 따른 값을 알아보죠.

 



 

다음과 같이 struct 의 형태로 표현 할 수 있고, x=-1:0.5:1 에 대한 각 수식의 값을 한번에 구할 수가 있습니다.

 

struct 에 한번에 똑 같은 값 또는 함수 등을 적용 할 때는 structfun() 함수를 이용 합니다.

 

 

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

 

ans =

f: [1 0.2500 0 0.2500 1]

g: [-1 -0.1250 1 3.1250 7]

h: [-0.8415 -0.4794 0 0.4794 0.8415]

  


 

위 수식에 대하여 cell 의 형태로 표현하고 위 x 의 범위에 대한 값을 구해 보죠.

 

cell 에 한번에 똑 같은 값 또는 함수 등을 적용 할 때는 cellfun() 함수를 이용 합니다.

 

 

위 코드에 따른 결과는 다음과 같습니다.

 

D{1} =

1.0000 0.2500 0 0.2500 1.0000

D{2} =

-1.0000 -0.1250 1.0000 3.1250 7.0000

D{3} =

-0.8415 -0.4794 0 0.4794 0.8415

  


 

마지막으로 function handle 을 두 번 이용해서 다음 수식을 표현해 보겠습니다.

 

 

적분은 quad() 함수를 이용하겠습니다.

 

quad() 함수의 사용 방법에 대해서는 아래 포스팅을 참조 하시기 바랍니다.

   

 

@ 을 두 번 써서 위 식을 표현 할 수 있습니다.

 

f = @(a,b) (quad(@(x) (x.^2 + b*x + 4), 0, a))

 

임의의 a, b 값에 대해 다음과 같은 결과가 나오는 것을 확인 할 수 있습니다.

 

>> f(1,2)

ans =

5.3333

 

>> f(4,0)

ans =

37.3333

 


 

MATLAB 에는 약간 독특한 cell 이라는 class 가 존재 합니다.

 

cell class 는 타입을 안 가리고 다 저장 하거든요.

 

숫자 문자를 가리지 않고 하나의 변수로 관리 할 수 있습니다.

 

struct class 처럼 field 로 구분하는 것도 아닌 게 한 변수에 막 집어 넣으니깐 처음에는 참 신기하더군요.

 

perl 을 접하신 분은 '당연한 거 아냐?' 하실 지도 …..

 

아무튼 이 cell 타입이라는 게 나중에는 참 쓸모가 많아 지니깐, 알아 두시면 도움이 됩니다.

 

아!! 여담으로 MATLAB 에서 perl script 도 실행이 가능 합니다.

 

MATLAB 에서 perl() 함수를 찾아 보시길~ 이런 것도 되? 하면서 좋아하실 분들도 있을 거라 생각 됩니다. 아닌가? ㅡㅡ;

   


 

cell class 의 변수를 설정 하는 방법은 다음과 같이 두 가지 방법이 있습니다.

 

  • 중괄호 {} 를 이용하는 방법

 

A={1:10, 'abc'; zeros(3), 'cell'}

A =

[1x10 double] 'abc'

[3x3 double] 'cell'

 

 

  • cell() 함수를 이용하는 방법

 

A=cell(2)

A=cell(2,2)

A =

[] []

[] []

 

위 명령들은 A 를 2행 2열의 empty cell로 만들어 줍니다.



 

cell A 의 각 인자에 값을 넣을때는 다음과 같이 표현 합니다.

 

A{1, 2}='1 row 2 column'

A =

[] '1 row 2 column'

[] []

 

 

위 코드는 A 의 1 행 2열에 문자열을 입력한 경우 입니다. matrix 에서는 각 인자의 값에 접근 할 때 ()괄호를 이용하였지만, cell class 에서는 중괄호를 이용한다는데 주의 하셔야 합니다.

 

괄호를 이용하여 A 의 2행 2열에 값을 입력하고 싶을 때는 다음과 같이 표현해야 합니다.

 

A(2, 2)={1:10} % 등호 우측에 중괄호를 이용하여 cell 을 넣어줌

A =

[] '1 row 2 column'

[] [1x10 double]

 

괄호를 이용하여 다음과 같이 접근 해 보죠.

 

A={1:10, 'abc'; zeros(3), 'cell'}

A =

[1x10 double] 'abc'

[3x3 double] 'cell'

 

B=A(1,2) % A 의 1 행 2열 에 괄호를 이용

B =

'abc'

 

class(B)

ans =

cell

 

B 는 cell class 의 값 입니다.

 

즉 B = {'abc'} 라고 표현한 것과 같은 것입니다. 



 

cell 에는 어떤 타입이든 담을 수 있기 때문에 cell 안에 cell을 담을 수도 있습니다.

 

A={1:10, 'abc'; zeros(3), 'cell'}

A =

[1x10 double] 'abc'

[3x3 double] 'cell'

 

B=cell(2)

B =

[] []

[] []

 

B{1,1}=A % B 의 1행 1열에 cell A 를 입력

B =

{2x2 cell} []

[] []

 

B{2,2}=ones(3)

B =

{2x2 cell} []

[] [3x3 double]

 

 

cell 안에 어떤 내용이 담겨 있나 구체적으로 알고 싶을 때는 cellplot() 함수를 이용하면 시각적으로 볼 수 있습니다.

 

cellplot(B,'legend')

 

celldisp() 함수를 이용하면 단순히 command 창에 그 값들을 나열하게 됩니다.

 

celldisp(B)

B{1,1}{1,1} =

1 2 3 4 5 6 7 8 9 10

B{1,1}{2,1} =

0 0 0

0 0 0

0 0 0

B{1,1}{1,2} =

abc

B{1,1}{2,2} =

cell

B{2,1} =

[]

B{1,2} =

[]

B{2,2} =

1 1 1

1 1 1

1 1 1

 



 

cell B 의 1행 1열안의 2행 2열에 있는 cell 이라는 문자열에 접근 하기 위해서는 다음과 같이 표현 하면 됩니다.

 

B{1,1}{2,2}

ans =

cell

 

 

cell 이라는 문자열의 2번째 글자인 e 를 나타내려면 다음과 같이 입력하면 됩니다.

 

B{1,1}{2,2}(2)

ans =

e

 



 

이제 cell A,B 를 C 라는 cell 에 넣어 볼까요...

 

C={A, B}

C =

{2x2 cell} {2x2 cell}

 

size(C)

ans =

1 2

 

C는 1행 2열의 cell 이 됩니다.

 

C={A ; B}

C =

{2x2 cell}

{2x2 cell}

 

size(C)

ans =

2 1

 

이렇게 하니깐 C 가 2행 1열의 cell 이 되죠.

 



 

그럼 2행 2열의 cell A와 2행 2열의 cell B 를 붙여서 4 행 2열을 만들고 싶으면 어떻게 해야 될까요.

 

이럴 때는 대괄호를 이용합니다.

 

D=[A B]

D =

[1x10 double] 'abc' {2x2 cell} []

[3x3 double] 'cell' [] [3x3 double]

 

D=[A ; B]

D =

[1x10 double] 'abc'

[3x3 double] 'cell'

{2x2 cell } []

[] [3x3 double]

 



 

: 콜론을 이용하여 cell D 에 다음과 같이 값을 할당 해 보죠.

 

D(:,1)={1, 2, 3, 4}

D =

[1] 'abc'

[2] 'cell'

[3] []

[4] [3x3 double]

 

위와 같은 표현은 구버전의 MATLAB 을 이용하시는 분들은 실행이 안 될 수 있습니다.

 

그럴 때는 deal() 함수를 이용하시면 됩니다.

 

[D{:,1}]=deal(1,2,3,4)

D =

[1] 'abc'

[2] 'cell'

[3] []

[4] [3x3 double]

 



 

콜론을 이용하여 cell 의 값을 반환하는 예를 보죠.

 

f=D{:,1}

f =

1

 

위 코드는 이상하게도 1 만 나오죠?

 

1, 2, 3, 4를 벡터로 나타낼 때는 다음과 같이 합니다.

 

f=cell2mat(D(:,1))

f =

1

2

3

4

 

cell2mat() 함수는 cell class 를 matrix 로 만들어 줍니다.

 

matrix 를 cell 로 만들어 줄 때는 mat2cell() 이라는 함수를 이용합니다.

 

A=magic(2)

A =

1 3

4 2

 

G=mat2cell(A,2,2)

G =

[2x2 double]

 

celldisp(G)

G{1} =

1 3

4 2

 

size(G)

ans =

1 1

 

위 결과를 보면 G 의 크기가 1행 1열이죠? 2 행 2열로 나타내고 싶은데 말이죠..

 

다음과 같이 하면 원하는 결과를 얻을 수 있습니다.

 

G2=mat2cell(A,[1 1],[1 1])

G2 =

[1] [3]

[4] [2]

 

size(G2)

ans =

2 2

 

숫자만으로 구성된 matrix 를 cell 로 표현 할 때는 num2cell() 함수를 사용하는 게 좀 더 편리 합니다.

 

G3=num2cell(A)

G3 =

[1] [3]

[4] [2]

 

size(G3)

ans =

2 2



  1. 샤오 2011.10.22 01:26

    A*x=b, A는 2*2 단순 숫자로 구성된 행렬, b는 2*1 단순 숫자로 구성된 행렬, A의 inverse를 구하여 b와 곱해 x를 구하는 소스좀 알켜주세요. R2011b 인데 잘안되네요.

  2. 남성 2011.10.22 21:08 신고

    방문해 주셔서 감사합니다.

    x = inv(A)*b

    또는

    x=A\b 하셔도 됩니다.






  3. 용마담 2012.01.13 15:20

    좋은 정보 감사합니다.
    매트랩에서 늘 매트릭스로 만들어서 변수들을 저장하는 방법만 쓰다보니 문자열 저장이 안 되서 좌절했었는데,
    cell 개념을 쓰면 되는군요. 애용하렵니다ㅎㅎ

  4. 올스파크 2014.05.09 16:03

    좋은 정보 감사히 잘 보고 갑니다~

오늘 포스팅에서는 symbolic math 를 통해 계산한 수식에 대해 함수를 만드는 방법에 대해 설명 드리겠습니다.

 

일단 다음과 같이 수식을 정의 해 보죠.

 

syms a b x

 

f=a*x^2+x + 8

 

f =

a*x^2 + x + 8

 

위 수식에서 a 값을 2*b 값으로 치환을 해보겠습니다. 치환 할 때는 subs() 함수를 이용합니다.

 

f1=subs(f, a, 2*b)

 

f1 =

2*b*x^2 + x + 8

 



그럼 이제 위 f1 식을 함수로 정의해 보겠습니다. symbolic 식을 함수로 표현 할 때는 matlabFunction() 이라는 함수를 사용합니다.

 

hf1 = matlabFunction(f1)

 

hf1 =

@(b,x)x+b.*x.^2.*2.0+8.0

 

 

위와 같이 matlabFunction() 함수를 사용하면 기본적으로 function handle로 결과를 반환 합니다. 입력이 b, x 인 function handle hf1 을 반환하는 것을 확인 할 수 있죠.




function 파일을 만들고 싶을 때는 command 창에 다음과 같이 명령어를 입력합니다.

 

matlabFunction(f1,'file','function_file1.m');

 

위의 결과로 function_file1.m 이라는 함수가 만들어 지고 다음과 같이 파일로 저장됩니다. 




위 결과를 보면 함수의 입력이 b, x 의 순서인 것을 확인 할 수 있습니다. 다음 명령어를 통해 입력의 순서를 x,b 로 설정해 보겠습니다.
 

matlabFunction(f1,'file','function_file1.m','vars',[x b]);

 

위 명령의 실행 결과 아래와 같이 x, b 의 순서로 설정되었습니다. 




이제 함수의 출력 변수 명을 변경해 보죠. 위 식에서 f1 이었던 출력 변수명을 out_f 라는 변수명으로 바꿔보죠.

 

matlabFunction(f1,'file','function_file1.m','vars',[x b],'outputs',{'out_f'} );

 

  
출력 변수 명을 설정 할 때는 위 명령어에서 중괄호{} 를 이용하였습니다. 즉 cell class 로 설정해 주셔야 합니다.

 

위 명령어의 결과로 다음과 같은 함수가 만들어 집니다. 




Matlab Editor 에서 스크립트 코딩시에 cell 모드 이용 방법에 대해 알아 본다.

 

Cell mode 는 코드를 구분하여 실행시킬 때 쓸 수 있고, matlab 코드로부터 report 작성시에도 각 단락 등을 구분 시켜 주는 역할을 한다.

아래 보는 밑줄친 부분(%% + 기호)을 클릭하면 그 부분에 %% 기호가 나타나면서 가로줄이 그어 진다.

또는 단순히 %% 를 써도 되고 control+space 단축키나 cell 메뉴에 들어가서도 셀 설정을 할 수가 있다.

  

셀 모드에서 %% 원본 이라 되어 있는 셀에 커서를 놓은 후에

동그라미 친 부분(Evaluate cell) 을 누르면 해당 셀만 실행이 되고 위 코드의 경우엔 아래와 같은 그래프가 나온다.

 

그 아래 셀로 커서를 옮겨서 14 번째 줄에서 2*x +1 에서 숫자 2를 2 만큼씩 크게 해 가면서 그래프를 그려 보자

물론 이 경우에 2를 4로 바꾼 후 에 현재 셀을 실행 시키고 또 6으로 바꾸고 현재셀을 실행 시키는 형태로도 할 수가 있지만, 여기선 어디까지나 셀 모드의 기능을 익히기 위한 것이므로

위 첫번재 그림의 빨간색 네모 칸에 2를 쓴 후에 그 옆의 + 버튼을 눌러 보자.

+ 버튼을 두번 눌렀을 때 14 번째 줄은

y=6*x+1;

로 바뀌며

위의 그림 역시


이렇게 바뀌는 것을 알 수 있다.

이처럼 cell mode 의 기능들을 이용하면 단순 반복 해야 하는 일들을 보다 효율적으로 수행할 수 있다.



+ Recent posts