Daniel Berg
2006-Nov-21 13:48 UTC
[R] Symbolic derivation using D in package stats - how do I properly convert the returned call into a character string?
Dear all, I am using the function 'D' in the 'stats' package to perform symbolic derivation. This works very well and it is much faster than e.g. Mathematica (at least for my purposes). First, I would like to thank the development team for this excellent function. However, I run into trouble in some cases, particularly when I am to do some operations on long expressions obtained from using D. The problem seems to occur when I convert a 'call' or an 'expression' to a 'character', then some parts of the original 'expression' is lost. Is there some way of transforming a call or an expression into a character string that I do not know of or alternatively, can I merge two calls or two expressions by a numerical operation, e.g. c = a / b where both a and b are symbolic expressions and I wish for c to be a symbolic expression as well? Take e.g. the following example: #--------------------------------- # First, I try with d=2, now it works: d<-2; u<-rep("u1",d); th<-rep("th1",d) for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } dC1 <- expression((((1 - 2 + u1^(-th1)) + u2^(-th1))^(-1/th1))) dC2 <- expression(u1) #These expressions were returned from a combination of several expressions of mine... for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } # I wish to create a new expression equal to dC1 / dC2 and I proceed as follows: F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") # To see that it works print dC1, dC2 and F and compare. # It also works for d=3, but for d=4 something strange happens: d<-4; u<-rep("u1",d); th<-rep("th1",d) for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } dC1 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + (((1 - 2 + u3^(-th3)) + u4^(-th3))^(-1/th3))^(-th2))^(-1/th2))^(-th1))^(-1/th1))) dC2 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + u3^(-th2))^(-1/th2))^(-th1))^(-1/th1))) for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") # Now paste(dC1) throws away parts of the expression. Try paste(dC1) # and see the end of second element. # You will get a 3-dim char vector where there is something missing at the end of the second element. #----------------------------------- I am running R 2.2.1 on windows. Any help, suggestions or comments in general will be highly appreciated. Thank you. Best wishes, Daniel Berg --------------------- danielberg.no
Gabor Grothendieck
2006-Nov-21 14:19 UTC
[R] Symbolic derivation using D in package stats - how do I properly convert the returned call into a character string?
You could try using Ryacas (home page at http://code.google.com/p/ryacas/):> library(Ryacas) > > u1 <- Sym("u1"); u2 <- Sym("u2"); u3 <- Sym("u3"); u4 <- Sym("u4") > th1 <- Sym("th1"); th2 <- Sym("th2"); th3 <- Sym("th3"); th4 <- Sym("th4") > > C1 <- ((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + (((1 -+ 2 + u3^(-th3)) + u4^(-th3))^(-1/th3))^(-th2))^(-1/th2))^(-th1))^(-1/th1)> C2 <- ((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) ++ u3^(-th2))^(-1/th2))^(-th1))^(-1/th1)> > dC1 <- deriv(C1, list("u1", "u2", "u3", "u4")) > dC2 <- deriv(C2, list("u1", "u2", "u3", "u4")) > > dC1 / dC2expression((u1^-th1 - 1 + ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-th1)^-(1/th1 + 1) * (((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-(th1 + 1) * (th1 * ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * u2^-(th2 + 1))))) * (th1 * th2)^2/(((u1^-th1 - 1 + ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-th1)^-(1/th1 + 1) * (((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-(th1 + 1) * (th1 * ((1/th2 + 1) * (th2 * u2^-(th2 + 1)) * (u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 2) * (th2 * u2^-(th2 + 1)) - (u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * ((th2 + 1) * u2^-(th2 + 2))))) - th1 * ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * u2^-(th2 + 1))) * (((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-(th1 + 2) * ((th1 + 1) * ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * u2^-(th2 + 1)))))/th2) + ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-(th1 + 1) * (th1 * ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * u2^-(th2 + 1)))) * ((u1^-th1 - 1 + ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-th1)^-(1/th1 + 2) * ((1/th1 + 1) * (((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-(th1 + 1) * (th1 * ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^-(1/th2 + 1) * (th2 * u2^-(th2 + 1)))))))/th2) * (th1 * th2)^2))> Simplify("%")expression((u1^-th1 - 1 + ((u2^-th2 - 1 + ((u3^-th3 - 1 + u4^-th3)^(-1/th3))^-th2)^(-1/th2))^-th1)^-(1/th1 + 1) * (th1 * u1^-(th1 + 1)) * th1/(th1 * ((u1^-th1 - 1 + ((u2^-th2 - 1 + u3^-th2)^(-1/th2))^-th1)^-(1/th1 + 1) * (th1 * u1^-(th1 + 1))))) On 11/21/06, Daniel Berg <daniel at danielberg.no> wrote:> Dear all, > > I am using the function 'D' in the 'stats' package to perform symbolic > derivation. > This works very well and it is much faster than e.g. Mathematica (at > least for my purposes). > First, I would like to thank the development team for this excellent > function. > > However, I run into trouble in some cases, particularly when I am to do > some operations on long expressions obtained from using D. > The problem seems to occur when I convert a 'call' or an 'expression' to > a 'character', then some parts of the original 'expression' is lost. > Is there some way of transforming a call or an expression into a > character string that I do not know of or alternatively, can I merge two > calls or two expressions by a numerical operation, e.g. c = a / b where > both a and b are symbolic expressions and I wish for c to be a symbolic > expression as well? > > Take e.g. the following example: > #--------------------------------- > # First, I try with d=2, now it works: > d<-2; u<-rep("u1",d); th<-rep("th1",d) > for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } > dC1 <- expression((((1 - 2 + u1^(-th1)) + u2^(-th1))^(-1/th1))) > dC2 <- expression(u1) > #These expressions were returned from a combination of several > expressions of mine... > for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } > # I wish to create a new expression equal to dC1 / dC2 and I proceed as > follows: > F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") > # To see that it works print dC1, dC2 and F and compare. > > # It also works for d=3, but for d=4 something strange happens: > d<-4; u<-rep("u1",d); th<-rep("th1",d) > for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } > dC1 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + (((1 - > 2 + u3^(-th3)) + u4^(-th3))^(-1/th3))^(-th2))^(-1/th2))^(-th1))^(-1/th1))) > dC2 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + > u3^(-th2))^(-1/th2))^(-th1))^(-1/th1))) > for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } > F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") > # Now paste(dC1) throws away parts of the expression. Try > paste(dC1) > # and see the end of second element. > # You will get a 3-dim char vector where there is something missing at > the end of the second element. > #----------------------------------- > > I am running R 2.2.1 on windows. > Any help, suggestions or comments in general will be highly appreciated. > > Thank you. > > Best wishes, > Daniel Berg > > --------------------- > danielberg.no > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
Duncan Murdoch
2006-Nov-21 15:15 UTC
[R] Symbolic derivation using D in package stats - how do I properly convert the returned call into a character string?
On 11/21/2006 8:48 AM, Daniel Berg wrote:> Dear all, > > I am using the function 'D' in the 'stats' package to perform symbolic > derivation. > This works very well and it is much faster than e.g. Mathematica (at > least for my purposes). > First, I would like to thank the development team for this excellent > function. > > However, I run into trouble in some cases, particularly when I am to do > some operations on long expressions obtained from using D. > The problem seems to occur when I convert a 'call' or an 'expression' to > a 'character', then some parts of the original 'expression' is lost. > Is there some way of transforming a call or an expression into a > character string that I do not know of or alternatively, can I merge two > calls or two expressions by a numerical operation, e.g. c = a / b where > both a and b are symbolic expressions and I wish for c to be a symbolic > expression as well? > > Take e.g. the following example: > #--------------------------------- > # First, I try with d=2, now it works: > d<-2; u<-rep("u1",d); th<-rep("th1",d) > for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } > dC1 <- expression((((1 - 2 + u1^(-th1)) + u2^(-th1))^(-1/th1))) > dC2 <- expression(u1) > #These expressions were returned from a combination of several > expressions of mine... > for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } > # I wish to create a new expression equal to dC1 / dC2 and I proceed as > follows: > F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") > # To see that it works print dC1, dC2 and F and compare. > > # It also works for d=3, but for d=4 something strange happens: > d<-4; u<-rep("u1",d); th<-rep("th1",d) > for(i in 1:d) { u[i] <- paste("u",i,sep=""); th[i] <- paste("th",i,sep="") } > dC1 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + (((1 - > 2 + u3^(-th3)) + u4^(-th3))^(-1/th3))^(-th2))^(-1/th2))^(-th1))^(-1/th1))) > dC2 <- expression((((1 - 2 + u1^(-th1)) + (((1 - 2 + u2^(-th2)) + > u3^(-th2))^(-1/th2))^(-th1))^(-1/th1))) > for(j in 1:(d-1)) { dC1<-D(expr=dC1,name=u[j]); dC2<-D(expr=dC2,name=u[j]) } > F <- paste("(",as.expression(dC1),")/(",as.expression(dC2),")",sep="") > # Now paste(dC1) throws away parts of the expression. Try > paste(dC1) > # and see the end of second element. > # You will get a 3-dim char vector where there is something missing at > the end of the second element. > #----------------------------------- > > I am running R 2.2.1 on windows. > Any help, suggestions or comments in general will be highly appreciated.That's an old version, but I think the problem is still present in the current one. A simple example is paste(as.expression(as.list(1:1000))) which on my system truncates the output just after the 121st element of the list. The problem is that deparse() has a maximum line width of around 500 characters, and you need more to fit your entire expression on one line, the way paste is trying to do. I suppose we could increase the buffer size in deparse (or make it dynamic), but I'm not sure that it's worthwhile. Why would you want to use paste on a long expression like that? Why not leave it as an expression? deparse() works fine to print it on multiple lines; I'm just not sure I see the value in allowing arbitrarily long lines here. (At a minimum, I think paste() should report a "line too long" error rather than silently truncating; I'm not saying the current behaviour is fine.) Duncan Murdoch