Передача параметров в решатель
Допустим, нам нужно решить кубическое уравнение x^3 + b*x + c = 0
для различных значений коэффициентов b
и c
. Если b
и c
— константы, то достаточно написать обычную функцию
function y = cubicpoly(x)
y = x^3 + b*x + c;
а затем вызвать её из решателя fzero
:
y = fzero(@cubicpoly, x0);
Однако в нашем случае b
и c
— параметры, которые нужно передать наряду с x
в cubicpoly
. Проблема в том, что решатель fzero
не даёт нам инструментов для этого. Не получится сделать ни так:
y = fzero(@cubicpoly, x0, список_параметров);
ни так
function y = cubicpoly(x, список_параметров)
...
Как же быть?
1. Вложенные функции
Первый способ - "вложить" функцию cubicpoly
вместе с решателем внутрь другой функции
function y = findzero(b, c, x0)
y = fzero(@cubicpoly, x0);
function y = cubicpoly(x)
y = x^3 + b*x + c;
end
end
Если раньше cubicpoly
обладала отдельной областью памяти, то теперь она "со всеми потрохами" принадлежит области памяти своей функции-обёртки findzero
. Соответственно, область видимости переменных b
и c
расширилась с cubicpoly
до findzero
, что даёт возможность изменять их, не меняя список аргументов cubicpoly
.
2. Анонимные функции
Пусть у нас есть функция, в которую параметры b
и c
передаются через список аргументов:
function y = cubicpoly(x, b, c)
y = x^3 + b*x + c;
Использовать её в таком виде нельзя из-за требований, предъявляемых fzero
(и действительно, как потом узнать, какой из массивов является массивом переменных?). Однако можно "замаскировать" её с помощью анонимной функции.
Пусть, для определенности, b = 2
, а c = 3.5
. Тогда
b = 2;
c = 3.5;
fun = @(x) cubicpoly(x, b, c);
x = fzero(fun, 0);
fun
— анонимная функция аргумента x
, которая "маскирует" функцию трёх аргументов cubicpoly
, так что требования fzero
будут выполнены.
Важный момент: если понадобится решить уравнение с новыми значениями параметров b
и c
, то недостаточно будет просто указать эти новые значения — нужно переопределить всю анонимную функцию. Например, так:
b = 4;
c = -1;
fzero(@(x) cubicpoly(x, b, c), 0)
Решатель fzero
был выбран нами совершенно произвольно. Аналогичным образом можно передавать дополнительные параметры и в другие решатели.
Передача параметров из решателя
Покажем теперь как решается обратная задача — как получить параметры из решателя "сверх обычных". Проделаем это на примере решателя дифференциальных уравнений ode45
.
Пусть задано дифференциальное уравнение y' = x + k*y
, в котором k
зависит от x
и y
: k = x^2 + y^2
. Нам нужно не только решать это уравнение при заданных начальных условиях, но и получить результирующее значение k
.
Запишем дифференциальное уравнение в виде функции:
function [dydx, k] = fun(x, y)
k = x.^2 + y.^2;
dydx = x + k.*y;
Особенность этой записи в том, что k
присутствует в ней в качестве выходного параметра.
Решаем уравнение:
[X, Y] = ode45(@fun, [0 5], 1);
А затем получим значение k
командой:
[dydx, k] = fun(X, Y);
Комментарии
comments powered by Disqus