자급자족하는 블로그

[MATLAB] 스크립트 사용법 및 Data 관리(Using Script and Managing Data) - 1 본문

MATLAB

[MATLAB] 스크립트 사용법 및 Data 관리(Using Script and Managing Data) - 1

YPSR 2018. 7. 23. 00:20

드디어 스크립트 파일 작성과 사용, 그를 위한 data 관리 및 파일 입출력에 대해 알아보겠습니다.

다만 이 모든 내용을 한 포스팅 안에 끝마치기는 어려울 것 같아, 두 파트로 나누어 진행하겠습니다.

본 포스팅에서는 스크립트 파일 작성 및 사용법, data 입출력에 대해서 소개하겠습니다

(파일 저장 및 불러오기에 대해서는 다음 포스팅에서 소개할 계획)



1. 스크립트 파일이란?


지금까지의 포스팅에서 종종 언급된 바 있지만 단 한번도 구체적으로 소개드린 적 없었죠.

교재에서 내리는 정의로는, 스크립트 파일이란 연속적인 MATLAB 명령어 모음이며, 곧 프로그램이라고 말합니다.

지금까지 우리는 Command window에서 직접 명령어를 하나하나 입력해가며 원하는 결과를 얻어냈다면, 스크립트 파일을 이용하면 한 번에 여러 명령어를 실행시킬 수 있는 것이죠.


Command window를 이용하면 간단한 연산을 빠르게 처리할 수 있다는 장점이 있었습니다.

하지만 복합적인 연산과 결과를 내기는 힘들죠.

스크립트 파일을 이용하면 보다 고차원적인 연산이 가능하며, 필요에 따라 수정도 가능하기 때문에 활용도가 매우 높습니다.


사실상 MATLAB을 이용한 프로그래밍이란 것은 스크립트 파일을 작성하는 것을 말합니다.



2. 스크립트 파일 작성 및 실행


스크립트 파일 작성은 Editor window에서 이루어집니다.

Editor window에서 사용하고자 하는 명령어 또는 변수 선언 등을 line-by-line으로 작성하시면 됩니다.

(굳이 line 하나에 명령어 하나만 작성할 필요는 없습니다만, 후에 원활한 수정 또는 디버깅을 위해서는 최대한 깔끔하게 작성하는 편이 좋겠죠)


아래는 교재에서 사용하는 예제입니다.

(예제 파일은 본 포스팅에 첨부되어 있습니다)


Fig 1. Example1: Find roots of a specific quadratic equation


프로그램의 내용은 간단합니다. 특정한 2차 방정식 하나를 선언해주고, 근의 공식을 이용하여 해당 방정식의 근을 계산해내는 프로그램입니다.

Command window를 이용했다면 6개의 명령어를 하나하나 입력해주어야겠지요.

스크립트 파일을 이용하면 실행버튼 하나만으로 위 연산을 실행시킬 수 있으니 확실히 간편한 장치라 할 수 있겠습니다.

(명령문 앞에 %를 붙임으로써 주석처리 가능)

(여러 줄 선택 후 ctrl+r/t로 주석 처리/미처리 가능)


보시면 x1과 x2의 값을 assign하는 과정에서 등호 기호 아래에 밑줄이 표시되어 있습니다.

Editor window에서 작업을 할 때, 예상되는 문제 또는 경고를 저런 식으로 미리 알려주는 것입니다.

물론 실행시켜보기 전에는 파악할 수 없는 에러도 있겠지만, 저런 경고를 통해 자잘한 수고로움을 덜 수 있죠.


제가 지금까지 본 경고 중에는 '선언된 변수가 프로그램 전반에 사용되지 않음', '선언된 변수가 반복문을 거치면서 크기가 계속 바뀜' 등이 있었습니다. 프로그램 실행에 치명적인 문제들은 아니지만, memory 관리나 프로그램 속도 및 효율에 있어서는 무시 못 할 것들이죠.


사실 본 예제에서는 저 부분이 문제가 되어서 경고를 주는 것은 아닙니다. 우리가 Command window를 이용해 command를 실행할 때, command 끝에 세미콜론(;)을 붙이느냐 안붙이느냐에 따라 Command window에의 결과값 출력 여부가 결정되었죠이 경우도 마찬가지입니다. 2차 방정식의 계수(a, b, c) 선언 시에는 모두 세미콜론(;)을 사용하였으므로, 프로그램을 실행했을 때 Command window에 출력되지 않을 것입니다. x1과 x2는 선언 시에 세미콜론(;)이 없기 때문에 계산되는대로 Command window에 결과값이 출력될 것입니다. 저 경고문은 바로 이것을 알려주기 위함입니다. '별 거 아닌 걸 이렇게 경고할 필요가 있나' 싶을텐데요, 본 예제에서야 큰 문제 없겠지만 10,000번 반복하는 반복문 내의 명령문에 세미콜론(;)을 붙여주지 않으면 Command window에 10,000개의 출력이 나타나겠죠


