ValueError: объект слишком глубокий для нужного массива в optimize.curve_fit

1

Я пытаюсь подобрать кинетическую модель роста и распада населения четырех переменных A, B, C, D в химической системе. Я пытаюсь решить следующую систему уравнений, которую я приложил в матричной форме:

Матричная форма уравнений

где t - временной шаг, k1, k2, k3 - константы в экспоненциальной функции. Я хочу подгонять кривые на основе этих уравнений для решения для k1, k2 и k3, учитывая мои популяции A, B, C, D.

Для этого я использую optimize.curve_fit, t - временной шаг в массиве (1000), X - матрица (4,1000) и где u и w - две матрицы:

from scipy import optimize

def func(t,X,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([[np.exp(-t*(k1+k2))],
                 [np.exp(-t*k3)],
                 [1]])

    return X*np.dot(u,w)


X = np.array([A,B,C,D]) # A,B,C,D are (1000,) arrays
# X.shape = (4, 1000)
# t.shape = (1000,)

optimize.curve_fit(func,t,X,method='lm')

Когда я запускаю этот фрагмент кода, я получаю следующий вывод:

ValueError: объект слишком глубокий для желаемого массива

Ошибка: результат вызова функции не является подходящим массивом поплавков.

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

Может ли кто-нибудь предложить, где проблема может быть в этом коде, и как я могу лучше всего решить проблему k1, k2, k3 с помощью функции подгонки кривой?

Спасибо

  • 1
    Есть по крайней мере , несколько проблем: func не нужен X параметр, ваш t является й парами. Кроме того, третий элемент в матрице w имеет длину один, он должен иметь длину 1000, чтобы соответствовать другим двум элементам выше
  • 0
    Ах да - X здесь плохое имя для переменной; Я должен назвать это `` Y, так что мой параметр x равен t а мой параметр y равен Y , где Y - матрица формы (4,1000). Для третьего элемента матрицы w я просто хочу, чтобы он был константой, поэтому, когда скалярное произведение берется с матрицей u, третий столбец в u возвращается как константа.
Показать ещё 1 комментарий
Теги:
scipy
chemistry

1 ответ

0
Лучший ответ

Как я уже упоминал в своем комментарии, вам не нужно передавать X на func. @WarrenWeckesser кратко объясняет, почему. Итак, вот как func должен быть:

def func(t,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2*k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([np.exp(-t*(k1+k2)),
                 np.exp(-t*k3),
                 np.ones_like(t)]) # must match shapes with above 

    return np.dot(u,w).flatten()

Выход в конце сплющен, потому что иначе он выдаст ошибку с curve_fit. Теперь мы проверяем это:

from scipy.optimize import curve_fit
t = np.arange(1000)*0.01
data = func(t, *[0.5, 2, 1])
data +=np.random.normal(size=data.shape)*0.01 # add some noise
po, pcov = curve_fit(func,t, data.flatten(), method='lm') #data must also be flattened
print(po)
#[ 0.50036411  2.00393807  0.99694513]
plt.plot(t, data.reshape(4,-1).T, t, func(t, *po).reshape(4,-1).T)

Оптимизированные значения довольно близки к оригинальным, и подгонка кажется хорошей Изображение 174551

  • 0
    Спасибо, Бренлла! Думаю, я немного запутался с функцией подбора кривой - спасибо за ясное объяснение и прекрасный пример кода! Он отлично работает на моих данных. Спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню