exponenta event banner

Корни скалярных функций

Решение нелинейного уравнения в одной переменной

fzero функция пытается найти корень одного уравнения с одной переменной. Эту функцию можно вызвать либо с начальной точкой из одного элемента, либо с двухэлементным вектором, обозначающим начальный интервал. Если дать fzero начальная точка x0, fzero сначала ищет интервал вокруг этой точки, где функция меняет знак. Если интервал найден, fzero возвращает значение, рядом с которым функция изменяет знак. Если такой интервал не найден, fzero прибыль NaN. Кроме того, если известны две точки, где значение функции отличается знаком, можно задать этот начальный интервал с помощью двухэлементного вектора; fzero гарантированно сужает интервал и возвращает значение около изменения знака.

Следующие разделы содержат два примера, иллюстрирующих поиск нуля функции с использованием начального интервала и начальной точки. В примерах используется функция humps.m, который поставляется с MATLAB ®. На следующем рисунке показан график humps.

x = -1:.01:2;
y = humps(x);
plot(x,y)
xlabel('x');
ylabel('humps(x)')
grid on

Figure contains an axes. The axes contains an object of type line.

Настройка параметров для fzero

Можно управлять несколькими аспектами fzero путем установки параметров. Параметры задаются с помощью optimset. Варианты включают в себя:

Использование начального интервала

График humps указывает, что функция отрицательна в x = -1 и положительно на x = 1. Вы можете подтвердить это, рассчитав humps в этих двух точках.

humps(1)
ans = 16
humps(-1)
ans = -5.1378

Следовательно, можно использовать [-1 1] как начальный интервал для fzero.

Итеративный алгоритм для fzero находит меньшие и меньшие субинтервалы [-1 1]. Для каждого субинтервала знак humps различается на двух конечных точках. По мере того, как конечные точки субинтервалов становятся все ближе и ближе, они сходятся к нулю для humps.

Отображение хода выполнения fzero на каждой итерации установите Display опция для iter с использованием optimset функция.

options = optimset('Display','iter');

Затем позвоните fzero следующим образом:

a = fzero(@humps,[-1 1],options)
 
 Func-count    x          f(x)             Procedure
    2              -1      -5.13779        initial
    3       -0.513876      -4.02235        interpolation
    4       -0.513876      -4.02235        bisection
    5       -0.473635      -3.83767        interpolation
    6       -0.115287      0.414441        bisection
    7       -0.115287      0.414441        interpolation
    8       -0.132562    -0.0226907        interpolation
    9       -0.131666    -0.0011492        interpolation
   10       -0.131618   1.88371e-07        interpolation
   11       -0.131618   -2.7935e-11        interpolation
   12       -0.131618   8.88178e-16        interpolation
   13       -0.131618   8.88178e-16        interpolation
 
Zero found in the interval [-1, 1]
a = -0.1316

Каждое значение x представляет наилучшую конечную точку на данный момент. Procedure в столбце указывается, используется ли на каждом шаге алгоритма биссекция или интерполяция.

Можно проверить, что значение функции в a близок к нулю путем ввода

humps(a)
ans = 8.8818e-16

Использование начальной точки

Предположим, что вы не знаете две точки, в которых функции значения humps отличаются знаком. В этом случае можно выбрать скаляр x0 в качестве отправной точки для fzero. fzero сначала ищет интервал вокруг этой точки, в которой функция изменяет знак. Если fzero находит такой интервал, он переходит к алгоритму, описанному в предыдущем разделе. Если такой интервал не найден, fzero прибыль NaN.

Например, задайте для начальной точки значение -0.2, Display опция для Iterи звоните fzero:

options = optimset('Display','iter');
a = fzero(@humps,-0.2,options)
 
Search for an interval around -0.2 containing a sign change:
 Func-count    a          f(a)             b          f(b)        Procedure
    1            -0.2      -1.35385          -0.2      -1.35385   initial interval
    3       -0.194343      -1.26077     -0.205657      -1.44411   search
    5          -0.192      -1.22137        -0.208       -1.4807   search
    7       -0.188686      -1.16477     -0.211314      -1.53167   search
    9          -0.184      -1.08293        -0.216      -1.60224   search
   11       -0.177373     -0.963455     -0.222627      -1.69911   search
   13          -0.168     -0.786636        -0.232      -1.83055   search
   15       -0.154745      -0.51962     -0.245255      -2.00602   search
   17          -0.136     -0.104165        -0.264      -2.23521   search
   18        -0.10949      0.572246        -0.264      -2.23521   search
 
Search for a zero in the interval [-0.10949, -0.264]:
 Func-count    x          f(x)             Procedure
   18        -0.10949      0.572246        initial
   19       -0.140984     -0.219277        interpolation
   20       -0.132259    -0.0154224        interpolation
   21       -0.131617   3.40729e-05        interpolation
   22       -0.131618  -6.79505e-08        interpolation
   23       -0.131618  -2.98428e-13        interpolation
   24       -0.131618   8.88178e-16        interpolation
   25       -0.131618   8.88178e-16        interpolation
 
Zero found in the interval [-0.10949, -0.264]
a = -0.1316

Конечные точки текущего субинтервала в каждой итерации перечислены в заголовках a и b, в то время как соответствующие значения humps на конечных точках перечислены в разделе f(a) и f(b)соответственно.

Примечание: Конечные точки a и b не перечислены в каком-либо конкретном порядке: a может быть больше, чем b или менее b.

Для первых девяти шагов, знак humps отрицательный на обеих конечных точках текущего субинтервала, который отображается на выходе. На десятом шаге знак humps является положительным при a, -0.10949, но отрицательно при b, -0.264. С этого момента алгоритм продолжает сужать интервал [-0.10949 -0.264], как описано в предыдущем разделе, пока оно не достигнет значения -0.1316.

Связанные темы