스크립트 파일 실행 또한 간단합니다. 작성한 스크립트 파일을 저장하고, 실행 버튼을 누르거나, 저장한 스크립트의 파일명을 Command window에 입력하면 됩니다. 아니면 F5를 눌러(단축키) 실행시킬 수도 있습니다.


Fig 2. Running a script file


위에서 말씀드린대로, x1과 x2의 결과만이 Command window에 출력됨을 확인할 수 있습니다.

여기서 중요한 것은, 1) 실행하고자 하는 스크립트 파일이 저장되어 있어야 하며, 2) 현재 디렉토리에 저장된 파일이 있어야 한다는 것입니다.

현재 디렉토리는 Current directory window에서 확인할 수 있다고 말씀드린 바 있는데요, 만약 현재 디렉토리에 스크립트 파일이 없다면 정상적인 실행이 이루어지지 않으며, 현재 디렉토리에 스크립트를 새로 저장하거나, 기존의 스크립트 파일이 있는 디렉토리로 접근할 수 있도록 MATLAB 경로에 추가해야 합니다. 이에 대해서는 MATLAB에서 알림을 줍니다(Fig 3 참고).


Fig 3. Changing the current directory or create new one



3. Data 입력


Fig 2를 보시면 아시겠지만, 스크립트 파일을 실행하면 내부의 변수들이 모두 Workspace window에 나타납니다.

사실 당연한 것인데요, 우리가 지금까지 Command window에서 작업을 할 때도 모두 Workspace window에 나타났었습니다. 말씀드렸듯이 스크립트 파일은 command의 모음이고, 결국 이를 실행한다는 것은 Command window에서 하나하나 실행하는 것과 마찬가지니까요.

다시 말해, Command window와 스크립트 파일은 memory zone을 공유한다는 뜻입니다.

이 때문에, 스크립트 실행에 필요한 변수를 선언(data 입력)하는 방법도 다양해집니다.


1) 스크립트 파일 내에서 선언


Example1과 같이, 스크립트 내에서 변수를 선언하고 활용하는 경우입니다.

다른 예제로 알려드리도록 하겠습니다.


Fig 4. Example 2: Calculate the mean score for three independent games. The scores are assigned in the script.


마찬가지로, 스크립트 내에서 모든 변수를 선언하는 방식입니다.

선언된 변수는 workspace에 저장되며, 후에 ave_points 연산 시에 입력으로 활용되는 것입니다.

이 경우 별도로 변수를 선언해줘야하는 수고로움은 없지만, 다른 input data를 사용하기 위해서는 스크립트 파일 자체를 수정해주어야 한다는 단점이 있습니다.


2) Command window에서 변수 선언 후 스크립트 파일에서 이를 활용


말씀드렸듯이, Command window와 스크립트 파일은 동일한 memory zone을 사용합니다. 때문에 스크립트 파일 내부에서 변수가 선언되지 않더라도, 이미 workspace에 저장되어 있기만 하다면 입력으로 사용 가능하다는 말이지요.

두 번째 방법은, 스크립트 실행 전에 Command window를 이용하여 변수를 미리 선언한 후, 스크립트 파일에서 이를 입력으로 사용하는 것입니다.


Fig 5. Example 3: Calculate the mean score for three independent games. The scores should be assigned before running script.


Fig 6. Input the scores and the result of example 3


이 경우에는 위와 달리 다양한 input data를 스크립트 수정 없이 활용할 수 있습니다.

다만 매번 변수를 직접 선언해주어야 하니 귀찮을 수 있겠네요.


3) 스크립트 파일 내에서 선언하되, 값을 Command window를 통해 직접 입력


이 경우는 input이라는 함수를 사용하는 방법입니다.

변수 자체는 스크립트 내에서 정의되지만, 값을 assign하는 것은 Command window에서 이루어지는데요,

input 함수에 관하여 간단히 설명드리고 넘어가겠습니다.


>> var_name = input('A message displayed in the Command window');


