Re: All the roots of a function in an interval
Gael Varoquaux <gael.varoquaux <at> normalesup.org>
2007-10-01 07:12:13 GMT
Hi Anne,
Thanks a lot for your reply, enlightening as usual.
On Sat, Sep 29, 2007 at 03:51:30PM -0400, Anne Archibald wrote:
> The easiest and most reliable method here is to simply sample the
> function at equispaced points the nearest distance apart they can be;
> then every sign change gives you an interval bracketing a root.
I did exactly as you suggested. It is indeed the best solution.
Unfortunately it is slowish, and cannot be well implemented with arrays.
Here is the code I got to, just in case it can be of some use for
somebody later on:
def find_x(m_K, m_Rb, delta_x):
""" Returns the 2D array of x for which:
m_K * sin(k_Rb * x) - m_Rb * sin(k_K *(x + delta_x)) == 0
with delta_x a 1D array.
"""
delta_x = c_[delta_x]
f = lambda x, delta_x: m_K*sin(k_Rb*x) - m_Rb*sin(k_K*(x + delta_x))
interval = linspace(-5*Delta_x, 5*Delta_x, 150)
scan = f(interval, delta_x)
sign_changes_mask = (scan[:, 1:]*scan[:, :-1])<0
min_num_x = (sign_changes_mask.sum(axis=-1)).min()
x = empty((len(delta_x), min_num_x))
indexes = arange(len(interval))
for index, this_delta_x in enumerate(delta_x.flat):
#this_x = _find_x(m_K, m_Rb, this_delta_x)
# Keep only the min_num_x inner most solutions:
(Continue reading)