# 오차의 분류: 모델 오차·해석 오차·계산 오차

#### 모델 오차

수치해석에서 다루는 물리 혹은 공학적 문제는 대체로 복잡한 실제계(physical system)를 어떤 수학적 모형으로 간략화한 형태로 표현된다. 물리적 현상을 표현하기 위해서는 여러 가지 가정이나 근사를 통해 문제 상황을 단순화한다. 예를 들어, 진동하는 물체의 운동방정식을 유도할 때 공기 저항을 무시하거나, 천체운동을 해석할 때 중력 이외의 힘을 무시하는 등 다양한 간소화 작업이 이루어진다. 이처럼 실제 현상과 이론적 모델 사이에 존재하는 불일치로 인해 발생하는 오차를 모델 오차라고 한다.

물리계에서 에너지가 보존되지 않는 현상을 단순화 모델에서 무시한다면, 결국 얻어지는 해는 실제 해와 다를 수밖에 없다. 모델 오차는 문제를 단순화한 정도에 따라 크기가 달라진다. 단순화의 정도가 심할수록 모델 오차가 커질 가능성이 있다. 그러나 모델이 복잡해질수록 해석 및 계산이 어려워지는 딜레마가 발생한다. 따라서 모델링 단계에서는 현실의 중요한 요인을 최대한 반영하면서도, 문제의 해석과 계산이 가능하도록 적절한 수준의 단순화를 해야 한다.

특정 미분방정식으로 현상을 기술할 때, 실제로는 존재하는 마찰, 온도 변화, 변형 등 다양한 요인이 누락되는 경우가 많다. 예를 들어 질량-스프링-댐퍼 계에서 스프링 비선형성이나 댐퍼의 온도 의존성이 무시되었다면, 그에 대한 차이가 모델 오차로 나타난다. 또한 연속체를 이산화(discretization)하여 유한 차원 공간에서 모델링하는 행위 자체도 거시적으로 보았을 때는 모델 오차의 한 형태로 간주할 수 있다.

모델 오차를 최소화하려면 물리적 근거가 타당하고, 해석적으로도 복잡도가 감당 가능하며, 계산적으로도 비용이 과도하게 들지 않는 수준에서 모델을 세워야 한다. 모델링 과정에서 등장하는 차원 축소나 변수 변경, 비선형 항의 선형화, 경계조건 혹은 초기조건의 단순화 등은 모두 모델 오차를 발생시킬 수 있는 주요 원인이므로, 수치해석자는 이 점을 면밀히 검토해야 한다.

모델 오차를 정량적으로 평가하기 위해서는, 한편으로는 충분히 정확하다고 판단되는 ‘기준 모델’ 혹은 실험 결과를 가지고 비교하는 방식이 자주 활용된다. 예를 들어, $f(\mathbf{x},t)$로 나타낸 어떤 동역학계에 대해 실제 관찰값 $\mathbf{x}*{\text{obs}}(t)$가 주어진 상황에서, 수학적 모델로부터의 해 $\mathbf{x}*{\text{model}}(t)$와의 차이를 비교함으로써 모델 오차를 대략적으로 추정한다. 이때 특정 시점 $t\_k$에서의 모델 오차를 다음과 같이 정의하기도 한다.

$$
\Delta\_{\text{model}}(t\_k) = |\mathbf{x}*{\text{obs}}(t\_k) - \mathbf{x}*{\text{model}}(t\_k)|
$$

여기서 $|\cdot|$는 적당한 벡터 노름으로, 예컨대 유클리드 노름이나 최대 노름 등을 쓸 수 있다. 만약 모델링 과정에서 사용한 가정이 관찰값과 크게 어긋난다면, $\Delta\_{\text{model}}(t\_k)$의 값이 전 구간에 걸쳐 매우 크게 나타날 것이다.

모델 오차가 적당히 작은 수준이라면, 이 모델을 사용하여 해석과 계산을 진행해도 유효한 해를 얻을 수 있다고 간주한다. 모델 오차가 지나치게 커서 현상을 설명하기에 부족하다면, 모델 자체를 수정하거나 추가적인 물리 인자를 고려해야 한다. 결국 모델 오차를 적절히 관리하는 것이 수치해석에서 매우 중요한 전 단계로 인식된다.

#### 해석 오차

실제 문제를 풀기 위해서는 모델에 대응하는 수학적 표현(미분방정식, 적분방정식 등)을 다양한 방법으로 풀어야 한다. 해석 오차는 문제에 대한 해를 구하는 과정에서 일어나는 근사로 인해 발생하는 오차를 의미한다. 예를 들어, 미분방정식의 해를 구하기 위해 수치적 방법(오일러 방법, 룬게-쿠타 방법 등)을 적용하면, 유한 차원의 점들에서만 해를 구하므로 연속해와의 차이가 생긴다.

