I came to ask this question from the very similar one where I "learned" how to employ fsolve to solve for solving implicit equations.
My equation is defined by this function:
def fn4(Fs):
return ( np.sum( (lamL * c + lamW * np.tan(np.radians(phi)))
/ (np.cos(lamA) * (1 + np.tan(lamA) * np.tan(np.radians(phi)) / Fs))
) / np.sum(lamW * np.sin(lamA))
)
where:
c = 10
phi = 30
lamela1 = {'W':887.36, 'alpha':np.radians(46.71), 'L':19.325}
lamela2 = {'W':1624.8, 'alpha':np.radians(22.054), 'L':14.297}
lamela3 = {'W':737.43, 'alpha':np.radians(1.9096), 'L':13.258}
lamele = [lamela1, lamela2, lamela3]
lamW = np.array([[i['W'] for i in lamele]])
lamA = np.array([[i['alpha'] for i in lamele]])
lamL = np.array([[i['L'] for i in lamele]])
Now, I solved this by making a simple recursion:
def iterf(f, Fsi):
if np.isclose(Fsi, fn4(Fsi)) == True:
return Fsi
else:
return iterf(f, fn4(Fsi))
which gives
iterf(fn4, 1)
1.8430
But when I try to use scipy.optimize.fsolve (as fsolve(fn4, 1)), then i get:
RuntimeWarning: divide by zero encountered in true_divide
/ (np.cos(lamA) * (1 + np.tan(lamA) * np.tan(np.radians(phi)) / Fs))
I don't know how exactly does fsolve work (which I'd like to learn), but my guess is that for the optimization it needs to input Fs as 0 at one point, which produces the zero-division. How can I use a function like this one to get the output?
EDIT:
The theoretical background is stability of soil slopes. The Fs, which is the result, is the factor of safety - a measure whose values is >1 for stable slopes, and <=1 for unstable slopes. The chosen method is really simple as it requires the solution of only this one equation. The slope is discretized with a number of "lamellae" or "columns", in this case only 3 for simplicity.
It looks like you're trying to solve
fn4(x) == x, that is, find a fixed point offn4. (If not, please clarify what the recursion is for.) However, the first argument offsolveis supposed to be the function for which you want a root, so you're actually callingfsolveto solvefn4(x) == 0.Recommendations:
fsolveis a legacy function; preferrootrootis generalized for multivariable problems, but you have a scalar function, so preferroot_scalar.root_scalarto solve for the fixed point as follows.