|
Текст подпрограммы и версий 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