# 블록 구조에서의 오차 전파 양상

블록 구조란 대규모 연산 과정에서 특정 부분(블록)으로 문제를 나누어 해결하고, 그 결과를 종합해 전체 해답을 구하는 과정을 말한다. 예컨대 대형 선형계 $\mathbf{A}\mathbf{x} = \mathbf{b}$를 풀 때, $\mathbf{A}$가 특정 패턴을 갖춘 블록 행렬(block matrix) 형태라면 이 블록들을 독립적으로 다루거나 재귀적으로 접근하여 연산 효율을 높일 수 있다. 그러나 이러한 블록 단위 해법 과정에서 발생하는 수치적 오차가 다시 전체 시스템으로 어떻게 전파되는지를 살펴보는 일은 매우 중요하다.

블록 구조를 염두에 둔 오차 분석에서는 일반적인 연속적 연산(스칼라 단위 연산)과 달리, 벡터나 행렬을 여러 구역으로 분할한 뒤 각각의 연산 과정에서 발생하는 측근 오차(local error)가 누적되어 전체 결과값에 얼마나 영향을 미치는지를 체계적으로 살펴본다. 즉, 각 블록 연산에서 나타나는 반올림오차, 절단오차, 혹은 재배열에 따른 부정확성 등이 전체 시스템을 복합적으로 교란하게 되며, 이때 시스템이 충분히 안정적인 구조를 가진다면 오차가 과도하게 증폭되지 않는다. 반면 작은 교란이 증폭되는 조건을 갖춘다면 전체 해가 매우 부정확해질 수 있다.

#### 블록 행렬과 연산 특징

블록 구조에서 가장 대표적인 예시는 블록 행렬(block matrix)을 통한 연산이다. 예를 들어, $\mathbf{A}$를 다음과 같은 2×2 블록 행렬로 구성한다고 하자.

$$
\mathbf{A} =  \begin{pmatrix} \mathbf{A\_{11}} & \mathbf{A\_{12}} \ \mathbf{A\_{21}} & \mathbf{A\_{22}} \end{pmatrix}
$$

이때 $\mathbf{A\_{11}}, \mathbf{A\_{12}}, \mathbf{A\_{21}}, \mathbf{A\_{22}}$는 각각 적절한 크기의 행렬 블록이다. 선형계 $\mathbf{A}\mathbf{x} = \mathbf{b}$를 푸는 일반적 과정을 블록 행렬 연산으로 대체할 때, 연산의 기본 단계인 LU 분해나 역행렬 계산, 혹은 직교화 등을 블록 단위로 수행할 수 있다. 블록 연산이 갖는 특징은 대규모 문제를 효율적으로 처리할 수 있게 해주지만, 국소적으로 발생한 오차가 전체에 전파되는 양상이 복잡해진다는 것이다.

예를 들어, 블록 LU 분해 방식을 고려해 보자. 블록을 이용해 $\mathbf{A} = \mathbf{L}\mathbf{U}$ 형태의 분해를 수행하는 과정을 약술하면 아래와 같은 연산 시퀀스를 수행한다.

1. 블록 $\mathbf{A\_{11}}$을 분해하여 $\mathbf{L\_{11}}, \mathbf{U\_{11}}$ 형태로 표현
2. 필요한 경우 $\mathbf{A\_{21}}$와 $\mathbf{A\_{12}}$의 업데이트
3. 나머지 블록 $\mathbf{A\_{22}}$에 대해 Schur complement를 취해 후속 연산 진행

이 과정에서 블록 단위의 반올림오차와 업데이트 오차가 누적되면서, 전체 시스템에서의 해 $\mathbf{x}$에 영향을 끼치게 된다. 가령 $\mathbf{A\_{11}}$의 분해 과정이 수치적으로 불안정하다면 그 영향이 바로 $\mathbf{A\_{21}}$와 $\mathbf{A\_{12}}$ 업데이트에 반영되고, 그 후에는 $\mathbf{A\_{22}}$를 구성하는 Schur complement가 달라질 수 있다. 이처럼 작은 블록에서의 수치적 손실이 전체 시스템의 정확도에 영향을 미치는 것이다.

#### 반올림오차의 전파

컴퓨터에서의 모든 실수 연산은 유한 정밀도의 부동소수점(floating-point) 연산으로 이루어지므로, 스칼라 연산 시점에 반올림오차(round-off error)가 발생한다. 블록 구조에 대한 연산 역시 궁극적으로 동일한 스칼라 단위 연산에 의해 진행되기에, 반올림오차는 각 블록 연산에서 포착되지 않는 미세 단계마다 조금씩 발생한다. 이때 특정 블록이 매우 큰 스케일(행렬의 크기가 크다거나, 해당 블록의 값이 매우 크거나 작다거나, 조건수(condition number)가 큰) 상태라면, 그것이 후속 블록 연산에 미치는 영향력이 더욱 커질 수 있다.

예컨대 블록 곱셈 $\mathbf{A\_{11}}\mathbf{A\_{12}}$를 계산할 때 발생하는 $\delta\_\mathrm{mul}$ 같은 반올림오차가 다음 단계인 Schur complement $\mathbf{A\_{22}} - \mathbf{A\_{21}}\mathbf{U\_{12}}$에서 추가로 누적될 수 있다. 실제로 $(\mathbf{A\_{22}} + \Delta\_{22}) - (\mathbf{A\_{21}} + \Delta\_{21})(\mathbf{U\_{12}} + \Delta\_{U\_{12}})$ 형태가 되어버리는 상황을 생각해보면, 각 항의 오차 성분이 서로 결합하여 또 다른 교란항을 생성한다.

이를 정식화하면 다음과 같이 볼 수 있다. 블록 연산 후의 실제 결과값을 $\tilde{\mathbf{A}}*{22}$라 하고, 이상적 이론값을 $\mathbf{A}*{22}^\*$라 할 때,

$$
\tilde{\mathbf{A}}*{22} = \mathbf{A}*{22}^\* + \Delta\_{22}
$$

여기서 $\Delta\_{22}$는 모든 중간 단계에서 발생한 반올림오차들이 합성되어 형성된 오차 항이다. 그리고 그 중 일부 항들은 $\mathbf{A\_{21}}$와 $\mathbf{U\_{12}}$가 큰 노름(norm)을 갖고 있거나, 이들이 매우 민감한 구조를 갖고 있을 때 증폭된다. 결국 $\Delta\_{22}$가 가진 노름이 원래 $\mathbf{A}\_{22}^\*$의 노름에 비해 얼마나 큰지에 따라 결과적으로 오차의 영향이 결정된다.

#### 블록 구조에서의 안정성과 조건수

블록 구조로 문제를 풀 때, 각 블록 자체가 안정적인 연산 절차를 갖추고 있어야 한다는 점이 중요하다. 작은 블록을 단순히 나눈다는 사실만으로 전체 문제에 대한 안정성이 확보되지는 않는다. 블록화를 통해 연산 횟수를 줄이거나 메모리 접근 패턴을 최적화함으로써 실질적인 계산 효율 향상을 얻을 수 있을 뿐, 오차가 과연 안정적으로 제어되는지는 별개의 문제다.

