2015-10-23 8 views
0

Я пытаюсь установить два глобальных параметра галактической модели, используя Scipy curve_fit в python. У меня есть массив независимых переменных и массив зависимых переменных. Первый 1/4 набора данных должен быть приспособлен к функции в зависимости от двух глобальных параметров и двух локальных параметров, следующей четверти другой функции в зависимости от двух глобальных параметров и двух локальных переменных и т. Д.Scipy Curve Fit Global Parameters

Есть ли в любом случае, что я могу написать функцию, которая вызовет соответствующую функцию с правильным индексом и глобальными параметрами через весь массив.

То, что я до сих пор:

def galaxy_func_inner(time,a,b,c,d): 
    telescope_inner = lt.station(rot_angle=c,pol_angle=d) 
    power = telescope_inner.calculate_gpowervslstarray(time)[0] 
    return a*np.array(power)+b 

    def galaxy_func_outer(time,a,b,c,d): 
    telescope_outer = lt.station(rot_angle=c,pol_angle=d) 
    power = telescope_outer.calculate_gpowervslstarray(time)[0] 
    return a*np.array(power)+b 

    def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h): 
     for t_index in range(len(time)): 
      if t_index in range(0,50): 
        return galaxy_func_outer(t_index,a,b,R,P) 
      elif t_index in range(50,100): 
        return galaxy_func_outer(t_index,c,d,R,P) 
      elif t_index in range(100,150): 
        return galaxy_func_inner(t_index,e,f,R,P) 
      elif t_index in range(150,200): 
        return galaxy_func_inner(t_index,g,h,R,P) 

Проблема заключается в том, что это подходит только в первый раз, но весь массив времени, и единственная точка устанавливается только в соответствующей точке модели, а не весь массив. Любая помощь в том, как переформулировать это? Я попытался переформулировать как:

def galaxy_func_global(xdata,R,P,a,b,c,d,e,f,g,h): 
    return galaxy_func_outer(xdata[0:50],a,b,R,P),galaxy_func_outer(xdata[50:100],c,d,R,P),galaxy_func_inner(xdata[100:150],e,f,R,P),galaxy_func_inner(xdata[150:200],g,h,R,P) 

, но я получаю сообщение об ошибке:

File "galaxy_calibration.py", line 117, in <module> 
    popt,pcov = curve_fit(galaxy_func_global,xdata,ydata) 
File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 555, in curve_fit 
    res = leastsq(func, p0, args=args, full_output=1, **kw) 
File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 369, in leastsq 
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n) 
File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 20, in _check_func 
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args))) 
File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 445, in _general_function 
    return function(xdata, *params) - ydata 
ValueError: operands could not be broadcast together with shapes (4,) (191,) 

Любая помощь будет высоко ценится.

+0

Добро пожаловать в переполнение стека! Вы можете получить более быстрый ответ, если вы предоставите [mcve]. Что-то мне непонятно, например: неужели 'galaxy_func_inner/outer' ожидает время или целочисленный индекс в качестве первого параметра? Именование переменных предложило бы первое, но когда вы вызываете эти функции в своих 'глобальных' функциях, вы даете им' t_index', а не t. –

ответ

0

Если вы хотите, чтобы сократить ваши входные данные в 4-х партий (на основе индекса из time точек) и обрабатывать данные в зависимости от партии, затем возвращать результаты в одном массиве, то вы можете сделать это :

def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h): 
    return np.concatenate([galaxy_func_outer(time[0:50],a,b,R,P), 
          galaxy_func_outer(time[50:100],c,d,R,P), 
          galaxy_func_inner(time[100:150],e,f,R,P), 
          galaxy_func_inner(time[150:200],g,h,R,P)]) 

Это нарежьте ваш time массив, чтобы выбрать каждый кусочек интереса, а затем вызвать соответствующую функцию для каждой части. Мне кажется, что эти функции возвращают простые np.array s, которые могут быть объединены, чтобы получить один массив в качестве результата.

(я просто понял, что я мог бы просто сказал: «что вы пытались почти совершенна, но вы должны объединить получившиеся массивов в один массив» :)


Обратите внимание, что есть в по крайней мере два способа решения проблем с размерами.

Во-первых, вы должны убедиться, что возвращаемое значение обеих ваших функций (galaxy...inner/outer()) является массивом 1d numpy. В противном случае у вас возникнут проблемы с вашим глобальным значением возврата.

Во-вторых, каждый метод подгонки предполагает функцию, возвращаемое значение которой имеет одинаковый размер (форму) в качестве входной переменной по очевидным причинам. Таким образом, вы можете столкнуться с проблемами с вашим текущим кодом, если time не составляет ровно 200 элементов, поскольку ваш результат будет усечен до 200 элементов, даже если time длиннее.По крайней мере, вы должны поставить

galaxy_func_inner(time[150:],g,h,R,P) 

в последний вызов функции, чтобы поймать все остальные точки из time, но если вы хотите, чтобы сделать это правильно, вызовите

def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h): 
    inds=np.floor(np.linspace(0,len(time)-1,5)) 
    return np.concatenate([galaxy_func_outer(time[0:inds[1]],a,b,R,P), 
         galaxy_func_outer(time[inds[1]:inds[2]],c,d,R,P), 
         galaxy_func_inner(time[inds[2]:inds[3]],e,f,R,P), 
         galaxy_func_inner(time[inds[3]:],g,h,R,P)]) 

Также обратите внимание, что оригинал ошибка формально такого рода:

File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 445, in _general_function 
    return function(xdata, *params) - ydata 
ValueError: operands could not be broadcast together with shapes (4,) (191,) 

Это говорит вам, что питон не может вычесть ydata от function(xdata,*params) (т.е. ваша модель подгонки), потому что одна из них имеет длину 4, а другая длина 191. Это связано с тем, что если ваша функция вызывает return a,b,c,d, тогда она вернет кортеж (a,b,c,d), поэтому возвращаемое значение будет иметь длину 4. Это больше что ваш ydata имеет длину 191, это может означать, что вы все равно столкнетесь с ошибкой.

+0

Спасибо за помощь. Не np.concatenate принимает только два аргумента - не четыре, как вы его написали? – Emma518

+0

Также в отношении ydata, имеющей длину 191, мой набор данных усечен в [0:49], [49:98], [98: 144], [144: 191]. Но проблема заключается в том, что она пытается сопоставить всю ydata с xdata одного из этих подсекций (что мы и хотим): def galaxy_func_global (xdata, R, P, a, b, c, d, e , f, g, h): return np.array ((galaxy_func_outer (xdata [0:49], a, b, R, P), galaxy_func_outer (xdata [49:98], c, d, R, P) , galaxy_func_inner (xdata [98: 144], e, f, R, P), galaxy_func_inner (xdata [144: 191], g, h, R, P))) – Emma518

+0

@ Emma518, 1. попробуйте 'concatenate' самостоятельно на тестовом примере: np.concatenate ([1,3], [2,5], [3,4], [6,7]). 2. Извините, но я не понимаю, что вы говорите. Вы * пробовали *, что я предложил? –

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