[英]Symbolic computation in R with Ryacas - results become character
I have a small MATLAB script mainly doing derivatives using symbolic toolbox that I want to rewrite into R. I chose Ryacas package because I found rSymPy too tricky to install... Here is my R code 我有一个小的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
}
}
It does not report any error. 它不报告任何错误。 However, the output shows that R isn't actually doing symbolic computation but returns characters.
但是,输出显示R实际上并未进行符号计算,而是返回了字符。 So I cannot evaluate the result.
所以我无法评估结果。 I tried
我试过了
> 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 ) ) ) ) ) )"
It seems that deriv.Sym(psi[i-1],z)
does the symbolic derivative and get the correct result. 似乎
deriv.Sym(psi[i-1],z)
做符号导数并得到正确的结果。 But if the result is assigned to a variable, it becomes character class. 但是,如果将结果分配给变量,它将成为字符类。 I feel confused about
expression()
, yacas()
, Sym()
and character. 我对
expression()
, yacas()
, Sym()
和character感到困惑。 Anyone can point out my mistake or help me clarify these concept? 任何人都可以指出我的错误或帮助我阐明这些概念吗? Thank you so much.
非常感谢。
Below corresponding MATLAB code for reference. 下面对应的MATLAB代码供参考。 The MATLAB code works just fine.
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])
There are several problems with the R code in the question: 问题中的R代码有几个问题:
it is attempting to assign an S3 object to elements of a logical matrix: 它正在尝试将S3对象分配给逻辑矩阵的元素:
typeof(NA) ## [1] "logical"
so R has converted it to character (since Sym
objects are internally character) which is as far as it can go. 因此R已将其尽可能地转换为字符(因为
Sym
对象内部是字符)。 f
needs to be defined as a list with 2 dimensions so that it can hold such objects: f
必须定义为具有2维的列表,以便它可以容纳此类对象:
f <- matrix(list(), 4, 4)
since f
is a list with 2 dimensions all references to elements of f
should use double square brackets as in: 由于
f
是具有2维的列表,因此对f
所有引用都应使用双方括号,如下所示:
f[[1, 1]] <- z^2 * exp(-z) / (1 - exp(-z))
similarly psi
should be initialized as: 同样,
psi
应该初始化为:
psi <- list()
and then referenced as: 然后引用为:
psi[[1]] <- z^2 * exp(-z) / (1 - exp(-z))
to evaluate f[[i, 1]]
use Eval
: 评估
f[[i, 1]]
使用Eval
:
Eval(f[[i, 1]], list(z = 1)) ## [1] 0.2432798
This also works but overwrites the Sym
object z
: 这也可以,但是会覆盖
Sym
对象z
:
z <- 1 Eval(f[[i, 1]])
in general code should be calling the generic deriv
and not by directly going to the specific method deriv.Sym
一般而言,代码应调用通用
deriv
而不是直接转到特定方法deriv.Sym
The revised code is in the section at the end which makes these changes as well as some stylistic improvements. 修改后的代码在最后一节中,进行了这些更改以及一些样式方面的改进。
Suggest you review the vignette that comes with Ryacas. 建议您查看Ryacas随附的小插图。 From the R console enter:
在R控制台中输入:
vignette("Ryacas")
Also review the Ryacas demos: 另请查看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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.