Kenenbek Arzymatov
Kenenbek Arzymatov

Reputation: 9119

Python scipy fsolve works incorrectly

I have equation:

import numpy as np
from scipy import optimize

def wealth_evolution(price, wealth=10, rate=0.01, q=1, realEstate=0.1, prev_price=56):
    sum_wantedEstate = 100
    for delta in range(1,4):
        z = rate - ((price-prev_price) / (price + q / rate))
        k = delta * np.divide(1.0, float(np.maximum(0.0, z)))
        wantedEstate = (wealth / (price + q / rate)) * np.minimum(k, 1) - realEstate
        sum_wantedEstate += wantedEstate
    return sum_wantedEstate

So I find the solution of this equation:

sol = optimize.fsolve(wealth_evolution, 200)

But if I substituted sol into equation I wouldn't get 0 (welth_evolution(sol)). Why it happens? fsolve finds the roots of f(x)=0.

UPD: The full_output gives:

(array([ 2585200.]), {'qtf': array([-99.70002298]), 'nfev': 14, 'fjac': array([[-1.]]), 'r': array([  3.45456519e-11]), 'fvec': array([ 99.7000116])}, 5, 'The iteration is not making good progress, as measured by the \n  improvement from the last ten iterations.')

Upvotes: 0

Views: 1828

Answers (1)

thomas
thomas

Reputation: 1813

Have you tried plotting your function?

import numpy as np
from scipy import optimize
from matplotlib import pyplot as plt
small = 1e-30
def wealth_evolution(price, wealth=10, rate=0.01, q=1, realEstate=0.1, prev_price=56):
    sum_wantedEstate = 100
    for delta in range(1,4):
        z = rate - ((price-prev_price) / (price + q / rate))
        k = delta * np.divide(1.0, float(np.maximum(small, z)))
        wantedEstate = (wealth / (price + q / rate)) * np.minimum(k, 1) - realEstate
        sum_wantedEstate += wantedEstate
    return sum_wantedEstate




price_range = np.linspace(0,10000,10000)
we = [wealth_evolution(p) for p in price_range]

plt.plot(price_range,we)
plt.xlabel('price')
plt.ylabel('wealth_evolution(price)')
plt.show()

enter image description here

At least for the parameters you specify it does not have a root, which is what fsolve tries to find. If you want to minimize a function you can try fmin. For this function this will not help though, because it seems to just asymptotically decay to 99.7 or so. So minimizing it would lead to infinite price.

So either you have to live with this or come up with a different function to optimize or constrain your search range (in which case you don't have to search, because it will just be the maximum value...).

Upvotes: 3

Related Questions