Как исправить ошибку fsolve, не добиваясь прогресса при работе с объектами? - PullRequest
0 голосов
/ 17 октября 2019

У меня есть несколько сложных классов для оценки финансовых инструментов. Когда я пытаюсь найти корень функции, которая выполняет оценку, я получаю: «RuntimeWarning: итерация не дает хорошего прогресса, что измеряется улучшением по сравнению с последними десятью итерациями».

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

Это воспроизводит ошибку, используя python 3.7 и scipy 1.3.

import numpy as np
from scipy.optimize import fsolve

class Obj:
    def __init__(self, values):
        self.values = values

    def process(self):
        self.proc_values = 3*self.values**2 - 27
        return self.proc_values

    def set_val(self, new_val):
        self.values = int(new_val)

ob_test = [Obj(10),Obj(10),Obj(10)]

def polyn_class(x, ob_test):
    sol = np.ones(len(ob_test))
    for i in range(len(ob_test)):
        ob_test[i].set_val(x[i])
        sol[i] = ob_test[i].process()
    return sol

print(fsolve(polyn_class, np.ones(3), args=(ob_test,)))

1 Ответ

0 голосов
/ 21 октября 2019

Я добавил:

def __repr__(self):
    return '<Obj> ' + str(self.values)

def polyn_class(x, ob_test):
    sol = np.ones(len(ob_test))
    for i in range(len(ob_test)):
        #ob_test[i].set_val(x[i])   # first
        ob_test[i] = Obj(x[i])      # second
        sol[i] = ob_test[i].process()
    print(ob_test)
    return sol

И получил этот прогон:

1001:~/mypy$ python3 stack58437679.py 
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 101, <Obj> 101, <Obj> 101]
[<Obj> 0, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 1]
[<Obj> 101, <Obj> 101, <Obj> 101]
[<Obj> 0, <Obj> 1, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 0]
[<Obj> 0, <Obj> 0, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 0]
[<Obj> 0, <Obj> 0, <Obj> 1]
[<Obj> 1, <Obj> 1, <Obj> 0]
[<Obj> 0, <Obj> 0, <Obj> 1]
/usr/local/lib/python3.6/dist-packages/scipy/optimize/minpack.py:162: RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last ten iterations.
  warnings.warn(msg, RuntimeWarning)

С версией комментария:

1003:~/mypy$ python3 stack58437679.py 
[<Obj> 1.0, <Obj> 1.0, <Obj> 1.0]
[<Obj> 1.0, <Obj> 1.0, <Obj> 1.0]
[<Obj> 1.0, <Obj> 1.0, <Obj> 1.0]
[<Obj> 1.0000000149011612, <Obj> 1.0, <Obj> 1.0]
[<Obj> 1.0, <Obj> 1.0000000149011612, <Obj> 1.0]
[<Obj> 1.0, <Obj> 1.0, <Obj> 1.0000000149011612]
[<Obj> 5.000000000008725, <Obj> 5.000000000008725, <Obj> 5.000000000008725]
[<Obj> 2.3333333333313933, <Obj> 2.333333333331395, <Obj> 2.333333333331394]
[<Obj> 3.400000000001398, <Obj> 3.400000000001393, <Obj> 3.4000000000013957]
[<Obj> 2.953488372092719, <Obj> 2.9534883720927243, <Obj> 2.9534883720927207]
[<Obj> 2.997071742313299, <Obj> 2.9970717423132904, <Obj> 2.9970717423132958]
[<Obj> 3.0000228882708972, <Obj> 3.000022888270916, <Obj> 3.000022888270905]
[<Obj> 2.999999988824147, <Obj> 2.9999999888241096, <Obj> 2.999999988824131]
[<Obj> 2.999999999999922, <Obj> 2.9999999999999964, <Obj> 2.999999999999954]
[3. 3. 3.]

При использовании set_val объектазначения всегда целые;при создании новых объектов значения объекта могут быть плавающими. В этом вся разница в итерации.

Что правильно?

self.values = values
self.values = int(new_val)
...