고전적으로 미분방정식을 푸는 과정에서 테일러 전개를 활용하거나, 전산적으로 격자를 생성한 뒤 유한차분법, 유한요소법, 유한체적법 등을 사용하여 해를 구하면, 각 방법이 갖는 고유한 근사가 들어가게 된다. 예를 들어, $t$축을 간격 $h$로 나누어 오일러 전진법으로 1차 근사를 하면, 해석 오차는 대개 $O(h)$ 정도로 나타난다. 조금 더 정밀한 룬게-쿠타 4차 방법을 사용하면, 보통 $O(h^4)$의 정확도를 기대할 수 있다.

계산 과정에서 발생하는 해석 오차를 일반적으로 척도화하는 방법 중 하나로 잔여(residual) 개념을 든다. 만약 어떤 시점 $t\_k$에서 유한 차분 스킴이 정확히 미분방정식을 만족하지 못한다면, 다음과 같은 잔여항 $R(t\_k)$를 정의할 수 있다.

$$
R(t\_k) = \mathbf{x}\_{n+1} - \mathbf{x}\_n - h,\mathbf{f}\bigl(\mathbf{x}\_n,t\_n\bigr)
$$

실제 연속 미분방정식에서는 $\mathbf{x}'(t\_n) = \mathbf{f}(\mathbf{x}(t\_n), t\_n)$가 정확히 성립해야 하지만, 유한 차분 스킴에서는 근사 과정으로 인해 남는 차이가 바로 $R(t\_k)$이다. 이 잔여가 누적되면 결국 해석 오차로 이어진다. 해석 오차는 보통 단계 크기 $h$나 격자 간격 등에 의해 주도되므로, 이를 조절함으로써 오차를 줄일 수 있다. 그러나 $h$가 너무 작아지면 계산량이 과도하게 늘어나므로, 현실적인 범위 안에서 최적의 균형을 찾는 것이 중요하다.

연속 문제를 해석적으로 풀이하여 폐형 해(closed-form solution)를 얻을 수 있다면 해석 오차가 0이 될 수도 있다. 그러나 실제 복잡한 문제는 대부분 폐형 해가 존재하지 않거나, 존재하더라도 그것을 구하는 과정이 지나치게 복잡하다. 따라서 수치근사를 통해 해를 얻게 되고, 그에 따른 해석 오차가 불가피하게 발생한다. 모델 오차가 일정 수준 이하라고 가정했을 때, 해석 오차는 다양한 수치 알고리즘의 정확도와 병렬 처리나 적응격자(adaptive mesh) 기법 등을 활용하여 어느 정도 관리할 수 있다.

#### 계산 오차

수치해석에서 가장 익숙하게 다루는 오차 중 하나가 계산 오차이다. 이는 컴퓨터로 실수를 표현할 때 사용하는 부동소수점(Floating-Point) 체계에서 기인한다. 컴퓨터는 실수를 한정된 유효숫자 내에서 근사하여 표현하므로, 실제 실수 연산과는 미세한 차이가 생긴다. 이러한 차이가 누적되거나 특정 연산 순서에 의해 극적으로 증폭될 수 있는데, 이를 계산 오차라고 부른다.

계산 오차는 크게 반올림 오차(round-off error)와 자름 오차(truncation error)로 나눌 수 있다. 반올림 오차는 컴퓨터가 내부적으로 실수를 이진 부동소수점 형태로 표현하는 과정에서 발생한다. 예를 들어 0.1과 같은 십진수를 이진 부동소수점으로 표현하면 정확히 0.1이 아니라 근사값이 저장된다. 이런 미세한 오차가 여러 번의 연산을 거쳐 누적되면 예기치 못한 계산 결과를 낳을 수 있다.

특정 연산 순서에 따라 반올림 오차가 달라지는 현상도 유명하다. 예를 들어 큰 수와 작은 수를 더할 때, 작은 수의 유효숫자가 대부분 손실될 수 있다. 이를 방지하기 위해서는 연산 순서를 바꾸어 상대적으로 비슷한 크기의 수들을 먼저 더하도록 하는 알고리즘적 기법을 고려할 수 있다. 고차원 선형연산이나 행렬연산에서 특히 이러한 반올림 오차 관리가 중요하다.

자름 오차는 어떤 특정 자리수 이후의 값을 잘라서(혹은 버림/내림) 연산하는 과정에서 생기는 오차다. 예를 들어 소수점 이하 세 자리까지만 저장하는 방식을 생각해보면, 실제 값과는 최대 $10^{-3}$의 차이가 항상 있을 수 있다. IEEE 표준 부동소수점(예: IEEE 754)에서는 유효숫자와 지수 범위를 정하여 실수를 표현하기 때문에, 매우 큰 수나 매우 작은 수를 다룰 때 언더플로(underflow) 혹은 오버플로(overflow)가 발생하기도 한다.

아래는 Python 예시 코드에서 부동소수점 연산 오차를 간단히 살펴볼 수 있는 예다.