블록 구조에서 조건수(condition number)를 고려할 때, 주로 $\mathbf{A}$의 블록 특성이나 Schur complement의 조건수 등이 주요 지표가 된다. 이를테면 $\mathbf{A\_{11}}$이 매우 작은 행렬이거나, $\mathbf{A\_{22}}$의 대역폭이 큰 반면에 수치적으로 불안정한 구조를 가질 경우, 국소 블록에서 발생한 오차가 전체 시스템에서 되돌릴 수 없을 정도로 증폭되기도 한다. 따라서 블록 구조 알고리즘을 설계할 때는, 각각의 블록 연산이 안정적으로 진행되도록 적절한 축소나 축약(예: 재배열, 부분 피벗팅)을 수행해야 한다.

블록 행렬 $\mathbf{A}$의 전형적인 부분 피벗팅(block pivoting) 방법은 다음과 같이 요약할 수 있다. 먼저 $\mathbf{A\_{11}}$ 블록이 충분히 안정적인 경우라면 그대로 사용하고, 그렇지 않을 경우에는 $\mathbf{A\_{21}}$이나 $\mathbf{A\_{12}}$ 혹은 더 크게는 $\mathbf{A\_{22}}$와 교체하는 식으로 일종의 피벗팅을 수행한다. 그러나 이는 블록 단위의 고차원 연산이므로, 그 과정에서 발생하는 수치적인 변동이 단순 스칼라 피벗팅보다 훨씬 복잡하게 전파될 수 있다.

#### 블록 삼각 계수 행렬로의 접근

블록 구조에서 오차 분석을 좀 더 단순화하려면, 블록 삼각 형태(block triangular form)로의 접근을 고려할 수 있다. 예컨대

$$
\begin{pmatrix} \mathbf{A\_{11}} & \mathbf{0} \ \mathbf{A\_{21}} & \mathbf{A\_{22}} \end{pmatrix}
$$

이런 식으로 상하 삼각 형태를 유지하도록 블록을 재배치하면, 각 블록 연산에서 발생하는 오차가 비교적 예측하기 쉬운 방식으로 누적된다. 물론 이렇게 단순화한 형태라도 실제 연산에서는 반올림오차가 누적되며, $\mathbf{A\_{21}}\mathbf{A\_{11}}^{-1}$ 등과 같은 곱셈 오차가 새롭게 나타난다. 그러나 구조가 삼각 형태로 단순화되어 있다면, $\mathbf{A\_{11}}$에서 발생한 오차가 $\mathbf{A\_{22}}$에 전파되는 경로가 제한되어 해석이 용이해진다. 이를 활용하여 실제로는 칼럼 블록 혹은 로우 블록을 기준으로 문제를 분할하고, 부분적으로 해결한 뒤 결합하여 오차를 추적한다.

또한 블록 트라이앵귤러 시스템을 푸는 과정에서, 역방향 안정성(backward stability)을 확보할 수 있는지도 체크해야 한다. 역방향 안정성이란, 실제로 발생하는 컴퓨터 연산 결과 $\tilde{\mathbf{x}}$가 “$\mathbf{A}$가 약간 교란된 $\tilde{\mathbf{A}}$일 때 그 완벽한 해”라고 해석될 수 있는가를 보는 개념이다. 블록 구조에서도 동일한 정의가 성립하며, 각 블록 연산 후 최종 해 $\tilde{\mathbf{x}}$가 마치 $\mathbf{A} + \Delta\mathbf{A}$에 대한 완전한 해였다고 간주할 수 있다면, 해당 알고리즘은 역방향 안정적이라고 부른다. 여기서 $\Delta\mathbf{A}$는 다시 블록 구조를 반영한 형태의 노름 제한 조건을 만족해야 하며, 이 점이 블록 단위 오차 분석에서 매우 중요한 핵심이다.

#### 블록 구조를 활용한 병렬 계산과 오차 전파

블록 구조는 병렬 계산 환경에서 효율적인 구현을 가능하게 한다. 예컨대 다수의 프로세서가 각각 독립적으로 특정 블록의 연산을 담당하고, 그 결과를 결합하여 전체 문제를 해결하면 전체 계산 시간을 크게 단축할 수 있다. 그러나 분산 환경에서 각각의 블록 계산 결과가 가령 통신 지연, 부분적인 동적 부하(balance) 불균형, 혹은 중간 반올림오차에 민감하게 반응하게 되면, 병렬 알고리즘 전반에서 오차가 예상치 못하게 증폭될 수 있다.

예를 들어 블록을 병렬로 곱셈하거나 분해하는 경우, 국소 블록에서 발생한 오차를 효율적으로 추적하기 위해서는 통신(communication) 과정에서 블록 경계(boundary)에 해당하는 요소가 올바르게 전달되었는지도 점검해야 한다. 이러한 통신 오차나 프로세서 간 부동소수점 환경 차이가 있으면, 동일한 소프트웨어를 사용하더라도 기계 환경마다 다른 결과가 도출될 수도 있다. 따라서 블록 구조 알고리즘에서 병렬 연산을 수행할 때는, 오차 추적을 위한 추가 방안을 마련하는 일이 필수적이다.

블록 Jacobi나 블록 Gauss-Seidel 같은 반복(iterative) 해법 역시 마찬가지다. 스칼라 Jacobi나 Gauss-Seidel 알고리즘을 확장해서, 한 번의 반복 단계에서 특정 블록 전체를 갱신하도록 구성할 수 있다. 이때 각 블록의 해가 갱신되는 과정에서, 블록 외부의 정보(다른 블록 해)와 얼마나 일관성 있게 정보가 전달되느냐에 따라 오차의 축적 양상이 결정된다. 특히 반복 알고리즘은 여러 번의 순환(iteration)을 거치므로, 작은 단위에서 발생한 오차라 하더라도 재차 반복되면서 확대될 가능성이 있다.

#### 블록 행렬 분해와 희소 구조

실제 대규모 문제는 희소(sparse) 행렬 구조를 가지고 있고, 이 희소성이 블록 단위로 드러나는 경우가 많다. 예컨대 희소 행렬에서 특정 부분은 밀집(dense)에 가깝고, 나머지 부분은 거의 0에 가까운 항만 모여 있어 블록 분할 시 큰 블록과 작은 블록이 혼재할 수 있다. 이때 큰 블록은 수치적으로 불안정해지기 쉽고, 작은 블록은 오차 전파 과정에서 그 영향력이 다르게 작용한다.

희소 블록 구조를 다룰 때는, 사실상 0으로 채워진 영역에서의 연산(예컨대 곱셈 결과가 0으로 유지되는 부분)에서 오차가 어떻게 전파되는지 고려해야 한다. 스칼라 차원에서 0과 매우 작은 값을 곱하는 과정에서 반올림오차가 상대적으로 클 수 있으며, 이것이 상호 누적되면 희소 구조가 무너질 수도 있다. 따라서 큰 블록과 작은 블록을 한꺼번에 섞어서 처리하기보다는, 희소 행렬에서의 블록 구조를 적절히 재정렬하여 삼각 혹은 대각 블록 기반으로 해결하는 접근이 권장된다. 다만 이 과정에서 발생하는 피벗팅, 블록 재배열, 행·열 압축 등의 조치가 또 다른 형태의 교란항을 만들어낼 수 있음은 주의해야 한다.

