# 잔차(Residual) 분석과 알고리즘 성능 평가지표

잔차는 근사해를 얻은 뒤에 실제 문제에서 요구되는 해와 얼마나 차이가 있는지를 측정하는 중요한 도구로 여겨진다. 특히 선형대수학적 문제에서 시스템이 $A \mathbf{x} = \mathbf{b}$로 주어졌을 때, 어떤 알고리즘을 통해 구한 근사해를 $\mathbf{\hat{x}}$라 하면 잔차 벡터 $\mathbf{r}$는 $\mathbf{r} = \mathbf{b} - A \mathbf{\hat{x}}$로 정의된다. 이때 $\mathbf{\hat{x}}$가 실제 해 $\mathbf{x}$와 얼마나 근접한지 직접적으로 파악하기는 어렵지만, 적어도 주어진 시스템을 어느 정도 만족시키는지(즉 $A \mathbf{\hat{x}} \approx \mathbf{b}$인지)를 잔차의 크기를 통해 간접적으로 평가할 수 있다. 따라서 잔차가 작을수록 $\mathbf{\hat{x}}$가 해당 문제에 대한 좋은 근사해일 가능성이 높다고 본다. 다만 잔차가 작은 것이 곧바로 실제 오차 $\mathbf{x} - \mathbf{\hat{x}}$가 작음을 의미하지는 않는다. 수치해석에서는 이 둘을 구별하기 위하여 전방오차(forward error), 후방오차(backward error) 등의 개념을 활용하고, 잔차 분석은 이 중에서 후방오차 개념과 밀접한 관련이 있다.

잔차는 다양한 방식으로 측정할 수 있다. 가장 흔히 사용하는 방법은 벡터 노름을 이용하는 것으로, 예를 들어 2-노름에서 잔차의 크기는 $|\mathbf{r}|\_2 = |\mathbf{b} - A \mathbf{\hat{x}}|\_2$로 계산된다. 더 나아가 실제 문제에서 해석적으로 중요한 관점은 상대 잔차(relative residual)인데, 이는 문제의 스케일을 고려하기 위해 잔차를 $|\mathbf{b}|\_2$와 비교하는 개념이다. 가령 상대 잔차를

$$
\frac{|\mathbf{b} - A \mathbf{\hat{x}}|\_2}{|\mathbf{b}|\_2}
$$

와 같은 형태로 정의할 때, $\mathbf{b}$의 크기 대비 $\mathbf{r}$가 얼마나 작은지를 살펴볼 수 있다. 이러한 개념은 수치해석 알고리즘의 정밀도(accuracy)와 안정성(stability)을 평가할 때 매우 중요하다.

실제로 수치해석 문제에서 $\mathbf{b}$가 영 벡터와 가까운 경우라면 문제의 크기가 작기 때문에 소수점 몇 자리의 차이가 전체 해를 왜곡하는 정도가 크게 나타날 수 있다. 반면 $\mathbf{b}$가 매우 큰 값일 경우에는 같은 양의 잔차라도 상대적인 영향이 작을 수 있다. 그러므로 단순히 $|\mathbf{r}|$만 관찰하기보다는 문제의 실제 크기에 비례하는 방식으로 잔차를 평가하는 절차가 필수적이다. 이 과정을 통해서 어떤 알고리즘이 다양한 크기의 문제에 대해서도 일관된 오차 성능을 내는지, 혹은 특정 범위 내에서만 유독 좋은 성능을 보이는지를 분석할 수 있다.

잔차가 오차를 완벽히 대변해 주지 못하는 상황을 명확히 이해하려면 후방오차와 전방오차의 개념 차이를 짚고 넘어갈 필요가 있다. 전방오차는 실제 해 $\mathbf{x}$와 근사해 $\mathbf{\hat{x}}$의 차이 $\mathbf{x} - \mathbf{\hat{x}}$에 집중한다. 반면 후방오차는 "주어진 문제를 약간 변형해야만 근사해를 정확한 해로 만들 수 있는가"라는 관점에서 측정된 양으로서 잔차 벡터 자체가 후방오차 개념에 직결된다. 즉, 후방오차가 작다는 것은 문제를 크게 변경하지 않고서도 근사해가 해당 문제의 '정확한 해'로 간주될 수 있음을 의미한다. 이런 이유 때문에 잔차를 직접 모니터링하고 작아지도록 유도하는 전략을 잘 세우면, 알고리즘이 주어진 문제를 얼마나 잘 풀고 있는지(후방안정성) 진단하는 효과적인 척도가 될 수 있다.

