Skip to content

Commit

Permalink
ci(horner): New tests for polynomial evaluation methods
Browse files Browse the repository at this point in the history
  • Loading branch information
howardjp committed Sep 8, 2023
1 parent 212f026 commit 9febc5e
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 27 deletions.
49 changes: 30 additions & 19 deletions R/horner.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,46 +69,57 @@

#' @export
horner <- function(x, coefs) {
y <- rep(0, length(x))
y <- rep(0, length(x))

for(i in length(coefs):1)
y <- coefs[i] + x * y
stopifnot(is.numeric(coefs))

return(y)
for (i in length(coefs):1) {
y <- coefs[i] + x * y
}

return(y)
}

#' @rdname horner
#' @export
rhorner <- function(x, coefs) {
n <- length(coefs)
n <- length(coefs)

stopifnot(is.numeric(coefs))

if(n == 1)
return(coefs)
if (n == 1) {
return(coefs)
}

return(coefs[1] + x * rhorner(x, coefs[2:n]))
return(coefs[1] + x * rhorner(x, coefs[2:n]))
}

#' @rdname horner
#' @export
naivepoly <- function(x, coefs) {
y <- rep(0, length(x))
y <- rep(0, length(x))

for(i in 1:length(coefs))
y <- y + coefs[i] * (x ^ (i - 1))
stopifnot(is.numeric(coefs))

return(y)
for (i in 1:length(coefs)) {
y <- y + coefs[i] * (x^(i - 1))
}

return(y)
}

#' @rdname horner
#' @export
betterpoly <- function(x, coefs) {
y <- rep(0, length(x))
cached.x <- 1
y <- rep(0, length(x))
cached.x <- 1

stopifnot(is.numeric(coefs))

for(i in 1:length(coefs)) {
y <- y + coefs[i] * cached.x
cached.x <- cached.x * x
}
for (i in 1:length(coefs)) {
y <- y + coefs[i] * cached.x
cached.x <- cached.x * x
}

return(y)
return(y)
}
32 changes: 32 additions & 0 deletions tests/testthat/test-betterpoly.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
library("testthat")
context("betterpoly")

test_that("betterpoly evaluates known polynomials correctly", {
expect_equal(betterpoly(1, c(1, 2, 3)), 6) # 1 + 2*1 + 3*1^2 = 6
expect_equal(betterpoly(0, c(5, 0, 0)), 5) # Testing zero
expect_equal(betterpoly(-1, c(1, -1, 1)), 3) # Testing negative x
expect_equal(betterpoly(1, c(0.5, 0.25)), 0.75) # Testing fractional coefficients
})

test_that("betterpoly handles edge cases", {
expect_error(betterpoly(1, c())) # Empty coefficients
expect_equal(betterpoly(1, c(5)), 5) # Single coefficient
})

test_that("betterpoly handles random coefficients and values", {
for (i in 1:5) {
coefs <- runif(10, -10, 10)
x_val <- runif(1, -10, 10)
expect_equal(betterpoly(x_val, coefs), sum(coefs * x_val^(0:(length(coefs) - 1))))
}
})

test_that("betterpoly handles large coefficients and values", {
large_coefs <- rep(10^6, 10)
expect_equal(betterpoly(1, large_coefs), sum(large_coefs))
})

test_that("betterpoly rejects non-numeric input", {
expect_error(betterpoly("a", c(1, 2, 3)))
expect_error(betterpoly(1, c("a", "b", "c")))
})
37 changes: 29 additions & 8 deletions tests/testthat/test-horner.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
library("testthat")
context("horner")

## If you're curious, it's from the Addams Family movie
beta <- c(2, 10, 11)
expect_equal(horner(5, beta), 327)
expect_equal(horner(87, beta), 84131)
expect_equal(horner(-10, beta), 1002)
expect_equal(horner(0, beta), 2)
test_that("horner evaluates known polynomials correctly", {
expect_equal(horner(1, c(1, 2, 3)), 6) # 1 + 2*1 + 3*1^2 = 6
expect_equal(horner(0, c(5, 0, 0)), 5) # Testing zero
expect_equal(horner(-1, c(1, -1, 1)), 3) # Testing negative x
expect_equal(horner(1, c(0.5, 0.25)), 0.75) # Testing fractional coefficients
})