#### 블록 순환 피벗팅 기법과 오차

블록 행렬을 대상으로 피벗팅(pivoting)을 수행할 때, 단순히 가장 큰 절댓값을 갖는 스칼라 항이 아닌, 가장 안정적이라고 판단되는 블록을 선택해야 할 때가 많다. 이를 블록 순환 피벗팅(block-cyclic pivoting) 혹은 블록 파티셔닝(block partitioning)이라고 부른다. 다만 각 블록의 스펙트럼 특성이나 조건수 등을 동시에 고려해가며 피벗팅 순서를 결정하는 일은, 스칼라의 부분 피벗팅과 비교해 훨씬 복잡하다.

예를 들어 실제 연산 과정에서 $\mathbf{A\_{ii}}$ 블록이 지나치게 작은 값(또는 노름이 작은 행렬)을 가지면, 해당 블록을 피벗으로 사용했을 때 발생하는 오차가 커질 수 있다. 이를 보완하기 위해 $\mathbf{A\_{jj}}$나 $\mathbf{A\_{ij}}$, $\mathbf{A\_{ji}}$ 블록과 교환하는 단계가 추가된다. 이때 각 교환(스왑) 연산에서 생기는 반올림오차나, 행·열 순서 변경에 따른 사후 업데이트 오차가 블록 전역에 누적될 수 있다.

정리하자면, 블록 행렬 피벗팅은 오차 전파 양상을 크게 복잡화한다. 큰 블록을 피벗으로 선택했을 때 반올림오차가 줄어드는 이점이 있는 반면, 교환 과정 그 자체가 새로운 오차 인자를 가져오기도 한다. 결국 문제의 구조(희소도, 대칭성, 조건수, 대각 우세 여부 등)를 고려하여, 블록 피벗팅이 실제 오차를 어느 정도까지 제어 가능한가를 수치적으로 검사해야 한다.

#### 블록 QR 분해와 직교성 손실

블록 LU 분해 외에도, QR 분해(orthogonal factorization)를 블록 단위로 구현할 수 있다. 블록 QR 분해 과정에서는 Householder 반사나 Givens 회전을 블록으로 일반화한 형태를 사용한다. 이때 각 단계에서 얻어지는 블록 직교 행렬(또는 유사 직교 행렬)이 이상적으로는 완벽히 직교해야 하지만, 실제로는 유한 정밀도 연산에서 점진적인 직교성 손실(loss of orthogonality)이 나타난다.

가령 블록 Householder 변환을 연속적으로 적용할 경우, 변환 블록들의 누적 오차 때문에 최종적으로 얻어지는 직교 행렬 $\mathbf{Q}$가 $\mathbf{Q}^\top \mathbf{Q} = \mathbf{I}$에서 크게 벗어날 수 있다. 이는 블록 크기가 커질수록, 그리고 변환이 여러 차례 반복될수록 더욱 두드러진다. 이 현상을 수학적으로 표현하면, 실제로 구현된 직교 행렬 $\tilde{\mathbf{Q}}$에 대해

$$
|\tilde{\mathbf{Q}}^\top \tilde{\mathbf{Q}} - \mathbf{I}| \le \epsilon
$$

형태의 근사적 조건을 만족시키려고 할 때, $\epsilon$이 문제 차원이나 블록 크기에 의존해 커질 수 있다. 즉, 블록별 연산에서 발생하는 오차가 반복적으로 누적되면서 직교성이 서서히 훼손되는 것이다.

이러한 직교성 손실은 다시 블록 형태의 R 행렬(위 삼각 혹은 사다리꼴 형태)에 영향을 주어, $\mathbf{A} \approx \tilde{\mathbf{Q}}\tilde{\mathbf{R}}$ 근사를 수행할 때 $\tilde{\mathbf{R}}$에도 교란항이 반영될 수 있다. 결국 블록 QR 분해를 통해 얻은 해석 결과(예컨대 최소제곱해나 고유값 분해의 전단계)에 미세 오차가 추가로 더해지며, 이를 통제하려면 블록 단위로 직교성 재조정(orthonormalization)을 하는 등 보강 기법을 사용하기도 한다.

#### 블록 구조에서의 역방향 오차 해석

블록 연산에 대한 역방향(backward) 오차 해석은, 스칼라 연산에 대한 역방향 해석의 확장판으로 이해할 수 있다. 다만 각 단계가 블록 단위로 진행되므로, 실제로는 스칼라 단위 연산에서 발생하는 오차를 일일이 추적하기보다는, 한 번의 블록 연산을 “단일 연산”으로 보고 해당 과정에서 발생하는 총괄 오차를 $\Delta \mathbf{A\_{ij}}$와 같은 형태로 설정해 둔다.

이를테면 블록 LU 분해 과정을 예로 들면, 어떤 블록 분해 연산 이후 실제 결과가

$$
\mathbf{A} + \Delta \mathbf{A} = \mathbf{L} \mathbf{U}
$$

와 같이 표현되었다고 할 때, $\Delta \mathbf{A}$가 충분히 작다는 점(예: $|\Delta \mathbf{A}| \le \eta |\mathbf{A}|$)을 역방향 안정성의 조건으로 삼는 식이다. 문제는 $\Delta \mathbf{A}$가 어떤 구조적 특성을 만족해야 하는가이다. 실제 블록 연산에서는 $\Delta \mathbf{A}$가 특정 블록에만 집중될 수도 있고, 블록 대각선 간 교란이 발생하지 않을 수도 있다. 각 알고리즘마다 어떤 형태의 구조적 오차(perturbation)가 허용되는지 미리 규명해야 하며, 이를 통해 사용자는 “이 알고리즘은 블록 구조를 유지하는 범위 내에서 역방향 안정적이다”라는 식으로 결론지을 수 있다.

그러나 실제 계산에서는, 블록 연산을 하나의 추상화된 단위로 다룬다 해도 내부적으로 수많은 스칼라 단위 연산이 수행된다. 이 때문에 단계별로 누적되는 오차가 전역적으로 어떻게 결합되는지, 각 블록 내에서의 수치 안정성과 전체적인 역방향 안정성 간에는 얼마나 간극이 있는지 파악이 중요하다.

블록 구조를 엄밀히 추적하는 역방향 오차 해석은, 전체 시스템 규모가 클수록 고차원 기법이 필요하고, 설사 그 해석 결과를 얻는다 해도 실무적으로 적용하기가 쉽지 않다. 그럼에도 불구하고 블록 구조가 점차 대규모 병렬 시스템에서 표준화되고 있기에, 이 분야에서의 오차 해석 연구는 꾸준히 확대되고 있다.

#### 블록 구조와 도메인 분할 기법

