2

我正在尝试为 编写一个自定义模型gnm,以适应 Voigt 配置文件。我已经定义

library(gnm) ; library(RcppFaddeeva)
VOIGT <- function(x) {
    list(predictors=list(Center=1, Sigma=1, Gamma=1, Alfa=1),
         variables=list(substitute(x)),
         term=function(predLabels, varLabels) {
        paste(predLabels[4], "* RcppFaddeeva::Voigt(", varLabels[1], ", ", predLabels[1], ", ", predLabels[2], ", ", predLabels[3], ")" )
    },
    start=function(theta) {
     theta[2] <- 1 ; theta[3] <- 1; theta[4] <- 1
        } )
}

class(VOIGT) <- "nonlin"  

但尝试使用它会给

Error in deriv.default(X[[i]], ...) : 
  Function 'RcppFaddeeva::Voigt' is not in the derivatives table

任何解决方法?或者这需要扩展gnm,还是其他一些完全不同的方法?

4

1 回答 1

1

您可以使用nls最小二乘法拟合模型。

例如,从 Voigt 配置文件生成一些数据:

library(RcppFaddeeva)
x <- seq(-1000, 1000)
v <- Voigt(x, 200, 100, 30)

n用作示例数据的样本点

n <- 50
id <- sort(sample(seq_along(v), n))
x2 <- x[id]
y2 <- v[id]

在响应中添加一些高斯噪声

y2 <- y2 + rnorm(n, mean = 0, sd = 1e-4)

绘制示例数据(见下文,最终拟合)

plot(y2 ~ x2)

从图中,我们可以看到中心在 250 左右,如果我们用高斯近似轮廓,我们可能会猜测 sigma 大约是 100(轮廓从中心下降到 sigma 的 3 倍左右)。这为我们的参数提供了起始值(我们可以尝试将 alpha 和 gamma 设置为 1)。

fit <- nls(y2 ~ alpha*Voigt(x2, x0, sigma, gamma), 
           start = list(alpha = 1, x0 = 250, sigma = 100, gamma = 1))
fit
#> Nonlinear regression model
#>   model: y2 ~ alpha * Voigt(x2, x0, sigma, gamma)
#>    data: parent.frame()
#>    alpha       x0    sigma    gamma 
#>   0.9884 201.0276 101.2246  27.2556 
#>  residual sum-of-squares: 5.771e-07
#> 
#> Number of iterations to convergence: 5 
#> Achieved convergence tolerance: 2.66e-06

将拟合模型添加到图中

lines(fitted(fit)~x2)

于 2019-12-31T15:44:03.990 回答