简体   繁体   English

使用Ryacas进行R中的符号计算-结果成为特征

[英]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")

Revised code 修改后的代码

# 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM