Текст подпрограммы и версий ass1r_c.zip , ass1d_c.zip |
Тексты тестовых примеров tass1r_c.zip , tass1d_c.zip |
Решение систем линейных алгебраических уравнений с разреженными матрицами методом сопряженных градиентов.
ass1r_c вычисляет решение системы линейных алгебраических уравнений Ax = b (где A - квадратная матрица общего вида, в том числе разреженная, порядка N) с заданной точностью EPS методом сопряженных градиентов, а также сумму квадратов компонент вектора невязки Ax - b .
Н.С.Бахвалов. Численные методы. Изд - во "Наука", 1973.
int ass1r_c (real *b, integer *n, S_fp suba, S_fp subat, real *x, real *rsq, integer *itmax, real *eps, real *g, real *h, real *xi, real *xj, integer *ierr)
Параметры
b - | вещественный вектор длины n, содержащий компоненты вектора правой части системы; |
n - | порядок матрицы системы (тип: целый); |
suba - |
подпрограмма вычисления вектора ax, первый оператор
которой имеет вид: int suba (float *x, float *ax), где x - вещественный вектор длины n, содержащий текущий вектор решения x; ax - вещественный вектор длины n, содержащий результирующий вектор ax; |
subat - |
подпрограмма вычисления вектора atx, первый оператор
которой имеет вид: int subat (float *x, float *atx), где x - вещественный вектор длины n, содержащий текущий вектор решения x; atx - вещественный вектор длины n, содержащий результирующий вектор atx; |
x - | вещественный вектор длины n, содержащий на входе в подпрограмму начальное приближение к решению системы, а на выходе - вычисленное решение системы; |
rsq - | вещественная переменная, содержащая вычисленную сумму квадратов компонент вектора невязки ax - b; |
itmax - | заданное максимальное допустимое количество итераций метода сопряженных градиентов (тип: целый); |
eps - | заданная точность, с которой необходимо вычислить решение системы (тип: вещественный); |
g, h, - xi, xj | вещественные векторы длины n, используемые в подпрограмме в качестве рабочих; |
ierr - | целая переменная, служащая для сообщения об ошибках, обнаруженных в ходе работы подпрограммы; при этом |
ierr=65 - | когда матрица системы вырождена; |
ierr=66 - | когда заданная точность не может быть достигнута за максимальное количество итераций. |
Версии
ass1d_c - | решение систем линейных алгебраических уравнений с разреженными матрицами методом сопряженных градиентов в режиме удвоенной точности. При этом параметры b, x, rsq, eps, g, h, xi, xj должны иметь тип double. |
Вызываемые подпрограммы
utas10_c - | подпрограмма выдачи диагностических сообщений при работе подпрограммы ass1r_c. |
utas11_c - | подпрограмма выдачи диагностических сообщений при работе подпрограммы ass1d_c. |
Замечания по использованию
В качестве начального приближения к решению системы может быть взят нулевой вектор. Все особенности структуры матрицы a системы должны учитываться в подпрограммах suba и subat. Если значение rsq велико, то это означает, что матрица системы близка к вырожденной и полученный вектор x представляет собой наилучшее приближение к решению в смысле наименьших квадратов. В подпрограммах ass1r_c и ass1d_c имеется внешняя структура с именем ass1rr_ , содержащая элемент целого типа iter. По окончании работы этих подпрограмм значение переменной iter полагается равной количеству выполненных итераций метода сопряженных градиентов. |
struct { int iter; } ass1rr_; #define ass1rr_1 ass1rr_ struct { float a[100] /* was [10][10] */; } _BLNK__; #define _BLNK__1 _BLNK__ int main(void) { /* System generated locals */ int i__1, i__2; /* Local variables */ extern int suba_c(); static int ierr; extern int ass1r_c(float *, int *, U_fp, U_fp, float *, float *, int *, float *, float *, float *, float *, float *, int *); static float b[10], g[10], h__[10]; static int i__, j, n; static float r__, x[10]; extern int subat_c(); static int itmax; static float xi[10], xj[10], eps, rsq; #define a_ref(a_1,a_2) _BLNK__1.a[(a_2)*10 + a_1 - 11] n = 10; i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { x[i__ - 1] = 0.f; /* l1: */ b[i__ - 1] = 1.f; } r__ = .1f; i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = n; for (j = 1; j <= i__2; ++j) { /* l2: */ a_ref(i__, j) = 0.f; } } i__2 = n; for (i__ = 1; i__ <= i__2; ++i__) { a_ref(i__, i__) = r__; /* l3: */ r__ += .1f; } eps = 1e-5f; itmax = n * 10; ass1r_c(b, &n, (U_fp)suba_c, (U_fp)subat_c, x, &rsq, &itmax, &eps, g, h__, xi, xj, &ierr); for (i__ = 0; i__ <= 5; i__+=5) { printf("\n %15.5e %15.5e %15.5e %15.5e %15.5e \n", x[i__], x[i__+1], x[i__+2], x[i__+3], x[i__+4]); } printf("\n %15.5e \n", rsq); printf("\n %5i \n", ass1rr_1.iter); return 0; } /* main */ int suba_c(float *x, float *v) { /* System generated locals */ int i__1, i__2; /* Local variables */ static int i__, j, n; #define a_ref(a_1,a_2) _BLNK__1.a[(a_2)*10 + a_1 - 11] /* Parameter adjustments */ --v; --x; /* Function Body */ n = 10; i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { v[i__] = 0.f; i__2 = n; for (j = 1; j <= i__2; ++j) { /* l1: */ v[i__] += a_ref(i__, j) * x[j]; } } return 0; } /* suba_c */ int subat_c(float *x, float *v) { /* System generated locals */ int i__1, i__2; /* Local variables */ static int i__, j, n; #define a_ref(a_1,a_2) _BLNK__1.a[(a_2)*10 + a_1 - 11] /* Parameter adjustments */ --v; --x; /* Function Body */ n = 10; i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { v[i__] = 0.f; i__2 = n; for (j = 1; j <= i__2; ++j) { /* l1: */ v[i__] += a_ref(j, i__) * x[j]; } } return 0; } /* subat_c */ Результаты: x = ( 10 , 5 , 10/3 , 2.5 , 2 , 5/3 , 10/7 , 1.25 , 10/9 , 1 ) rsq = 0.19785e - 8 iter = 11