Re: [R] A strange behaviour in the graphical function curve
Berend Hasselman bhh at xs4all.nl writes: Yes. curve expects the function you give it to return a vector if the input argument is a vector. This is clearly documented for the argument expr of curve. Thanks a lot, Berend! In fact, I didn't read carefully the documentation of curve. Anyway, I wouldn't know how to transform my function into one that would be accepted by curve, so your feedback has been very useful for me. -Sergio. __ R-help@r-project.org 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.
Re: [R] A strange behaviour in the graphical function curve
Berend Hasselman bhh at xs4all.nl writes: Your function miBeta returns a scalar when the argument mu is a vector. Use Vectorize to vectorize it. Like this VmiBeta - Vectorize(miBeta,vectorize.args=c(mu)) VmiBeta(c(420,440)) and draw the curve with this curve(VmiBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) Berend Taking into account what you have pointed out, I reprogrammed my function as follows, as an alternative solution to yours: zetas - function(alpha) {z - qnorm(alpha/2); c(z,-z)} # First transformation function Tzx - function(z, sigma_p, mu_p) sigma_p*z + mu_p # Second transformation function Txz - function(x, sigma_p, mu_p) (x - mu_p)/sigma_p BetaG - function(mu, alpha, n, sigma, mu_0) { lasZ - zetas(alpha) # Zs corresponding to alpha sigma_M - sigma/sqrt(n) # sd of my distribution lasX - Tzx(lasZ, sigma_M, mu_0) # Transformed Zs into Xs # Now I consider mu to be a vector composed of m's NewZ - lapply(mu, function(m) Txz(lasX, sigma_M, m)) # NewZ is a list, the same length as mu, with 2D vectors # The result will be a vector, the same length as mu (and NewZ) sapply(NewZ, function(zz) pnorm(zz[2]) - pnorm(zz[1])) } miBeta - function(mu) BetaG(mu, 0.05, 36, 48, 400) plot(miBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) I hope this is useful to people following this discussion, -Sergio. __ R-help@r-project.org 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.
Re: [R] A strange behaviour in the graphical function curve
See below On Fri, 12 Apr 2013, Julio Sergio wrote: Berend Hasselman bhh at xs4all.nl writes: Your function miBeta returns a scalar when the argument mu is a vector. Use Vectorize to vectorize it. Like this VmiBeta - Vectorize(miBeta,vectorize.args=c(mu)) VmiBeta(c(420,440)) and draw the curve with this curve(VmiBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) Berend Taking into account what you have pointed out, I reprogrammed my function as follows, as an alternative solution to yours: zetas - function(alpha) {z - qnorm(alpha/2); c(z,-z)} # First transformation function Tzx - function(z, sigma_p, mu_p) sigma_p*z + mu_p # Second transformation function Txz - function(x, sigma_p, mu_p) (x - mu_p)/sigma_p BetaG - function(mu, alpha, n, sigma, mu_0) { lasZ - zetas(alpha) # Zs corresponding to alpha sigma_M - sigma/sqrt(n) # sd of my distribution lasX - Tzx(lasZ, sigma_M, mu_0) # Transformed Zs into Xs # Now I consider mu to be a vector composed of m's NewZ - lapply(mu, function(m) Txz(lasX, sigma_M, m)) # NewZ is a list, the same length as mu, with 2D vectors # The result will be a vector, the same length as mu (and NewZ) sapply(NewZ, function(zz) pnorm(zz[2]) - pnorm(zz[1])) } miBeta - function(mu) BetaG(mu, 0.05, 36, 48, 400) plot(miBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) I hope this is useful to people following this discussion, -Sergio. Adding to what you have defined above, consider the benefit that true vectorization provides: BetaGv - function(mu, alpha, n, sigma, mu_0) { lasZ - zetas( alpha ) # Zs corresponding to alpha sigma_M - sigma/sqrt( n ) # sd of my distribution lasX - Tzx( lasZ, sigma_M, mu_0 ) # Transformed Zs into Xs # Now fold lasX and mu into matrices where columns are defined by lasX # and rows are defined by mu lasX_M - matrix( lasX, nrow=length(mu), ncol=2, byrow=TRUE ) mu_M - matrix( mu, nrow=length(mu), ncol=2 ) ) # Compute newZ NewZ - Txz( lasX_M, sigma_M, mu_M ) # NewZ is a matrix, where the first column corresponds to lower Z, and # the second column corresponds to upper Z # The result will be a vector, the same length as mu pnorm(NewZ[,2]) - pnorm(NewZ[,1]) } miBetav - function(mu) BetaGv(mu, 0.05, 36, 48, 400) system.time( miBeta( seq( 370, 430, length.out=1e5 ) ) ) system.time( miBetav( seq( 370, 430, length.out=1e5 ) ) ) On my machine, I get: system.time( miBeta( seq( 370, 430, length.out=1e5 ) ) ) user system elapsed 1.300 0.024 1.476 system.time( miBetav( seq( 370, 430, length.out=1e5 ) ) ) user system elapsed 0.076 0.000 0.073 So a bit of matrix manipulation speeds things up considerably. (That being said, I have a feeling that some algorithmic optimization could speed things up even more, using theoretical considerations.) --- Jeff NewmillerThe . . Go Live... DCN:jdnew...@dcn.davis.ca.usBasics: ##.#. ##.#. Live Go... Live: OO#.. Dead: OO#.. Playing Research Engineer (Solar/BatteriesO.O#. #.O#. with /Software/Embedded Controllers) .OO#. .OO#. rocks...1k __ R-help@r-project.org 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.
Re: [R] A strange behaviour in the graphical function curve
On Apr 12, 2013, at 7:58 AM, Julio Sergio wrote: Berend Hasselman bhh at xs4all.nl writes: Your function miBeta returns a scalar when the argument mu is a vector. Use Vectorize to vectorize it. Like this VmiBeta - Vectorize(miBeta,vectorize.args=c(mu)) VmiBeta(c(420,440)) and draw the curve with this curve(VmiBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) Berend Taking into account what you have pointed out, I reprogrammed my function as follows, as an alternative solution to yours: zetas - function(alpha) {z - qnorm(alpha/2); c(z,-z)} # First transformation function Tzx - function(z, sigma_p, mu_p) sigma_p*z + mu_p # Second transformation function Txz - function(x, sigma_p, mu_p) (x - mu_p)/sigma_p BetaG - function(mu, alpha, n, sigma, mu_0) { lasZ - zetas(alpha) # Zs corresponding to alpha sigma_M - sigma/sqrt(n) # sd of my distribution lasX - Tzx(lasZ, sigma_M, mu_0) # Transformed Zs into Xs # Now I consider mu to be a vector composed of m's NewZ - lapply(mu, function(m) Txz(lasX, sigma_M, m)) # NewZ is a list, the same length as mu, with 2D vectors # The result will be a vector, the same length as mu (and NewZ) sapply(NewZ, function(zz) pnorm(zz[2]) - pnorm(zz[1])) } miBeta - function(mu) BetaG(mu, 0.05, 36, 48, 400) plot(miBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) I hope this is useful to people following this discussion, This could be completely tangential to your problem with vectorization of arguments to 'curve'. Feel free to ignore. The second of your functions looks to be doing the same as the R function 'scale'. I would have expected it to be applied first and then to have an 'unscale' operation performed to restore (but I am not aware that there is an inbuilt function with that feature): umat - sweep( mat, 2, attr(m2, 'scaled:scale'), '*') umat - sweep( umat, 2, attr(m2, 'scaled:center'), '+') # Or perhaps this where 'sx' was the result of a 'scale' call: scale(sx, -attr(sx, 'scaled:center'), 1/attr(sx,'scaled:scale') ), - attr(sx, 'scaled:center') -- David -Sergio. __ R-help@r-project.org 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. David Winsemius, MD Alameda, CA, USA __ R-help@r-project.org 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.
Re: [R] A strange behaviour in the graphical function curve
On 12-04-2013, at 05:15, Julio Sergio julioser...@gmail.com wrote: I thought the curve function was a very flexible way to draw functions. So I could plot funtions like the following: # I created a function to produce functions, for instance: fp - function(m,b) function(x) sin(x) + m*x + b # So I can produce a function like this ff - fp(-0.08, 0.2) ff(1.5) # Is the same as executing sin(1.5) - 0.08*1.5 + 0.2 # Let's plot this plot(fp(0.1,0.1),xlim=c(-2*pi,2*pi),col=red) curve(fp(0,0)(x),add=T) curve(ff(x),add=T,col=blue) When I get to plot some more complex functions, curve, instead of taking the argument function as a black-box, i.e., something that takes an argument (the x) and returns a value (the y), seems to inspect the inner code of the argument function in a way that even R itself doesn't do. See what I'm talking about: # A function that returns a 2-element vector, given a # single argument zetas - function(alpha) {z - qnorm(alpha/2); c(z,-z)} # A transformation function - it can take a vector as # its z argument Tzx - function(z, sigma_p, mu_p) sigma_p*z + mu_p # Another transformation function similar to the # previous one - it can take a vector as its x argument Txz - function(x, sigma_p, mu_p) (x - mu_p)/sigma_p # The general function with several arguments BetaG - function(mu, alpha, n, sigma, mu_0) { lasZ - zetas(alpha) # It is a vector sigma_M - sigma/sqrt(n) lasX - Tzx(lasZ, sigma_M, mu_0) # Another vector(transf. from lasZ) NewZ - Txz(lasX, sigma_M, mu) # A new vector:transf. from lasX # And the result is a single value: pnorm(NewZ[2]) - pnorm(NewZ[1]) } # Now, let's have a function of a single argument, giving # particular values to all other arguments; so miBeta depends # only on the value of the argument 'mu' miBeta - function(mu) BetaG(mu, 0.05, 36, 48, 400) # I can call this function with 420 and it works miBeta(420) # But when the time comes to plot the function, it doesn't work curve(miBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) When I called miBeta with any value the R interpreter didn't complain. However, curve seems to go deeper than the R interpreter and issues several error messages: Error en curve(miBeta, xlim = c(370, 430), xlab = mu, ylab = L(mu)) : 'expr' did not evaluate to an object of length 'n' Además: Mensajes de aviso perdidos In x - mu_p : longitud de objeto mayor no es múltiplo de la longitud de uno menor Do you have any idea on why curve behaves this way? Yes. curve expects the function you give it to return a vector if the input argument is a vector. This is clearly documented for the argument expr of curve. Your function miBeta returns a scalar when the argument mu is a vector. Use Vectorize to vectorize it. Like this VmiBeta - Vectorize(miBeta,vectorize.args=c(mu)) VmiBeta(c(420,440)) and draw the curve with this curve(VmiBeta,xlim=c(370,430), xlab=mu, ylab=L(mu)) Berend __ R-help@r-project.org 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.