Метод прогонки, також відомий як алгоритм Томаса, дозволяє розв'язувати СЛАР з Тридіагональною матрицею, і є спрощенням методу Гауса для таких обмежень. Працює за лінійний час.
Система має такий вигляд:
де
та
. В матричній формі це записується так:
В цілому, метод не є числово стійким, але є таким у декількох випадках, таких як діагонально панівна матриця або додатноозначена матриця.[1]
Розв'язок проводиться в два кроки, як і в методі Гауса, прямому, та зворотному. В прямому ході ми обчислюємо:
та
Тепер розв'язок знаходимо зворотнім ходом:
/* Розв'язок повертається в x. c та d модифікуються!*/
void TridiagonalSolve (const double *a, const double *b, double *c, double *d, double *x, unsigned int n){
/* Modify the coefficients. */
c[0] /= b[0]; /* Division by zero risk. */
d[0] /= b[0]; /* Division by zero would imply a singular matrix. */
for (unsigned int i = 1; i < n; i++){
double id = 1 / (b[i] - c[i-1] * a[i]); /* Division by zero risk. */
c[i] *= id; /* Last value calculated is redundant. */
d[i] = (d[i] - d[i-1] * a[i]) * id;
}
/* Now back substitute. */
x[n - 1] = d[n - 1];
for (int i = n - 2; i >= 0; i--)
x[i] = d[i] - c[i] * x[i + 1];
}
Доведення методу вимагає ручного виконання деяких спеціалізованих Гаусових вилучань.
Припустимо, що невідомі - це
, і що рівняння до розв'язання такі:
![{\displaystyle {\begin{aligned}b_{1}x_{1}+c_{1}x_{2}&=d_{1};&i&=1\\a_{i}x_{i-1}+b_{i}x_{i}+c_{i}x_{i+1}&=d_{i};&i&=2,\ldots ,n-1\\a_{n}x_{n-1}+b_{n}x_{n}&=d_{n};&i&=n.\end{aligned}}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/dd8bbff3bb4e36f120d59ecc7c5854a2137da246)
Розглянемо таку зміну другого (
) рівняння за допомогою першого рівняння:
![{\displaystyle ({\mbox{equation 2}})\cdot b_{1}-({\mbox{equation 1}})\cdot a_{2}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/096af1f0329b463e799af9020b2c5f6cf26568d4)
що дасть:
![{\displaystyle (a_{2}x_{1}+b_{2}x_{2}+c_{2}x_{3})b_{1}-(b_{1}x_{1}+c_{1}x_{2})a_{2}=d_{2}b_{1}-d_{1}a_{2}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/a017059f504db572accc852057a5c84403c4f1bf)
![{\displaystyle (b_{2}b_{1}-c_{1}a_{2})x_{2}+c_{2}b_{1}x_{3}=d_{2}b_{1}-d_{1}a_{2}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/c29f11b54ef0df02fc78dadc5d3d31cbba5607d8)
у висліді маємо, що
було вилучено з другого рівняння. Використовуючи подібну тактику зі зміненим другим рівнянням, щодо третього маємо:
![{\displaystyle (a_{3}x_{2}+b_{3}x_{3}+c_{3}x_{4})(b_{2}b_{1}-c_{1}a_{2})-((b_{2}b_{1}-c_{1}a_{2})x_{2}+c_{2}b_{1}x_{3})a_{3}=d_{3}(b_{2}b_{1}-c_{1}a_{2})-(d_{2}b_{1}-d_{1}a_{2})a_{3}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/c01caf36ba33be3c38d0350f01021637a05f34ef)
![{\displaystyle (b_{3}(b_{2}b_{1}-c_{1}a_{2})-c_{2}b_{1}a_{3})x_{3}+c_{3}(b_{2}b_{1}-c_{1}a_{2})x_{4}=d_{3}(b_{2}b_{1}-c_{1}a_{2})-(d_{2}b_{1}-d_{1}a_{2})a_{3}.\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/8a460726ec8f0360b2fcf5444bed76c510ade53b)
Цього разу було вилучено
якщо повторювати цю процедуру до рядка
; (змінене) рівняння
міститиме лише одну змінну,
. Таке рівняння ми можемо розв'язати і використати результат для того, щоб розв'язати рівняння
і так далі допоки всі невідомі не знайдені.
Очевидно, що коефіцієнти у змінених рівняннях ставатимуть все більш заплутаними якщо розписувати їх явно. Але змінені коефіцієнти (з тильдою) можна виразити рекурсивно:
![{\displaystyle {\tilde {a}}_{i}=0\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/e210c99a1f6ca6935924b3a37cd9fd0966cdd31b)
![{\displaystyle {\tilde {b}}_{1}=b_{1}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/d665fe279e901efb3378f9e9ac51ecd9fb49208f)
![{\displaystyle {\tilde {b}}_{i}=b_{i}{\tilde {b}}_{i-1}-{\tilde {c}}_{i-1}a_{i}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/24b90c138b7f767b0f3c44574ffd36a26f1b7707)
![{\displaystyle {\tilde {c}}_{1}=c_{1}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/39c3a3f4eaa3d60f01b50b55dbed91e57e899e46)
![{\displaystyle {\tilde {c}}_{i}=c_{i}{\tilde {b}}_{i-1}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/d35d457feb1abd9fcb08bf12e6d4bbd2e2980dfa)
![{\displaystyle {\tilde {d}}_{1}=d_{1}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/c34a1db69df8d939794c22bf58784ed96b39602d)
![{\displaystyle {\tilde {d}}_{i}=d_{i}{\tilde {b}}_{i-1}-{\tilde {d}}_{i-1}a_{i}.\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/6c3a39e54d53a19db46fc28b7343cfd41fbc6c42)
Для дальшого пришвидшення процесу,
можна нормувати діленням (якщо немає ризику ділення на число занадто близьке до нуля), тепер змінені коефіцієнти позначені рисочкою будуть:
![{\displaystyle a'_{i}=0\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/16fd2284497345375ae65c8e50eacc93f959081d)
![{\displaystyle b'_{i}=1\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/39dbee4e6fc82b634eef00a5979ea6e314ec3f80)
![{\displaystyle c'_{1}={\frac {c_{1}}{b_{1}}}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/81f1effc1938252a160342264da02ae179760427)
![{\displaystyle c'_{i}={\frac {c_{i}}{b_{i}-c'_{i-1}a_{i}}}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/6801d9c76438832156d061920d752f6dc47dae8e)
![{\displaystyle d'_{1}={\frac {d_{1}}{b_{1}}}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/346ef5d869bd41ed9c6adb71a84f5a96a0473a3d)
![{\displaystyle d'_{i}={\frac {d_{i}-d'_{i-1}a_{i}}{b_{i}-c'_{i-1}a_{i}}}.\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/bf51e4af0878575a20f3cc1fe541b747b64c4345)
це дає нам наступну систему з тими самими невідомими і коефіцієнтами вираженими через початкові:
![{\displaystyle {\begin{array}{lcl}b'_{i}x_{i}+c'_{i}x_{i+1}=d'_{i}\qquad &;&\ i=1,\ldots ,n-1\\b'_{n}x_{n}=d'_{n}\qquad &;&\ i=n.\\\end{array}}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/071afe13dc3a480d11ec8b2d8252e9fd5fc12ff5)
Останнє рівняння містить лише одне невідоме. Розв'язуючи його, приводимо наступне останнє рівняння до одного невідомого. І так далі:
![{\displaystyle x_{n}=d'_{n}/b'_{n}\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/9b61c47987edb32dffd55e1178282764e500cfe9)
![{\displaystyle x_{i}=(d'_{i}-c'_{i}x_{i+1})/b'_{i}\qquad ;\ i=n-1,n-2,\ldots ,1.}](https://wikimedia.org/api/rest_v1/media/math/render/svg/96bafb4d2c46cf9d47ba6ef61c1365eed7da12c5)
- ↑ Pradip Niyogi (2006). Introduction to Computational Fluid Dynamics. Pearson Education India. с. 76. ISBN 978-81-7758-764-7.