root_finding¶
Function summary¶
find_n_roots (func[, args, n, x0, dx, p, ...]) |
Find the first n zeros/roots of a function |
fixed_point_no_accel (func, x0[, args, xtol, ...]) |
Find a fixed point of the function (NO CONVEGENCE ACCELERATION!!!). |
Module listing¶
Routines for finding zeros/roots of equations.
-
geotecha.mathematics.root_finding.
find_n_roots
(func, args=(), n=1, x0=0.001, dx=0.001, p=1.0, max_iter=2000, atol=1e-08, rtol=1e-05, debug=False, fsolve_kwargs={})[source]¶ Find the first n zeros/roots of a function
Root/zero finding can be tempramental. Small dx, p`=1, and large `max_iter will probably find the roots/zeros but it may take some time.
Parameters: func : callable f(x, *args)
A function that takes at least one argument.
args : tuple, optional
Any extra arguments to func. Default args=().
n : float, optional
Number of roots to find, Default n=1.
x0 : float, optional
An x value less than the first root. This is NOT the initial guess of fsolve! Default x0=0.001.
dx : float, optional
Initial interval length to check for root in. Default dx=0.001.
p : float, optional
Factor to increase dx by up untill first root is found. Default p=1.0.
max_iter : int, optional
Maximum iterations when searching for an interval containing a root. Default max_iter=2000. Note this is not the same as fsolve maxfev keword argument.
atol, rtol : float, optional
numpy.allclose parameters. Used for checking if found the same root. Default atol=1e-8, rtol=1e-5.
debug : True/False, optional
Print calculations to stdout. Default debug=False
fsolve_kwargs : dict, optional
dict of kwargs to pass to scipy.optimize.fsolve. Default fsolve_kwargs={}.
Returns: roots : 1d ndarray
Array of len n containing the first n roots of func.
Notes
Here is approximately what happens:
- func is evaluated with x0 and args to give y0
- x is incremented by dx to give x1
- func is evaluated with x1 and args to give y1
- If y0 and y1 have the same sign then there is no root between x0 and x1.
- dx is multiplied by p and the x is incremented again.
- successive intevals are checked until y0 and y1 are of different sign indicating that there is a root somewhere between x0 and x1.
- scipy.optimize.fsolve is used to find the root. If it is the first root then the the left end of the interval, the current x0, is used as the initial guess for fsolve. If it is a later root then the guess for fsolve is the x-axis intercept of the straight line joining (x0, y0) and (x1, y1).
- Once a root is found, the search begins for the next root which starts between the root and the current x1. The current dx value, the one that contained the root is reduced by a fifth and off we go again.
There are a few checks:
- At least five intervals must be checked before a possible root
interval is found. If less than five occur then we go back to the starting point of that roots search and use a reduced dx.
There is a maximum limit to the number of iterations used for each root
It is possible that the algorithm will, when searching for succesive roots, find identical roots. This is wrong. The current interval size along with the current dx will be reduced and the search will continue. If the same root is found five times then the root finding parameters are inappropriate and an error message will be raised.
-
geotecha.mathematics.root_finding.
fixed_point_no_accel
(func, x0, args=(), xtol=1e-08, maxiter=500)[source]¶ Find a fixed point of the function (NO CONVEGENCE ACCELERATION!!!).
Based on scipy.optimize.fixed_point but no convergence acelleration (RTRW)
Given a function of one or more variables and a starting point, find a fixed-point of the function: i.e. where
func(x0) == x0
.Parameters: func : function
Function to evaluate.
x0 : array_like
Fixed point of function.
args : tuple, optional
Extra arguments to func.
xtol : float, optional
Convergence tolerance, defaults to 1e-08.
maxiter : int, optional
Maximum number of iterations, defaults to 500.
Notes
Does NOT use Steffensen’s Method using Aitken’s
Del^2
convergence Acceleration. See Burden, Faires, “Numerical Analysis”, 5th edition, pg. 80Examples
>>> from scipy import optimize >>> def func(x, c1, c2): ... return np.sqrt(c1/(x+c2)) >>> >>> c1 = np.array([10,12.]) >>> c2 = np.array([3, 5.]) >>> optimize.fixed_point(func, [1.2, 1.3], args=(c1,c2)) array([ 1.4920333 , 1.37228132]) >>> fixed_point_no_accel(func, [1.2, 1.3], args=(c1,c2)) array([ 1.4920333 , 1.37228132])
Sometimes iterations should converge but fail when acceleration convergence is used:
>>> def fn(n, kl, ks, i0): ... return np.log(kl/ks/n) / np.log((i0 *n/(n - 1))) + 1 >>> fixed_point_no_accel(fn, 1.001, args=[6, 2, 3.7477525683]) 1.300... >>> optimize.fixed_point(fn, 1.001, args=[6, 2, 3.7477525683]) Traceback (most recent call last): RuntimeError: Failed to converge after 500 iterations, value is nan