정밀도 문제
정밀도 문제 (Precision Issues)
그래프를 그리는데 시간 축 데이터가 이상하게 찌그러져 보인 적이 있나요? OpenGL 기반 그래픽스 툴킷은 단정밀도(single precision)로 렌더링해서, 시간처럼 값이 큰 데이터를 다룰 때 정밀도 한계를 그대로 드러내는 경우가 있어요. 여기서 그 원인과 우회 방법을 확인할 수 있어요.
출처: 문서
본문
OpenGL 그래픽스 툴킷("qt"와 "fltk")은 렌더링에 단정밀도를 사용해요. 이 제한은 특히 datenum, datestr, datestruct, datetick 함수로 다루는, 연속 날짜(serial date)에 대한 시계열 플롯에서 두드러져요.
연속 날짜는 시간을 "0년부터 경과한 일수"로 부호화해요. 시간·분·초는 그 소수 부분으로 들어가요. 1999년 12월 31일의 연속 날짜 값은 730485였어요. 이 정수부를 갖는 배정밀도 변수는 소수부에서 약 1.2e-10(대략 5마이크로초)의 분해능을 허용해요. 그런데 단정밀도에서는 분해능이 약 0.06, 즉 45분 수준으로 줄어들어요. 이보다 더 세밀한 단위로 타임스탬프 데이터를 그리려 하면 그래프가 왜곡돼요.
우회 방법은 두 가지가 있어요. 하나는 "gnuplot" 그래픽스 툴킷을 쓰는 거고, 다른 하나는 시간 값에서 2000년, 즉 datenum (2000, 0, 0) 또는 730485를 빼는 거예요. 달력 구조가 2000년마다 반복되기 때문에, 연·월·일·요일의 관계는 변하지 않고 datetick 함수가 만드는 눈금과 눈금 레이블도 그대로 정확해요. 다만 연도에서 천 년 단위 숫자가 빠질 뿐이에요. 그래서 "2020"은 "20"으로 표시돼요. 예를 들어 보죠.
# timestamps of 24 hours in one minute steps
t = datenum (2020, 1, 1):(1/1440):datenum (2020, 1, 2);
# some example time series data
x = -cos (2*pi*t) + rand (size (t)) / 10;
subplot (1, 2, 1);
plot (t, x);
datetick ("x");
xlabel ("serial date");
title ("problem");
subplot (1, 2, 2);
plot (t - 730485, x);
datetick ("x");
xlabel ("2000 years off");
title ("workaround");
왼쪽 subplot은 2000년을 빼지 않은 원래 값이라 그래프가 왜곡되고, 오른쪽은 730485를 빼서 정상적으로 그려져요. 이와 비슷하게, 다른 데이터도 기준점을 옮기거나 비율을 재조정해서 이 문제를 우회할 수 있어요.
더 알아보기
- 날짜를 숫자로 부호화하는
datenum과 눈금을 만드는datetick함수를 함께 살펴보세요. - 그래픽스 툴킷 간 차이도 이어서 확인해 보면 좋아요.