Текст подпрограммы и версий de01r_c.zip , de01d_c.zip , de85r_c.zip , de85d_c.zip |
Тексты тестовых примеров tde01r_c.zip , tde01d_c.zip , tde85r_c.zip , tde85d_c.zip |
Вычисление решения задачи Коши для устойчивой системы обыкновенных дифференциальных уравнений первого порядка с большой константой Липшица методом Лоусона.
Решается задача Коши для устойчивой системы M обыкновенных дифференциальных уравнений первого порядка
(1) Y ' = F(X, Y) , Y = ( y1,..., yM ) , F = ( f1( X, y1,..., yM ),..., fM( X, y1,..., yM ) )
с начальными условиями, заданными в точке XN:
Y(XN) = YN , YN = ( y1,..., yM ) .
Предполагается, что среди характеристических корней матрицы Якоби ∂F / ∂y функции F имеются большие по модулю корни. Решение вычисляется в одной точке XK, которая является концом интервала интегрирования. Предполагается также, что система (1) может быть достаточно хорошо аппроксимирована линейной однородной системой с кусочнопостоянными коэффициентами, т.е. на каждом из [ xn, xn + H ], на которые разбивается весь интервал интегрирования, она может быть аппроксимирована системой вида
Y ' = AY ,
где A - постоянная матрица, вообще говоря, своя для каждого отрезка. Для интегрирования системы применяется метод Лоусона.
Метод Лоусона является одношаговым методом и заключается в следующем. Допустим, что искомое решение системы (1) уже вычислено в некоторой точке x = xn интервала интегрирования, т.е. известно yn ≈ y(xn). Для отыскания решения y(xn + 1) = y(xn + H) в следующем узле xn + 1 = xn + H выполняются такие действия. Исходная система уравнений с помощью замены искомой функции y (x) на xn ≤ x ≤ xn + H по формуле
y(x) = exp [ ( x - xn ) A0 ] Z(x) ,
где A0 - некоторая постоянная матрица, преобразуется в систему уравнений относительно новой неизвестной функции Z(X):
(2) Z ' (x) = F1(x, z) = exp [ - ( x - xn ) A0 ] { F(x, exp [ ( x - xn ) A0 ] Z(x)) - - A0 exp [ ( x - xn ) A0 ] Z(x) }
Матрица Якоби ∂ F1 / ∂Z системы (2) и матрица Якоби ∂F / ∂y системы (1) связаны между собой соотношением
∂ F1 / ∂Z = exp [ - (x - xn) A0] { ∂F / ∂y - A0 } exp [ ( x - xn ) A0 ]
Указанное преобразование выполняется самой подпрограммой. В качестве матрицы A0 подпрограмма выбирает матрицу ∂F / ∂y, вычисленную либо в точке ( xn, yn ), либо в некоторой предыдущей точке ( xn - k, yn - k ). Если шаг H достаточно мал, то данное преобразование позволяет уменьшить характеристические корни матрицы ∂ F1 / ∂Z по сравнению с характеристическими корнями матрицы ∂F / ∂y. А это приводит к уменьшению константы Липшица системы (2) по сравнению с константой Липшица системы (1).
Для решения системы (2) применяются классический метод Рунге - Кутта четвертого порядка точности, причем одновременно с решением (2) производится обратное преобразование от функции Z (x) к функции Y (x).
Все компоненты решения вычисляются с контролем точности по мере погрешности, который заключается в следующем. Если некоторая компонента приближенного решения по абсолютной величине не меньше некоторой наперед заданной константы P, то контроль точности для этой компоненты ведется по относительной погрешности, иначе - по абсолютной. Абсолютная погрешность приближенного решения оценивается по правилу Рунге.
J.Douglas Lowson, Generalized Runge - Kutta processes for stable systems with large lipshitz constants, SIAM Journal on Numerical Analisys, 1967, Vol.4, No 3.
int de01r_c (real *f, real *fj, integer *m, real *xn, real *yn, real *xk, real *hmin, real *eps, real *p, integer *n, real *h, real *y, real *r, integer *ierr)
Параметры
f - |
подпрограмма вычисления правой части системы в
точке x. Первый оператор подпрограммы должен иметь вид: int f (float *x, float *y, float *dy, int *m). Здесь x и y - значения независимой и зависимой переменных, соответственно. Вычисленное значение правой части должно быть помещено в dy. В случае системы уравнений, т.е. m ≠ 1, параметры y и dy представляют одномерные массивы длиной m (тип параметров x, y и dy: вещественный); |
fj - |
подпрограмма вычисления матрицы Якоби правой
части системы. Первый оператор подпрограммы должен иметь вид: int fj (float *x, float *y, float *df, int *m). Здесь x и y - значения независимой и зависимой переменных, соответственно, причем y представляет одномерный массив длины m. df - двумерный массив размера m*m. Вычисленное значение матрицы Якоби ∂F / ∂y должно быть помещено в массив df, при этом частная производная от правой части i - ого уравнения F по j - ой переменной y (j) запоминается в df (i, j), т.е. df (i, j) = ∂Fi / ∂yj (тип параметров x, y и df: вещественный); |
m - | количество уравнений в системе (тип: целый); |
xn, yn - | начальные значения аргумента и решения; в случае системы уравнений (т.е. m ≠ 1) yn представляет одномерный массив длины m; |
xk - | значение аргумента, при котором требуется вычислить решение задачи Коши (конец интервала интегрирования); xk может быть больше, меньше или равно xn (тип: вещественный); |
hmin - | минимальное значение абсолютной величины шага, которое разрешается использовать при интегрировании данной системы уравнений (тип: вещественный); |
eps - | допустимая мера погрешности, с которой требуется вычислить все компоненты решения (тип: вещественный); |
p - | граница перехода, используемая при оценке меры погрешности решения (тип: вещественный); |
n - |
целый параметр, управляющий режимом вычисления
матрицы A0 и имеющий следующие значения: Если n ≤ 0 , (т.е. имеет произвольное отрицательное или нулевое значение), то матрица A0 вычисляется только один раз и полагается равной значению A0 = ∂F / ∂y в точке [x = x0, y = y0] на протяжении всего интервала интегрировария; если n > 0, то матрица A0 изменяется периодически, при этом она остается постоянной на протяжении каждого ряда из n последовательных шагов и вычисляется вновь на первом шаге каждого ряда, т.е. матрица A0 = ∂F / ∂y вычисляется только в следующих точках: [x = x0, y = y0] при x0 ≤ x ≤ xn; [x = xn, y = yn] при xn < x ≤ x2n; [x = x2n, y = y2n] при x2n < x≤ x3n; Чем сильнее меняется матрица Якоби ∂F / ∂y системы при изменении x, тем меньше должно быть значение параметра n. В частности, если n = 1, то матрица Якоби системы ∂F / ∂y будет вычисляться в каждой точке xn, yn . |
h - | вещественная переменная, содержащая начальное значение шага интегрирования; может задаваться с учетом направления интегрирования, т.е. положительным, если xn < xk, отрицательным, если xn > xk, или без всякого учета в виде абсолютной величины; |
y - | искомое решение задачи Коши, вычисленное подпрограммой при значении аргумента xk; для системы уравнений (когда m ≠ 1) задается одномерным массивом длины m. В случае совпадения значений параметров xn и xk значение y полагается равным начальному значению yn (тип: вещественный); |
r - | одномерный рабочий массив вещественного типа длины 5*m*m+7*m+1; |
ierr - | целая переменная, значение которой в результате работы подпрограммы полагается равным 65, если какая - нибудь компонента решения не может быть вычислена с требуемой точностью eps. В этом случае интегрирование системы прекращается; при желании интегрирование системы можно повторить обращением к подпрограмме с новыми значениями параметров hmin, h и n. |
Версии
de01d_c - | вычисление решения задачи Коши для устойчивой системы обыкновенных дифференциальных уравнений первого порядка с большой константой Липшица в конце интервала интегрирования методом Лоусона с удвоенным числом значащих цифр. При этом параметры xn, yn, xk, hmin, eps, p, h, y, r и параметры x, y, dy в подпрограмме f и x, y, df в подпрограмме fj должны иметь тип double; |
de85r_c - |
вычисление решения задачи Коши для устойчивой
системы обыкновенных дифференциальных уравнений первого
порядка с большой константой Липшица в конце
интервала интегрирования методом Лоусона. В отличии от
подпрограммы de01r_c первый оператор подпрограммы
de85r_c не содержит в списке формальных параметров
имени подпрограммы вычисления матрицы Якоби и имеет
следующий вид: int de85r_c (real *f, integer *m, real *xn, real *yn, real *xk, real *hmin, real *eps, real *p, integer *n, real *h, real *y, real *r, integer *ierr) При использовании этой подпрограммы пользователь не составляет подпрограмму вычисления матрицы Якоби. Все параметры подпрограммы de85r_c имеют тот же смысл, что и одноименные параметры подпрограммы de01r_c; |
de85d_c - | вычисление решения задачи Коши для устойчивой системы обыкновенных дифференциальных уравнений первого порядка с большой константой Липшица в конце интервала интервала интегрирования методом Лоусона с удвоенным числом значащих цифр. Первый оператор подпрограммы имеет тот же вид, что и в подпрограмме de85r_c, при этом параметры xn, yn, xk, hmin, eps, p, h, y, r и параметры x, y, dy в подпрограмме f должны иметь тип double. |
Вызываемые подпрограммы
de00r_c - de00d_c | выполнение одного шага интегрирования системы обыкновенных дифференциальных первого порядка с большой константой Липшица методом Лоусона; |
utde20_c - utde21_c | подпрограммы выдачи диагностических сообщений |
Подпрограммы de00r_c, utde20_c вызываются при работе подпрограммы de01r_c, а подпрограммы de00d_c, utde21_c - при работе de01d_c. |
Замечания по использованию
Данная подпрограмма предназначена для интегрирования таких нелинейных систем, которые могут быть достаточно хорошо аппроксимированы линейной однородной системой с кусочнопостоянными коэффициентами, т.е. на каждом из отрезков [x, x + H] , на которые разбивается весь интервал интегрирования, они могут быть аппроксимированы системой вида Y ' = AY где A - постоянная матрица, вообще говоря, своя для каждого отрезка. В общем случае заданная точность не гарантируется. При работе подпрограммы значения параметров m, xn, yn, xk, hmin, eps, p, n сохраняются. При работе подпрограмм f и fj значения параметров x, y, m не должны изменяться. Если после работы подпрограммы нет необходимости иметь начальное значение решения yn, то параметры yn и y при обращении к ней можно совместить. При этом следует иметь в виду, что в случае аварийного выхода из подпрограммы, т.е. со значением ierr = 65, значение параметра yn будет испорчено. Подпрограммы de01r_c и de01d_c предназначены также для решения задачи Коши для жестких дифференциальных уравнений (1). |
y1' = (- 500 + 2 x) y1 + (1 - x /10 ) y2 + (1 + 1/(x + ) sin y1 , y1( = 49 y2' = (- 1000 - 10 x) y1 + (1 + x /10 ) y2 + (2 + 1/(x + 2) ) cos y2 , y2( = 50 1 ≤ x ≤ 6
Приводятся подпрограммы вычисления правой части системы и матрицы Якоби правой части, а также фрагмент вызывающей программы и результаты счета.
int main(void) { /* Local variables */ extern int de01r_c(U_fp, U_fp, int *, float *, float *, float *, float *, float *, float *, int *, float *, float *, float *, int *); static float hmin; static int ierr; extern int f_c(); static float h__; static int m, n; static float p, r__[35], y[2]; extern int fj_c(); static float xk, xn, yn[2], eps; m = 2; xn = 1.f; yn[0] = 49.f; yn[1] = 50.f; hmin = 1e-10f; eps = 1e-4f; p = 100.f; h__ = .01f; xk = 6.f; n = 2; de01r_c((U_fp)f_c, (U_fp)fj_c, &m, &xn, yn, &xk, &hmin, &eps, &p, &n, &h__, y, r__, &ierr); printf("\n %16.7e %16.7e \n", y[0], y[1]); printf("\n %16.7e \n", h__); printf("\n %5i \n", ierr); return 0; } /* main */ int f_c(float *x, float *y, float *dy, int *m) { /* Builtin functions */ double sin(double), cos(double); /* Parameter adjustments */ --dy; --y; /* Function Body */ dy[1] = (*x * 2.f - 500.f) * y[1] + (1.f - *x * .1f) * y[2] + (1.f / (*x + 1.f) + 1.f) * (float)sin(y[1]); dy[2] = (-1e3f - *x * 10.f) * y[1] + (*x * .1f + 1.f) * y[2] + (1.f / (*x + 2.f) + 2.f) * (float)cos(y[2]); return 0; } /* f_c */ int fj_c(float *x, float *y, float *df, int *m) { /* Builtin functions */ double cos(double), sin(double); #define df_ref(a_1,a_2) df[(a_2)*2 + a_1] /* Parameter adjustments */ df -= 3; --y; /* Function Body */ df_ref(1, 1) = *x * 2.f - 500.f + (1.f / (*x + 1.f) + 1.f) * (float)cos(y[1]); df_ref(1, 2) = 1.f - *x * .1f; df_ref(2, 1) = -1e3f - *x * 10.f; df_ref(2, 2) = *x * .1f + 1.f - (1.f / (*x + 2.f) + 2.f) * (float)sin(y[2]); return 0; } /* fj_c */ Результаты: y(1) y(2) h -4.175740488392-02 -5.087148371158+01 2.500000000001-03 ierr = 0
Результаты решения этой же задачи, полученные с помощью подпрограммы de85r_c
-4.175740472033-02 -5.087148363417+01 5.000000000003-03 ierr = 0
Результаты решения этой же задачи, полученные с помощью подпрограммы de25r_c
-4.175740429849-02 -5.087148203468+01 1.756831014061-03 ierr = 0