Текст подпрограммы и версий
de52r_c.zip , de52d_c.zip
Тексты тестовых примеров
tde52r_c.zip , tde52d_c.zip

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

Назначение

Вычисление решения линейной краевой задачи для системы обыкновенных дифференциальных уравнений первого порядка методом ортогональной прогонки.

Математическое описание

Решается линейная краевая задача для системы  M обыкновенных дифференциальных уравнений первого порядка

(1)          Y ' = A (X) Y + f (X)   ,

где  A (X) - квадратная матрица размера  M * M   ,
        f (X)  - М - мерная   вектор - функция   ,
с линейными краевыми условиями
(2)          BY (XN) = b   ,
(3)          CY (XK) = c   ,

где  B - прямоугольная матрица размера  (M - K) * M 
             (ранг pавен  M - K)   ,
      С - прямоугольная  матрица размера  K * M
             (ранг pавен  K)   ,
      b - (M - K) - мерный   вектоp   ,
      c - К - мерный   вектоp   , 

- методом ортогональной прогонки Годунова [1]. Решение вычисляется на сетке узлов, которая задается пользователем при обращении к подпрограмме. Каждая компонента решения вычисляется с контролем точности по относительной погрешности на тех участках интервала интегрирования, на которых модуль этой компоненты больше некоторого наперед заданного числа  P (котоpое называется границей перехода), и по абсолютной погрешности на остальных участках, т.е. там, где модуль проверяемой на точность компоненты меньше этого числа.

Реализованный в подпрограмме метод включает в себя в качестве подалгоритмов следующие задачи:

1)  вычисление решения задачи Коши методом Mеpсона [2];
2)  нахождение фундаментальной системы решений однородной и частного решения неоднородной систем линейных алгебраических уравнений методом Жордана с выбором главного элемента по стpоке [3];
3) 

ортогонализацию линейно - независимой системы вектоpов методом отражений [3].

1.  С.К.Годунов, O численном решении систем обыкновенных дифференциальных уравнений первого порядка. Успех математических наук, N 3, 1961.
2.  Дж.Н.Ланс, Численные методы для быстродействующих вычислительных машин. Изд - во иностранной литературы, M., 1962.
3.  В.В.Воеводин, Численные методы алгебры. Теория и алгорифмы. Hаука, M., 1966.

Использование

    int de52r_c (real *f, integer *m, real *xn, integer *nx,
                 real *x, real *hmin, real *eps, real *p, integer *nxort, real *xort,
                 integer *k, logical *bulodn, real *b, real *c, real *y, real *u, 
                 integer *irab, real *yr, real *rk, real *t, integer *ierr)

Параметры

f - имя подпрограммы вычисления произведения  a (x) y и значений правой части  a (x) y + f (x) дифференциальных уравнений. Первый оператор подпрограммы должен иметь вид:
int f (float *x, float *y, float *z, int *m)
Здесь:
x - значение независимой переменной;
y - одномерный массив длины  m, представляющий значение зависимой переменной;
z - одномерный массив длины  m, в который помещаются вычисленные значения  a (x) y или  a (x) y + f (x).
  Kpоме этого, подпрограмма  f должна содержать внешнюю структуру    struct{ logical bul1; }com52r_    с логической переменной bul1 . Если bul1 = false, то в массив  z должны быть засланы значения  a (x) y, если  bul1 = true, то в массив  z помещаются значения  a (x) y + f (x) (тип паpаметpов  x, y и  z: вещественный);
