IDL/Math

시스템 변수 !EXCEPT 소개

이상우_IDL 2016. 11. 23. 23:37
728x90

IDL에서는 !로 시작하는 소위 "시스템 변수"라는 것들이 있습니다. 말 그대로 IDL 내부에서 돌아가는 각종 작업들에 대한 세부 설정을 제어하는 역할을 하는 숨은 변수들이라고 보면 됩니다. 그 중에서 !EXCEPT라는 시스템 변수에 관하여 소개를 해보고자 합니다. 이 시스템변수의 이름의 의미는 Exceptional, 즉 예외적인 상황이라는 의미인데요. 여기서는 숫자 계산에 있어서 비정상적인 결과가 산출되는 상황을 의미합니다. 예를 들어 다음과 같이 어떤 숫자를 0으로 나누게 되면 무한대(Infinity) 값이 산출되는데, 이런 상황은 숫자 계산에 있어서 정상적인 결과는 아닙니다.


IDL> PRINT, 6.7/0.0

          Inf

% Program caused arithmetic error: Floating divide by 0


이와 유사한 상황들이 또 있을 수 있는데, 통칭하여 Arithmetic Error, 즉 산술계산상의 에러라고 합니다. 아마 여러분들도 내부적으로 뭔가 계산 결과를 얻기 위한 IDL 프로그램을 만들어서 돌릴 때 간혹 유사한 메시지가 뜨는 것을 보신 적이 있을 것으로 생각합니다. 예를들어 다음과 같은 IDL 프로그램을 실행할 경우를 생각해 봅시다.


PRO test_arithmetic_error


a = 6.7

b = 0.0

PRINT, a+b

PRINT, a*b

PRINT, a/b

PRINT, a-b


END


실제로 이 프로그램을 실행시키면 콘솔창에서는 다음과 같은 메시지가 뜹니다.


IDL> test_arithmetic_error

% Compiled module: TEST_ARITHMETIC_ERROR.

      6.70000

      0.00000

          Inf

      6.70000

% Program caused arithmetic error: Floating divide by 0


프로그램의 내용에 이미 나와 있듯이 a/b 나눗셈 연산으로 인하여 이러한 메시지가 떴음을 짐작할 수 있습니다. 그런데 이러한 메시지는엄밀히 말하면 "오류(Error)" 메시지가 아닙니다. 왜냐하면 IDL에서 "오류"가 발생할 경우에는 프로그램이 아예 중단되면서 어느 라인에서 문제가 있었는지까지도 출력이 되거든요. 그런데 지금 이러한 경우는 메시지를 출력은 해주기는 하지만 그렇다고 프로그램의 실행 자체가 중단까지 되지는 않습니다. 사실 이러한 상황은 "오류"가 아니라 "경고(Warinig)"에 해당됩니다. 이와 같이 경고의 상황일 경우에는 문제가 있었다고 귀띔은 해주지만 프로그램 실행을 중단시키지도 않고 정확히 어느 지점에서 문제가 발생했는지도 알려주지 않습니다. 따라서 그냥 뭔가 일이 있었나보다 하고 무시할 수도 있지만, 그래도 내 프로그램의 정확히 어느 부분에서 문제가 발생했는지를 알아내야 할 경우도 있습니다. 이 때 등장하는 것이 바로 !EXCEPT 시스템 변수입니다. 이 !EXCEPT 시스템 변수의 값은 우리가 직접 바꿀 수 있습니다. IDL 콘솔창에서 다음과 같이 이 값을 2로 바꿔 봅시다.


IDL> !EXCEPT = 2


이렇게 변경을 한후에 위의 IDL 프로그램을 다시 실행해보면 이번엔 다음과 같은 메시지가 출력됩니다.


IDL> test_arithmetic_error

% Compiled module: TEST_ARITHMETIC_ERROR.

      6.70000

      0.00000

          Inf

% Program caused arithmetic error: Floating divide by 0

% Detected at TEST_ARITHMETIC_ERROR    7 /Users/Sangwoo/Documents/IDL/blog/test_arithmetic_error.pro

      6.70000