블록 구조는 편미분방정식(PDE) 문제를 수치적으로 풀 때 사용되는 도메인 분할(domain decomposition) 기법에서도 중요한 역할을 한다. 넓은 물리 영역을 여러 작은 서브도메인(sub-domain)으로 분할하고, 각 서브도메인에서 국소적인 문제를 해결한 뒤, 분할 경계에서의 적절한 적합 조건(matching condition)을 도입하여 전체 해를 결합하는 방식이다. 이를 블록 구조로 해석하면, 각 서브도메인에 대응하는 계수 행렬을 하나의 블록으로 간주할 수 있다.

예컨대 $\mathbf{A}$가 대규모 2차원 혹은 3차원 격자에서 유도된 이산화 행렬이라고 할 때, 도메인 분할에 의해 다음과 같은 블록 행렬 형태를 생각할 수 있다.

$$
\mathbf{A} =  \begin{pmatrix} \mathbf{A\_{11}} & \mathbf{A\_{12}} & \cdots & \mathbf{A\_{1m}} \ \mathbf{A\_{21}} & \mathbf{A\_{22}} & \cdots & \mathbf{A\_{2m}} \ \vdots & \vdots & \ddots & \vdots \ \mathbf{A\_{m1}} & \mathbf{A\_{m2}} & \cdots & \mathbf{A\_{mm}} \end{pmatrix}
$$

여기서 $\mathbf{A\_{ii}}$는 각 서브도메인 내부에 해당하는 계수를 나타내는 블록이며, $\mathbf{A\_{ij}}$는 서브도메인 경계에서 상호작용하는 항을 담고 있다. 이러한 블록 구조를 활용하여 각 서브도메인(블록)을 독립적으로 풀거나, 적절한 초기 조건 하에서 반복적으로 경계를 갱신하면서 전체 해에 근접해 가는 방식으로 병렬 계산을 수행할 수 있다.

도메인 분할 기법에서는 블록 간 경계 접합부에서의 반올림오차가 어떻게 전파되는지가 중요하다. 경계부에서 한 블록의 해가 다른 블록으로 전달될 때, 수치 정밀도 제한으로 인해 생기는 오차가 다시 그 블록 내부에서 확산될 수 있기 때문이다. 블록 경계에서 발생한 작은 오차가 서브도메인 내부로 전파되어, 해당 서브도메인 해에 영향을 미치고, 이는 다시 인접 블록으로 되먹임되면서 전체 해에 누적되는 식이다. 이러한 오차 누적을 방지하려면, 각 블록 해가 충분히 안정적으로 구해지도록 세심한 알고리즘 설계가 필요하다.

#### 블록 슈어 보완과 예조건

도메인 분할에서 중요한 도구 가운데 하나가 슈어 보완(Schur complement)이다. 블록 행렬을 다음처럼 두 블록으로 분할했다고 하자.

$$
\mathbf{A} =  \begin{pmatrix} \mathbf{A\_{11}} & \mathbf{A\_{12}} \ \mathbf{A\_{21}} & \mathbf{A\_{22}} \end{pmatrix}, \quad \mathbf{x} = \begin{pmatrix} \mathbf{x\_1} \ \mathbf{x\_2} \end{pmatrix}, \quad \mathbf{b} = \begin{pmatrix} \mathbf{b\_1} \ \mathbf{b\_2} \end{pmatrix}.
$$

선형계 $\mathbf{A}\mathbf{x} = \mathbf{b}$를 풀기 위해, $\mathbf{A\_{11}}$이 비가역(inv invertible)이라고 가정하면 슈어 보완 $\mathbf{S} = \mathbf{A\_{22}} - \mathbf{A\_{21}}\mathbf{A\_{11}}^{-1}\mathbf{A\_{12}}$을 사용할 수 있다. 이는 실제 계산에서 $\mathbf{A\_{11}}^{-1}$을 미리 구해야 하므로, 그 과정에서 발생하는 오차가 곧바로 슈어 보완 항인 $\mathbf{S}$에 반영된다. 그리고 이 $\mathbf{S}$가 도메인 경계 결합(block 간 상호작용)에 해당한다면, 해당 부분에서의 오차가 곧 전체 문제로 전파될 수 있다.

슈어 보완을 이용한 해법은, $\mathbf{S}$에 대한 시스템을 푼 뒤 다시 앞의 블록들을 복원하는 방식으로 진행된다. 이때 $\mathbf{S}$ 자체의 조건수가 클 경우 작은 교란이라도 크게 증폭될 수 있고, 그렇게 증폭된 오차가 해 전체에 퍼져 나갈 위험이 있다. 따라서 블록 구조를 기반으로 한 알고리즘을 사용할 때, 슈어 보완에 대한 안정성 분석이 뒤따라야 하며, 필요하다면 블록 단위의 예조건(preconditioning)을 도입해 조건수 개선을 시도한다.

예컨대 도메인 분할 방정식을 푸는 과정에서, 경계 문제만을 추출한 뒤 이를 위한 예컨디셔너를 구성하는 방식이 널리 사용된다. 실제로는 블록 행렬 $\mathbf{A}$의 인접 블록들끼리만 상호작용하는 희소 구조를 이용해, 슈어 보완을 근사적으로 계산하는 블록 예조건자를 설계하기도 한다. 이는 큰 블록에서 발생하는 수치 오차를 국소화하고, 반올림오차가 전체로 퍼지기 전에 블록 내에서 일정 수준으로 제어할 수 있는 길을 열어 준다.

#### 블록 반복 해법과 수렴 특성

블록 구조에서 반복 해법(예: 블록 Krylov 방법, 블록 GMRES, 블록 CG 등)을 적용하면, 여러 개의 열 벡터를 동시에 갱신하여 해를 구하는 방식으로 확장할 수 있다. 예컨대 블록 GMRES를 수행하면, 잔차(residual) 벡터도 블록 형태로 묶어서 한 번에 여러 개의 선형계에 대한 정보(또는 하나의 계수 행렬에 여러 우변이 있는 다중 선형계)에 대응할 수 있다. 이런 방식은 병렬 연산 환경에서 효율성을 높일 수 있으나, 역으로 보면 한 열(혹은 한 블록)에서 발생한 오차가 다른 열로도 확산될 수 있는 경로가 생길 수 있다.

블록 Krylov 방법에서의 오차 전파를 살펴보면, 보통 정규의 Krylov 반복이 가지는 오차 축소 경향이 유사하게 나타나지만, 블록 간 중복 정보가 상호 교환되면서 미세한 불안정성이 생길 수 있다. 예컨대 어떤 블록 칼럼이 수치적으로 취약한 상태에 놓이면, 새로운 Krylov 서브스페이스 벡터를 구성할 때 그 오차가 그대로 다음 반복 단계로 확장될 가능성이 있다. 특히 정밀도가 낮은 환경에서(예: 단정도(single precision) 계산) 이러한 오차 전파 현상이 두드러질 수 있다.

