Оптимизация свертки функции с помощью lmfit.Model или scipy.optimize.curve_fit

Используя либо lmfit.Model, либо scipy.optimize.curve_fit, я должен оптимизировать функцию, выходные данные которой необходимо свернуть с некоторыми экспериментальными данными, прежде чем они будут соответствовать некоторым другим экспериментальным данным. Подводя итог, рабочий процесс выглядит примерно так:

(1) Функция A определена (например, функция Гаусса). (2) Выход функции A свернут с экспериментальным сигналом, называемым данными B. (3) Параметры функции A оптимизированы для свертки, упомянутой в (2), чтобы полностью соответствовать некоторым другим экспериментальным данным, называемым данными C.

Я сворачиваю вывод функции A с данными B, используя преобразования Фурье, следующим образом:

from scipy.fftpack import fft, ifft

    def convolve(data_B, function_A):
        convolved = ifft(fft(IRF) * fft(model)).real
        return convolved

Как я могу использовать lmfit.Model или scipy.optimize.curve_fit для соответствия «свернутым» данным C?

Обновлено: В ответ на представленный ответ я включил свой шаг свертки в уравнение, используемое для подгонки, следующим образом:

#1 component exponential distribution:
def ExpDecay_1(x, ampl1, tau1, y0, x0, args=(new_y_irf)): # new_y_irf is a list. 
    h = np.zeros(x.size) 
    lengthVec = len(new_y_decay)
    
    shift_1 = np.remainder(np.remainder(x-np.floor(x0)-1, lengthVec) + lengthVec, lengthVec)
    shift_Incr1 = (1 - x0 + np.floor(x0))*new_y_irf[shift_1.astype(int)]
    
    shift_2 = np.remainder(np.remainder(x-np.ceil(x0)-1, lengthVec) + lengthVec, lengthVec)
    shift_Incr2 = (x0 - np.floor(x0))*new_y_irf[shift_2.astype(int)]
    
    irf_shifted = (shift_Incr1 + shift_Incr2)
    irf_norm = irf_shifted/sum(irf_shifted)
    h = ampl1*np.exp(-(x)/tau1)
    conv = ifft(fft(h) * fft(irf_norm)).real # This is the convolution step.
    return conv

Однако, когда я пытаюсь это сделать:

gmodel = Model(ExpDecay_1)

Я получаю это:

gmodel = Model(ExpDecay_1) Traceback (последний последний вызов): Файл "", строка 1, в gmodel = Модель (ExpDecay_1) Файл "C:\Users\lopez\Anaconda3\lib\site-packages\lmfit\model.py", строка 273, в инициализации self._parse_params() Файл "C:\Users\lopez\Anaconda3\lib\site-packages\lmfit\model.py", строка 477, в _parse_params если fpar.default == fpar.empty: ValueError: истинное значение массива с более чем одним элементом двусмысленный. Используйте a.any() или a.all()

Обновлено еще раз: мне удалось заставить его работать следующим образом:

import pandas as pd
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
import numpy as np
from lmfit import Model
from scipy.fftpack import fft, ifft

def Test_fit2(x, arg=new_y_irf, data=new_y_decay, num_decay=1):
    IRF = arg
    DATA = data
    def Exp(x, ampl1=1.0, tau1=3.0): # This generates an exponential model.
        res = ampl1*np.exp(-x/tau1)
        return res
    def Conv(IRF,decay): # This convolves a model with the data (data = Instrument Response Function, IRF).
        conv = ifft(fft(decay) * fft(IRF)).real
        return conv
    if num_decay == 1: # If the user chooses to use a model equation with one exponential term.
        def fitting(x, ampl1=1.0, tau1=3.0): 
            exponential = Exp(x,ampl1,tau1)
            convolved = Conv(IRF,exponential)
            return convolved
        modelling = Model(fitting)
        res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
    if num_decay == 2: # If the user chooses to use a model equation with two exponential terms.
        def fitting(x, ampl1=1.0, tau1=3.0, ampl2=1.0, tau2=1.0): 
            exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)
            convolved = Conv(IRF,exponential)
            return convolved
        modelling = Model(fitting)
        res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
    if num_decay == 3: # If the user chooses to use a model equation with three exponential terms.
        def fitting(x, ampl1=1.0, tau1=3.0, ampl2=2.0, tau2=1.0, ampl3=3.0, tau3=5.0): 
            exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)+Exp(x,ampl3,tau3)
            convolved = Conv(IRF,exponential)
            return convolved
        modelling = Model(fitting)
        res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
    if num_decay == 4: # If the user chooses to use a model equation with four exponential terms.
        def fitting(x, ampl1=1.0, tau1=0.1, ampl2=2.0, tau2=1.0, ampl3=3.0, tau3=5.0, ampl4=1.0, tau4=10.0): 
            exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)+Exp(x,ampl3,tau3)+Exp(x,ampl4,tau4)
            convolved = Conv(IRF,exponential)
            return convolved
        modelling = Model(fitting)
        res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
    return res
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
324
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Всегда полезно опубликовать полный, минимальный пример того, что вы пытаетесь сделать. Без полного примера возможны только расплывчатые ответы.

Вы можете просто выполнять свертки в своей функции модели, обернутой lmfit.Model, передавая массив ядра для использования в свертке. Или вы можете создать ядро ​​и функцию свертки и выполнить свертка как часть процесса моделирования, как описано, например, на https://lmfit.github.io/lmfit-py/examples/documentation/model_composite.html

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

Спасибо. Да, теперь я понимаю, что вопрос был очень расплывчатым. Тем не менее, ваш ответ был правильным. Я узнал, что люди сделали это, включив этап свертки в функцию. Теперь у меня проблемы с вводом данных (списка), используемых для свертки, в качестве одного из аргументов функции, потому что, если я добавлю их как параметр, lmfit.Model выдает ошибку, упомянутую в отредактированном вопросе.

Pin 8 19.12.2020 13:20

Не могли бы вы быть так любезны взглянуть на отредактированный вопрос? Если вы не видите ничего плохого в этом, все в порядке. Большое спасибо за Вашу помощь.

Pin 8 19.12.2020 13:27

Другие вопросы по теме