```python
a = 0.1
b = 3.0
c = a * b
print(c)  # 0.30000000000000004
```

실제 계산 결과는 0.3이 아니라 0.30000000000000004와 같이 출력된다. 이처럼 내부 표현에서 비롯한 작은 차이가 곧 계산 오차가 된다. 일정 수준 이하라면 문제되지 않을 수 있지만, 이 오차가 반복 계산을 통해 누적되거나, 민감한 해(ill-conditioned problem)를 구할 때에는 해석 오차와 동등하게 중요한 영향을 미친다.

행렬연산 예시로, 큰 조건수(condition number)를 가진 행렬의 역행렬을 구하거나, 연립방정식을 푸는 과정에서 반올림 오차가 크게 증폭될 수 있다. 예컨대 $n \times n$ 크기의 행렬 $\mathbf{A}$의 $\kappa(\mathbf{A})$가 매우 크다면, $\mathbf{A}^{-1}$ 계산 시 컴퓨터 내부 부동소수점 한계로 인해 심각한 오차가 발생하기 쉽다.

#### 해석 오차와 계산 오차의 종합적 고찰

해석 오차와 계산 오차는 서로 독립적으로 존재하기보다는 실제 계산 과정에서 상호 작용하는 경우가 많다. 예를 들어, 어떤 수치적 스킴이 높은 정밀도를 갖더라도, 내부적으로 반올림 오차가 크게 발생하여 결과적으로 전체 오차가 크게 나타날 수 있다. 반대로 반올림 오차가 상대적으로 작아도, 해석 자체가 저차 근사를 사용하면 해석 오차가 지배적이 되어 결과가 부정확해질 수 있다.

해석 오차가 주로 격자나 시간 단계 같은 매개변수(예: $h$)에 의해 조절될 수 있다면, 계산 오차는 컴퓨터 하드웨어나 소프트웨어의 부동소수점 표현 방식에 크게 좌우된다. 해석 오차가 줄어들도록 $h \to 0$으로 세분화하면, 계산 단계가 많아지고 반올림 오차가 누적될 가능성이 커진다. 따라서 적절한 $h$의 선택, 수치 알고리즘의 조건수, 알고리즘 안정성(stability) 분석 등이 종합적으로 이루어져야 한다.

#### 절대 오차와 상대 오차

수치해석에서 오차를 측정할 때 절대 오차(absolute error)와 상대 오차(relative error)가 자주 쓰인다. 어떤 참값 $x\_{\text{true}}$와 근사값 $x\_{\text{approx}}$가 주어졌다고 하자. 이때 절대 오차는

$$
\bigl|x\_{\text{true}} - x\_{\text{approx}}\bigr|
$$

로 정의되며, 상대 오차는

$$
\frac{\bigl|x\_{\text{true}} - x\_{\text{approx}}\bigr|}{\bigl|x\_{\text{true}}\bigr|}
$$

로 정의된다(단, $x\_{\text{true}} \neq 0$). 상대 오차는 참값을 기준으로 한 편차의 크기를 보여주므로, 매우 작은 값이나 매우 큰 값에 대한 오차 해석 시에 유용하다. 예를 들어, 아주 작은 값의 계산에서 $10^{-8}$ 정도의 절대 오차는 상대적으로 엄청난 오차가 될 수도 있고, 반대로 큰 값에서는 무시해도 될 수준일 수 있다.

상대 오차가 중요한 이유는, 계산 알고리즘이 다루는 수의 크기에 따라 반올림 오차가 상대적으로 달라질 수 있기 때문이다. 실제로 부동소수점 체계에서는 수의 크기에 따라 가용한 유효숫자가 일정하지 않으므로, 큰 값에서의 작은 변화가 반올림 과정에서 사라질 위험이 있다. 반면 작은 수에서는 몇 자릿수만 남아도 전체 값이 크게 달라지므로, 상대 오차가 빠르게 커질 수 있다.

#### 전진 오차(Forward Error)와 후진 오차(Backward Error)

수치해석에서 해나 매개변수의 작은 변화에 대한 민감도를 분석할 때, 전진 오차와 후진 오차 개념이 자주 사용된다. 전진 오차는 단순히 “계산된 해와 참해 사이의 차이”를 가리킨다. 예를 들어, 어떤 함수 $f(\mathbf{x}) = \mathbf{y}$에 대해 문제를 풀 때 구한 근사해 $\mathbf{x}\_{\text{approx}}$가 있을 경우, 전진 오차는

$$
|\mathbf{x}*{\text{true}} - \mathbf{x}*{\text{approx}}|
$$

와 같이 나타낼 수 있다. 여기서 $|\cdot|$는 특정 벡터 노름이며, $\mathbf{x}\_{\text{true}}$는 실제 해(이론적으로 혹은 높은 정밀도로 계산된 참값)라고 가정한다.

반면 후진 오차는 “계산된 해가 정확한 해가 되도록 하는 문제(조금 다른 문제)의 오차”를 의미한다. 예컨대, 연립선형방정식 $\mathbf{A}\mathbf{x} = \mathbf{b}$를 푸는 과정에서 근사해 $\mathbf{x}\_{\text{approx}}$가 나왔을 때,

$$
\mathbf{r} = \mathbf{b} - \mathbf{A}\mathbf{x}\_{\text{approx}}
$$

가 0이 아니면, $\mathbf{x}\_{\text{approx}}$는 엄밀히 $\mathbf{A}\mathbf{x} = \mathbf{b}$의 해가 아니다. 하지만 다음과 같이 약간 수정된 문제

$$
(\mathbf{A} + \Delta \mathbf{A}),\mathbf{x}\_{\text{approx}} = \mathbf{b} + \Delta \mathbf{b}
$$

의 정확한 해로 해석할 수 있다면, 이 문제에 대한 후진 오차는 $\Delta \mathbf{A}$나 $\Delta \mathbf{b}$의 크기로 측정된다. 즉, 근사해가 원래 문제는 아니더라도 “거의 비슷한 문제”에 대해서는 정확한 해가 될 수 있으며, 이때 “거의 비슷한 문제”로부터의 오차가 후진 오차로 해석된다. 후진 오차가 작다는 것은 “원래 문제에서 큰 변형을 일으키지 않아도 계산된 해가 정확해지도록 만들 수 있다”는 의미이므로, 수치 알고리즘의 안정성(Stability)과 직결된다.

#### 조건수(Condition Number)

수치선형대수학이나 비선형 최적화 등을 비롯한 다양한 분야에서, 문제의 민감도를 나타내는 지표로 조건수(condition number)가 사용된다. 조건수는 해가 입력(문제의 계수나 초기조건 등)의 작은 변화에 얼마나 민감하게 반응하는지를 정량적으로 보여주는 척도다.

예를 들어, 연립선형방정식 $\mathbf{A}\mathbf{x} = \mathbf{b}$에서 행렬 $\mathbf{A}$의 조건수 $\kappa(\mathbf{A})$는 다음과 같이 정의된다.

$$
\kappa(\mathbf{A}) = |\mathbf{A}| ,|\mathbf{A}^{-1}|
$$

여기서 $|\cdot|$는 벡터나 행렬에 대한 어떤 하위 호환되는 노름(subordinate norm)이다(예: 1-노름, 무한 노름, 2-노름 등). 만약 $\kappa(\mathbf{A})$가 매우 크다면, $\mathbf{A}$의 작은 변화가 해 $\mathbf{x}$에 큰 변화를 야기할 수 있다는 의미이며, 반올림 오차나 다른 오류가 쉽게 증폭될 가능성이 높다. 이를 ‘ill-conditioned’하다고 부르며, 수치적 알고리즘 측면에서 까다로운 문제를 의미한다.

조건수가 큰 문제를 풀 때에는 단순한 가우스 소거(Gaussian elimination)나 역행렬을 직접 구하는 방식만으로는 만족스러운 정확도를 얻기 어렵다. 정규방정식(normal equation)이나 QR 분해, SVD 분해 등의 기법, 혹은 사전조건자(preconditioner) 기법 등을 통해 문제를 재구성함으로써 실질적인 조건수를 낮출 수 있다. 이는 모델 오차, 해석 오차, 계산 오차 중 특히 계산 오차(반올림 오차)의 증폭을 억제하는 데 효과적이다.

#### 안정성(Stability)과 수치 알고리즘의 설계

수치 알고리즘은 정밀도가 높은 연산 체계 위에서라면 이론적으로 매우 정확한 결과를 낼 수 있어야 한다. 그러나 실제 컴퓨터에서 제한된 유효숫자를 사용함에 따라, 알고리즘 자체가 반올림 오차를 증폭하는 방향으로 설계되어 있으면 결과가 급격히 나빠질 수 있다. 이를 방지하기 위해서는 알고리즘이 안정적(stable)이어야 하며, 보통은 후진 안정성(backward stability)을 가진 알고리즘이 선호된다.

후진 안정성은 “알고리즘이 구한 해는, 원래 문제와 매우 가까운 (미세하게 수정된) 문제에 대한 정확한 해”임을 의미한다. 예를 들어, 고전적인 LU 분해에 피보팅(pivoting) 전략을 더한 가우스 소거법은 일반적으로 후진 안정성을 만족하는 것으로 알려져 있다. 반면, 조건수가 큰 문제에서는 피보팅을 해도 증폭되는 오차가 커서 결과가 크게 흔들릴 수 있다.

연립방정식을 비롯한 다양한 계산 문제에서 후진 안정성을 만족하는 알고리즘을 찾는 것이 주요 관심사다. 예를 들어, 다항식 근 찾기(polynomial root finding), 고윳값(eigenvalue) 계산, FFT(Fast Fourier Transform) 연산 등에서도 뒤에서부터 문제를 살짝 변형시켜도 괜찮을 정도의 안정성을 갖는 방법이 연구되고 있다.

