# Optionally define the parent function that calls the dispatcher
#abs_max <- function(...) UseFunction('abs_max', ...)
# By convention the guard is defined before the concrete function variant
guard(abs_max.recursive1, is.numeric(a) && length(a) > 1)
abs_max.recursive1 <- function(a) abs_max(a[1], abs_max(a[2:length(a)]))
guard(abs_max.recursive2, is.numeric(a) && length(a) == 1)
abs_max.recursive2 <- function(a) a
guard(abs_max.csv, isa(DataObject,a) & hasa(data,a))
abs_max.csv <- function(a) abs_max(as.numeric(strsplit(a$data, ',')[[1]]))
# The explicit form allows multiple guard functions
guard(abs_max.twoArg, c( function(a,b) is.numeric(a), function(a,b) is.numeric(b)) )
abs_max.twoArg <- function(a, b) max(abs(a), abs(b))
ensure(abs_max.twoArg, result >= a | result >= b)
# Using a guard of TRUE acts as a default condition
guard(abs_max.twoArgDefault, TRUE)
abs_max.twoArgDefault <- function(a,b) abs_max(as.numeric(a), as.numeric(b))
# Define constructor for DataObject
create.DataObject <- function(T, data, name=NA) list(name=name, data=data)
# Test some output
abs_max(2,-3) # Calls abs_max.twoArg
abs_max("3","-4") # Calls abs_max.twoArgDefault
abs_max(3,"-4") # Calls abs_max.twoArgDefault
a <- rnorm(10)
abs_max(a) # Calls abs_max.recursive1
b <- create(DataObject, c('12,-3,-5,8,-13,3,1,3'))
abs_max(b) # Calls abs_max.csv
## Newton-Raphson optimization
converged <- function(x1, x0, tolerance=1e-6) abs(x1 - x0) < tolerance
minimize <- function(x0, algo, max.steps=100)
{
step <- 0
old.x <- x0
while (step < max.steps)
{
new.x <- iterate(old.x, algo)
if (converged(new.x, old.x)) break
old.x <- new.x
}
new.x
}
guard(iterate.nr, isa(NewtonRaphson, algo))
iterate.nr <- function(x, algo) x - algo$f1(x) / algo$f2(x)
guard(iterate.gd, isa(GradientDescent, algo))
iterate.gd <- function(x, algo) x - algo$step * algo$f1(x)
create.GradientDescent <- function(T, f1, step=0.01) list(f1=f1,step=step)
fx <- function(x) x^2 - 4
f1 <- function(x) 2*x
f2 <- function(x) 2
algo <- create(NewtonRaphson, f1=f1,f2=f2)
minimize(3, algo)
algo <- create(GradientDescent, f1=f1,step=0.1)
minimize(3, algo)Run the code above in your browser using DataLab