Этот пример показывает, как решить численно трудную задачу граничного значения с помощью продолжения, что эффективно разбивает задачу на последовательность более простых задач.
Для рассмотрим дифференциальное уравнение
āxsin (¼ x).
Проблема возникает на интервале и подчиняется граничным условиям
-2,
= 0.
Когда 10-4, решение уравнения подвергается быстрому переходу = 0, поэтому его трудно решить численно. Вместо этого в этом примере используется продолжение для итерации нескольких значений e = 10-4. Каждое из промежуточных решений используется в качестве первоначального предположения для следующей задачи.
Чтобы решить эту систему уравнений в MATLAB, необходимо кодировать уравнения, граничные условия и начальное предположение, прежде чем вызывать решатель задач граничных значений bvp4c. Требуемые функции можно либо включить в качестве локальных функций в конце файла (как здесь сделано), либо сохранить их как отдельные именованные файлы в каталоге по пути MATLAB.
Используя замены y = y ′, можно переписать уравнение как систему уравнений первого порядка
,
(¼ x).
Запись функции для кодирования уравнений с сигнатурой dydx = shockode(x,y), где:
x является независимой переменной.
y является зависимой переменной.
dydx(1) дает уравнение для ′, иdydx(2) дает уравнение для ′.
Сделайте функцию векторизованной, чтобы shockode([x1 x2 ...],[y1 y2 ...]) прибыль [shockode(x1,y1) shockode(x2,y2) ...]. Этот подход повышает производительность решателя.
Соответствующая функция:
function dydx = shockode(x,y) pix = pi*x; dydx = [y(2,:) -x/e.*y(2,:) - pi^2*cos(pix) - pix/e.*sin(pix)]; end
Примечание.В конце примера все функции включаются как локальные.
Решатель BVP требует, чтобы граничные условия были в форме )) = 0. В этой форме граничными условиями являются:
2 = 0,
= 0.
Запись функции для кодирования граничных условий с сигнатурой res = shockbc(ya,yb), где:
ya - значение граничного условия в начале интервала ].
yb - значение граничного условия в конце интервала ].
Соответствующая функция:
function res = shockbc(ya,yb) % boundary conditions res = [ya(1)+2 yb(1)]; end
Аналитические якобинцы для функции ОДУ и граничных условий могут быть легко вычислены в этой задаче. Предоставление якобинцев делает решатель более эффективным, так как решателю больше не нужно аппроксимировать их с конечными различиями.
Для функции ОДУ матрица Якобиана
].
Соответствующая функция:
function jac = shockjac(x,y,e) jac = [0 1 0 -x/e]; end
Аналогично, для граничных условий матрицами якобиана являются
1000]0010].
Соответствующая функция:
function [dBCdya,dBCdyb] = shockbcjac(ya,yb) dBCdya = [1 0; 0 0]; dBCdyb = [0 0; 1 0]; end
Используйте постоянное предположение для решения на сетке из пяти точек в ].
sol = bvpinit([-1 -0.5 0 0.5 1],[1 0]);
Если попытаться решить уравнение непосредственно с помощью 10-4, то решатель не сможет преодолеть плохое кондиционирование задачи вблизи точки перехода x = 0. Вместо этого для получения решения = 10-4 в этом примере используется продолжение путем решения последовательности для , 10-3 и 10-4. Выходные данные решателя в каждой итерации действуют как предположение для решения в следующей итерации (вот почему переменная для начального предположения отbvpinit является sol, и выходные данные решателя также называются sol).
Поскольку значение якобиана зависит от значения , задайте опции в цикле, задающие shockjac и shockbcjac функции для якобинцев. Кроме того, включите векторизацию с shockode кодируется для обработки векторов значений.
e = 0.1; for i = 2:4 e = e/10; options = bvpset('FJacobian',@(x,y) shockjac(x,y,e),'BCJacobian',@shockbcjac,'Vectorized','on'); sol = bvp4c(@(x,y) shockode(x,y,e),@shockbc, sol, options); end
Постройте график результатов из bvp4c для сетки и раствора ). При продолжении решатель может обрабатывать разрывы при = 0.
plot(sol.x,sol.y(1,:),'-o'); axis([-1 1 -2.2 2.2]); title(['There Is a Shock at x = 0 When e =' sprintf('%.e',e) '.']); xlabel('x'); ylabel('solution y');

Здесь перечислены локальные функции решателя BVP bvp4c вызывает для вычисления решения. Кроме того, эти функции можно сохранить в виде собственных файлов в каталоге по пути MATLAB.
function dydx = shockode(x,y,e) % equation to solve pix = pi*x; dydx = [y(2,:) -x/e.*y(2,:) - pi^2*cos(pix) - pix/e.*sin(pix)]; end %------------------------------------------- function res = shockbc(ya,yb) % boundary conditions res = [ya(1)+2 yb(1)]; end %------------------------------------------- function jac = shockjac(x,y,e) % jacobian of shockode jac = [0 1 0 -x/e]; end %------------------------------------------- function [dBCdya,dBCdyb] = shockbcjac(ya,yb) % jacobian of shockbc dBCdya = [1 0; 0 0]; dBCdyb = [0 0; 1 0]; end %-------------------------------------------