#### 복합 예시: 모델·해석·계산 오차의 결합

물리 모델을 세워 이를 이산화(discretization)한 뒤, 유한차분법 등으로 근사 해를 구하고, 컴퓨터로 연산하는 상황을 생각해 보면, 세 종류의 오차가 차례차례 혹은 동시에 영향을 미친다.

가령, 열전도방정식을 2차원 영역에서 해석할 때, 열전달 계수가 실제와 다르게 설정되어 있다면 모델 오차가 발생한다. 거기에다 시간축과 공간격자를 유한하게 나누는 과정에서 해석 오차가 발생하며, 한 스텝 한 스텝 계산할 때마다 컴퓨터 내부에서 부동소수점 반올림 및 자름 오차가 누적된다. 최종적으로 얻는 해가 실제 물리 현상과 다를 때, 단순히 격자를 세분화해서 해석 오차를 줄이는 것만으로는 한계가 있을 수 있다. 물리 모델 자체가 부정확하거나, 계산 오차가 특정 구간에서 폭발적으로 증폭되면, 결국 원하는 정확도를 얻지 못한다.

이런 복합적 측면을 이해하고, 문제의 전체 파이프라인(모델링 → 수치적 근사 → 계산 알고리즘 → 하드웨어 구현)에 걸쳐서 오차를 추적하고 관리하는 과정이 수치해석의 핵심이다. 모델 오차가 허용 범위를 넘어서는지, 해석 오차가 안정적으로 수렴할 수 있는지, 계산 오차가 어느 정도인지, 그리고 이들 간에 상호 증폭 요인이 있는지 세심하게 고려해야 한다.

#### 오차 전파(Error Propagation)와 민감도(Sensitivity)

오차는 한 단계에서 발생한 뒤 소멸되지 않고, 이후 계산 단계에서 증폭되거나 다른 형태로 전달될 수 있다. 이를 오차 전파라고 한다. 한편, 어떤 함수나 알고리즘이 입력의 작은 변동에 대해 출력이 얼마나 크게 변동하는지를 민감도 혹은 감도(Sensitivity)라고 한다. 두 개념은 서로 밀접하게 연관된다. 민감도가 높으면, 모델 오차나 해석 오차, 계산 오차 중 하나라도 입력 단계에서 조금만 발생해도 최종 결과가 크게 변할 가능성이 있다.

예를 들어, 함수 $y=f(x)$에서 $x$가 소량 $\Delta x$만큼 변할 때 $y$가 $\Delta y$만큼 변한다고 하자. 1차 근사로,

$$
\Delta y \approx f'(x) ,\Delta x
$$

가 성립한다. 만약 $|f'(x)|$가 매우 크다면, $\Delta x$가 작은 값이더라도 $\Delta y$가 크게 발생한다. 이 현상은 다변수 벡터 함수 $\mathbf{y} = \mathbf{f}(\mathbf{x})$에서도 야기되는데, 이 경우 야코비(Jacobian) 혹은 미분(gradient) 연산자가 큰 노름 값을 갖는다면, 입력의 작은 변화가 출력의 큰 변화를 일으키는 민감한 함수로 간주할 수 있다. 이런 민감성이 바로 오차 전파의 토대가 된다.

#### 직접 전파(Forward Propagation)와 역전파(Backward Propagation)

오차 전파는 일반적으로 두 가지 방식으로 살펴볼 수 있다. 하나는 입력 쪽에 존재하는 오차가 순차적으로 계산 과정(알고리즘의 순방향 단계를 따라) 출력으로 번지는 현상을 추적하는 직접 전파(forward propagation)다. 다른 하나는 계산 결과가 주어졌을 때 이 결과를 만들기 위해 입력값이 어찌 바뀌었을지 추정하는 역전파(backward propagation) 방식이다.

이전 장에서 언급한 전진 오차와 후진 오차 개념도 이러한 관점에서 연결된다. 전진 오차는 입력(혹은 참해) 대비 출력(근사해)의 차이를 곧장 살피므로 직접 전파적 시각에 가깝다. 후진 오차는 “계산 결과가 정확해지도록 원래 문제를 조금 뒤에서 변형해야 한다”는 식의 사고방식을 취하므로, 역전파적인 시각과 관련이 깊다.

수치알고리즘을 설계할 때, 후진 안정성을 만족하는 방법은 대체로 “역전파” 관점에서 문제의 민감도를 줄이도록 구성된다. 예컨대, 어떤 방법이 후진 안정성을 갖는다면, 실제로 발생한 반올림 오차나 근사 오차를 문제의 계수나 조건에 미세하게 반영시키는 형태로 해석해도 무리가 없을 만큼, 계산 과정이 극도로 왜곡되지 않는다는 의미가 된다.

