Проблема с корнями нелинейного уравнения

#python #numerical-methods #nonlinear-optimization

#python #численные методы #нелинейная оптимизация

Вопрос:

У меня есть гиперболическая функция, и мне нужно найти ее 0. Я пробовал различные классические методы (деление пополам, Ньютон и так далее).

Вторые производные непрерывны, но недоступны аналитически, поэтому я должен исключить методы, использующие их.

Для целей моего приложения метод Newton является единственным, обеспечивающим достаточную скорость, но он относительно нестабилен, если я недостаточно близок к фактическому нулю. Вот простой скриншот:

введите описание изображения здесь

Нуль находится где-то около 0,05. и поскольку функция расходится на 0, если я беру начальное значение предположения, превышающее минимальное местоположение определенной степени, то у меня, очевидно, проблемы с асимптотой.

Существует ли в этом случае более стабильный метод, который в конечном итоге предлагал бы скорости, сравнимые с Newton?

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

Любая помощь будет оценена.

Комментарии:

1. Хотите показать нам уравнение?

2. Привет @YvesDaoust, к сожалению, функция на самом деле не является явной и не имеет замкнутой формы, которую я могу просто опубликовать, более того, вычисляется и собирается в различных модулях. Это просто похоже на гиперболическую функцию, вот почему я использовал этот пример. Однако это scheleton должно быть что-то вроде y = A / x ^ 2 B / x с константами A и B. График, который я опубликовал, просто y = (1 / x) -20

Ответ №1:

Метод Деккера или Брента должен быть почти таким же быстрым, как Ньютон. Если вы хотите что-то простое для самостоятельной реализации, иллинойский вариант метода regula-falsi также достаточно быстр. Все это методы брекетинга, поэтому не должны покидать домен, если начальный интервал находится внутри домена.

 def illinois(f,a,b,tol=1e-8):
    '''regula falsi resp. false postion method with
        the Illinois anti-stalling variation'''
    fa = f(a)
    fb = f(b)
    if abs(fa)<abs(fb): a,fa,b,fb = b,fb,a,fa
    while(np.abs(b-a)>tol):
        c = (a*fb-b*fa)/(fb-fa)
        fc = f(c)
        if fa*fc < 0:
            fa *= 0.5
        else:
            a, fa = b, fb
        b, fb = c, fc
    return b, fb
 

Комментарии:

1. спасибо, regula-falsi, на самом деле хорошо справляется с моей проблемой. Теперь я буду тестировать на разных прогонах

Ответ №2:

Как насчет использования log(x) вместо x?

Комментарии:

1. Это создает разрыв при x = 1. Также я не думаю, что он сохраняет позицию 0

2. функция это что-то в виде 1 / x

3. Это не так … log(1) = 0 , но оно непрерывное. Затем, когда вы нашли x , конечно, вы берете exp(x) , чтобы получить оригинал x .

4. тогда я не понял, вы предлагаете построить функцию 1 / log (x), скажем, найти 0 с помощью newton или эквивалента, а затем exp (x), чтобы получить исходный результат?

5. Вы оставляете значения функции такими, какие они есть (я предполагаю, что это не просто ваша актуальная проблема 1/x - 20 , потому что тогда x=1/20 и весь вопрос тривиален), но изобретаете z = log(x) и рассматриваете новую функцию y = f(z) . Если вы построите это, это может быть более линейным и может быть решено Newton без проблем.

Ответ №3:

В вашем случае ответ @sams-studio может сработать, и я бы попробовал это в первую очередь. В аналогичной ситуации — также в многовариантном контексте — я использовал гомотопические методы Ньютона.

По сути, вы ограничиваете шаг Ньютона до тех пор, пока абсолютное значение y не уменьшится. Самый дешевый способ реализации — это половина шага Ньютона, если y увеличивается с последнего шага. После нескольких шагов вы возвращаетесь к Newton с полной сходимостью второго порядка.

Disclamer: Если вы можете связать свое решение (вы знаете максимум x ), ответ от @Lutz Lehmann также был бы моим первым выбором.

Комментарии:

1. На самом деле у меня нет верхней границы, но поскольку мой ‘x’ — это толщина, он не может идти до бесконечности, но я не знаю верхнего значения априори. Я всегда могу вставить искусственную верхнюю границу, которая достаточно велика. Я посмотрю на гомотопические методы Ньютона. спасибо за предложение