Я записал экспериментальные температуры в пяти точках от поверхности твердого тела.На каждом временном шаге я хочу подогнать эти показания к теоретической кривой, определенной моей функцией: Temp_Function_JLT (X, h).
X - это многомерный массив, который включает координаты x, а также время, начальную температуру и свойства материала (все независимые переменные).«h» - коэффициент теплопередачи, который для целей этого упражнения я пытаюсь оптимизировать (оставив физику на минуту.)
Это определение моей температурной функции:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pickle
import scipy.optimize as opt
from scipy.special import erfc
def Temp_Function_JLT(X,ht):
# Work around the fact that only one independent variable can be passed to optimize.curve_fit
x,t,T0,q,alpha,rho,c,k = X
term_a = q/ht
term_b = erfc(x/np.sqrt(4*alpha*t))
term_c = np.exp(((ht*x)/(np.sqrt(alpha)*np.sqrt(k*rho*c)))+((ht**2)/(k*rho*c)))
term_d = erfc((ht*np.sqrt(t))/(np.sqrt(k*rho*c)) + (x/np.sqrt(4*alpha*t)))
Temperature = (term_a * (term_b - term_c * term_d)) + T0 - 273
return Temperature
Функция работает.Я могу запустить его с некоторыми начальными параметрами и получить разумные значения.Что еще более важно для этого вопроса, если я назову его со следующими данными:
t = 1
x_test = np.linspace(0.004,0.02,5) # TC locations
time_test = range(1,180,30)
T0_test = 25 + 273
q_test = 20000
h_test = 10
Я получу массив пустышек в виде решения формы (1,), которое дает ответ на np.ndim из 1 (Это было упомянуто в следующих предыдущих вопросах:
Наименьшие линейные квадраты: scipy.optimize.curve_fit () throws "Результат от вызова функции не является правильным массивом с плавающей точкой."
Подгонка векторной функции с Curve_fit в Scipy
Подгонка 2D-функции Гаусса с использованием scipy.optimize.curve_fit - ValueError и minpack.error
Проблема возникает, когда я вызываю opt.curve_fit (). Indepth_temperas - это список, который содержит каждый тест в виде массива. Я перебираю его (для перебора каждого теста), а затем выполняю подгонку для каждой строки (каждый разшаг), согласно следующему коду:
for i,test in enumerate(indepth_temperatures):
# Iterate over every row
for j,row in enumerate(test):
# Define tuple that contains all independent variables
X = (TC_depth,
times[i][j],
T0_temperatures[i] + 273,
20000,
pmma_alpha,
pmma_rho,
pmma_c,
pmma_k)
print(Temp_Function_JLT(X,h0))
print(row)
print('---')
# Call function to optimize curve fit on h
popt, pcov = opt.curve_fit(Temp_Function_JLT,X,row,h0)
print(popt)
Для первой итерации я получаю следующий результат:
[23.2034 23.2034 23.2034 23.2034 23.2034] # comes from print(Temp_Function_JLT(X,h0))
[23.937 22.619 22.59 24.884 21.987000000000002] # comes from print(row)
После этой ошибки:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-67-9c4545fd257b> in <module>()
22 print('---')
23 # Call function to optimize curve fit on h
---> 24 popt, pcov = opt.curve_fit(Temp_Function_JLT,X,row,h0)
25 print(popt)
~\AppData\Local\Continuum\anaconda2\envs\py36\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
749 # Remove full_output from kwargs, otherwise we're passing it in twice.
750 return_full = kwargs.pop('full_output', False)
--> 751 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
752 popt, pcov, infodict, errmsg, ier = res
753 cost = np.sum(infodict['fvec'] ** 2)
~\AppData\Local\Continuum\anaconda2\envs\py36\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
392 with _MINPACK_LOCK:
393 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 394 gtol, maxfev, epsfcn, factor, diag)
395 else:
396 if col_deriv:
error: Result from function call is not a proper array of floats.
Я попытался вернутьсяиз моей функции np.ravel (Temperature) или Temperature.flatten () без удачи.Ошибка остается, и я не могу понять, почему это там.Как я уже упоминал, я проверил размеры возврата моей функции, и это одномерный массив.
Любая помощь будет принята с благодарностью!
ОБНОВЛЕНИЕ: Я понял, что это трудно скопироватьэтот код, так что это упрощенная версия:
Temp_Function_JLT (X, h0): остается прежним.
pmma_rho = 1200 # kg/m3
pmma_c = 1500 # J/kgK
pmma_k = 0.16 # W/mK
pmma_alpha = pmma_k/(pmma_rho*pmma_c)
x_test = np.linspace(0.004,0.02,5) # TC locations
t = 1
T0_test = 25 + 273
q_test = 20000
h_test = 10
X = (x_test,t,T0_test,q_test,pmma_alpha,pmma_rho,pmma_c,pmma_k)
y_data = [23.937 22.619 22.59 24.884 21.987000000000002]
opt.curve_fit(Temp_Function_JLT, X, y_data, h_test)