如何在我的 TMB .cpp 文件中包含更多 objective 函数?
How do I include more objective functions in my TMB .cpp file?
TMB objective 函数似乎是在保存到 <name>.cpp
文件的一个函数块中定义的。然后,在编译文件后,通过使用命令 dyn.load(dynlib(<name>))
加载来访问每个 objective 函数。
是否可以在每个 .cpp
文件中存储多个 objective 函数?例如,下面两个objective函数非常相似,但目前需要保存到不同的文件中:
// TMB Tutorial but with fixed variance
#include <TMB.hpp> // Links in the TMB libraries
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x); // Data vector transmitted from R
PARAMETER(mu); // Parameter value transmitted from R
Type sigma = 1.0;
Type f; // Declare the "objective function" (neg. log. likelihood)
f = -sum(dnorm(x,mu,sigma,true)); // Use R-style call to normal density
return f;
}
和
// TMB Tutorial
#include <TMB.hpp> // Links in the TMB libraries
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x); // Data vector transmitted from R
PARAMETER(mu); // Parameter value transmitted from R
PARAMETER(sigma); //
Type f; // Declare the "objective function" (neg. log. likelihood)
f = -sum(dnorm(x,mu,sigma,true)); // Use R-style call to normal density
return f;
}
MakeADFun()
的 "map" 参数允许您将参数固定为特定值。
在这个例子中,我们只需要compile/load后一个模板。首先,我们将模板写入文件,编译并加载生成的 DLL。
library(TMB)
file_conn <- file('test.cpp')
writeLines("
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x);
PARAMETER(mu);
PARAMETER(sigma);
Type f;
f = -sum(dnorm(x,mu,sigma,true));
return f;
}
", file_conn)
close(file_conn)
compile('test.cpp')
dyn.load(dynlib('test'))
我们可以使用相同的 DLL 来拟合具有和不具有不同 sigma 的模型。
n <- 100
x <- rnorm(n = n, mean = 0, sd = 1)
f1 <- MakeADFun(data = list(x = x),
parameters = list(mu = 0, sigma = 1),
DLL = 'test')
f2 <- MakeADFun(data = list(x = x),
parameters = list(mu = 0, sigma = 1),
DLL = 'test',
map = list(sigma = factor(NA)))
opt1 <- do.call('optim', f1)
opt2 <- do.call('optim', f2)
当使用 "map" 时,指定的参数(在本例中为 sigma)固定为 "parameters" 中给定的值。
Post-优化,我们进行完整性检查——mus 应该几乎相同。
> opt1$par
mu sigma
0.08300554 1.07926521
> opt2$par
mu
0.08300712
打开和关闭随机效果有点困难。 here 给出了一个例子,您可以在其中使用 CppAD::Variable()
检查是否减少负对数似然。
对于不同的 objective 函数(不是彼此的子集),您可以将 DATA_INTEGER
或 DATA_STRING
传递到模板中,例如就像他们在 glmmTMB here 中所做的那样,并根据 DATA_*
.
的值选择 objective 函数
我只是想弄清楚@alexforrence 的意思
For unalike objective functions (not subsets of one another), you could pass a DATA_INTEGER or DATA_STRING into the template, e.g. like they did in glmmTMB here, and pick the objective function depending on the value of that DATA_*
原来 TMB github 上有一个 code snippet 涵盖了这个场景,我在这里复制它:
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_STRING(model_type);
if (model_type == "model1") {
#include "model1.h"
} else
if (model_type == "model2") {
#include "model2.h"
} else {
error ("Unknown model type")
}
return 0;
}
也就是说,传入一个字符串,告诉 objective 函数选择哪个模型,然后将该函数的文本包含在单独的 .h
文件中。
TMB objective 函数似乎是在保存到 <name>.cpp
文件的一个函数块中定义的。然后,在编译文件后,通过使用命令 dyn.load(dynlib(<name>))
加载来访问每个 objective 函数。
是否可以在每个 .cpp
文件中存储多个 objective 函数?例如,下面两个objective函数非常相似,但目前需要保存到不同的文件中:
// TMB Tutorial but with fixed variance
#include <TMB.hpp> // Links in the TMB libraries
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x); // Data vector transmitted from R
PARAMETER(mu); // Parameter value transmitted from R
Type sigma = 1.0;
Type f; // Declare the "objective function" (neg. log. likelihood)
f = -sum(dnorm(x,mu,sigma,true)); // Use R-style call to normal density
return f;
}
和
// TMB Tutorial
#include <TMB.hpp> // Links in the TMB libraries
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x); // Data vector transmitted from R
PARAMETER(mu); // Parameter value transmitted from R
PARAMETER(sigma); //
Type f; // Declare the "objective function" (neg. log. likelihood)
f = -sum(dnorm(x,mu,sigma,true)); // Use R-style call to normal density
return f;
}
MakeADFun()
的 "map" 参数允许您将参数固定为特定值。
在这个例子中,我们只需要compile/load后一个模板。首先,我们将模板写入文件,编译并加载生成的 DLL。
library(TMB)
file_conn <- file('test.cpp')
writeLines("
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(x);
PARAMETER(mu);
PARAMETER(sigma);
Type f;
f = -sum(dnorm(x,mu,sigma,true));
return f;
}
", file_conn)
close(file_conn)
compile('test.cpp')
dyn.load(dynlib('test'))
我们可以使用相同的 DLL 来拟合具有和不具有不同 sigma 的模型。
n <- 100
x <- rnorm(n = n, mean = 0, sd = 1)
f1 <- MakeADFun(data = list(x = x),
parameters = list(mu = 0, sigma = 1),
DLL = 'test')
f2 <- MakeADFun(data = list(x = x),
parameters = list(mu = 0, sigma = 1),
DLL = 'test',
map = list(sigma = factor(NA)))
opt1 <- do.call('optim', f1)
opt2 <- do.call('optim', f2)
当使用 "map" 时,指定的参数(在本例中为 sigma)固定为 "parameters" 中给定的值。
Post-优化,我们进行完整性检查——mus 应该几乎相同。
> opt1$par
mu sigma
0.08300554 1.07926521
> opt2$par
mu
0.08300712
打开和关闭随机效果有点困难。 here 给出了一个例子,您可以在其中使用 CppAD::Variable()
检查是否减少负对数似然。
对于不同的 objective 函数(不是彼此的子集),您可以将 DATA_INTEGER
或 DATA_STRING
传递到模板中,例如就像他们在 glmmTMB here 中所做的那样,并根据 DATA_*
.
我只是想弄清楚@alexforrence 的意思
For unalike objective functions (not subsets of one another), you could pass a DATA_INTEGER or DATA_STRING into the template, e.g. like they did in glmmTMB here, and pick the objective function depending on the value of that DATA_*
原来 TMB github 上有一个 code snippet 涵盖了这个场景,我在这里复制它:
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_STRING(model_type);
if (model_type == "model1") {
#include "model1.h"
} else
if (model_type == "model2") {
#include "model2.h"
} else {
error ("Unknown model type")
}
return 0;
}
也就是说,传入一个字符串,告诉 objective 函数选择哪个模型,然后将该函数的文本包含在单独的 .h
文件中。