2014-12-15 2 views
0

Я использовал fsolve, чтобы найти нули примера синусовой функции и отлично работал. Однако я хотел сделать то же самое с набором данных. Два списка поплавков, затем преобразованные в массивы с numpy.asarray(), содержащие значения (x, y), а именно: «t» и «ys».Python fsolve не принимает массив поплавков. Как его реализовать?

Хотя я нашел related questions, мне не удалось реализовать предоставленный в них код, поскольку я пытаюсь показать здесь. Наши интересующие массивы хранятся в 2D-списке (данные [i] [j], где «i» соответствует переменной (например, данные [0] == t == time == x values), а «j» - значения указанной переменной вдоль оси х (например, данные [1] == Force). Имейте в виду, что каждый из данных [I] представляет собой массив поплавки.

Не могли бы вы предложить пример кода, который принимаетдва входы (две упомянутые массивы) и возвращает его пересекающиеся точки с определенной функцией (например, «у = 0»).

Я включил некоторые тесты я сделал в отношении других связанных с этим вопросом. (@HYRY ' s ответ)

Я не думаю, что это релевантно, но я использую Spyder через Anaconda.

Заранее благодарен!

""" 
Following the answer provided by @HYRY in the 'related questions' (see link above). 
At this point of the code, the variable 'data' has already been defined as stated before. 
""" 
from scipy.optimize import fsolve 

def tfun(x): 
    return data[0][x] 

def yfun(x): 
    return data[14][x] 

def findIntersection(fun1, fun2, x0): 
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)] 

print findIntersection(tfun, yfun, 0) 

который возвращает следующую ошибку

File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 36, in tfun 
    return data[0][x] 

IndexError: arrays used as indices must be of integer (or boolean) type 

Полный выход, как это следующим образом:

Traceback (most recent call last): 

    File "<ipython-input-16-105803b235a9>", line 1, in <module> 
    runfile('E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py', wdir='E:/Data/Anaconda/[...]/00-Latest') 

    File "C:\Anaconda\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 580, in runfile 
    execfile(filename, namespace) 

    File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 44, in <module> 
    print findIntersection(tfun, yfun, 0) 

    File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 42, in findIntersection 
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)] 

    File "C:\Anaconda\lib\site-packages\scipy\optimize\minpack.py", line 140, in fsolve 
    res = _root_hybr(func, x0, args, jac=fprime, **options) 

    File "C:\Anaconda\lib\site-packages\scipy\optimize\minpack.py", line 209, in _root_hybr 
    ml, mu, epsfcn, factor, diag) 

    File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 42, in <lambda> 
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)] 

    File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 36, in tfun 
    return data[0][x] 

IndexError: arrays used as indices must be of integer (or boolean) type 
+0

Можете ли вы добавить немного больше подробностей о том, что произошло, когда вы пытались использовать код из связанных вопросов? Не полные следы стека или такие, но только что-то, чтобы дать представление о том, почему это могло бы не сработать. –

+0

Отредактировано. Надежда теперь понятна. –

+0

Вы индексируете массив с помощью 'x', который представляет собой массив с плавающей запятой. Поплавки как индексы массивов не имеют смысла. – Evert

ответ

0

Вы можете «преобразовать» а наборы данных (массивы) для непрерывных функций с помощью интерполяция. scipy.interpolate.interp1d - это фабрика, которая предоставляет вам полученную функцию, которую вы могли бы использовать с вашим алгоритмом поиска корней. --edit-- примера для вычисления пересечения греха и соза из 20 образцов (я использовал кубический сплайн-интерполяцию, так как кусочно-линейные дает предупреждение о гладкости):

>>> import numpy, scipy.optimize, scipy.interpolate 
>>> x = numpy.linspace(0,2*numpy.pi, 20) 
>>> x 
array([ 0.  , 0.33069396, 0.66138793, 0.99208189, 1.32277585, 
    1.65346982, 1.98416378, 2.31485774, 2.64555171, 2.97624567, 
    3.30693964, 3.6376336 , 3.96832756, 4.29902153, 4.62971549, 
    4.96040945, 5.29110342, 5.62179738, 5.95249134, 6.28318531]) 
>>> y1sampled = numpy.sin(x) 
>>> y2sampled = numpy.cos(x) 
>>> y1int = scipy.interpolate.interp1d(x,y1sampled,kind='cubic') 
>>> y2int = scipy.interpolate.interp1d(x,y2sampled,kind='cubic') 
>>> scipy.optimize.fsolve(lambda x: y1int(x) - y2int(x), numpy.pi) 
array([ 3.9269884]) 
>>> scipy.optimize.fsolve(lambda x: numpy.sin(x) - numpy.cos(x), numpy.pi) 
array([ 3.92699082]) 

Обратите внимание, что интерполяция даст вы «догадываетесь» о том, какие данные должны быть между точками выборки. Невозможно сказать, насколько хороши эти догадки. (но для моего примера вы можете видеть, что это довольно хорошая оценка)

+0

Это похоже на вопрос.Я сделаю несколько примеров, чтобы продемонстрировать эту функциональность в ближайшие недели, чтобы завершить ответ. –

+0

Большое спасибо за пример. Для меня теперь это кажется полным. Я предполагаю, что точность по существу связана с интервалом между значениями выборки х и относительным изменением значений y в сравнении с этим интервалом по оси x. –

Смежные вопросы