이전의 경우와는 분명히 차이가 있습니다. 즉, 경고 메시지를 출력하는 것은 동일하지만, 문제가 어느 라인에서 발생했는지까지도 알려주게 됩니다. 물론 이 상황도 여전히 "경고"의 상황이기 때문에 프로그램의 실행은 중단되지 않습니다. 문제가 발생한 위치를 알려준다는 차이만 있을 뿐입니다. 이번엔 !EXCEPT의 값을 다음과 같이 1로 변경한 후 위 IDL 프로그램을 실행해 보세요. 그러면 우리가 처음에 봤던 것과 동일한 메시지가 출력되는 것을 확인할 수 있습니다. 즉 !EXCEPT의 기본(Default) 값은 1이란 것을 알 수 있습니다. 실제로 이 시스템 변수가 가질 수 있는 값은 0, 1, 2 셋 중 하나입니다. 그렇다면 0일 경우는 어떨까요? 다음과 같이 값을 0으로 변경하고 프로그램을 실행해 봅시다.


IDL> !EXCEPT = 0


그러면 그 결과는 다음과 같습니다.


IDL> test_arithmetic_error

% Compiled module: TEST_ARITHMETIC_ERROR.

      6.70000

      0.00000

          Inf

      6.70000


즉, 이 경우에는 경고 메시지 자체가 아예 나오질 않습니다. 그리 바람직한 상황은 아니겠지요. 따라서 가급적이면 이 값을 기본값인 1인 채 그대로 작업을 하되, 필요에 따라 2로 변경을 하는 것이 가장 좋습니다. 그런데 어차피 이렇다면 !EXCEPT의 값을 아예 2로 설정해두고 사용하는 것은 어떨까요? 그것은 물론 유저의 자유입니다만 권장은 하지 않습니다. 왜냐하면 이 값이 2일 경우 프로그램의 연산 시간이 좀 더 늘어납니다. IDL 도움말에서 !EXCEPT에 관한 설명을 보면 약 5% 정도 더 시간이 걸린다고 되어 있습니다. 저도 실제로 테스트를 해본 결과 이러한 현상을 확인할 수 있었습니다. 위의 프로그램을 다음과 같이 수정해 봅시다.


PRO test_arithmetic_error


TIC

a = 6.7

b = 0.0

PRINT, a+b

PRINT, a*b

PRINT, a/b

PRINT, a-b

TOC


END


참고로 여기에 추가한 TIC, TOC 명령은 IDL에서 프로그램 실행 소요시간을 측정하는데 사용되는 방법입니다. TIC 명령과 TOC 명령 사이의 내용들이 실행되는데 소요된 시간을 초 단위로 출력해주기 때문에 알아두시면 꽤 유용하게 활용할 수 있습니다. 어쨌든 위 프로그램을 !EXCEPT의 값이 1인 경우와 2인 경우 각각 실행해보고 그 소요시간을 보시기 바랍니다. 컴퓨터의 사양이나 여건에 따라 차이는 날수 있겠지만 제 컴퓨터에서는 다음과 같이 결과가 나옵니다.


Time elapsed: 8.2015991e-05 seconds. (1일 경우)

Time elapsed: 0.00011110306 seconds. (2일 경우)


이 정도면 5%가 아니라 거의 30% 정도의 차이인데요. 여러분 컴퓨터에서는 어느 정도일지 궁금합니다. 분명한 것은 !EXCEPT의 값을 2로 설정하는 것이 시간 효율 측면에서는 그리 바람직하지 않다는 것입니다. 만약 산술적인 오류가 발생하는 지점이 프로그램 내에 많이존재할 경우에는 낭비되는 시간이 더 커질 수 있습니다. 따라서 !EXCEPT의 값을 2로 설정하는 것은 프로그램의 문제를 정확히 진단하는 목적으로만 일시적으로 사용하고, 일상적인 상황에서는 기본값인 1로 사용하는 것을 권장합니다.

LIST