#### 예시: 수치 적분에서의 오차 전파

연속함수 $f(x)$를 구간 $\[a,b]$에서 적분한다고 하자. 가령 구간 분할을 통해 단순한 사다리꼴법(Trapezoidal rule)으로 적분하는 경우를 생각해 보자.

$$
\int\_{a}^{b} f(x),dx \approx \sum\_{k=0}^{N-1} \frac{h}{2}\bigl{ f(x\_k) + f(x\_{k+1}) \bigr}
$$

여기서 $x\_k = a + k,h$이고, $N,h = b-a$이다. 이 근사식에서 해석 오차는 사다리꼴 공식의 이론적 오차항(주로 $O(h^2)$로 알려짐)으로 구성된다. 그런데 만약 $f(x\_k)$ 값을 계산하는 과정에서 부동소수점 반올림이 발생한다면, 각 항마다 미세한 계산 오차가 포함된다. 그러면 이 오차가 $N$개 항을 모두 합산하면서 누적된다.

특히 $N$이 커질수록 해석 오차(격자 분할 오차)는 줄어들 수도 있지만, 그와 동시에 계산 횟수가 많아지면서 계산 오차(반올림 오차)가 누적되어 전파될 위험이 커진다. 예를 들어 $h \to 0$로 갈수록 이론적으로 해석 오차는 줄어들겠지만, 실제 컴퓨터에서 무한정 작게 만들 수는 없다. 매우 미세한 $h$를 택하면 각 단계마다 발생하는 반올림 오차가 누적되어 전체 오차가 오히려 커질 수 있다. 이를 “오차 최소화의 최적 지점”이라고 하며, 이 지점을 찾기 위해서는 해석 오차와 계산 오차의 균형을 고려해야 한다.

#### 병렬 처리(Parallel Computing)와 오차

현대의 고성능 계산(HPC) 환경에서는 연립방정식, 적분, 미분방정식 풀기 등을 병렬로 수행하는 경우가 많다. 이때 각 프로세서에서 독립적으로 계산한 결과를 합산하거나, 반복 과정에서 값을 교환하게 되는데, 연산 순서가 달라지면 부동소수점 반올림 결과도 달라질 수 있다. 특히 큰 규모의 선형 연산(예: 벡터 합)에서 덧셈 순서만 바꿔도 계산 오차가 다르게 누적된다.

가령 $\mathbf{x}$와 $\mathbf{y}$가 매우 큰 차원을 갖는 벡터이고, 이들의 스칼라 곱(inner product) $\mathbf{x}^T \mathbf{y}$를 여러 스레드에서 나누어 계산한 뒤 최종적으로 합치는 경우를 가정하자. 어떤 스레드는 $\mathbf{x}$의 앞쪽 절반, 다른 스레드는 뒤쪽 절반을 맡아 부분합을 계산한 후, 최종적으로 이 부분합들을 더하면 순차 계산과는 다른 반올림 경로가 만들어진다. 이는 전형적인 병렬 환경에서의 비결정성(nondeterminism) 문제로, 결과의 재현성(reproducibility)에 영향을 준다.

이런 특성은 해석 오차와는 직접 관련이 없지만, 계산 오차의 전파와 증폭에 큰 영향을 미친다. 대규모 선형대수 연산이나 미분방정식 해석에서 병렬 알고리즘을 사용할 때에는, 연산 순서를 적절히 설계하거나, Kahan 보정 알고리즘(Kahan summation) 같은 기법을 적용하여 반올림 오차 누적을 줄일 수 있다.

#### 예제: Python에서 대규모 벡터 합

아래 코드는 Python에서 큰 벡터를 만들어 합산하는 예시다. 벡터의 원소를 무작위로 생성하고, 두 가지 방식(순차 합산과 분할 합산)으로 더한 결과의 차이를 관찰할 수 있다.

```python
import numpy as np

N = 10_000_000
np.random.seed(0)

# 무작위 벡터
x = np.random.rand(N)

# 순차 합산
sum_sequential = 0.0
for val in x:
    sum_sequential += val

# 분할 합산 (대략 반씩)
sum_first_half = np.sum(x[:N//2])
sum_second_half = np.sum(x[N//2:])
sum_parallel_style = sum_first_half + sum_second_half

print(f"Sequential sum: {sum_sequential}")
print(f\"Parallel-style sum: {sum_parallel_style}\")
print(f\"Difference: {abs(sum_sequential - sum_parallel_style)}\")
```

실행할 때마다 무작위 시드 혹은 배열 크기를 달리 설정하면, 두 합 사이에 미세한 차이가 발생하기도 한다. 수치적 안정성과 관련된 엄밀한 계산에서는 이러한 차이가 큰 비중을 차지할 수 있다.

#### mermaid를 이용한 오차 전파 시각화