수치해석 알고리즘의 성능 평가지표 중에는 단순히 잔차나 오차의 크기뿐 아니라 계산 복잡도, 메모리 사용량, 수렴 속도, 알고리즘의 안정성 등을 함께 고려한다. 특히 선형계 문제에서 반복법을 사용할 경우에는 매 반복마다 잔차가 어떻게 변화하는지, 특정 임곗값 이하로 잔차가 감소하는 데 필요한 반복 횟수가 얼마나 되는지를 중요하게 관찰한다. 반면 직접해법(direct method)의 경우에는 잔차를 단 한 번 구해보고, 계산 결과가 주어진 임계치 이상으로 큰 오차를 보이는지 여부를 판별하는 방식으로 알고리즘의 정확도를 측정하기도 한다. 문제의 성격과 사용자 요구에 따라 절대 오차 대신 잔차를 선택함으로써, 알고리즘의 실질적 효율성과 유용성을 더 직관적으로 파악하기도 한다.

정확도와 효율성 외에도 알고리즘의 안정성은 매우 중요한 평가지표로 간주된다. 수치적 안정성(Numerical stability)은 입력 데이터나 중간 계산 과정에서 발생하는 작은 오차가 최종 결과에 얼마나 크게 누적되어 나타나는지를 측정하는 기준이다. 예를 들어, 선형계 $A \mathbf{x} = \mathbf{b}$를 풀 때 $A$의 조건수(condition number)가 크면, 근사해 계산 시 발생하는 미소한 오차가 증폭될 가능성이 높아진다. 따라서 잔차 $\mathbf{r}$가 결코 작아지지 않고, 전방오차 $\mathbf{x} - \mathbf{\hat{x}}$가 불안정하게 커지기 쉬운 구조가 된다. 이런 맥락에서 알고리즘의 강건성(robustness)을 평가하기 위해서는 조건수와 더불어 잔차 분석이 함께 이뤄져야 한다.

아래는 간략히 잔차의 계산과 이를 활용한 알고리즘 성능 평가 과정을 순서도로 나타낸 예시이다

