che sto cercando di implementare il seguente convoluzione in R
, ma non ottenere il risultato atteso:imprevisto Convoluzione Risultati
$$ C _ {\ sigma} [i] = \ sum \ limits_ {k = -P }^P SDL _ {\ sigma} [ik, i] \ centerdot S [i] $$
dove $ S [i] $ è un vettore di intensità spettrali (un segnale Lorentzian/spettro NMR), e $ i \ in [1, N] $ dove $ N $ è il numero di punti dati (in esempi reali, forse 32K valori). Questa è l'equazione 1 in Jacob, Deborde e Moing, Chimica bioanalitica analitica (2013) 405: 5049-5061 (DOI 10.1007/s00216-013-6852-y).
$ SDL _ {\ sigma} $ è una funzione per calcolare la seconda derivata di una curva di Lorentz, che ho implementato come segue (sulla base degli equazione 2 nel documento):
SDL <- function(x, x0, sigma = 0.0005){
if (!sigma > 0) stop("sigma must be greater than zero.")
num <- 16 * sigma * ((12 * (x-x0)^2) - sigma^2)
denom <- pi * ((4 * (x - x0)^2) + sigma^2)^3
sdl <- num/denom
return(sdl)
}
sigma
è la larghezza di picco a metà massimo e x0
è il centro del segnale di Lorentzian.
Credo che SDL
funzioni correttamente (perché i valori restituiti hanno una forma simile alla derivata empirica di Savitzky-Golay 2). Il mio problema è di attuare $ C _ {\ sigma} $, che ho scritto come:
CP <- function(S = NULL, X = NULL, method = "SDL", W = 2000, sigma = 0.0005) {
# S is the spectrum, X is the frequencies, W is the window size (2*P in the eqn above)
# Compute the requested 2nd derivative
if (method == "SDL") {
P <- floor(W/2)
sdl <- rep(NA_real_, length(X)) # initialize a vector to store the final answer
for(i in 1:length(X)) {
# Shrink window if necessary at each extreme
if ((i + P) > length(X)) P <- (length(X) - i + 1)
if (i < P) P <- i
# Assemble the indices corresponding to the window
idx <- seq(i - P + 1, i + P - 1, 1)
# Now compute the sdl
sdl[i] <- sum(SDL(X[idx], X[i], sigma = sigma))
P <- floor(W/2) # need to reset at the end of each iteration
}
}
if (method == "SG") {
sdl <- sgolayfilt(S, m = 2)
}
# Now convolve! There is a built-in function for this!
cp <- convolve(S, sdl, type = "open")
# The convolution has length 2*(length(S)) - 1 due to zero padding
# so we need rescale back to the scale of S
# Not sure if this is the right approach, but it doesn't affect the shape
cp <- c(cp, 0.0)
cp <- colMeans(matrix(cp, ncol = length(cp)/2)) # stackoverflow.com/q/32746842/633251
return(cp)
}
Per il riferimento, il calcolo della seconda derivata è limitata a una finestra di circa 2000 punti di dati per risparmiare tempo. Penso che questa parte funzioni bene. Dovrebbe produrre solo distorsioni banali.
Ecco una dimostrazione di tutto il processo e il problema:
require("SpecHelpers")
require("signal")
# Create a Lorentzian curve
loren <- data.frame(x0 = 0, area = 1, gamma = 0.5)
lorentz1 <- makeSpec(loren, plot = FALSE, type = "lorentz", dd = 100, x.range = c(-10, 10))
#
# Compute convolution
x <- lorentz1[1,] # Frequency values
y <- lorentz1[2,] # Intensity values
sig <- 100 * 0.0005 # per the reference
cpSDL <- CP(S = y, X = x, sigma = sig)
sdl <- sgolayfilt(y, m = 2)
cpSG <- CP(S = y, method = "SG")
#
# Plot the original data, compare to convolution product
ylabel <- "data (black), Conv. Prod. SDL (blue), Conv. Prod. SG (red)"
plot(x, y, type = "l", ylab = ylabel, ylim = c(-0.75, 0.75))
lines(x, cpSG*100, col = "red")
lines(x, cpSDL/2e5, col = "blue")
Come si può vedere, il prodotto di convoluzione da CP
utilizzando SDL
(in blu) non assomiglia la convoluzione prodotto da CP
utilizzando il metodo SG
(in rosso, che è corretto, fatta eccezione per la scala). Mi aspetto che i risultati dell'utilizzo del metodo SDL
debbano avere una forma simile ma una scala diversa.
Se sei rimasto con me finora, a) grazie, e b) riesci a vedere cosa c'è che non va? Senza dubbio, ho un malinteso fondamentale.
Perché è stato migrato qui? – KannarKK
@KannarKK Ho richiesto di eseguire la migrazione. Dopo 24 ore, aveva ricevuto solo 3 o 4 visualizzazioni su CV, dove al momento sembrano ricevere 3-6 domande al minuto, a volte. Quindi affondò rapidamente, fuori dalla vista. –
Ciononostante, sembrerebbe essere più adatto per CV perché si concentra sulla presenza di un problema concettuale. Forse aveva solo bisogno di una taglia più grande? – russellpierce