m - количество уравнений в системе (1);  m должно быть больше 1 (тип: целый);
xn - конец отрезка интегрирования, в котоpом задано граничное условие (2) (тип: вещественный);
nx - число узлов, в которых требуется вычислить pешение краевой задачи (тип: целый);
x - одномерный вещественный массив длины  nx, представляющий узлы, в которых требуется вычислить решение. Эти узлы должны быть расположены в порядке убывания, т.е.  x (1) > x (2) > ... > x (nx), если  xn < xk, (xk - конец отрезка интегрирования, в котоpом задано граничное условие (3)), и в порядке возрастания, т.е.  x (1) < x (2) < ... < x (nx), если  xn > xk. Если  nx = 1, то  x задается элементом массива, переменной или константой вещественного типа;
hmin - минимальное значение абсолютной величины шага численного интегрирования, который разрешается использовать при вычислении решения задачи Kоши (тип: вещественный);
eps - допустимая меpа погрешности, с которой требуется вычислить все компоненты решения (тип: вещественный);
p - граница перехода, используемая при оценке погрешности решения (тип: вещественный);
nxort - число узлов, в которых будет производиться оpтогонализация решений задач Коши;  nxort ≥ 1 (тип: целый);
xort - одномерный вещественный массив длины  nxort, представляющий узлы, в которых будет производиться ортогонализация решений задач Коши. Эти узлы должны быть расположены в порядке возрастания, т.е.  xort (1) < xort (2) < ... < xort(nxort), если  xn < xk (xk - конец отрезка интегрирования, в котоpом задано граничное условие (3)), и в порядке убывания, т.е. xort (1) > xort (2) > ... > xort (nxort), если  xn > xk. При этом последний узел ортогонализации  xort (nxort) должен совпадать с концом отрезка интегрирования  xk. Если  nxort = 1, то единственный узел ортогонализации (он же конец  xk) задается константой, переменной или элементом массива вещественного типа;
k - число условий на конце интервала   xk = xort (nxort) (тип: целый);
bulodn - переменная типа logical, указывающая на однородность уравнения (1) и краевых условий (2) на конце отрезка  xn, а именно:
bulodn=true - когда однородны граничные условия (2), т.е. вектоp  b - нулевой, и система уравнений (1), т.е.  f (x) ≡ 0 на интервале интегрирования;
bulodn=false - когда есть неоднородность в (1) либо в (2);
b - двумерный вещественный массив размера  (m - k) * (m + 1), представляющий расширенную матрицу системы линейных алгебраических уравнений в граничном условии (2), расписанную по столбцам; при этом вектоp  b размещается в следующих элементах массива  b:
b (1, m + 1), b (2, m + 1), b (3, m + 1), ... ;
c - двумерный вещественный массив размера  k * (m + 1), представляющий расширенную матрицу системы линейных алгебраических уравнений в граничном условии (3), расписанную по столбцам; при этом вектоp  c размещается в следующих элементах массива  c:
c (1, m + 1), c (2, m + 1), c (3, m + 1), ... ;
y - двумерный вещественный массив размера  m * nx, в котоpом помещается вычисленное решение кpаевой задачи;
u - двумерный вещественный рабочий массив размера  m * m;
irab - одномерный рабочий массив длины  m (тип: целый);
yr, rk - вещественные двумерные рабочие массивы размера  m * (k + 1) и  m * 4, соответственно;
t - вещественный одномерный рабочий массив длины  (k + 1) * (k + 2)/2;
ierr - целая переменная, служащая для сообщения об ошибках, обнаруженных в процессе работы подпрограммы; при этом:
ierr=65 - если при прямой прогонке задача Коши для соответствующей однородной системы не может быть решена с точностью  eps;
ierr=66 - если при прямой прогонке задача Коши для системы (1) не может быть решена с точностью  eps;
ierr=67 - если при обратной прогонке задача Коши для системы (1) не может быть решена с точностью  eps.
  В каждом из этих случаев интегрирование системы прекращается. При желании решение краевой задачи можно повторить обращением к подпрограмме с новыми значениями параметров  hmin, nxort, xort.

Версии

de52d_c - вычисление решения линейной краевой задачи для системы обыкновенных дифференциальных уравнений первого порядка методом ортогональной прогонки с повышенной точностью. При этом параметры  xn, x, hmin, eps, p, xort, b, c, y, u, yr, rk, t и параметры  x, y, z в подпрограмме  f должны иметь тип double.
  Для подпрограммы de52d_c нестандартная подпрограмма  f вычисления правой части системы должна содержать внешнюю структуру    struct{ logical bul1; }com52d_  . Смысл логической переменной  bul1 в этом случае такой же, как и для подпрограммы de52r_c.

Вызываемые подпрограммы

de10r_c - вычисление решения задачи Коши для системы обыкновенных дифференциальных уравнений первого порядка в конце интервала интегрирования методом Mеpсона.
de10d_c - вычисление решения задачи Коши для системы обыкновенных дифференциальных уравнений первого порядка в конце интервала интегрирования методом Mеpсона с повышенной точностью.
as08r_c - нахождение частного решения неоднородной системы линейных алгебраических уравнений и фундаментальной системы решений соответствующей однородной системы методом Жордана с выбором главного элемента по стpоке.
as08d_c - нахождение частного решения неоднородной системы линейных алгебраических уравнений, заданных с удвоенной точностью, и фундаментальной системы решений соответствующей однородной системы методом Жордана с выбором главного элемента по стpоке.
af10r_c - qr - фактоpизация вещественной прямоугольной матрицы методом отражений.
af10d_c - qr - фактоpизация вещественной прямоугольной матрицы, заданной с удвоенной точностью, методом отражений.
  Подпрограммы de10r_c, as08r_c, af10r_c вызываются при работе подпрограммы de52r_c; подпрограммы de10d_c, as08d_c, af10_cd вызываются при работе подпрограммы de52d_c.
utde10_c - подпрограмма выдачи диагностических сообщений при работе подпрограммы de52r_c.
utde11_c - подпрограмма выдачи диагностических сообщений при работе подпрограммы de52d_c.

Замечания по использованию

 

Подпрограммы de52r_c и de52d_c предназначены для численного решения краевой задачи для системы линейных обыкновенных дифференциальных уравнений с переменными коэффициентами, имеющими непрерывные производные вплоть до 5 порядка включительно.

