Подпрограммы оптимизации Scipy только находят один ответ - PullRequest
0 голосов
/ 28 февраля 2019

Учитывая эту функцию:

def f(x):
    return (1-x**2)**m * ((1-x)/2)**n

, где m и n являются константами, скажем, оба 0.5 для примера.

Я пытаюсь использоватьфункции из scipy.optimize для решения для x при заданном значении y.Меня интересуют только значения x от -1 до 1. Построение функции с помощью

x = numpy.arange(0, 1, 0,1)
matplotlib.pyplot.plot(x, f(x))

показывает, что эта функция является разновидностью искаженной параболы, охватывающей диапазон от 0 до 0,65.Итак, давайте попробуем решить это для y = 0.3:

def f(x):
    return (1 - x**2)**m * ((1-x)/2)**n - 0.3
print(scipy.optimize.newton_krylov(f, 0.5))
0.6718791645800665

Это выглядит как раз для одного из возможных решений.Но есть два.Второе должно быть около -0,9.Попробуйте то, что я мог бы для первоначального предположения, я не могу найти это второе решение.Метод Ньютона-Крылова вообще не дает сходимости для xin < 0, но ни один из решателей не может найти это второе решение.

Я что-то упустил?Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

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

Первый - найти максимумы f(x) и разбить ваш поисковый домен на.Затем вы можете сделать начальное предположение в каждом домене и решить с помощью newton_krylov.

def f(x):
    # Here is our function
    return (1-x**2)**m * ((1-x)/2)**n


def minf(x):
    # Here is where we find an optima and split the domain
    return -f(x)


def fy(x):
    # This is where you want your y value target defined
    return abs(f(x) - .3)

if __name__ == "__main__":
    x = numpy.arange(-1., 1., 1e-3, dtype=float)
    # pyplot.plot(x, f(x))
    # pyplot.show()

    minx = minimize(minf, 0.0)['x']

    # Make an initial guess in each domain
    a1 = minx - 1.6 * minx
    a2 = minx + 1.6 * minx

    print(newton_krylov(fy, a1))
    print(newton_krylov(fy, a2))

Выходные данные:

[0.67187916]
[-0.95279992]
0 голосов
/ 28 февраля 2019

Метод сходится по крайней мере для x = -0,9:

scipy.optimize.newton_krylov(f, -0.9)
#array(-0.9527983). 

Он расходится для x приблизительно в [-0,85 ... 0,06].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...