{% @mermaid/diagram content="flowchart LR
A((입력값)) --> B\[계산 알고리즘]
B --> C((출력값))
B --> D((오차 누적))
D --> C" %}

이 단순화된 흐름도는 입력값에서 시작해 어떤 알고리즘을 거쳐 출력값을 구하는 동시에, 내부에서 발생하는 오차가 계속 누적되어 최종 결과에 영향을 주는 과정을 시각화한다. 실제 수치 알고리즘에서는 모델 오차, 해석 오차, 계산 오차가 뒤섞여 매우 복잡한 양상을 띠지만, 전반적 개념은 위와 같이 정리할 수 있다.

#### 오차 제어(Error Control)와 적응 기법(Adaptive Methods)

수치해석에서 효율적이고 정확한 해를 얻기 위해서는, 모델 오차·해석 오차·계산 오차가 얼마나 발생하는지를 추적하고 제어하는 체계가 필요하다. 특히 해석 오차와 계산 오차는 문제의 규모와 특성에 따라 동적으로 바뀔 수 있으므로, 적응 기법(adaptive methods)을 도입하는 경우가 많다. 예를 들어 미분방정식을 풀 때, 고정된 시간 간격 $h$로 진행하는 대신, 국소적(local) 오차가 특정 기준보다 크면 $h$를 줄이고, 그렇지 않으면 $h$를 늘리는 식으로 자동 조절을 시도한다.

적분 혹은 미분방정식 문제에서 적응 기법을 사용하는 전형적인 예는 ‘적응형 룬게-쿠타(Adaptive Runge-Kutta, ARK)’ 방법이다. 이 기법은 각 스텝에서 저차(예: 4차)와 고차(예: 5차)의 두 해를 동시에 구한 뒤, 둘의 차이를 근사 오차로 추정한다. 이 오차가 기준치보다 크면 스텝을 다시 줄여 계산을 반복하고, 기준치 이하라면 스텝 크기를 키워서 계산 효율을 높인다. 이때 오차는 주로 해석 오차에 해당하지만, 스텝을 지나치게 세분화하면 계산 오차(반올림 누적)가 커질 수 있으므로, 실제 구현에서는 계산 오차도 함께 고려한다.

비슷하게 유한요소법(Finite Element Method, FEM)에서의 적응 기법은 메쉬(mesh) 부화(refinement)나 재부화(coarsening)를 수행한다. 특정 요소(element) 내의 추정 오차가 크면 요소를 더 잘게 나누어 근사 정확도를 높이고, 오차가 작으면 상대적으로 요소를 합쳐서 계산량을 줄이는 식이다. 모델 오차가 허용 범위 내라면, 이런 적응적 해석 오차 관리가 큰 효과를 거둘 수 있다.

모델 오차가 지나치게 커서 수치적으로 아무리 정교한 근사를 해도 물리적 현상을 잘못 반영한다면, 궁극적으로 얻어지는 해에 대한 신뢰도가 낮아진다. 따라서 ‘오차 제어’라는 관점에서 본다면, 먼저 모델링 단계에서 중요한 요인을 빠뜨리지 않았는지를 검증하는 과정이 필수적이다. 그 뒤 해석 오차를 제어하기 위해 적절한 시간 간격, 공간 격자 크기, 근사 차수 등을 선택하고, 계산 오차가 임계값 이상 누적되지 않도록 알고리즘의 안정성과 조건수를 관리하는 것이 기본이다.

#### 다중 스케일(Multiscale) 문제에서의 오차 관리

물리 혹은 공학적 현상 중에는 여러 길이 스케일(예: 나노 \~ 매크로)이나 시간 스케일(초 \~ 년)을 동시에 포함하는 다중 스케일(multiscale) 문제가 존재한다. 이를 모델링할 때에는 보통 여러 단계의 근사와 축소 기법이 들어가므로, 모델 오차가 다단계에 걸쳐서 발생한다. 예를 들어, 양자역학적 스케일에서 나오는 현상을 상위 스케일(연속체 역학)으로 전달하는 과정에서 상당한 근사를 적용할 수밖에 없다. 이렇게 되면 초기부터 모델 오차가 누적되고, 그 이후 수치 알고리즘으로 해를 구하면서 해석 오차·계산 오차까지 더해진다.

다중 스케일 문제에서 해석 오차를 관리하기 위해, 문제를 연계하는 인터페이스(경계면) 부근에서 세밀한 해석을 수행하고, 나머지 영역에서는 단순화된 해석을 적용하는 적응형 다중 스케일 기법이 사용된다. 예컨대 유한요소법과 분자역학(Molecular Dynamics)을 혼합한 결합 모델(bridging scale model)에서는, 원자 수준 계산이 필수적인 소영역에만 분자역학을 적용하고, 그 외 영역에는 탄성연속체 모델을 활용한다. 이때 서로 다른 모형 간 인터페이스에서 발생하는 불연속성이나 과도한 근사로 인한 모델 오차가 고려되어야 한다.

모델 오차가 과도하면, 수치적으로 아무리 정교하게 계산해도 해석의 의미가 희석된다. 반대로 모델 오차를 줄이기 위해 모든 스케일을 동시에 풀어내려 하면, 계산비용이 기하급수적으로 늘어나 해석 자체가 불가능해질 수 있다. 따라서 다중 스케일 문제에서는 물리적 메커니즘의 우선순위를 파악하고, 반드시 필요한 스케일만 세밀하게 모델링하되, 계산 관점에서도 적절한 해석 오차와 계산 오차가 상호 균형을 이루도록 해야 한다.

#### 확률적(Probabilistic) 해석과 오차

여러 실증적 현상에서는 측정 오차나 불확실성(uncertainty)이 존재하므로, 확률론적 접근을 통해 모델과 해석, 계산 과정을 평가하는 방법이 대두된다. 확률적 해석에서는 모델 입력(초기조건, 매개변수 등)을 확률 분포로 표현하고, 수치계산 결과의 분포(평균, 분산 등)를 구한다. 이를 통해 해가 어떤 범위 내에서 오차나 변동을 가질 확률이 얼마나 되는지를 추정한다.

확률적 해석에서 말하는 오차는 ‘불확정성(UQ, Uncertainty Quantification)’과 밀접한 관련이 있다. 측정값에 원래 노이즈가 있거나, 모델 파라미터에 대한 정보가 불완전할 수 있다. 이는 전통적인 결정론적(deterministic) 모델 오차와는 구별되는 개념이지만, 결국 모델의 불확실성이 오차의 한 형태로 작용한다. 또한 수치적으로는 몬테카를로(Monte Carlo) 시뮬레이션, 폴리 혼합법(Polynomial Chaos Expansion, PCE) 같은 기법을 통해 확률적 해석을 수행할 때, 해석 오차와 계산 오차 역시 중첩되어 나타난다.

결국 실제 문제에서의 ‘오차’는 단순히 결정론적 알고리즘 정확도뿐 아니라, 입력이나 환경의 무작위성으로 인한 불확정성을 포함한다. 이는 모델 오차, 해석 오차, 계산 오차가 확률적 프레임워크 안에서 함께 다루어져야 함을 의미한다.

#### 복잡한 현상의 예시: 난류(Turbulence) 해석

유체역학에서의 난류(turbulence) 해석은 모델·해석·계산 오차가 복합적으로 작용하는 대표 사례다. 난류는 시간적·공간적으로 매우 빠르고 불규칙한 변화를 보이므로, 완전한 모델을 구축하기가 극도로 어렵다. 실험적으로도 정확한 데이터 확보가 어려우며, 난류 모형(turbulence model)은 다양한 근사 기법(RANS, LES, DNS 등)에 따라 복잡도가 크게 달라진다.

DNS(Direct Numerical Simulation)는 나보-스톡스 방정식을 격자를 매우 세밀하게 하여 직접 풀어내는 방법이지만, 필요한 격자 수와 계산량이 막대하다. 이는 해석 오차를 최소화할 수 있는 이상적인 접근이지만, 현실적으로 대형 레이놀즈 수(Reynolds number) 상황에서는 불가능에 가깝다. LES(Large Eddy Simulation)는 큰 와류(에디)에 대해서만 직접 계산하고, 작은 스케일은 모델링으로 처리하는 방법이다. 이는 모델 오차와 해석 오차 사이의 절충점이다. RANS(Reynolds-Averaged Navier–Stokes)는 더 거칠게 평균화하여 모델에 의존도가 높으므로, 모델 오차가 상당히 클 수 있다.

계산 오차 측면에서도, 난류 해석은 고차 스키마(numerical scheme)를 사용하여 에너지 보존이나 안정성을 유지해야 한다. 순차적·반복적 계산 단계에서 반올림 오차가 축적되면 물리적 현상과 무관한 인공적 발산(numerical blow-up)이나 수치 진동(numerical oscillation)이 나타날 수 있다. 따라서 난류 해석에서 단순히 해석 오차를 낮추기 위해 격자 크기를 한없이 줄이기보다는, 하드웨어와 알고리즘이 감당 가능한 범위 내에서 최적의 조건을 찾으려는 노력이 동반된다.

#### 종합

이처럼 모델 오차·해석 오차·계산 오차는 다양한 맥락에서 상호 작용하며, 문제의 규모와 성격에 따라 서로 다른 양상으로 나타난다. 실제 공학이나 과학 계산에서는 세 종류의 오차를 구분하여 이해하되, 동시에 통합적으로 관리하는 전략이 필요하다. 모델링 단계에서 물리적·수학적 근거가 충분한지, 해석 단계에서 적절한 근사 수준과 격자·시간 분할 스킴을 선택했는지, 계산 단계에서 반올림 오차와 자름 오차가 과도하게 누적되지 않는지 등을 전반적으로 살펴보아야 한다.
