Как мне ускорить этот root Finder в python? - PullRequest
0 голосов
/ 18 июня 2020

Основываясь на блестящем ответе пользователя с именем halex , я создал программу, которая находит все корни функции одной переменной и одного параметра и ищет root в области этой переменной. Это выглядит следующим образом:

import math

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

def bisect(f,x1,x2,Param, switch=0,epsilon=1.0e-9):
    f1 = f(x1,Param)
    if f1 == 0.0:
        return x1
    f2 = f(x2,Param)
    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,Param)
        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_adv(f, a, b, Param, eps=1e-6):
    print ('The roots on the interval [%f, %f] are:' % (a,b))
    rootlist = []
    while 1:
        x1,x2 = rootsearch(f,a,b,Param,eps)
        if x1 != None:
            a = x2
            root = bisect(f,x1,x2,Param,1)
            if root != None:
                pass
                # print (round(root,-int(math.log(eps, 10))))
                rootlist.append(round(root, -int(math.log(eps, 10))))
        else:
            print ('\nDone')
            return rootlist
            break

Чтобы найти все корни между a и b, вы можете просто написать

roots_adv(a,b,MyArbitraryParameter)

Но это очень медленно! Подскажите, как сделать это максимально быстро в Python?

...