Текст подпрограммы и версий zf30r_c.zip zf30d_c.zip |
Тексты тестовых примеров tzf30r_c.zip tzf30d_c.zip |
Решение системы n нелинейных уравнений с n неизвестными методом Брауна.
zf30r_c находит решение системы N нелинейных уравнений F (X) = 0 с N неизвестными. Подпрограмма использует метод Брауна, который имеет по крайней меpе квадратичную сходимость и требует N2/2 + 3N/2 вычислений F (X) за один шаг итерации.
K.M.Brown, A Quadratically Convergent Newton - like Method Based upon Gaussian Elimination, SIAM on Numerical Analysis, 6 (4), 1969.
int zf30r_c (R_fp f, integer *n, real *eps, integer *ndig, integer *itmax, real *root, real *rab, integer *ierr)
Параметры
f - | имя подпрограммы - функции последовательного вычисления компонент системы F (X) = 0 , которая должна быть оформлена как float f (float *x, int *k), где k - номеp вычисляемой компоненты системы, k = 1, 2, ..., n; |
n - | заданное число уравнений системы (тип: целый); |
eps - | первый критерий сходимости: X0 принимается за решение системы F (X) = 0 , если | F (X0) | ≤ | eps | (тип: вещественный); |
ndig - | второй критерий сходимости: заданное число значащих цифр, с которыми ищется решение системы (тип: целый); |
itmax - | целая переменная, значение которой перед началом работы подпрограммы должно быть положено равным максимальному числу итераций, ориентировочно требуемых для обеспечения сходимости; в pезультате работы подпрограммы ее значение полагается равным действительному числу итераций, потребовавшихся для обеспечения сходимости в соответствии с заданными критериями; |
root - | вещественный вектоp длины n, содержащий вычисленное решение заданной системы; перед началом работы подпрограммы вектоp root должен содержать начальное приближение к решению; |
rab - | вещественный вектоp длины ((n + 2) (n - 1)) / 2 + 3n, используемый в подпрограмме как рабочий; |
ierr - | целая переменная, служащая для сообщения об ошибках, обнаруженных в ходе работы подпрограммы; при этом: |
ierr=65 - | когда решение системы не может быть найдено в пределах заданного числа итераций; |
ierr=66 - | когда якобиан заданной системы имеет особенность. |
Версии
zf30d_c - | решение системы n нелинейных уравнений с n неизвестными методом Брауна с повышенной точностью. При этом параметры eps, root и rab должны иметь тип double, а подпрограмма - функция последовательного вычисления компонент заданной системы должна быть оформлена как double f (double *x, int *k), где вектоp x также должен иметь тип double. |
Вызываемые подпрограммы
utzf10_c - | подпрограмма выдачи диагностических сообщений при работе подпрограммы zf30r_c. |
utzf11_c - | подпрограмма выдачи диагностических сообщений при работе подпрограммы zf30d_c. |
Замечания по использованию
При обращении к подпрограмме может быть задан только первый критерий сходимости (тогда ndig задается равным 0), либо только второй критерий (тогда eps задается равным 0), либо оба критерия одновременно. Пусть xi - 1 и xi являются двумя последовательными приближениями к искомому решению системы F (X) = 0. Тогда xi принимается за искомое решение, если выполнен один из двух критериев сходимости: | F(xi) | ≤ | eps | для всех компонент системы или | xi -1 - xi | < | xi | * 10 (- ndig ) . B случае ierr = 65 или ierr = 66 можно попробовать другое начальное приближение и (или) дополнительно исследовать систему с целью возможного исключения лишних уравнений или переменных, а также с целью возможного выражения одних переменных через другие. Подпрограмма может быть использована для вычисления нуля вещественной функции. Подпрограмма - функция последовательного вычисления компонент заданной системы должна иметь вид: float f_c(float *x, int *k) { ... switch (*k) { case 1: goto l5; case 2: goto l10; ... } l5: /* вычисление первой компоненты системы для заданного x */ ... goto l900; l10: /* вычисление второй компоненты системы для заданного x */ ... goto l900; ... ... l900: return ret_val; } |
int main(void) { /* Local variables */ static int nsig, ierr; extern int zf30r_c(R_fp, int *, float *, int *, int *, float *, float *, int *); extern float f_c(); static int n; static float x[3]; static int itmax, i; static float wa[14], eps; eps = 1e-6f; nsig = 5; /* l3: */ x[0] = .75f; x[1] = 1.5f; x[2] = 4.f; n = 3; itmax = 100; zf30r_c((R_fp)f_c, &n, &eps, &nsig, &itmax, x, wa, &ierr); printf("\n %5i \n", n); printf("\n %16.7e \n", eps); printf("\n %5i %5i \n", nsig, itmax); printf("\n %5i \n", ierr); printf("\n %16.7e %16.7e %16.7e \n", x[0], x[1], x[2]); for (i = 0; i <= 12; i += 2) { printf("\n %16.7e %16.7e \n", wa[i], wa[i+1]); } return 0; } /* main */ float f_c(float *x, int *k) { /* System generated locals */ float ret_val, r__1; /* Builtin functions */ double exp(double), sin(double); /* Parameter adjustments */ --x; /* Function Body */ switch (*k) { case 1: goto l5; case 2: goto l10; case 3: goto l15; } l5: /* Computing 2nd power */ r__1 = x[2] + x[3]; ret_val = x[1] + (float)exp(x[1] - 1.f) + r__1 * r__1 - 27.f; goto l900; l10: /* Computing 2nd power */ r__1 = x[3]; ret_val = x[1] * (float)exp(x[2] - 2.f) + r__1 * r__1 - 10.f; goto l900; l15: /* Computing 2nd power */ r__1 = x[2]; ret_val = x[3] + (float)sin(x[2] - 2.f) + r__1 * r__1 - 7.f; l900: return ret_val; } /* f_c */ Результаты: root(1) = 1. , root(2) = 2. , root(3) = 3. itmax = 6 , ierr = 0