beta <- c(-1, 0, 1)
expect_equal(horner(c(1, 2, 3), beta), c(0, 3, 8))
test_that("horner handles edge cases", {
expect_error(horner(1, c())) # Empty coefficients
expect_equal(horner(1, c(5)), 5) # Single coefficient
})

test_that("horner handles random coefficients and values", {
for (i in 1:5) {
coefs <- runif(10, -10, 10)
x_val <- runif(1, -10, 10)
expect_equal(horner(x_val, coefs), sum(coefs * x_val^(0:(length(coefs) - 1))))
}
})

test_that("horner handles large coefficients and values", {
large_coefs <- rep(10^6, 10)
expect_equal(horner(1, large_coefs), sum(large_coefs))
})

test_that("horner rejects non-numeric input", {
expect_error(horner("a", c(1, 2, 3)))
expect_error(horner(1, c("a", "b", "c")))
})
32 changes: 32 additions & 0 deletions tests/testthat/test-naivepoly.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
library("testthat")
context("rhorner")

test_that("rhorner evaluates known polynomials correctly", {
expect_equal(rhorner(1, c(1, 2, 3)), 6) # 1 + 2*1 + 3*1^2 = 6
expect_equal(rhorner(0, c(5, 0, 0)), 5) # Testing zero
expect_equal(rhorner(-1, c(1, -1, 1)), 3) # Testing negative x
expect_equal(rhorner(1, c(0.5, 0.25)), 0.75) # Testing fractional coefficients
})

test_that("rhorner handles edge cases", {
expect_error(rhorner(1, c())) # Empty coefficients
expect_equal(rhorner(1, c(5)), 5) # Single coefficient
})

test_that("rhorner handles random coefficients and values", {
for (i in 1:5) {
coefs <- runif(10, -10, 10)
x_val <- runif(1, -10, 10)
expect_equal(rhorner(x_val, coefs), sum(coefs * x_val^(0:(length(coefs) - 1))))
}
})

test_that("rhorner handles large coefficients and values", {
large_coefs <- rep(10^6, 10)
expect_equal(rhorner(1, large_coefs), sum(large_coefs))
})

test_that("rhorner rejects non-numeric input", {
expect_error(rhorner("a", c(1, 2, 3)))
expect_error(rhorner(1, c("a", "b", "c")))
})
32 changes: 32 additions & 0 deletions tests/testthat/test-rhorner.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
library("testthat")
context("rhorner")

test_that("rhorner evaluates known polynomials correctly", {
expect_equal(rhorner(1, c(1, 2, 3)), 6) # 1 + 2*1 + 3*1^2 = 6
expect_equal(rhorner(0, c(5, 0, 0)), 5) # Testing zero
expect_equal(rhorner(-1, c(1, -1, 1)), 3) # Testing negative x
expect_equal(rhorner(1, c(0.5, 0.25)), 0.75) # Testing fractional coefficients
})

test_that("rhorner handles edge cases", {
expect_error(rhorner(1, c())) # Empty coefficients
expect_equal(rhorner(1, c(5)), 5) # Single coefficient
})

test_that("rhorner handles random coefficients and values", {
for (i in 1:5) {
coefs <- runif(10, -10, 10)
x_val <- runif(1, -10, 10)
expect_equal(rhorner(x_val, coefs), sum(coefs * x_val^(0:(length(coefs) - 1))))
}
})

test_that("rhorner handles large coefficients and values", {
large_coefs <- rep(10^6, 10)
expect_equal(rhorner(1, large_coefs), sum(large_coefs))
})

test_that("rhorner rejects non-numeric input", {
expect_error(rhorner("a", c(1, 2, 3)))
expect_error(rhorner(1, c("a", "b", "c")))
})

0 comments on commit 9febc5e

Please sign in to comment.