r - 在 R 中翻译 matlab fminsearchbnd?
问题描述
我正在尝试将 Matlab 代码转换为 R,找到两个函数的最小误差。
这是 Matlab 代码:
erro=@(x) sum(((f14.*x(2)./(((x(1))/0.9924)+x(5))-(f14.*x(2)./(((x(1))/0.9924)+x(5))-x(3)).*exp(-(((x(1))/0.9924)+x(5))*(t-t1)))-mo).^2)./std(mo)+ sum (((f15.*x(2)./((x(1)+x(5)))-(f15.*x(2)./((x(1)+x(5)))-x(4)).*exp(-((x(1)+x(5))).*(t-t1)))-no).^2)/std(no);
x=fminsearchbnd(erro,xo,[0 0 200 0.9 0],[])
% x = 0.0123128476186327 13.5174782795704 368.926386686419 76.4422946745777 8.28109088192835e-09
所以我首先尝试了 pracma-package,不幸的是我可以找到 fminbnd() 和 fminsearch() 函数,但没有 fminsearchbnd()。有没有办法将这两者结合起来?或者谁能想到不同的解决方案?我用 "method = c("L-BFGS-B") 尝试了 optim() 函数,它给了我迄今为止最好的结果。但是我想知道是否有办法在 Matlab 和 R 中获得完全相同的结果。
我对 R 的翻译:
t <- c(0.5, 1, 2, 3)
mo <- c(368.54, 374.04, 381.75, 390.92)
no <- c(76.46, 75.96, 75.14, 74.23)
f15 <- c(0.003431)
f14 <- c(1-f15)
xo <- c(0.01211952, 13.30265, 368.54, 76.46, -0.000504064)
erro <- function(x){sum(((f14*x[2]/(((x[1])/0.9924)+x[5])-(f14*x[2]/(((x[1])/0.9924)+x[5])-x[3])*exp(-(((x[1])/0.9924)+x[5])*(t-t[1])))-mo)^2)/std(mo)
+ sum (((f15*x[2]/((x[1]+x[5]))-(f15*x[2]/((x[1]+x[5]))-x[4])*exp(-((x[1]+x[5]))*(t-t[1])))-no)^2)/std(no)}
x <- optim(xo, erro, lower = c(0, 0, 200, 0.9, 0), method = c("L-BFGS-B"))
# $par
#[1] 0.01230393 13.30265160 368.54000000 76.44231900 0.00000000
感谢您的帮助,请原谅任何错误,这是我的第一篇文章,我对matlab一无所知!;)
更新:我想将 optim-results 与 MATLAB 中的不同值进行比较,所以我尝试了:
mo <- c(322.79, 327.06, 323.11, 322.60)
no <- c(70.01023605, 64.18709552, 59.03694208, 55.83444661)
lo <- c(0.2573, 0.2525, 0.2398, 0.2388)
xo <- c(0.07856273, 24.87679, 322.79, 70.01024, 0.03182682)
我得到错误'L-BFGS-B需要'fn'的有限值'所以我将我的第一个界限从0设置为0.00001,结果是:
[1,] 1e-05 24.91 322.79 68.59785 0.09070217
但是,我的第一个值始终保持在下限,而 Matlab 的结果是:
0.05460 28.88570 324.74040 68.58710 0.03620
解决方案
最低生活的地区非常平坦。因此,为了在 R 中获得好的结果,可以添加一个显式的数值梯度,因为使用的梯度optim()
可能不够准确。在这里,我们使用“numDeriv”包中的梯度函数。
f15 <- c(0.003431); f14 <- c(1-f15)
t <- c(0.5, 1, 2, 3)
mo <- c(322.79, 327.06, 323.11, 322.60)
no <- c(70.01023605, 64.18709552, 59.03694208, 55.83444661)
lo <- c(0.2573, 0.2525, 0.2398, 0.2388)
# starting parameters
xo <- c(0.07856273, 24.87679, 322.79, 70.01024, 0.03182682)
erro <- function(x){
sum(((f14*x[2]/(((x[1])/0.9924)+x[5])-(f14*x[2]/(((x[1])/0.9924)+x[5])-x[3])*exp(-(((x[1])/0.9924)+x[5])*(t-t[1])))-mo)^2)/sd(mo) + sum (((f15*x[2]/((x[1]+x[5]))-(f15*x[2]/((x[1]+x[5]))-x[4])*exp(-((x[1]+x[5]))*(t-t[1])))-no)^2)/sd(no)
}
# minimum value at MATLAB solution xm
xm <- c(0.05460, 28.88570, 324.74040, 68.58710, 0.03620)
erro(xm)
## [1] 6.367856
# numerical gradient
erro_gr <- function(x) numDeriv::grad(erro, x)
s <- optim(xo, erro, gr = erro_gr,
lower = c(1.e-07, 0, 200, 0.9, 0),
method = c("L-BFGS-B"))
s$par;s$value
## [1] 0.08281183 28.97220 324.7395 68.58882 0.008001717
## [1] 6.367579
这甚至比 MATLAB 解决方案 6.367856 还要小,见上文。
推荐阅读
- javascript - 重叠的chart.js堆叠图
- python - 在运行 python 文件时使用 argv 更改目录
- spring-security - 在 jwt 令牌中加密 user_name
- performance - 在测试数据的性能评估中缺少预测标签
- google-cloud-platform - 无法读取查询结果并将其写回 BigQuery
- haskell - 如何使用 parsec 忽略任意标记?
- excel - VBA 宏使用单词 SaveAs FileFormat:=wdFormatPDF 创建 .docx
- mysql - MySQL准备的带有参数的语句不返回数据
- sql-server - 如何从 SQL Server 表生成 Reshift 兼容表架构
- python - 如何在所有变量都是分类的 pandas 数据框中识别 nan 值?