위의 명령이 바로 input 함수를 이용한 명령입니다. 위 명령을 Command window에서 입력했을 때, 작은따옴표 내부의 메시지가 Command window에 출력되고, 특정 값을 입력한 뒤 Enter 키를 누르면 값이 var_name에 assign되는 것입니다.


아래 Example 4를 보시면 이해가 빠르게 될 것입니다.


Fig 7. Example 4: Calculate the mean score for three independent games. The scores are assigned by input command.


Fig 8. The result of example 4


보시는 바와 같이, 스크립트 내에서 game1, game2, game3라는 변수는 정의되지만 75, 93, 68이라는 값은 Command window에서 입력되는 것을 확인할 수 있습니다. 이 경우에는 스크립트의 수정 없이, 그리고 변수 선언의 번거로움 없이도 다양한 input data를 가지고 평균 점수를 구할 수 있겠죠.


숫자가 아닌 문자형 data를 assign할 수도 있습니다.


>> var_name = input('A message displayed in the Command window', 's');


위와 같이 's'를 추가로 작성해주면, 이는 곧 문자형의 값이 assign될 것임을 알려주는 역할을 합니다.

이미 assign될 변수가 문자형임을 말해주었기 때문에, 문자열 입력시 작은따옴표를 쳐주지 않아도 됩니다.



4. Data 출력


앞서 언급한 바 있듯이, MATLAB에서는 세미콜론(;)의 사용 여부에 따라 명령 결과의 자동 출력 여부가 결정됩니다.

이러한 자동 출력 외에도, MATLAB에서는 별도의 data 출력 함수를 제공하고 있는데요, disp 함수와 fprintf가 그것입니다.


1) disp


세미콜론(;)을 붙이지 않았을때의 자동 출력에는 변수명이 함께 출력됩니다.

disp 함수는 변수명을 출력하지 않고 변수값만을 출력할 때 유용하게 쓰일 수 있으며, 또한 단순히 출력하고자 하는 텍스트 또는 메시지가 있을 때 사용할 수 있는 함수입니다.

사용법은 아래와 같습니다.


>> disp(var_name) % var_name에 assign된 값을 출력

>> disp('text as string') % 특정 메시지를 출력


disp 함수는 출력 후에 자동으로 줄바꿈(enter)을 출력합니다. 따라서 disp 함수를 쓸 때마다 새로운 줄에서 출력이 됩니다.

아래는 disp 함수를 이용한 예제와 그 결과입니다.


Fig 9. Example 5: Calculate the mean score for three independent games. The scores are assigned by input command. The result is printed by disp command.


Fig 10. The result of example 5


disp 함수를 이용하여 array도 출력할 수 있습니다.

Array 출력 시 각 element들이 row-by-row 방식으로 출력되며, 각 row의 element들은 공백으로 구분되어 출력됩니다.

종종 각 데이터의 정보(변수명, 단위 등)도 함께 disp 함수로 출력하는 경우가 있는데, 이때는 공백을 잘 맞춰서 출력해주는 것이 좋겠죠.


Fig 11. Example 6: Print the population to year. The result is printed by disp command.


Fig 12. The result of example 6


2) fprintf


fprintf 함수는 disp 함수보다 더 복잡하고 다양한 출력을 할 수 있는 함수입니다.

예를 들어 텍스트 중간에 변수를 함께 넣어 출력할 수도 있습니다.

심지어는 파일 형태로의 출력에도 사용되는 함수입니다(이에 대해서는 다음 포스팅에서 다룰 계획).

하지만 그만큼 사용하는 데에 조금 더 귀찮고 복잡한데요, 천천히 알아보도록 합시다.


(1) 간단한 텍스트 출력

간단한 텍스트 출력은 disp 함수와 사용법이 동일합니다.


>> fprintf('text typed in as a string');


위와 같이 명령을 하면 작은따옴표 안의 텍스트가 Command window에 출력됩니다.

다만 disp 함수와 다른 점은, fprintf 함수의 경우에는 줄바꿈을 자동으로 추가해주지 않는다는 것입니다.

때문에 줄바꿈을 뜻하는 \n을 별도로 입력해주어야 합니다. \n과 같은 문자를 이스케이프 문자(escape character)라고 하는데요, \n 외에도 몇가지 escape character가 있습니다.


 \n

 줄바꿈(enter)

 \t

 줄 내에서 공백(horizontal tap)

 \b

 직전 문자 삭제(backspace)