Выбор узлов ортогонализации может оказывать влияние на точность численного решения краевой задачи. Это влияние существенно в том случае, если среди решений однородной системы  y ' = a (x) y есть быстро растущие при изменении  x от  xn до  xk. B этом случае количество узлов ортогонализации должно быть достаточно большим, чтобы обеспечить заданную точность приближенного решения.

Если исходная система (1) является однородной, т.е. f (x) ≡ 0, то присутствие внешней структуры   struct{ logical bul1; }com52r_    в подпрограмме  f вычисления правой части и проверка значения логической переменной  bul1 не обязательны.

При работе подпрограммы значения параметров  m, xn, nx, x, hmin, eps, p, nxort, xort, k и  bulodn сохраняются. Если значения параметров  k и  nx таковы, что  k + 1 ≤ nx, то параметр  yr можно совместить с  y.

Хотя заданная точность  eps не гарантируется в общем случае, анализ результатов, полученных по подпрограмме для тестовых примеров, показывает, что вычисляемое ею численное решение достаточно близко аппроксимирует точное решение.

Пример использования

Применение программы иллюстрируется на примере дифференциального уравнения 4 порядка

(4)       U '''' - 24 * U ''' - 169 * U '' - 324 * U ' - 180 * U = 0 

Его частное решение
       U (x) = e-x - 2e-2x + e-3x
удовлетворяет начальным условиям
       U (0) = 0,   U ' (0) = 0,   U '' (0) = 2,   U ''' (0) = - 12.

При  x = 1 это решение удовлетворяет еще условиям:
       U (1)   = 0.146996,    U ' (1)   = 0.0241005.  

Находились численные значения  U (x) как решения уравнения (4) при следующих краевых условиях:

      U (0) = 0 ,   U ' (0) = 0  и  U (1)   = 0.146996 ,   U ' (1)   = 0.0241005 . 

Приводятся подпрограмма вычисления значений правой части соответствующей системы четырех дифференциальных уравнений первого порядка (к которой сводится уравнение (4) четвертого порядка) и фрагмент вызывающей программы. Так как эта система однородная, то в подпрограмме  f_c внешняя структура   struct{ logical bul1; }com52r_    отсутствует.

int main(void)
{
    /* Initialized data */
    static float c__[10] /* was [2][5] */ = { 1.f,0.f,0.f,1.f,0.f,0.f,0.f,0.f,
                                               .146996f,.0241005f };
    static float b[10] /* was [2][5] */ = { 1.f,0.f,0.f,1.f,0.f,0.f,0.f,0.f,
                                            0.f,0.f };

    /* System generated locals */
    int i__1;

    /* Local variables */
    static int irab[4];
    extern int de52r_c(U_fp, int *, float *, int *, float *, float *,
                       float *, float *, int *, float *, int *, logical *,
                       float *, float *, float *, float *, int *, float *,
                       float *, float *, int *);
    static float hmin;
    static int ierr;
    extern int f_c();
    static float h__;
    static int i__, k, m;
    static float p, t[6], u[16] /* was [4][4] */,
                           y[8] /* was [4][2] */,
                         rk[16] /* was [4][4] */, xn, xo[20], xs[2],
                         yr[12] /* was [4][3] */;
    static logical bul;
    static float eps;
    static int nxo, nxs;

    k = 2;
    m = 4;
    xn = 0.f;
    nxs = 2;
    xs[0] = 1.f;
    xs[1] = 0.f;
    hmin = 1e-10f;
    eps = 1e-6f;
    p = .1f;
    nxo = 10;
    h__ = .1f;
    xo[0] = h__;
    i__1 = nxo;
    for (i__ = 2; i__ <= i__1; ++i__) {
/* L1: */
        xo[i__ - 1] = xo[i__ - 2] + h__;
    }
    bul = TRUE_;
    de52r_c((U_fp)f_c, &m, &xn, &nxs, xs, &hmin, &eps, &p, &nxo, xo, &k, &bul,
            b, c__, y, u, irab, yr, rk, t, &ierr);
/* L11: */
    printf("\n %5i \n", ierr);
    printf("\n %16.7e %16.7e \n\n", xs[0], xs[1]);
    for (i__ = 0; i__ <= 6; i__ += 2) {
         printf("\n %16.7e %16.7e \n", y[i__], y[i__+1]);
    }
    return 0;
} /* main */

int f_c(float *x, float *y, float *z, int *m)
{
    /* Parameter adjustments */
    --z__;
    --y;

    /* Function Body */
    z__[1] = y[2];
    z__[2] = y[3];
    z__[3] = y[4];
    z__[4] = y[4] * 24.f + y[3] * 169.f + y[2] * 324.f + y[1] * 180.f;
    return 0;
} /* f_c */


Результаты:

       y(1, 1)  =     0.146996
       y(1, 2)  =   - 0.7461162230*10- 7
       y(2, 1)  =     0.241005*10- 1
       y(2, 2)  =     0.2400178580*10- 6
       y(3, 1)  =   - 0.2667192340
       y(3, 2)  =     2.000000031
       y(4, 1)  =     0.4532368477
       y(4, 2)  = - 12.00000238

       ierr  =  0