Текст подпрограммы и версий
zf30r_c.zip  zf30d_c.zip 
Тексты тестовых примеров
tzf30r_c.zip  tzf30d_c.zip 

Подпрограмма:  zf30r_c

Назначение

Решение системы  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