我有一个小的MATLAB脚本,主要使用符号工具箱进行衍生,我想重写为R.我选择了Ryacas包,因为我发现rSymPy太难以安装......这是我的R代码
# install.packages('Ryacas')
library(Ryacas)
z <- Sym("z")
psi=c()
psi[1]=z^2*exp(-z)/(1-exp(-z))
psi[2]=z^2*exp(-z)/(1-exp(-z))*log(z)
psi[3]=z^2*exp(-z)/(1-exp(-z))*log(z)^2
f=matrix(NA,4,4)
f[1,1]=z^2*exp(-z)/(1-exp(-z))
for(i in 2:4){
f[i,1]=deriv.Sym(psi[i-1],z)
j=2
while(j<=i){
f[i,j]=deriv.Sym(expression(f[i,j-1]/f[j-1,j-1]),z)
j=j+1
}
}
它不会报告任何错误。但是,输出显示R实际上不进行符号计算但返回字符。所以我无法评估结果。我试过了
> i=2
> deriv.Sym(psi[i-1],z)
expression(((1 - exp(-z)) * (2 * (z * exp(-z)) - z^2 * exp(-z)) -
z^2 * exp(-z)^2)/(1 - exp(-z))^2)
> f[i,1]
[1] "( D( z , 1 ) ( ( ( z ^ 2 ) * ( Exp ( ( - z ) ) ) ) / ( 1 - ( Exp ( ( - z ) ) ) ) ) )"
似乎deriv.Sym(psi[i-1],z)
执行符号导数并获得正确的结果。但是如果将结果赋给变量,它就变成了字符类。我对expression()
,yacas()
,Sym()
和角色感到困惑。任何人都可以指出我的错误或帮助我澄清这些概念?非常感谢你。
下面对应的MATLAB代码供参考。 MATLAB代码工作正常。
syms c;
psi(1)=c^2*exp(-c)/(1-exp(-c));
psi(2)=c^2*exp(-c)/(1-exp(-c))*log(c);
psi(3)=c^2*exp(-c)/(1-exp(-c))*log(c)^2;
f(1,1)=c^2*exp(-c)/(1-exp(-c));
for i=2:4
f(i,1)=diff(psi(i-1),c);
j=2;
while j<=i
f(i,j)=diff(f(i,j-1)/f(j-1,j-1),c);
j=j+1;
end
end
g11=matlabFunction(f(1,1));
fplot(g11,[0,10])
figure
g22=matlabFunction(f(2,2));
fplot(g22,[0,10])
figure
g33=matlabFunction(f(3,3));
fplot(g33,[0,10])
figure
g44=matlabFunction(f(4,4));
fplot(g44,[0,10])
答案 0 :(得分:3)
问题中的R代码有几个问题:
它正在尝试将S3对象分配给逻辑矩阵的元素:
typeof(NA)
## [1] "logical"
所以R已将其转换为字符(因为Sym
对象在内部
这是尽可能远的。 f
需要定义为列表
具有2个尺寸,以便它可以容纳这样的物体:
f <- matrix(list(), 4, 4)
由于f
是一个包含2个维度的列表,因此对f
元素的所有引用都应使用双方括号,如下所示:
f[[1, 1]] <- z^2 * exp(-z) / (1 - exp(-z))
同样psi
应初始化为:
psi <- list()
然后引用为:
psi[[1]] <- z^2 * exp(-z) / (1 - exp(-z))
评估f[[i, 1]]
使用Eval
:
Eval(f[[i, 1]], list(z = 1))
## [1] 0.2432798
这也可以,但会覆盖Sym
对象z
:
z <- 1
Eval(f[[i, 1]])
应该调用泛型deriv
而不是直接转到特定方法deriv.Sym
修订后的代码在最后一节中进行了这些更改以及一些风格上的改进。
建议您查看Ryacas附带的小插曲。从R控制台输入:
vignette("Ryacas")
同时回顾Ryacas演示:
demo(package = "Ryacas")
# install.packages('Ryacas')
library(Ryacas)
z <- Sym("z")
psi <- list()
psi[[1]] <- z^2 * exp(-z) / (1 - exp(-z))
psi[[2]] <- z^2 * exp(-z) / (1 - exp(-z)) * log(z)
psi[[3]] <- z^2 * exp(-z) / (1 - exp(-z)) * log(z)^2
f <- matrix(list(), 4, 4)
f[[1,1]] <- z^2 * exp(-z) / (1 - exp(-z))
for(i in 2:4) {
f[[i, 1]] <- deriv(psi[[i-1]], z)
j <- 2
while(j <= i) {
f[[i, j]] <- deriv(f[[i, j-1]] / f[[j-1, j-1]], z)
j <- j + 1
}
}
i <- 2
deriv(psi[[i-1]], z)
f[[i, 1]]
Eval(f[[i, 1]], list(z = 1))