블록 반복 기법에서도 예조건(preconditioner)을 도입해 수렴 속도를 개선하고, 동시에 오차가 특정 블록에서 지나치게 확대되지 않도록 제어하는 전략을 취할 수 있다. 이 과정에서도 블록 예조건자의 조건수와 구조를 면밀히 살펴, 결국 최종적으로는 $|\mathbf{r}| / |\mathbf{b}|$ 형태의 잔차 규준이 원하는 수준 이하가 되도록 조정한다. 다만 모든 블록에서 오차가 균질하게 축소되는지 확인해야 하며, 필요하다면 블록별로 다른 형태의 예조건을 적용하는 방법도 고려한다.

#### 블록 고유값 문제와 오차

선형계뿐 아니라, 고유값 문제(eigenvalue problem)에도 블록 구조를 도입할 수 있다. 대규모 행렬 $\mathbf{A}$의 몇몇 고유값과 고유벡터만을 구하고 싶거나, 특정 스펙트럼 영역만 집중적으로 분석하고 싶다면 블록 Arnoldi 방법 또는 블록 Lanczos 방법을 도입해 효율적 탐색을 할 수 있다. 이때도 오차 분석은 스칼라 Arnoldi나 Lanczos와 기본적으로 유사하지만, 블록 간 정규화(normalization)와 직교화(orthogonalization)에서 발생하는 수치 오류가 더 복합적으로 작용한다.

블록 Lanczos에서 각 반복 단계마다 얻어지는 직교화 벡터의 블록 크기가 크면 클수록, 한 단계 내에서 누적되는 직교성 손실이 더 커진다. 결과적으로 고유값 근사치가 왜곡되거나, 순서가 뒤바뀔 우려도 있다. 이를 막기 위해서는 블록 벡터를 반복 과정에서 재직교화(reorthogonalization)하거나, 추가적인 정규화 과정을 삽입해 오차가 임계치를 넘지 못하도록 관리해야 한다.

블록 고유값 해법에서의 시프트-인버스(shift-and-invert) 기법을 활용할 때에도, 블록 구조가 크게 작용한다. 시프트-인버스 방식은 $(\mathbf{A} - \sigma \mathbf{I})^{-1}$ 연산을 반복적으로 수행하며 특정 스펙트럼 근방의 고유값을 찾는다. 그러나 $\mathbf{A} - \sigma \mathbf{I}$의 블록 LU 혹은 블록 QR 분해를 매번 진행하면, 해당 역행렬 적용 과정에서 발생하는 반올림오차가 곧 고유값 근사치에 누적될 가능성이 있다. 결국 블록 단위의 오차 전파가 고유값 추정의 정확도까지 좌우하게 된다.

#### 블록 기반 HPC에서의 오차 추적

오늘날 대규모 병렬 컴퓨팅 환경(HPC)에서는 블록 구조를 활용하는 것이 거의 필수에 가깝다. GPU나 다중 노드 클러스터 상에서 고속 연산을 구현하기 위해, 큰 행렬을 작은 서브 블록으로 분할하고 이를 여러 프로세서에 배분하여 동시에 계산한다. 이러한 병렬 환경에서 오차 전파를 추적하기 위해서는, 각 노드에서 발생한 반올림오차가 통신 과정을 통해 다른 노드로 전달될 때 어떻게 증폭 또는 감소되는지를 자세히 살펴봐야 한다.

특히 블록 간 통신량을 줄이기 위해 지역(local) 정보를 최대한 활용하는 알고리즘 설계가 중요한데, 이때 지역적으로 누적된 오차가 전역(global) 해에 치명적인 악영향을 미치지 않도록 보장해야 한다. 예를 들어, 어느 한 노드에서 담당하는 블록에 발생한 숫자적 언더플로우(underflow)나 오버플로우(overflow)가 인접 블록의 계산 단계에서 조기 감지되지 못한다면, 최종 결과가 완전히 왜곡될 수 있다. 따라서 블록 구조 HPC 알고리즘에서는 부분적인 동기화(synchronization) 지점이나 자주 사용되는 통계 검사를 통해, 각 블록이 만족스러운 수치 정확도를 달성했는지 모니터링할 필요가 있다.

환경에 따라서는 이종(hybrid) 연산이 진행될 수도 있다. 어떤 블록은 CPU가 처리하고, 다른 블록은 GPU가 처리하거나, 혹은 일부 블록은 고정소수점 연산기를 사용하는 식이다. 이런 혼합 모드에서 반올림 규칙이 다르고, 데이터 형식이 호환되지 않을 경우, 블록 경계에서의 변환(conversion) 단계가 추가적인 오차를 일으킬 수 있다. 블록 구조가 커질수록 이러한 변환 지점이 늘어나므로, 최적화 단계에서 반드시 오차 전파를 평가해봐야 한다.

#### 블록 기법에서의 재배열과 스케일링

블록 구조를 더 적합하게 만들기 위해, 행렬의 행과 열을 재배열(reordering)하거나 개별 블록을 적절히 스케일링(scaling)하는 기법이 적용되기도 한다. 예컨대 어떤 블록이 단위 행렬에 가까운 구조여서 조건수가 양호하고, 다른 블록이 매우 큰 값을 갖는 구조라면, 이러한 불균형이 전체 연산의 정밀도에도 영향을 미친다. 따라서 미리 각 블록을 스케일링하여 어느 정도 균일한 크기를 갖도록 만들면, 반올림오차 발생을 줄이고 계산 안정성을 높일 수 있다.

일반적인 스케일링은 행과 열에 대각 행렬을 곱해 $\mathbf{D\_r} \mathbf{A} \mathbf{D\_c}$ 형태로 바꾼 뒤, 이 새로운 행렬에 대해 블록 분할이나 분해를 수행한다. 그 결과 스케일된 블록들 $\mathbf{A\_{ij}}$가 모두 적당한 크기를 유지하게 되면, 블록 곱셈이나 분해 과정에서 발생할 수 있는 반올림오차가 제어 가능 수준으로 떨어진다. 다만 스케일링이 너무 심하거나 적절하지 못하면, 역으로 어떤 블록이 지나치게 작아지는 부작용이 생길 수 있으므로 주의가 필요하다.

추가로, 희소 구조를 최적화하기 위해 reordering 알고리즘(예: Cuthill–McKee, Metis 등)을 이용할 때, 결과적으로 블록 대각 구조를 만들어낼 수도 있다. 이때 주어진 문제에 맞추어 희소 패턴을 최대한 유지하면서, 블록 간 연결이 최소화되도록 분할하면, 오차 전파 경로 역시 단축된다. 통신 비용이 줄어들고, 각 블록 안에서 정밀도를 관리하기 쉬워진다. 그러나 reordering 자체가 이미 스칼라 교환(swap) 연산을 수반하고, 그 과정에서 부분 피벗팅과 유사한 유형의 반올림오차가 발생할 수 있다는 점은 늘 염두에 두어야 한다.

#### 블록 구조와 다중 우변 시스템

많은 실제 응용에서, 동일한 계수 행렬 $\mathbf{A}$에 대해 서로 다른 우변 벡터 $\mathbf{b\_1}, \mathbf{b\_2}, \dots$를 갖는 다중 선형계

