我的目标函数:
helper.post<-function(monthly.mean.return,
start.capital, #initial nest egg
target.legacy,
monthly.inflation.post,
monthly.withdrawals,
n.obs){
req = matrix(start.capital, n.obs+1, 1) #matrix for storing target weight
for (a in 1:n.obs) {
#cat("a: ",a,"\n")
req[a + 1, ] = req[a, ] * (1 + monthly.mean.return - monthly.inflation.post) - monthly.withdrawals[a,]
}
ending.value=req[nrow(req),]
#ending.value
value=target.legacy - ending.value
return(abs(value))
}
使用以下优化结构,更改两个值之间的 n.obs 会产生相同的输出:
即,如果 n.obs = 288 或 n.obs = 336,则给出相同的值。
optimize(f=helper.post,
start.capital = 1000000,
target.legacy = 1000000,
monthly.inflation.post=0.002083333,
monthly.withdrawals = matrix(rep(10000,n.obs)),
n.obs = n.obs,
lower = 0,
upper = 1,
tol = 0.00000000000000000000000000000000001)$minimum
正确值似乎是一个估计值,而不是正确值。知道我可能做错了什么吗?对于如此精确的优化工作,不同的优化工具会更好吗?我尝试了 uni-root,但它似乎不起作用,因为端点不是相反的符号..
uniroot( helper.post,
c(0, 1),
start.capital = start.capital,
target.legacy = target.legacy,
monthly.inflation.post=monthly.inflation.post,
monthly.withdrawals = monthly.withdrawals,
n.obs = n.obs)$root
最佳答案
让我们从稍微重写您的代码开始。我用向量替换了一列矩阵。我还添加了一个用于返回错误本身或其绝对值的选项。当尝试使用 optim
最小化错误时,您需要使用绝对值,而当尝试使用 uniroot
查找其根时,您需要使用值本身。
helper.post <- function(monthly.mean.return,
start.capital,
target.legacy,
monthly.inflation.post,
monthly.withdrawals,
n.obs,
return.abs = TRUE) {
req <- numeric(n.obs + 1)
req[1] <- start.capital
for (month in 1:n.obs) {
req[month + 1] <- req[month] *
(1 + monthly.mean.return - monthly.inflation.post) -
monthly.withdrawals[month]
}
ending.value <- req[n.obs + 1]
error <- target.legacy - ending.value
return(ifelse(return.abs, abs(error), error))
}
现在让我们优化它:
n.obs <- 288
optimize(f = helper.post,
start.capital = 1000000,
target.legacy = 1000000,
monthly.inflation.post = 0.002083333,
monthly.withdrawals = matrix(rep(10000,n.obs)),
n.obs = n.obs,
lower = 0,
upper = 1,
tol = 1e-20)$minimum
# [1] 0.01208333
让我们用 uni.root
检查解决方案:
uniroot(helper.post,
c(0, 1),
start.capital = 1000000,
target.legacy = 1000000,
monthly.inflation.post = 0.002083333,
monthly.withdrawals = matrix(rep(10000,n.obs)),
n.obs = n.obs,
return.abs = FALSE,
tol = 1e-20)$root
# [1] 0.01208333
他们匹配。一个或另一个工具没有任何问题......
如果您使用不同的 n.obs
值再次运行,您将得到完全相同的结果。为什么?因为您为起始资本和目标资本选择了恒定的提款和相等的值:您获得的输出是从一个月到下一个月保持余额恒定所需的利率,无论总月数如何。
事实上,这是您想要放入单元测试中的东西。因为这是一个预期的且易于解释的结果。我想到的另一个问题是,如果您将所有地方的提款额都设为零。那么你会期望你的答案与通货膨胀率相匹配。尝试一下,看看它确实有效。
关于R 优化返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17515967/