Table 1. Escape characters


아래는 fprintf 함수를 이용한 간단한 예시입니다.


Fig 13. Examples of use of fprintf command and escape characters


(2) 텍스트와 변수를 함께 출력


텍스트와 특정 변수를 동시에 출력하기 위해서는 fprintf 함수를 아래와 같이 사용하면 됩니다.


>> fprintf('text as string %-5.2f additional text', var_name);

>> fprintf('...text...%g...%g...%f...', var1,  var2, var3);


짐작하시듯이, 오른쪽에 입력된 변수의 값이 % 문자가 들어있는 부분에 들어가 출력되는 방식입니다.

두번째와 같이 여러 변수를 입력할 수도 있습니다. 이 때 변수값은 입력된 순서대로 출력됩니다.


중요한 부분은 바로 변수가 들어가는 부분인데요(%-5.2f, %g 등), 이를 formatting element라고 합니다.

Formatting element는 변수가 어떻게 출력될지를 결정하는데요, 그 구조는 아래와 같습니다.


Fig 14. Structure of Formatting element


Flag와 field width, precision은 옵션이고, conversion character는 필수로 입력해주어야 합니다. 순서대로 알아봅시다.


Flag는 숫자 출력에 있어서 공백의 표현 방법, + 부호 표시 등 부수적인 것들에 대한 것입니다.

Flag에는 아래의 종류가 있으며, 각 역할은 다음과 같습니다.


 -(minus sign) 

 변수를 좌측 정렬하여 출력.

 +(plus sign)

 변수의 부호를 함께 출력. 음수의 경우는 자동으로 출력됨.

 0(zero)

 Field의 남는 자리를 0으로 출력.

Table 2. Flags for formatting element


Field width는 출력하는 수의 표현에 할당하는 digit의 개수를 말합니다. 예를 들어 8.2를 출력하기 위해서는 최소 3개의 digit이 필요합니다(부호와 소숫점에도 digit이 할당되어야 함). Precision은 소숫점 아래 몇째자리까지 출력할 것인지를 결정하는 역할을 합니다.


Conversion character는 숫자를 정수형으로 표현할 지 또는 실수형으로 표현할지, 실수형이라면 지수부를 이용할 지 이용하지 않을 지 등을 결정하는 역할을 합니다. Conversion character에는 아래와 같은 종류가 있습니다.


 e

 지수부의 밑을 e로 표현(ex. 1.709098e+001).

 E

 지수부의 밑을 E로 표현(ex. 1.709098E+001).

 f

 지수부 없이 표현(ex. 17.090980).

 g

 e 또는 f와 동일. 단, 출력하는 길이가 짧음.

 G

 E 또는 f와 동일. 단, 출력하는 길이가 짧음.

 i

 정수형으로 표현.

Table 3. Conversion characters for formatting element


예제와 함께 알아보도록 합시다.


Fig 15. Example 7: Calculate the mean score for three independent games. The scores are assigned by input command. The result is printed by fprintf command.


Fig 16. The result of example 7.


보시면 %f에 의해 출력된 경우에는 실수형으로 표현되며 소숫점 아래 여섯째 자리까지 출력이 됩니다.

%+.2f에 의해 출력된 경우에는 + 부호가 함께 출력되고, 소숫점 아래 두번째 자리까지만 출력되었네요.

%09g의 경우, 소숫점 아래 넷째 자리까지만 출력되는데, 확실히 f에 비해 짧은 표현이네요. 총 9개의 digit을 할당했으므로 소숫점 제외 8개의 digit이 숫자 표현에 쓰이는데, 남는 두 digit은 0으로 출력되었습니다.

%i로 실수형을 표현하려니 실수형이 그대로 출력되는 것을 볼 수 있는데요, 아무래도 정수형 변수만이 정수형으로 출력될 수 있는 듯 합니다.


과연 array도 fprintf로 출력이 가능할까요?

물론 가능합니다. 그런데 출력방식은 disp 함수와 다릅니다.

disp 함수는 row-by-row 방식으로 data를 출력한다면, fprintf는 column-by-column 방식으로 array element를 출력합니다.


Fig 17. Example 8: Print the square roots from 1 to 5.


Fig 18. The result of example 8.



오늘의 포스팅은 여기서 마치도록 하겠습니다. 감사합니다.




example1_180722.m

example2_180722.m

example3_180722.m

example4_180722.m

example5_180722.m

example6_180722.m

example7_180722.m

example8_180722.m




Comments