Python: поиск нескольких корней нелинейного уравнения

Предположим, следующая функция:

f(x) = x * cos(x-4)

С участиемx = [-2.5, 2.5] эта функция пересекает0 вf(0) = 0 а такжеf(-0.71238898) = 0.

Это было определено с помощью следующего кода:

import math
from scipy.optimize import fsolve
def func(x):
    return x*math.cos(x-4)
x0 = fsolve(func, 0.0)
# returns [0.]
x0 = fsolve(func, -0.75)
# returns [-0.71238898]

Как правильно использоватьfzero (или любой другой искатель корней Python), чтобы найти оба корня в одном вызове? Есть ли другойscipy функция, которая делает это?

fzero ссылка

 Roland Smith24 окт. 2012 г., 20:15
@ strimp099: f (x) полностью отличается от func (x). Так что вы пытаетесь решить?
 Rohit Jain24 окт. 2012 г., 19:52
@mayhewr. Похоже, твоя математика не такая уж туманная. ;)
 Jason Strimpel24 окт. 2012 г., 20:31
Извините, очень неряшливо. Обновлен f (x)
 voithos24 окт. 2012 г., 20:43
Эта серия сообщений в списке рассылки Scipy может быть актуальной:mail.scipy.org/pipermail/scipy-user/2007-September/013870.html
 mayhewr24 окт. 2012 г., 19:48
Может быть, моя математика туманна, но неf(0) = 2 там?

Ответы на вопрос(3)

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

Тем не менее, вы можете переключать math.cos () с помощью numpy.cos (), и это будет векторизовать вашу функцию, чтобы она могла решать сразу несколько значений, например, fsolve (func, np.arange (-10,10,0.5)).

 pv.24 окт. 2012 г., 23:13
И если ваши функции принадлежат к определенному классу, есть это:openopt.org/interalg
Решение Вопроса

чтобы она могла принимать в качестве аргумента либо скалярный, либо пустой массив:

>>> import numpy as np
>>> f = lambda x : x * np.cos(x-4)

Затем передайте вектор аргументовfsolve.

>>> x = np.array([0.0, -0.75])
>>> fsolve(f,x)
array([ 0.        , -0.71238898])
 minibuffer02 авг. 2017 г., 23:22
Как вы проходите в якобиане в таком случае, если мы этого хотим? Просто проходя вjac=jac с аналитическим якобианом даетTypeError: Shape mismatch.

книгиЧисленные методы в разработке с Python Яан Киусалас:

import math

def rootsearch(f,a,b,dx):
    x1 = a; f1 = f(a)
    x2 = a + dx; f2 = f(x2)
    while f1*f2 > 0.0:
        if x1 >= b:
            return None,None
        x1 = x2; f1 = f2
        x2 = x1 + dx; f2 = f(x2)
    return x1,x2

def bisect(f,x1,x2,switch=0,epsilon=1.0e-9):
    f1 = f(x1)
    if f1 == 0.0:
        return x1
    f2 = f(x2)
    if f2 == 0.0:
        return x2
    if f1*f2 > 0.0:
        print('Root is not bracketed')
        return None
    n = int(math.ceil(math.log(abs(x2 - x1)/epsilon)/math.log(2.0)))
    for i in range(n):
        x3 = 0.5*(x1 + x2); f3 = f(x3)
        if (switch == 1) and (abs(f3) >abs(f1)) and (abs(f3) > abs(f2)):
            return None
        if f3 == 0.0:
            return x3
        if f2*f3 < 0.0:
            x1 = x3
            f1 = f3
        else:
            x2 =x3
            f2 = f3
    return (x1 + x2)/2.0

def roots(f, a, b, eps=1e-6):
    print ('The roots on the interval [%f, %f] are:' % (a,b))
    while 1:
        x1,x2 = rootsearch(f,a,b,eps)
        if x1 != None:
            a = x2
            root = bisect(f,x1,x2,1)
            if root != None:
                pass
                print (round(root,-int(math.log(eps, 10))))
        else:
            print ('\nDone')
            break

f=lambda x:x*math.cos(x-4)
roots(f, -3, 3)

roots находит все корниf в интервале [a, b].

 halex04 февр. 2015 г., 09:23
@NicorLengert Спасибо за упоминание. Я отредактировал ответ
 Nicor Lengert04 февр. 2015 г., 09:10
спасибо за сценарий. в Python версии 2.x math.ceil возвращает число с плавающей запятой, поэтому вам нужно преобразовать n в int (n)

Ваш ответ на вопрос