$$
\mathbf{A}\mathbf{x\_i} = \mathbf{b\_i}
$$

를 동시에 풀어야 할 때가 있다. 예컨대 시간 영역을 여러 지점으로 쪼개서, 물리량(압력, 온도, 전위 등)을 매 타임스텝마다 갱신하거나, 파라미터 스위핑(parameter sweeping)을 수행하는 경우 등이 그렇다. 이런 상황에서 블록 구조 기법을 사용하면, $\mathbf{B} = \[\mathbf{b\_1}\ \mathbf{b\_2}\ \dots]$ 형태로 우변을 하나의 블록 행렬로 묶고,

$$
\mathbf{A} \begin{pmatrix} \mathbf{x\_1} & \mathbf{x\_2} & \cdots \end{pmatrix} = \begin{pmatrix} \mathbf{b\_1} & \mathbf{b\_2} & \cdots \end{pmatrix} = \mathbf{B}
$$

를 해결하는 식으로 계산을 진행한다. 이 경우 블록 LU 분해나 블록 QR 분해를 한 번만 구한 뒤, 여러 우변 블록에 대해 전진대체(forward substitution)와 후진대체(back substitution) 또는 그에 해당하는 연산을 반복 수행하면 된다. 이를 통해 연산 시간을 크게 단축할 수 있지만, 그 과정에서 오차가 어떻게 축적되는지 또한 주의 깊게 살펴야 한다.

특히 다중 우변 블록 $\mathbf{B}$가 서로 스케일이 크게 다른 열(벡터)들을 포함할 때, 전진대체와 후진대체 과정에서 일부 열이 수치적으로 매우 취약해질 수 있다. 예컨대 $\mathbf{b\_1}$의 크기가 비교적 작고, $\mathbf{b\_2}$의 크기가 매우 크다면, 분해된 블록(예: $\mathbf{L}$, $\mathbf{U}$)에 들어 있는 반올림오차가 $\mathbf{x\_2}$ 계산 시에 더욱 크게 영향을 미칠 수 있다. 이를 막기 위해서는 $\mathbf{B}$를 열 단위로 적절히 스케일링하거나, 각 열에 대해 독립적인 정밀도 관리를 수행하기도 한다.

블록 구조에서 다중 우변 시스템을 풀 때 고려해야 할 또 다른 사항은 병렬화다. 우변 열이 많아질수록, 병렬로 처리할 여지가 커지며, 이는 HPC 환경에서 매우 매력적인 선택지가 된다. 그러나 블록 연산 과정에서 어떤 열(블록)이 오차에 민감한지 사전에 파악하지 못하면, 특정 노드가 다른 노드보다 훨씬 큰 반올림오차를 유발할 수도 있다. 심지어 $\mathbf{A}$가 동일하더라도, 우변 벡터의 특성(분포, 크기, 희소 패턴 등)에 따라 오차 전파 양상이 달라질 수 있다.

#### 다중 물리(multiphysics) 문제와 다중 블록

현대 과학기술 문제는 하나의 물리 모델만이 아니라, 여러 분야의 물리가 결합된 다중 물리(multiphysics) 모델을 자주 다룬다. 이를 이산화하면, 서로 다른 물리 방정식들이 각기 다른 블록에 해당하여, 전체 계수 행렬이 자연스럽게 블록 블록으로 구성된다. 예컨대 전자기장과 열 전도, 구조 해석이 상호 결합된 문제에서는,

$$
\mathbf{A} =  \begin{pmatrix} \mathbf{A\_{EE}} & \mathbf{A\_{ET}} & \mathbf{A\_{ES}} \ \mathbf{A\_{TE}} & \mathbf{A\_{TT}} & \mathbf{A\_{TS}} \ \mathbf{A\_{SE}} & \mathbf{A\_{ST}} & \mathbf{A\_{SS}} \end{pmatrix}
$$

처럼 구성될 수 있다. 여기서 $E, T, S$는 각각 전자기(electromagnetic), 열(thermal), 구조(structural)를 가리키는 블록이다. 이처럼 블록이 커지고, 블록 간 상호 작용(term coupling)이 복잡할수록, 작은 교란 오차가 다른 물리적 해석 지점으로까지 빠르게 전파된다.

다중 물리 모델의 블록 계수 행렬은 각 물리 방정식의 종류나 난이도에 따라 수치적으로 다르게 작용한다. 예컨대 전자기 방정식 블록은 보통 복소수 행렬이거나 매우 높은 스케일의 계수가 포함될 수 있고, 열 방정식 블록은 주로 실수 행렬이며, 구조 방정식 블록은 대칭 양의 정부호(symmetric positive definite)를 갖는 경우가 많다. 이런 식으로 성격이 다른 블록들이 서로 결합해 있으므로, 한 물리 블록에서 발생하는 반올림오차가 다른 블록에서 어떻게 증폭·감쇄되는지 확인하려면, 블록별 조건수뿐 아니라 블록 사이 coupling 정도, 대각 우세성 여부, 복소 행렬 특성 등을 종합적으로 살펴야 한다.

블록 분해를 이용해 다중 물리 문제를 푸는 전형적인 방법 중 하나는, 각각의 물리 블록을 독립적 서브문제로 여겨 순차 또는 병렬로 해를 구하고, 경계 혹은 인터페이스에서 상호작용 조건을 갱신하면서 여러 번 반복하는 고정점 반복 혹은 이터레이션 방식을 쓰는 것이다. 이 과정에서 수많은 블록 간 교환 연산이 일어나므로, 매 단계마다 발생하는 반올림오차가 다음 단계에 누적되어 전체 해가 수렴하는 속도와 정확도에 큰 영향을 준다. 특히 문제의 성질상 매우 큰 블록이 존재하거나(예: 전자기 블록), 비선형성을 가진 블록이 있으면(예: 열 방정식에 온도 의존성 재료 물성), 오차 전파 양상이 더욱 복잡해진다.

#### 블록 다중격자(multigrid) 기법

다중격자(multigrid) 방법을 블록 구조와 결합한 기법도 있다. 다중격자 방법은 해상도를 여러 수준(level)으로 나누어, 저해상도 격자에서 거친(global) 오차 성분을 보정하고, 고해상도 격자에서 미세(local) 오차 성분을 보정하는 식으로 작동한다. 만일 각 레벨에서의 문제를 블록 구조로 처리한다면, 레벨마다 독립적으로 나눠진 블록들이 서로 다른 스케일의 계수 행렬을 다룰 수 있다.

예컨대 레벨 1(가장 거친 격자)에서

$$
\mathbf{A}^{(1)} =  \begin{pmatrix} \mathbf{A^{(1)}*{11}} & \mathbf{A^{(1)}*{12}} \ \mathbf{A^{(1)}*{21}} & \mathbf{A^{(1)}*{22}} \end{pmatrix}
$$

을 풀고, 레벨 2에서

$$
\mathbf{A}^{(2)} =  \begin{pmatrix} \mathbf{A^{(2)}\_{11}} & \cdots \ \vdots & \ddots \end{pmatrix}
$$

