R/Simpson.R

#' Validates the correctness of the arguments passed to X.
#'
#' @param object The object to validate.
#' @export
validate.simpson = function(object) {
	number.of.terms = (object@start - object@end + 1)
	if (number.of.terms %% 2 != 0) {
		stop("Simpson's Rule can only be used on an even number of values.")
	}
	if (object@start >= object@end) {
		stop("End must be greater than Start.")
	}
	if (length(object@x) != length(object@y)) {
		stop("X and Y must be the same length.")
	}
}

#' A subclass of \link{Integrator} that performs
#' integration according to Simpson's rule.
#' @export
Simpson = setClass("Simpson", contains = "Integrator", validity = validate.simpson)

#' Performs integration according to Simpson's rule.
#'
#' @param object The object containing the values to integrate.
#'
#' @return The numerical integral of the provided values.
#' @export
setMethod("integrateIt",
		  signature = (type = "Simpson"),
		  function(type, ...) {
		  	start.index  = which(type@x == type@start)
		  	end.index    = which(type@x == type@end)
		  	target.range = start.index : end.index

		  	x.range = type@x[target.range]
		  	y.range = type@y[target.range]

		  	# h is defined with the definition of Simpson's rule
		  	h = (type@end - type@start) / (length(target.range) - 2)
		  	edges = type@y[start.index] + type@y[end.index]

			evens  = sum(2 * x.range[seq(2, end.index - 1, 2)])
			odds   = sum(4 * y.range[seq(3, end.index, 2)])
			return((edges + odds + evens) * h / 3 )

		  })

#' Initializes Simpson objects, and validates them.
#'
#' @param .Object Simpson. The object to initialize.
#' @export
setMethod("initialize", signature(.Object = "Simpson"),
		  function(.Object, x, y, start, end) {
		  	.Object@x = x
		  	.Object@y = y
		  	.Object@start = start
		  	.Object@end = end
		  	# Ensure the arguments are valid before
		  	# attempting to integrate
		  	validate.simpson(.Object)
		  	.Object@result = integrateIt(.Object)
		  	return(.Object)
		  }
)
alexjweil/integrateIt documentation built on May 10, 2019, 8:54 a.m.