I've been trying to write a program in R that implements Newton's method. I've been mostly successful, but there are two little snags that have been bothering me. Here's my code:
Newton<-function(f,f.,guess){
#f <- readline(prompt="Function? ")
#f. <- readline(prompt="Derivative? ")
#guess <- as.numeric(readline(prompt="Guess? "))
a <- rep(NA, length=1000)
a[1] <- guess
a[2] <- a[1] - f(a[1]) / f.(a[1])
for(i in 2:length(a)){
if(a[i] == a[i-1]){
break
}
else{
a[i+1] <- a[i] - f(a[i]) / f.(a[i])
}
}
a <- a[complete.cases(a)]
return(a)
}
I can't get R to recognize the functions f and f. if I try using readline() to prompt for user input. I get the error "Error in Newton() : could not find function "f."" However, if I comment out the readlines (as above), define f and f. beforehand, then everything works fine.
I've been trying to make R calculate the derivative of a function. The problem is that the class object with which R can take symbolic derivatives is expression(), but I want to take the derivative of a function() and have it give me a function(). In short, I'm having trouble with type conversion between expression() and function().
I have an ugly but effective solution for going from function() to expression(). Given a function f, D(body(f)[[2]],"x") will give the derivative of f. However, this output is an expression(), and I haven't been able to turn it back into a function(). Do I need to use eval() or something? I've tried subsetting, but to no avail. For instance:
g <- expression(sin(x))
g[[1]]
sin(x)
f <- function(x){g[[1]]}
f(0)
sin(x)
when what I want is f(0) = 0 since sin(0) = 0.
EDIT: Thanks all! Here's my new code:
Newton<-function(f,f.,guess){
g<-readline(prompt="Function? ")
g<-parse(text=g)
g.<-D(g,"x")
f<-function(x){eval(g[[1]])}
f.<-function(x){eval(g.)}
guess<-as.numeric(readline(prompt="Guess? "))
a<-rep(NA, length=1000)
a[1]<-guess
a[2]<-a[1]-f(a[1])/f.(a[1])
for(i in 2:length(a)){
if(a[i]==a[i-1]){break
}else{
a[i+1]<-a[i]-f(a[i])/f.(a[i])
}
}
a<-a[complete.cases(a)]
#a<-a[1:(length(a)-1)]
return(a)
}
This first problem arises because readline reads in a text string, whereas what you need is an expression. You can use parse() to convert the text string to an expression:
f <-readline(prompt="Function? ")
sin(x)
f
# [1] "sin(x)"
f <- parse(text = f)
f
# expression(sin(x))
g <- D(f, "x")
g
# cos(x)
To pass in values for the arguments in the function call in the expression (whew!), you can eval() it in an environment containing the supplied values. Nicely, R will allow you to supply those values in a list supplied to the envir= argument of eval():
> eval(f, envir=list(x=0))
# [1] 0
Josh has answered your question
For part 2 you could have used
g <- expression( sin(x) )
g[[1]]
# sin(x)
f <- function(x){ eval( g[[1]] ) }
f(0)
# [1] 0
f(pi/6)
# [1] 0.5
BTW, having recently written a toy which calculates fractal patterns based on root convergence of Newton's method in the complex plane, I can recommend you toss in some code like the following (where the main function's argument list includes "func" and "varname" ).
func<- gsub(varname, 'zvar', func)
funcderiv<- try( D(parse(text=func), 'zvar') )
if(class(funcderiv) == 'try-error') stop("Can't calculate derivative")
If you're more cautious, you could include a an argument "funcderiv" , and wrap my code in
if(missing(funcderiv)){blah blah}
Ahh, why not: here's my complete function for all to use and enjoy:-)
# build Newton-Raphson fractal
#define: f(z) the convergence per Newton's method is
# zn+1 = zn - f(zn)/f'(zn)
#record which root each starting z0 converges to,
# and to get even nicer coloring, record the number of iterations to get there.
# Inputs:
# func: character string, including the variable. E.g., 'x+ 2*x^2' or 'sin(x)'
# varname: character string indicating the variable name
# zreal: vector(preferably) of Re(z)
# zim: vector of Im(z)
# rootprec: convergence precision for the NewtonRaphson algorithm
# maxiter: safety switch, maximum iterations, after which throw an error
#
nrfrac<-function(func='z^5 - 1 ', varname = 'z', zreal= seq(-5,5,by=.1), zim, rootprec=1.0e-5, maxiter=1e4, drawplot=T, drawiterplot=F, ...) {
zreal<-as.vector(zreal)
if(missing(zim)) zim <- as.vector(zreal)
# precalculate F/F'
# check for differentiability (in R's capability)
# and make sure to get the correct variable name into the function
func<- gsub(varname, 'zvar', func)
funcderiv<- try( D(parse(text=func), 'zvar') )
if(class(funcderiv) == 'try-error') stop("Can't calculate derivative")
# Interesting "feature" of deparse : default is to limit each string to 60 or64
# chars. Need to avoid that here. Doubt I'd ever see a derivative w/ more
# than 500 chars, the max allowed by deparse. To do it right,
# need sum(nchar(funcderiv)) as width, and even then need to do some sort of
# paste(deparse(...),collapse='') to get a single string
nrfunc <- paste(text='(',func,')/(',deparse(funcderiv, width=500),')', collapse='')
# first arg to outer() will give rows
# Stupid Bug: I need to REVERSE zim to get proper axis orientation
zstart<- outer(rev(zim*1i), zreal, "+")
zindex <- 1:(length(zreal)*length(zim))
zvec <- data.frame(zdata=as.vector(zstart), zindex=zindex, itermap=rep(0,length(zindex)), badroot=rep(0,length(zindex)), rooterr=rep(0,length(zindex)) )
#initialize data.frame for zout.
zout=data.frame(zdata=rep(NA,length(zstart)), zindex=rep(NA,length(zindex)), itermap=rep(0,length(zindex)), badroot=rep(0,length(zindex)), rooterr=rep(0,length(zindex)))
# a value for rounding purposes later on; yes it works for rootprec >1
logprec <- -floor(log10(rootprec))
newtparam <- function(zvar) {}
body(newtparam)[2] <- parse(text=paste('newz<-', nrfunc, collapse=''))
body(newtparam)[3] <- parse(text=paste('return(invisible(newz))'))
iter <- 1
zold <- zvec # save zvec so I can return original values
zoutind <- 1 #initialize location to write solved values
while (iter <= maxiter & length(zold$zdata)>0 ) {
zold$rooterr <- newtparam(zold$zdata)
zold$zdata <- zold$zdata - zold$rooterr
rooterr <- abs(zold$rooterr)
zold$badroot[!is.finite(rooterr)] <- 1
zold$zdata[!is.finite(rooterr)] <- NA
# what if solvind = FFFFFFF? -- can't write 'nothing' to zout
solvind <- (zold$badroot >0 | rooterr<rootprec)
if( sum(solvind)>0 ) zout[zoutind:(zoutind-1+sum(solvind)),] <- zold[solvind,]
#update zout index to next 'empty' row
zoutind<-zoutind + sum(solvind)
# update the iter count for remaining elements:
zold$itermap <- iter
# and reduce the size of the matrix being fed back to loop
zold<-zold[!solvind,]
iter <- iter +1
# just wonder if a gc() call here would make any difference
# wow -- it sure does
gc()
} # end of while
# Now, there may be some nonconverged values, so:
# badroot[] is set to 2 to distinguish from Inf/NaN locations
if( zoutind < length(zindex) ) { # there are nonconverged values
# fill the remaining rows, i.e. zout.index:length(zindex)
zout[(zoutind:length(zindex)),] <- zold # all of it
zold$badroot[] <- 2 # yes this is safe for length(badroot)==0
zold$zdata[]<-NA #keeps nonconverged values from messing up results
}
# be sure to properly re-order everything...
zout<-zout[order(zout$zindex),]
zout$zdata <- complex(re=round(Re(zout$zdata),logprec), im=round(Im(zout$zdata),logprec) )
rootvec <- factor(as.vector(zout$zdata), labels=c(1:length(unique(na.omit(as.vector(zout$zdata))))))
#convert from character, too!
rootIDmap<-matrix(as.numeric(rootvec), nr=length(zim))
# to colorize very simply:
if(drawplot) {
colorvec<-rainbow(length(unique(as.vector(rootIDmap))))
imagemat<-rootIDmap
imagemat[,]<-colorvec[imagemat] #now has color strings
dev.new()
# all '...' arguments used to set up plot
plot(range((zreal)),range((zim)), t='n',xlab='real',ylab='imaginary',... )
rasterImage(imagemat, range(zreal)[1], range(zim)[1], range(zreal)[2], range(zim)[2], interp=F)
}
outs <- list(rootIDmap=rootIDmap, zvec=zvec, zout=zout, nrfunc=nrfunc)
return(invisible(outs))
}
Related
Consider the function f which takes decision-tree node parameters {-1,+1} and maps it to an one-hot vector [0,0,0,1] for example.
I think this will end up being one of the bottlenecks of a program I'm working on, so I'd like to know if anyone finds a faster way to map the parameters to the vector.
f<-function(h){
# function takes as arguments:
# an m-bit vector of potential split decisions (h)
# function returns:
# an m+1-length one-hot indicator vector
theta_vec = c(rep(0,length(h)+1))
position = length(h)+1
for(bit in seq(1,length(h),2)){
if(h[bit]>0){
position=position
}
else{
position=position/2
}
}
theta_vec[position]=1
return(theta_vec)
}
Thank you for your help
I think I've got a solution that runs in a quarter of the time. Are you able to refactor so that you use (0,1) instead of (-1,1); and use it as lists of rows instead of a vector? I find its easier to interpret when thinking about the problem, although the function below could be re-written to use a vector as input.
findPos <- function(h){
# find number of rows from input
N <- length(h)
# go through and pick out the values in each tree that are valid based
# on previous route
out <- c(h[[1]], rep(0, N-1))
for(i in 2:N){
out[i] <- h[[i]][sum(out[i:(i-1)] * 2^(i-1)/(2^((i-1):1))) + 1]
}
# now find the final position in the bottom row and return as a vector
out_pos <- sum(out * 2^N/(2^(1:N))) + 1
full_vec <- rep(0, 2^N)
full_vec[out_pos] <- 1
return(full_vec)
}
# couple of e.gs
f(c(0,1,1))
findPos(list(0, c(1,1)))
f(c(1,1,1))
findPos(list(1, c(1,1)))
# works with larger trees
findPos(list(1, c(1,1), c(1,0,0,0)))
# check time using microbenchmark package
microbenchmark::microbenchmark(
"old" = {
f(c(0,1,1))
},
"new" = {
findPos(list(0, c(1,1)))
}
)
Best
Jonny
I need a function created by a list of commands to fully evaluate so that it is identical to the "manual" version of the function.
Background: I am using ScaleR functions in Microsoft R Server and need to apply a set of transformations as a function. ScaleR is very picky about needing to be passed a function that is phrased exactly as specified below:
functionThatWorks <- function(data) {
data$marital_status_p1_ismarried <- impute(data$marital_status_p1_ismarried)
return(data)
}
I have a function that creates this list of transformations (and hundreds more, hence the need to functionalize its writing).
transformList <- list ("data$ismarried <- impute(data$ismarried)",
"data$issingle <- impute(data$issingle)")
This line outputs the evaluated string that I want to the console, but I am unaware of a way to move it from console output to being used in a function:
cat(noquote(unlist(bquote( .(noquote(transformList[1]))))))
I need to evaluate functionIWant so that it is identical to functionThatWorks.
functionIWant <- function(data){
eval( cat(noquote(unlist(bquote( .(noquote(transformList[1])))))) )
return(data)
}
identical(functionThatWorks, functionIWant)
EDIT: Adding in the answer based on #dww 's code. It works well in ScaleR. It is identical, minus meaningless spacing.
functionIWant <- function(){}
formals(functionIWant) <- alist(data=NULL)
functionIWant.text <- parse(text = c(
paste( bquote( .(noquote(transformList[1]))), ";", "return(data)\n")
))
body(functionIWant) <- as.call(c(as.name("{"), functionIWant.text))
Maybe something like this?
# 1st define a 'hard-coded' function
f1 <- function (x = 2)
{
y <- x + 1
y^2
}
f1(3)
# [1] 16
# now create a similar function from a character vector
f2 <- function(){}
formals(f2) <- alist(x=2)
f2.text <- parse(text = c('y <- x + 1', 'y^2'))
body(f2) <- as.call(c(as.name("{"), f2.text))
f2(3)
# [1] 16
i know might of u think this question and duplicated,but i do really have something kinda freaks me out, i was learning R and i had assignment to do something i do manage to solve it but i wonder why this error appear while the 2 code is very similar, is that something i don't understand in R
the first who has give me an error was :
makeCacheMatrix <- function(x = matrix()) {
#i for invirse
i <- NULL
set <- function(y){
x <<- y
i <<- NULL
}
get <- function(){x}
setinv <- function(solved){i <<- solved}
getinv <- function(){i}
#a list that has the 4 internal methods
list(set = set, get = get,
setinv = setinv,
getinv = getinv)
}
## Write a short comment describing this function
# this method check first if the data already cached,
# if they are it return it with message says "Getting cached data"
# if not it calculated, cache it and then return it
cacheSolve <- function(x, ...) {
## Return a matrix that is the inverse of 'x'
i <- x$getinv()
if(!is.null(i)){
message("Getting cached data")
return(i)
}
#calculate the inverse
x <- x$get()
i <- solve(x)
#print(i)
#print(class(i))
x$setinv(i)
i
}
this is how i call my function and the only result i get is
ps uncomment the print and clas funs will give the correct answers:
> source('~/R/cachematrix[not workng].R')
> x <- makeCacheMatrix(matrix(rnorm(16), 4,4))
> cacheSolve(x)
Error in x$setinv : $ operator is invalid for atomic vectors
after some time i said to myself why using too match variable and i use the methods inside each other for more sample code (one line is better)
but somehow the code works, for me it's the same code the only thing i have did the to pass the methods to each other instead of passing it into variable then pass the variable to method (it's the same really)
the code became like this now :
## Write a short comment describing this function
# this method retuen a matrix that has a list
# this list has 4 method as getters and sitters
makeCacheMatrix <- function(x = matrix()) {
#i for invirse
i <- NULL
set <- function(y){
x <<- y
i <<- NULL
}
get <- function(){x}
setinv <- function(solved){i <<- solved}
getinv <- function(){i}
#a list that has the 4 internal methods
list(set = set, get = get,
setinv = setinv,
getinv = getinv)
}
## Write a short comment describing this function
# this method check first if the data alredy cached,
# if they are it return it with messege sys "Getting cached data"
# if not it calculated, cache it and then return it
cacheSolve <- function(x, ...) {
## Return a matrix that is the inverse of 'x'
i <- x$getinv()
if(!is.null(i)){
message("Getting cached data")
return(i)
}
#calculate the invirse
i <- solve(x$get())
#cache the invirse for later
x$setinv(i)
i
}
and this's how i call my function:
> source('~/R/ProgrammingAssignment2/cachematrix.R')
> x <- makeCacheMatrix(matrix(rnorm(16), 4,4))
> cacheSolve(x)
[,1] [,2] [,3] [,4]
[1,] 0.09904578 -0.4586855 -0.2487849 -0.3421875
[2,] -1.84896897 0.8476203 0.7990204 0.5919526
[3,] 0.70645287 -0.1508695 -0.7141914 -0.2729974
[4,] 1.37441746 -0.9853108 -0.5607929 0.6553295
works good, i just wanna know what happen there, and why the first code give me an error and the second one didn't while both suppose to have the same logic, Thanks in advance mates
ps. i'm using : R version 3.3.2 on linux mint 18.1 with the latest version of rstudio
I would like to calculate the sum of list, which contains in every element the text mpfr1.
I have the following Code:
library(Rmpfr)
###### Central generalized Cofactorial #####
CgenC <- function(n,k,sigma){
i <- 0:k
B <- (-1)^i *choose(k,i)*pochMpfr((-i)*sigma, n)
CgenC <- sum(B)*1/(factorial(k))
return(CgenC)
}
#helpfunction
hfun <- function(d,n,k,sigma,gamma){
G <- choose(n,d)*CgenC(d,k,sigma)*pochMpfr(-(gamma), n-d)
return(G)
}
NCgenC <- function(n,k,sigma,gamma){
s <- k:n
E <- sapply(s,hfun,n=n,k=k,sigma=sigma,gamma=gamma)
NCgenC <- sum(E)
return(NCgenC)
}
Probably there is also a better way than using the helpfunction, but I am new to programming.
After that E Looks like:
[[1]]
'mpfr1' 58841424144769590802398501576045837205738093472425577422395207203116722951724046.536490917270720694092667549937401176716842829058677975377719677884520463728524151109618958095938032339354615748413119902638793141568563928308460798662023212923799608873996653084247997838235897625734493429191314427738979926169378387781579463813022200592226827918068083534511231048810054263460272712110560165030802860741581172618182744896043856500473312651443547811890843652043285582186302263502988917786388502716155013416710062301717698574066162109375
[[2]]
'mpfr1' 82871275202593779087122604776157996409481088998845801228666944089795992655102472.642373430793692374125929134125303485357643757531745742076715050078321471532137607446428722005372960997898005609266610074855955157895396722193218695989672456706464857213288691436880384233954098045336023019010212578667162712025383678754362300085837501918162183612037828788745867290227442574306429529728922577115900369140687795454923720717749187763638945864480587157831212835424687567575261647966653471636794832585905467382683540344896738333277759879099376438826851654084748588502407073974609375
...etc.
Thus, R cannot compute the sum, since it is a list and there is always the mpfr1.
I hope that I have been clear. Can somebody tell me how to calculate the sum?
Use Rmpfr::mpfr2array function to turn your list of mpfr number into an array of mpfr numbers then use the native R sum function.
library(Rmpfr)
vect = rep(0, 5)
for(i in 1:5){
vect[i] = mpfr(x=10^-(10*i), precBits=100)
}
# My vector has just turned to a list
vect
# Sum of list is an error
sum(vect)
# Turn it to a vector
converted_vect = Rmpfr::mpfr2array(vect, dim = length(vect))
converted_vect
# Now my sum and prod work fine and the precision is not lost
sum(converted_vect)
prod(converted_vect)
The function mpfr2array is not suposed to be called by the user, it is an internal tool for the package. However it's one way to solve the problem.
I have below function. I cannot alter the function in any way except the first block of code in the function.
In this simple example I want to display apply some function on returning object.
The point is the name of variable returned by function may vary and I'm not able to guess it.
Obviously I also cannot wrap the f function into { x <- f(); myfun(x); x }.
The below .Last.value in my on.exit call represents the value to be returned by f function.
f <- function(param){
# the only code I know - start
on.exit(if("character" %in% class(.Last.value)) message(print(.Last.value)) else message(class(.Last.value)))
# the only code I know - end
# real processing of f()
a <- "aaa"
"somethiiiing"
if(param==1L) return(a)
b <- 5L
"somethiiiing"
if(param==2L) return(b)
"somethiiiing"
return(32)
}
f(1L)
# function
# [1] "aaa"
f(2L)
# aaa
# [1] 5
f(3L)
# integer
# [1] 32
Above code with .Last.value seems to be working with lag (so in fact not working) and also the .Last.value is probably not the way to go as I want to use the value few times like if(fun0(x)) fun1(x) else fun2(x), and because returned value might be a big object, copy it on the side is also bad approach.
Any way to use on.exit or any other function which can help me to run my function on the f function results without knowing result variable name?
In a similar way to how you are modifying the function, you could easily wrap it as well. Here's a reproducible example.
library(data.table)
append.log<-function(x) {
cat(paste("value:",x,"\n"))
}
idx.dt <- data.table:::`[.data.table`
environment(idx.dt)<-asNamespace("data.table")
idx.wrap <- function(...) {
x<-do.call(idx.dt, as.list(substitute(...())), envir=parent.frame())
append.log(if(is(x, "data.table")) {
nrow(x)
} else { NA })
x
}
environment(idx.wrap)<-asNamespace("data.table")
(unlockBinding)("[.data.table",asNamespace("data.table"))
assign("[.data.table",idx.wrap,envir=asNamespace("data.table"),inherits=FALSE)
dt<-data.table(a=1:10, b=seq(2, 20, by=2), c=letters[1:10])
dt[a%%2==0]
Since R 3.2.0 it is fully possible, thanks to new function returnValue.
Working example below.
f <- function(x, err = FALSE){
pt <- proc.time()[[3L]]
on.exit(message(paste("proc.time:",round(proc.time()[[3L]]-pt,4),"\nnrow:",as.integer(nrow(returnValue()))[1L])))
Sys.sleep(0.001)
if(err) stop("some error")
return(x)
}
dt <- data.frame(a = 1:5, b = letters[1:5])
f(dt)
f(dt, err=T)
f(dt)
f(dt[dt$a %in% 2:3 & dt$b %in% c("c","d"),])