등을 풀어나가는 식이다. 각 레벨에서의 오차가 블록 단위로 관리되며, 상위 레벨(더 미세한 격자)로 올라갈수록 $\mathbf{A}^{(k)}$가 대규모·고차원 구조가 되므로, 이때 발생하는 반올림오차의 누적에 주의해야 한다. 실제로 다중격자 스무딩(smoothing) 과정에서, 어떤 블록이 매우 질 나쁜 조건수를 갖고 있으면 그 레벨에서의 오차가 다음 레벨로 옮겨가는 과정에서 충분히 감소하지 못하고 잔존하게 될 수 있다.

또한 다중격자 주기(cycle) 안에서 상향이동(prolongation)과 하향이동(restriction) 오퍼레이터들도 블록 구조로 정의될 수 있다. 예컨대 서브도메인이 여러 개일 때, 각 도메인별 보간(interpolation) 혹은 제한(restriction) 연산이 독립적으로 적용된다. 이때 보간 연산에 따른 반올림오차가 실제 해상도 높은 격자에서 크게 부풀어오를 수 있으며, 제한 연산에서 소실된 부분들이 미세하지만 중요한 정보가 되어 역으로 오차 전파 경로가 만들어지기도 한다. 따라서 블록 기반 다중격자 기법에서는 각 레벨 간 전이(transfers) 단계까지 포함하여 오차 감쇠율과 전파 양상을 세밀하게 분석해야 한다.

#### 블록 수준에서의 반복적 정제(Iterative Refinement)

대규모 문제에서 직접 LU 분해 등을 통해 해를 구한 뒤, 최종적으로 남은 오차를 줄이기 위해 반복적 정제(iterative refinement)를 수행하는 경우가 많다. 보통은

$$
\mathbf{r} = \mathbf{b} - \mathbf{A}\tilde{\mathbf{x}}
$$

형태로 잔차를 구한 뒤, $\mathbf{A}\delta \mathbf{x} = \mathbf{r}$을 다시 풀어 $\tilde{\mathbf{x}} \leftarrow \tilde{\mathbf{x}} + \delta \mathbf{x}$로 갱신하는 절차를 반복한다. 이를 블록 구조로 확장하면, 각 블록에 대한 잔차를 구분하여, 국소적으로 정제를 수행하는 시나리오를 고려할 수 있다. 즉,

$$
\begin{pmatrix} \mathbf{r\_1} \ \mathbf{r\_2} \end{pmatrix} = \begin{pmatrix} \mathbf{b\_1} \ \mathbf{b\_2} \end{pmatrix} - \begin{pmatrix} \mathbf{A\_{11}} & \mathbf{A\_{12}} \ \mathbf{A\_{21}} & \mathbf{A\_{22}} \end{pmatrix} \begin{pmatrix} \tilde{\mathbf{x}}\_1 \ \tilde{\mathbf{x}}\_2 \end{pmatrix}
$$

를 계산한 뒤, 블록 미분해 상태에서 $\mathbf{A} \delta \mathbf{x} = \mathbf{r}$를 직접 풀 수도 있고, 블록 LU 분해가 존재하면 그것을 활용해 $\delta \mathbf{x}$를 구할 수도 있다. 그러나 반복적 정제를 여러 차례 돌리는 과정에서, 블록 간 교차 항에 의한 오차가 계속적으로 재주입(re-injected)될 위험도 생긴다. 예컨대 $\delta \mathbf{x}*1$ 계산 시에는 $\mathbf{r\_2}$의 오차가 $\mathbf{A*{21}}$을 통해 전파되고, 이것이 다음 반복에서 $\mathbf{r\_1}$의 계산에 영향을 미치는 식이다.

반복적 정제 기법이 블록 구조에서도 안정적으로 동작하려면, 블록 분해가 역방향 안정성을 어느 정도 확보하고 있어야 하고, 각 단계의 정제 과정에서 발생하는 반올림오차가 이전 단계의 해를 지나치게 왜곡하지 않도록 주의 깊게 설정해야 한다. 이를 위해 정제 횟수를 무작정 늘리기보다는, 중간에 적절한 재직교화(re-orthogonalization)나 재스케일링(rescaling)을 해주어 오차 전파를 최소화하는 방법이 제안되기도 한다.

#### 블록 구조에서의 균등 정확도(uniform accuracy)

블록 구조가 중첩된 문제, 혹은 상호 이질적인 물리 현상을 다루는 문제에서 유용하긴 하나, 모든 블록에서 균등하게 높은 정확도를 달성하기는 쉽지 않다. 예컨대 어떤 블록은 수치적 난이도가 높아 오차가 크게 발생하나, 다른 블록은 비교적 수월해 적은 오차만 발생하는 식으로 블록별 편차가 존재할 수 있다. 그 결과 전역적으로는 모순된 해를 만들어내거나, 특정 블록에서 비롯된 오차가 전체 시스템의 해석 결과를 지배할 수 있다.

특히 블록이 서로 상이한 물리 현상을 의미한다면, 물리적으로 중요한 블록에서 발생하는 오차를 줄이는 전략에 집중하고, 덜 중요한 블록에 대해서는 약간의 오차를 감수하는 식의 차등화 기법도 고려된다. 이는 고정소수점 연산이나 혼합 정밀도(mixed precision) 기법과 결합하여, 자원 사용량을 최적화하면서도 주요 블록의 정확도를 보장하려는 시도로 이어지곤 한다.

이러한 균등 정확도 문제는, 최종적으로 어떤 규준(norm)으로 오차를 측정하느냐에 따라 다르게 해석될 수 있다. 만일 블록별 유클리드 노름(2-노름)을 모두 동일하게 만족시켜야 한다면, 가장 취약한 블록에 맞추어 전체 계산 리소스를 늘려야 할 수도 있다. 반대로 특정 블록의 노름이 다른 블록에 비해 매우 큰 경우, 오차 전파 분석 결과 일부 블록에서의 소량 교란이 전체 오차에 크게 기여할 수 있어, 해당 블록에만 별도의 예조건이나 수치 안정화 기법을 적용하기도 한다.

#### 블록 크기 선택의 난제

블록 구조를 적용할 때, 블록을 얼마나 크게 또는 작게 잡을지 결정하는 것은 결코 단순하지 않다. 대체로 블록 크기가 커질수록 병렬화에 대한 스레드(또는 노드) 활용도가 낮아질 수 있으나, 블록 내부 연산에서의 벡터화(vectorization)나 캐시(cache) 효율은 좋아진다. 반면 블록이 지나치게 작아지면, 블록 경계가 많아지면서 통신 부하와 경계에서의 오차 전파 가능성이 동시에 커질 수 있다. 이 둘 사이에서 최적 균형점을 찾는 것이 관건이다.