{% @mermaid/diagram content="flowchart LR
A\["초기 입력<br>(A, b)"] --> B\[근사해 계산<br>x^]
B --> C\[잔차 계산<br>r = b - A x^]
C --> D\[잔차 크기 측정]
D --> E\[알고리즘 성능 평가 및<br>개선 여부 판단]" %}

이 순서도에서 보이듯, 먼저 문제를 정의하고(행렬 A와 벡터 b), 적절한 알고리즘을 통해 근사해 x^를 구한 뒤, 잔차 r의 크기를 평가한다. 잔차가 요구하는 임계값 이하로 충분히 줄어들었다면 알고리즘이 만족할 만한 해를 주었다고 판단한다. 잔차가 크거나 계산 과정에서 수렴이 잘 이뤄지지 않으면 다른 알고리즘을 적용하거나 초기값, 매개변수, 조건 등을 재설정하여 다시 시도하기도 한다.

이러한 모든 과정을 종합하여, 잔차 분석은 알고리즘이 실제 문제 조건을 얼마나 충실히 만족시키는지를 살피는 일종의 지표 역할을 한다. 뒤이어 논의되는 알고리즘 성능 평가지표들을 함께 고려할 때, 문제 규모, 연산 복잡성, 오류 전파 가능성 등을 종합적으로 평가할 수 있다. 이는 단순히 해의 정확도만을 따지는 것이 아니라, 실제 계산 환경(컴퓨터 연산 정밀도, 시간 복잡도, 메모리 리소스 등)에서 알고리즘을 잘 운용하기 위한 필수 요소이기도 하다.

#### 잔차 기반의 알고리즘 수렴 판정과 정밀도 측정

실제 계산 과정에서 잔차는 매우 편리한 수렴 판정 기준으로 작동한다. 예를 들어 반복법을 수행할 때, $k$번째 반복에서 구한 해 $\mathbf{\hat{x}}^{(k)}$에 대한 잔차 $\mathbf{r}^{(k)} = \mathbf{b} - A \mathbf{\hat{x}}^{(k)}$를 측정하고, 그 크기가 일정 임계값 이하(예: $|\mathbf{r}^{(k)}|\_2 \le \varepsilon$)로 내려가면 알고리즘을 정지시키는 방식을 쓴다. 이때 $\varepsilon$는 사용자가 요구하는 정확도의 한계로 간주한다. 만약 잔차가 예상보다 천천히 감소하거나 특정 지점 이하로 감소하지 않는다면, 알고리즘 자체가 발산하거나 매우 느리게 수렴함을 의심해볼 수 있다. 또한 이러한 잔차 기반의 수렴 판정은 알고리즘이 실제 선형계 $A \mathbf{x} = \mathbf{b}$를 충분히 만족시키고 있는지를 간접적으로 가늠하게 해준다.

다만 앞서 언급했듯 잔차가 충분히 작아도 전방오차 $\mathbf{x} - \mathbf{\hat{x}}$가 작다고 보장되지 않을 수 있다. 예컨대 조건수가 큰 $A$에서는 작은 변동이 큰 해의 차이를 유발할 수 있으므로, 아무리 $|\mathbf{r}|$이 작아도 실제 해와의 오차가 어느 정도일지는 $A$의 민감도, 즉 $\kappa(A) = |A|\_2 |A^{-1}|\_2$ 등에 크게 좌우된다. 이처럼 문제의 조건수를 고려한 잔차 해석을 통해, 단순 잔차 크기 이외에도 전방오차에 대한 상한이나 추정치를 구해볼 수 있다. 가장 대표적인 추정식 중 하나로 다음이 자주 사용된다.

$$
|\mathbf{x} - \mathbf{\hat{x}}|\_2  \le \kappa(A) \frac{|\mathbf{r}|\_2}{|A|\_2 |\mathbf{\hat{x}}|\_2}
$$

이 식은 전형적인 형태로, $\kappa(A)$가 매우 클 경우 작은 잔차로부터 실제 오차의 상한을 충분히 작게 보장하기 어렵다는 점을 시사한다.

#### 전방오차와 후방오차, 그리고 잔차의 역할

수치해석에서 '좋은 알고리즘'이라는 의미는 크게 두 측면에서 해석된다. 전방정밀도(forward accuracy)가 높다는 것은 결과가 이론적 참값과 가깝다는 뜻이고, 후방안정성(backward stability)은 알고리즘이 실행되는 과정에서 발생하는 연산 오차를 문제에 대한 미세한(작은 노름 크기의) 변경으로 돌릴 수 있다는 의미다. 후방안정성은 잔차가 얼마나 작게 유지되는지(다시 말해 문제를 얼마나 조금만 바꿔도 근사해가 정확한 해가 될 수 있는지)와 직결되므로, 잔차 분석은 후방오차 관점에서 매우 중요한 지표로 작용한다.

예를 들어, 후방안정하다는 것은 결국 알고리즘으로 얻어진 근사해 $\mathbf{\hat{x}}$에 대하여, 원래의 $A$나 $\mathbf{b}$가 아닌 약간 변형된(매우 근소한 차이를 갖는) $\widetilde{A}$, $\widetilde{\mathbf{b}}$에 대해서는 정확한 해로 볼 수 있음을 의미한다. 즉,

$$
\widetilde{A},\mathbf{\hat{x}} = \widetilde{\mathbf{b}}
$$

를 만족하는 $\widetilde{A}, \widetilde{\mathbf{b}}$가 존재하고,

$$
|\widetilde{A} - A|\ \text{및}\ |\widetilde{\mathbf{b}} - \mathbf{b}|
$$

이 충분히 작을 때 그러한 알고리즘을 후방안정하다고 한다. 이때 잔차 $\mathbf{r} = \mathbf{b} - A\mathbf{\hat{x}}$가 작은 것은 $\widetilde{A}\approx A$와 $\widetilde{\mathbf{b}}\approx \mathbf{b}$를 쉽게 만족시킬 수 있음을 시사한다.

물론 전방안정성이 부족한 경우라면(가령 문제의 조건수가 매우 크거나 알고리즘이 수치적으로 취약할 때), 아무리 잔차가 작아도 실제 해와의 차이 $\mathbf{x} - \mathbf{\hat{x}}$는 여전히 크게 날 수 있다. 따라서 알고리즘 자체가 후방안정적이어도, 문제 자체가 불안정(ill-conditioned)하다면 전방오차가 커질 수 있으므로 문제 설정 단계부터 조건수를 고려하는 것이 중요하다.

#### 잔차 노름과 다양한 측정 기준

잔차의 크기를 측정할 때 벡터 노름으로 2-노름을 사용하고, 문제에 따라 1-노름이나 무한노름($\infty$-노름)을 쓰기도 한다. 일반적으로 2-노름은 유클리드 길이를 의미하여 $|\mathbf{v}|\_2 = \sqrt{v\_1^2 + v\_2^2 + \cdots + v\_n^2}$로 정의된다. $\infty$-노름은 벡터 성분 중 절댓값이 가장 큰 것을 취하고, 1-노름은 성분들의 절댓값을 모두 더한 값을 취한다. 여러 노름은 서로 다른 관점에서 잔차를 평가하며, 알고리즘 수행 단계에서 상황에 맞는 노름을 적절히 택해 사용한다. 예컨대 $L^1$-문제나 일부 특수 목적의 알고리즘에서는 1-노름이나 $\infty$-노름이 중요하게 쓰인다.

한편, 상대 잔차나 정규화된 잔차 등을 쓰는 경우에는 문제의 실제 크기를 고려하여 각 벡터 성분을 나누어 준 뒤 잔차를 합산 또는 최댓값으로 측정한다. 예를 들어, 계수 행렬 $A$의 특정 행이 매우 큰 값을 가질 때 그만큼 해당 행의 잔차 항이 커지는 것은 자연스러울 수 있으므로, 이를 단순히 "큰 잔차"라고 치부할 것인지, 아니면 해당 스케일을 보정하여 비교적 '정상 범위'로 간주할 것인지가 달라질 수 있다. 따라서 상대 잔차, 혹은 균등 스케일(normalized scale)에 기반한 잔차를 활용하면 더욱 공정하고 의미 있는 평가가 가능하다.

#### 알고리즘 성능 평가지표에서 잔차가 갖는 함의

수치해석에서 알고리즘을 평가할 때 잔차는 단 하나의 지표일 뿐, 전부가 아니다. 전방오차, 계산 복잡도, 메모리 사용량, 알고리즘 구현의 용이성, 확장 가능성 등과 함께 종합적으로 살펴야 한다. 그러나 잔차가 작으면 적어도 원래 문제나 혹은 그에 가까운 문제의 해를 '잘' 만족시키고 있다는 점에서, 후방안정성의 영역에서 높은 점수를 얻는다. 반대로 잔차가 큰 상태에서 전방오차를 따지는 것은 애초에 문제의 기본 골조($A \mathbf{x} = \mathbf{b}$)부터 만족하지 않는다는 뜻이므로, 해당 알고리즘이 문제 자체를 제대로 풀고 있지 않다고 볼 수도 있다.

실제 예시로서, 반복 알고리즘(예: CG(Conjugate Gradient), GMRES(Generalized Minimal Residual), BiCGSTAB(Biconjugate Gradient Stabilized)) 등을 적용할 때 매 반복마다

$$
\mathbf{r}^{(k)} = \mathbf{b} - A,\mathbf{\hat{x}}^{(k)}
$$

의 노름이 빠르게 줄어들면 알고리즘이 효율적으로 수렴한다고 판단한다. 이때 '빠르게'라는 표현은 통상 지수적 감소 혹은 목표 허용오차 $\varepsilon$ 이하로 내려가는 데 필요한 반복 횟수가 짧다는 의미로 파악된다. 반면 직접해법(direct method)으로 $LU$ 분해나 $QR$ 분해 등을 통해 $\mathbf{\hat{x}}$를 구했을 때에는 잔차가 매우 작게(계산 기계 오차 수준) 나타나는 것이 일반적이며, 이를 통해 알고리즘이 정확히 동작했음을 대체로 신뢰하게 된다.

#### 잔차 중심의 사후오차 추정과 후처리 기법

근사해 $\mathbf{\hat{x}}$가 구해진 뒤에 오차를 사후(posterior)적으로 추정하는 여러 방법 중에서, 잔차를 활용하는 것은 가장 직관적이고 계산이 간단하다는 장점이 있다. 예를 들어, $A \mathbf{\hat{x}} - \mathbf{b}$가 충분히 작다고 판단된다면, 문제를 조금만 바꿔도(바꾸는 양은 잔차의 노름 정도로 제한) $\mathbf{\hat{x}}$가 그 바뀐 문제의 '정확한 해'가 될 수 있음을 의미한다. 이를 통해 뒤늦게라도 알고리즘의 성능을 평가하고, 필요하면 반복 개선(iterative refinement), 사후 보정(corrector step) 같은 방식을 적용하여 해를 더 정밀하게 개선한다.

가령 반복 개선(iterative refinement)은 한 번 직접해법을 통해 얻은 해가 있을 때, 다음과 같은 보정 과정을 거치는 대표적 방법 중 하나다:

{% @mermaid/diagram content="flowchart LR
A\["해 x^ 구하기<br>(direct)"] --> B\["잔차 r = b - A x^<br>계산"]
B --> C\["오차 보정 문제<br>A e = r 풀기"]
C --> D\["새 해 x^ <- x^ + e"]
D --> B" %}

이 기법에서의 핵심은 잔차를 새로운 '미소 문제'로 규정하고, 이를 다시 풀어 나감으로써 얻어지는 보정 벡터 $\mathbf{e}$를 더해 해를 반복적으로 갱신한다는 점이다. 실제 머신 오차 환경에서 $LU$ 분해를 이용해 $A$를 한 번만 분해해두고(또는 $QR$ 분해 등), 잔차를 빠르게 계산해 보정 문제 $A \mathbf{e} = \mathbf{r}$를 다시 푸는 과정을 반복함으로써 해의 정밀도를 향상시킬 수 있다. 이처럼 잔차가 작아질수록(또는 일정 수준 이하로 유지될수록) 해는 더욱 문제에 부합하는 형태로 수렴한다.

#### 잔차와 사후오차 추정의 확장: 미분방정식 및 범용적 응용

수치선형해석에서 다루는 주제 중 하나가 편미분방정식(PDE)을 비롯한 고차원 문제의 근사해를 구하는 일이기도 하다. 이때 유한요소법(FEM), 유한차분법(FDM), 유한체적법(FVM) 등의 다양한 기법으로 해를 구성하면, 실제 해와 근사해가 어떻게 다른지를 추정하기 위해 잔차 개념이 자연스럽게 확장된다. 예를 들어 유한요소법에서 어떤 영역 $\Omega$를 격자로 분할하고, 각 요소(element)에서의 해를 다항식 공간(또는 스플라인 등)에 근사한다고 할 때, 정규 방정식(혹은 변분형 방정식)을 풀고 난 뒤의 잔차는 요소의 내부 혹은 경계에서 얼마나 '수행되지 않은'(unresolved) 오차가 남아 있는지를 가늠하는 잣대가 된다.

구체적으로, PDE가

$$
-\nabla \cdot (k(\mathbf{x}) \nabla u(\mathbf{x})) = f(\mathbf{x}) \quad\text{in}\ \Omega,
$$

와 같은 형태(2차 타원형 PDE)라 하면, 유한요소 근사해 $u\_h(\mathbf{x})$를 구한 뒤에 실제 방정식 연산자를 거쳤을 때 남는 편차, 즉

$$
R\_h(\mathbf{x}) = f(\mathbf{x}) + \nabla \cdot \bigl(k(\mathbf{x}) \nabla u\_h(\mathbf{x})\bigr)
$$

를 '잔차'라고 부른다. 이때 $R\_h(\mathbf{x})$가 영역 전체에서 작을수록, 적어도 PDE 오퍼레이터 관점에서는 $u\_h$가 좋은 근사해임을 짐작할 수 있다. 또한 경계 조건이나 접속 조건 등에 대한 불일치를 표현하는 잔차 항도 함께 측정하여 종합적으로 사후오차 추정을 수행한다. 수치해석 알고리즘의 견지에서 이런 잔차가 크면 아직 해가 충분치 않다고 보고, 요소 분할을 더 촘촘히(적응적 재분할) 하거나, 다항차수를 높이는 방식으로 해 공간을 확장하여 오차를 줄여나간다. 잔차가 작아지면 해당 영역은 이미 충분히 근사되었다고 판단하여 계산량을 줄이는 식으로 균형점을 찾는다.

이는 선형계 문제에서의 잔차와 본질적으로 동일한 개념적 틀 위에 서 있으나, PDE 문제에 대해서는 공간적으로 어디에서 잔차가 크게 발생하는지를 평가하고, 이를 바탕으로 해석적으로 의미 있는 결정을 내린다는 점에서 확장된 응용 사례라 할 수 있다. 즉, 전역 노름(예: $|R\_h|\_{L^2(\Omega)}$)으로 잔차 전체의 크기를 평가할 수도 있고, 국소 노름(특정 요소 내부 노름)으로 어느 부분에서 오차가 많이 나타나는지 진단함으로써 국부 재분할(local refinement)을 수행할 수도 있다.

#### 잔차 모니터링과 적응형 알고리즘

수치해석의 적응형 알고리즘(adaptive algorithm)은 잔차를 모니터링하여 계산 자원을 효율적으로 분배하는 데 큰 가치를 둔다. 반복 알고리즘의 맥락에서, 매 반복마다 잔차가 지수적으로 감소하는지, 혹은 특정 임계값 이하로 거의 수렴했는지를 관찰하면서 임의의 종료 시점을 고른다. PDE 근사해의 맥락에서는 요소별 잔차를 계산하여, 잔차가 큰 요소는 좀 더 세밀한 해석(예: 요소 분할)을 적용해 오차를 줄이고, 잔차가 이미 작아 충분히 수렴했다고 볼 수 있는 요소는 그대로 두어 전체 계산 복잡도를 최소화한다. 이를 통해 전역 오차를 일정 수준 이하로 내리면서도 불필요한 계산을 억제하는 결과를 얻을 수 있다.

적응형 알고리즘은 잔차 기반의 사후오차추정(a posteriori error estimation)을 중추로 삼는다. 예를 들어 유한요소법에서 흔히 사용되는 잔차 기반 사후오차추정 공식은 일반적으로 다음과 같은 형태를 갖는다. 어떤 요소 $K$에서의 잔차 항을 $R\_K$라 하고, 각 요소 경계나 이웃 요소와의 접합부에서 발생하는 불연속(이행조건)을 $J\_E$라 할 때,

$$
|u - u\_h| \approx \Bigl(\sum\_{K} \eta\_K^2\Bigr)^{1/2},
$$

여기에서 $\eta\_K$는 보통

$$
\eta\_K^2 = |h\_K (R\_K)|^2\_{L^2(K)} + \sum\_{E \subset \partial K}|h\_E^{1/2} J\_E|^2\_{L^2(E)}
$$

와 같은 형태로 주어지는 잔차 기반 항이다. $h\_K$, $h\_E$는 각 요소나 경계의 특성 길이(characteristic length)다. 이 식에서 $R\_K$와 $J\_E$가 크면 해당 부분이 근사오차를 크게 유발하고 있음을 의미하므로, 그 요소나 경계 근방의 메쉬(mesh) 분할을 세분화하여 오차를 효과적으로 줄일 수 있다.

#### 잔차를 활용한 실전 계산 예시

실제로 $A \mathbf{x} = \mathbf{b}$ 형태의 간단한 선형계에도 잔차 기반의 사후오차추정을 적용할 수 있다. 간단한 Python 예시를 살펴보면 다음과 같은 식으로 잔차를 계산하고, 이를 모니터링하며 반복 알고리즘을 돌릴 수 있다.

```python
import numpy as np

# A와 b가 주어진 상황에서, 반복법의 한 예시 (예: 단순 Richardson iteration)
def richardson_iteration(A, b, x0, alpha, tol, max_iter):
    x = x0.copy()
    for k in range(max_iter):
        r = b - A @ x
        if np.linalg.norm(r, 2) < tol:
            break
        x = x + alpha * r
    return x, k

# 예시 실행
n = 5
A = np.array([[4,1,0,0,0],
              [1,4,1,0,0],
              [0,1,4,1,0],
              [0,0,1,4,1],
              [0,0,0,1,3]], dtype=float)
b = np.array([1,2,3,4,5], dtype=float)
x0 = np.zeros(n)
alpha = 0.25
tol = 1e-6
max_iter = 10000

sol, num_iter = richardson_iteration(A, b, x0, alpha, tol, max_iter)
res = b - A @ sol

print("근사해 :", sol)
print("반복 횟수 :", num_iter)
print("최종 잔차 노름 :", np.linalg.norm(res, 2))
```

이 예시에서 잔차가 충분히 작아졌는지 판정하는 기준은 `np.linalg.norm(r,2) < tol` 부분이다. 이처럼 잔차가 사용자가 설정한 허용 범위 이하로 떨어지면 반복을 종료한다. 그 후 최종적으로 얻어진 $\mathbf{\hat{x}}$와 잔차를 다시 한 번 확인함으로써, 실제 알고리즘이 의도대로 잘 작동했는지를 사후적으로 평가한다. 더욱 고급화된 기법에서는 $A$의 조건수나 추가 정보를 활용하여 $\mathbf{x} - \mathbf{\hat{x}}$의 전방오차도 추정하게 되는데, 그때 역시 잔차가 기본적인 지표로 쓰인다.

#### 잔차와 수치 안정성 관점에서의 알고리즘 해석

여러 반복 기법이나 직전열해법(direct solver)을 운용할 때, 잔차는 단순한 정확도 지표를 넘어 알고리즘의 내부 동작 및 안정성을 평가하는 창구 역할을 한다. 잔차가 특정 구간에서 갑자기 커지거나, 예상한만큼 줄지 않는다면 수치오차가 증폭되고 있거나, 문제가 ill-conditioned이거나, 혹은 특정 분해(예: LU 분해) 과정에서 피벗팅(pivoting)이 제대로 이뤄지지 않는 등의 원인을 의심해볼 수 있다.

가령 $LU$ 분해를 통한 직접해법에서 수치적으로 안정적인 알고리즘을 얻기 위해서는 부분 피벗팅(partial pivoting)이나 완전 피벗팅(complete pivoting)을 적절히 수행해야 한다. 만약 피벗팅이 부적절하게 이루어졌다면 실제 해와는 거리가 있는데도 잔차가 명목상 작아 보이거나, 반대로 잔차가 이상하게 커지는 결과를 낳을 수 있다. 이때 잔차를 지속적으로 모니터링하여, 전형적인 수치 안정성 문제(예: 큰 라운딩 오류 발생)를 조기 경고하는 체계를 갖출 수 있다. 예컨대 $Ax=b$를 풀 때, $A$를 부분 피벗팅 없이 $L\_0 U\_0$로 분해했다고 하자. 만약 $A$가 거의 특이(singular)하거나 매우 큰 조건수를 갖는다면 근사해가 생산되는 과정에서 부동소수점 연산에 의해 큰 오차가 축적될 수 있고, 실제로 계산된 해를 $\mathbf{\hat{x}}$라고 할 때 $\mathbf{r} = \mathbf{b}-A \mathbf{\hat{x}}$를 구해보면 초기에 예측했던 것보다 큰 값이 나타날 수 있다. 혹은 $\mathbf{r}$ 자체는 우연히 작게 나타나지만, 다른 형태의 지표(예: $|\mathbf{x}|$ 대비 해의 크기 변화)가 비정상적으로 큰 것이 발견될 수도 있다. 이런 복합적 지표를 종합적으로 평가하면, 잔차가 안정성 점검의 첫 단서를 제공함을 알 수 있다.

#### 고차원 문제에서의 잔차 해석과 추가적 고려사항

수치 선형대수 문제 이외에도, 머신러닝이나 통계적 회귀(regression) 문제 등 다양한 영역에서 잔차(residual)는 핵심적 분석 도구로 활용된다. 예컨대 최소제곱법(LS, least squares)은 기본적으로

$$
\min\_{\mathbf{x}} |\mathbf{b} - A \mathbf{x}|\_2^2
$$

\[라인피드] 를 푸는 과정이며, 여기서 $\mathbf{r} = \mathbf{b} - A \mathbf{x}$가 잔차 벡터 역할을 한다. 이 잔차 $\mathbf{r}$가 0에 가까울수록, 주어진 데이터 $\mathbf{b}$를 행렬 $A$에 의해 잘 설명하는 파라미터(해) $\mathbf{x}$를 찾았다고 해석할 수 있다. 하지만 실제로는 노이즈나 모델 차이 등으로 인해 $\mathbf{r}$가 완전히 0이 되는 경우는 드물며, 오히려 잔차의 분포와 크기를 면밀히 분석함으로써 모델의 적합도나 편향 등을 진단한다.

이와 유사한 맥락에서, 다양한 알고리즘은 잔차를 스스로 계산하여 내부 수렴 여부를 점검하는 과정을 거친다. 예를 들어 비선형 방정식에서 사용하는 뉴턴(Newton) 방법도, 갱신식

$$
\mathbf{x}^{(k+1)} = \mathbf{x}^{(k)} - \bigl(D F(\mathbf{x}^{(k)})\bigr)^{-1}F(\mathbf{x}^{(k)})
$$

\[라인피드] 을 기반으로 반복 시마다 $F(\mathbf{x}^{(k)})$를 잔차(여기서는 해석적으로 $F(\mathbf{x})=0$이 목표)로 간주하여, 그 크기가 충분히 줄어드는지 확인한다. 만약 잔차가 충분히 작아지지 않으면 라인서치(line search)나 댐핑(damping) 기법 등을 추가 적용하여 안정성을 높인다. 이런 맥락에서 잔차는 단순한 $\mathbf{b} - A\mathbf{x}$의 형태에 국한되지 않고, 일반적인 “목표 함수(또는 연산자)와의 불일치”를 평가하는 확장된 개념으로 볼 수 있다.

#### GMRES, Krylov 서브스페이스 기법에서의 잔차 최소화

선형계 $\mathbf{A x} = \mathbf{b}$를 반복적으로 풀 때, Krylov 서브스페이스 방법들이 적극적으로 사용된다. 그 중 대표적인 GMRES(Generalized Minimal Residual) 알고리즘은 $\mathbf{r}$의 2-노름을 반복마다 최소화하는 과정으로 정의된다. 즉, $k$번째 반복에서

$$
\mathbf{\hat{x}}^{(k)} \in \mathbf{x}\_0 + \mathcal{K}\_k(\mathbf{A}, \mathbf{r}\_0)
$$

\[라인피드] 가 되도록, 여기서 $\mathbf{r}\_0 = \mathbf{b} - \mathbf{A}\mathbf{x}\_0$, 그리고 Krylov 서브스페이스는

$$
\mathcal{K}\_k(\mathbf{A}, \mathbf{r}\_0) = \mathrm{span}{\mathbf{r}\_0, \mathbf{A}\mathbf{r}\_0, \mathbf{A}^2\mathbf{r}\_0, \ldots, \mathbf{A}^{k-1}\mathbf{r}\_0}
$$

\[라인피드] 로 정의된다. 그리고 $|\mathbf{b} - \mathbf{A}(\mathbf{x}\_0 + \mathbf{v})|\_2$를 최소화함으로써, 가능한 한 빠르게 잔차의 노름을 줄이는 방향으로 해를 갱신한다.

GMRES 알고리즘의 내부에서는 Arnoldi 분해(Arnoldi decomposition)를 통해 직교 기저를 형성하고, 그 과정에서 Hessenberg 선형계를 풀어 잔차를 최소화할 수 있는 계수를 결정한다. 핵심 포인트는 “잔차가 최소가 되도록” 목적을 설정한다는 점이며, 따라서 수렴이 빠르면 적은 반복 횟수 안에 잔차를 크게 감소시킬 수 있다. 그러나 조건수가 매우 크거나 스펙트럼 분포가 좋지 않은 $\mathbf{A}$에서는 잔차가 기대만큼 줄지 않을 수 있고, 이때 프리컨디셔너(preconditioner)를 사용하여 $\mathbf{A}$를 더 잘-conditioned된 형태로 바꿔서 잔차 감소 속도를 높일 수 있다. 그 역시 잔차 관찰을 통해 “얼마나 빨리 줄어드는지”를 실시간으로 평가하므로, 잔차 해석이 Krylov 방법론에서도 매우 중요한 역할을 담당한다.

#### 알고리즘 복잡도, 성능, 자원 사용량과 잔차의 균형

수치해석 알고리즘의 평가에서 잔차나 전방오차와 더불어 중요한 질문은 “이 오차(또는 잔차) 수준에 도달하기 위해 얼마만큼의 계산 자원(연산량, 메모리, 실행 시간 등)을 투입해야 하는가”이다. 예컨대 매우 복잡한 알고리즘일수록 적은 반복 횟수로 잔차를 줄이는 데 성공할 수 있으나, 각 반복 단계의 비용이 높다면 총 연산량은 도리어 늘어날 수 있다. 반면 계산량이 적은 단순 알고리즘(예: 단순한 Richardson 방법)은 각 반복이 가볍지만 잔차가 천천히 줄어들거나 특정 조건에서 발산할 수도 있다.

실제 HPC(고성능 컴퓨팅) 환경에서 잔차를 모니터링할 때, 매 반복마다 잔차 노름을 계산하는 것조차도 비용이 될 수 있다. 대규모 병렬 환경에서 노름 계산은 전역 통신(global communication)을 필요로 하므로, 반복 알고리즘의 스케일링(scalability)에 영향을 준다. 따라서 잔차 계산을 매번 수행하기보다는, 특정 주기(예: 5번 혹은 10번 반복마다 한 번)로 계산하거나, 추정 공식을 통해 잔차가 현재 대략 어느 범위에 있음을 가늠하는 등의 기법도 활용된다. 물론 최종적으로는 잔차 노름이 충분히 작아져야 신뢰할 만한 해로 간주할 수 있으나, 대규모 병렬 계산에서 이러한 절충안이 흔히 사용된다는 점이 실무적으로 중요하다.

#### 잔차와 정교한 사후 분석을 통한 알고리즘 비교

수치해석 알고리즘을 서로 비교하려면, 동일한 초기값이나 동일한 문제 설정에서 잔차가 감소하는 양상을 그래프로 시각화해서 관찰하는 방법이 자주 활용된다. 예컨대 세 가지 알고리즘 A, B, C가 있을 때, 반복 횟수를 $k$라 할 때 $|\mathbf{r}^{(k)}|$를 로그 스케일로 표현하면, 어떤 알고리즘이 더 빠른 속도로 잔차를 감소시키는지 직관적으로 비교할 수 있다. 이것은 GMRES, CG, BiCGSTAB, MINRES 등 Krylov 기반 알고리즘 비교 시 전형적으로 쓰이는 방식이다.

한편 동일한 문제에서도 프리컨디셔너를 달리 적용해 보면서 잔차가 감소하는 곡선이 어떻게 바뀌는지를 모니터링하는 것도 중요하다. 프리컨디셔닝을 잘 선택하면 같은 문제라도 잔차가 급격하게 줄어드는 이점을 얻을 수 있고, 잘못된 프리컨디셔너를 사용하면 잔차가 더디게 줄거나 오히려 발산할 수도 있다. 이처럼 잔차 그래프는 알고리즘 비교의 직관적 자료로써, 전방오차나 다른 수치적 지표와 함께 통합적으로 활용된다.

#### 잔차의 다양한 해석과 시스템 식별, 필터링 분야에서의 활용

시스템 식별(system identification)이나 칼만 필터(Kalman filter) 기반의 추정 알고리즘 등에서도 잔차는 중요한 관측 지표가 된다. 예컨대 칼만 필터의 갱신(update) 단계에서 예상 측정값과 실제 측정값의 차이는 잔차(innovation)로 불리는데, 이 값이 충분히 작고 통계적으로 백색 잡음(white noise)에 가깝다면, 필터가 잘 동작하고 있다고 간주한다. 반대로 잔차가 특정 패턴을 띄거나 분산이 갑자기 커지면 시스템 모델이 잘못되었거나 노이즈 수준이 달라졌을 가능성을 의심한다. 이는 일종의 “확장된 수치 문제”에서의 잔차 개념 적용 사례라 할 수 있다.

잔차를 기반으로 하는 이런 진단은 단순히 수치적 선형계 해석을 넘어 실제 공정 제어나 신호 처리, 머신러닝 모델 평가 등 폭넓은 영역에 파급된다. 공정 제어 분야에서는 모델 예측 제어(MPC)에서 예측 모델과 실측 값의 차이(잔차)를 모니터링하여, 모델 파라미터나 입력 변수를 즉시 보정하는 메커니즘이 존재한다. 결국 잔차가 상징하는 “예측과 실제의 차이”라는 아이디어가, 다양한 엔지니어링 및 과학 분야에서 일관된 형태로 나타나는 셈이다.

#### 잔차 분석의 실제 적용 시 주의점

잔차가 문제 해석에서 강력한 무기가 되지만, 한편으로는 다음과 같은 주의 사항들을 함께 고려해야 한다. 문제의 조건수가 매우 클 경우 잔차가 작아도 전방오차가 클 수 있다는 점, 잔차 노름의 선택(2-노름, 1-노름, $\infty$-노름 등)에 따라 해석이 달라질 수 있다는 점, 상대 잔차가 실제로는 원하는 정확도 판단에 더 적합할 수 있다는 점 등이다. 또한 실제 계산 환경에서 부동소수점 연산 오류가 누적되면 잔차 자체가 기계 오차 범위 이내로 접근하는 것을 더 이상 구분하기 어려워질 수도 있다.

이러한 주의점을 종합하면, 잔차가 어느 한 지표로서 알고리즘의 품질과 문제 충실도를 확인하는 유력한 잣대가 되는 것은 사실이지만, 전방오차 분석, 문제의 condition number, 연산자 스펙트럼, 실제 어플리케이션 요구 정밀도 등과 함께 종합적으로 판단해야 한다고 말할 수 있다. 특히 대규모 문제에서는 단계별 잔차 평가가 매끄럽게 이뤄지도록 사전에 코드를 설계하고, 잔차가 기계 오차에 도달해 더 이상 유의미한 구분이 불가능해지는 시점을 파악하는 것이 실제 구현 측면에서 핵심적인 작업이 된다.