또한, 블록 크기는 알고리즘 안정성 측면에서도 영향을 미친다. 블록이 너무 크면, 해당 블록 내에서 발생하는 반올림오차가 일시에 대규모로 전파될 수 있으며, 블록 LU 분해나 QR 분해 같은 연산에서 직교성 손실이나 조건수 악화를 일으킬 가능성이 높아진다. 반면 블록이 너무 작다면, 각 블록에서 발생하는 오차는 국소적이겠지만 블록 간 통신 및 경계 처리 과정에서 전체적으로 더 많은 합성(interactions)을 일으켜, 결과적으로 예기치 못한 오차 누적을 야기할 수도 있다.

실제로는 문제의 희소도(sparsity), 물리적 도메인 분할, 재배열 가능성 등을 종합적으로 고려하여 블록 크기를 설정한다. 예컨대 2D 또는 3D 격자 문제에서 한쪽 방향으로만 블록을 자를 수도 있고, 여러 방향으로 등분할할 수도 있다. 병렬 시스템의 구조(GPU, 멀티코어, 클러스터 등)도 블록 선택에 있어 중요한 요소다.

#### 사례 연구: 블록 구조를 이용한 유한요소 해석

유한요소법(FEM)으로 유체 역학 혹은 구조 역학 문제를 풀 때, 시스템은 자연스럽게 블록 구조가 되기도 한다. 예컨대 어떤 문제에서 변위(displacement)와 압력(pressure)을 동시에 풀어야 하거나, 전기장과 자성장 방정식을 결합한 PDE를 풀어야 할 때, 각 물리량에 대응하는 자유도(degree of freedom)가 부분 행렬로서 블록을 형성한다. 다음과 같은 예시를 생각해 볼 수 있다.

$$
\begin{pmatrix} \mathbf{K\_{uu}} & \mathbf{K\_{up}} \ \mathbf{K\_{pu}} & \mathbf{K\_{pp}} \end{pmatrix} \begin{pmatrix} \mathbf{u} \ \mathbf{p} \end{pmatrix} = \begin{pmatrix} \mathbf{f\_u} \ \mathbf{f\_p} \end{pmatrix},
$$

여기서 $\mathbf{u}$는 변위 벡터, $\mathbf{p}$는 압력(또는 라그랑주 승수, 다른 물리량 등) 벡터를 나타낸다. $\mathbf{K\_{uu}}, \mathbf{K\_{up}}, \mathbf{K\_{pu}}, \mathbf{K\_{pp}}$는 각각 해당 블록의 계수 행렬이다. 이 시스템을 직접 풀거나 반복 해법을 적용할 때, 블록 단위로 처리가 가능하므로 수치적 효율이 좋아진다. 그러나 $\mathbf{K\_{pu}}, \mathbf{K\_{up}}$가 많이 밀집되어 있거나, 조건수가 안 좋은 경우라면, 작은 오차가 빠르게 전역으로 확산될 수 있다.

블록 피벗팅, 블록 재배열, 블록 LU 분해, 혹은 블록 Schur 보완 방식을 사용해도 마찬가지로 오차 전파를 주의 깊게 살펴야 한다. 예컨대 슈어 보완 $\mathbf{S} = \mathbf{K\_{pp}} - \mathbf{K\_{pu}} \mathbf{K\_{uu}}^{-1} \mathbf{K\_{up}}$의 조건수가 불량하면, 작은 라운딩 에러라도 크게 증폭될 위험이 크다. 이러한 이유로, FEM 문제에서의 블록 구조 해법은 종종 문제 특성(대칭성, 양의 정부호성, 혼합 요소, 구속 조건 등)에 맞게 특별히 설계된 예조건 기법이나 크기 조정(scaling) 전략과 함께 쓰인다.

#### 블록 안정화 기법의 예

블록 구조 해법을 쓸 때, 부가적인 안정화 기법(stabilization technique)을 도입하여 오차 전파를 막으려는 시도가 많다. 대표적으로,

* **블록 대각 사전조건(block diagonal preconditioning)** 큰 블록들을 대각선 위로만 추출해, 그 부분만을 정확히(또는 근사적으로) 역행렬 형태로 사용하고, 오프 블록들은 무시하거나 희소 근사로 대체한다. 이를 통해 블록 대각 항 자체에 대한 오차 전파는 줄이고, 나머지 연산은 반복 해법을 통해 보정한다.
* **블록 주대각선 균질화(heavy diagonal scaling)** 블록 크기가 지나치게 다른 경우, 큰 블록의 특정 행이나 열에 대각 스케일을 곱해줘서 수치적으로 균형을 맞춘다. 그러면 곱셈 또는 분해 과정에서 계산이 조금 더 안정적으로 이뤄지고, 병렬 배분 시에도 연산이 고르게 분산될 가능성이 높아진다.
* **블록별 재직교화(orthonormalization)** 직교 기반 해법(블록 QR, 블록 Krylov, 블록 Lanczos 등)을 사용할 때, 각 블록 벡터가 일정 수준 이상의 직교성을 잃지 않도록 주기적으로 재직교화 단계(예: Modified Gram–Schmidt)를 적용한다. 스칼라 방식보다 연산 비용이 크긴 하지만, 블록 크기가 크고 반복 횟수가 많을 경우 직교성 손실이 도미노처럼 번지는 사태를 방지할 수 있다.
* **블록 재분할(block repartitioning)** 계산 과정 중간에, 더 효율적인 병렬 활용과 오차 제어를 위해 블록 경계를 재설정하는 방법. 예컨대 처음에는 고정된 크기로 블록을 나누었다가, 특정 단계에서 오차가 집중되는 부분을 찾아 블록을 재귀적으로 분할한다거나, 반대로 과도하게 잘게 나눠진 블록을 합치는 식이다.

이와 같은 안정화 기법들은 문제 특성에 따라 서로 조합되기도 하며, 적절한 파라미터(예: 재직교화 빈도, 스케일링 계수, 재분할 시점 등)를 선택해야 한다.

#### 블록 구조 오차 분석의 향후 과제

블록 구조를 이용한 수치해석 알고리즘은 계속해서 발전 중이며, 특히 대규모 HPC 환경에서 표준적인 방식으로 자리를 잡아가고 있다. 동시에, 오차 분석 측면에서는 여전히 풀리지 않은 난제들이 많다. 예컨대,

* 복합 다중 물리 모델에서, 서로 다른 비선형 요소들이 블록 구조로 분할되어 있을 때 오차가 어떤 패턴으로 교차-증폭(cross-amplification)되는가.
* 매우 큰 크기의 블록 구조를 다루는 GPU·멀티코어 환경에서, 정확도가 어느 한계 이하로 떨어지지 않도록 보장하는 방법은 무엇인가.
* 혼합 정밀도 계산, 저랭크 근사, 재배열·피벗팅 등이 복합적으로 적용될 때 오차 전파를 정밀하게 추적할 수 있는 모델은 어떻게 구축하는가.
* 블록 역방향 안정성(backward stability)을 이론적·실험적으로 평가할 수 있는 체계적 도구가 더 필요한 것은 아닌가.

이러한 과제들을 해결하기 위해서는, 전통적인 수치해석 방법론뿐 아니라, 병렬 컴퓨팅, 메모리 계층 구조, 부동소수점 표준(IEEE 754, bf16 등)에 대한 깊은 이해가 동반되어야 한다.
