Nothing
# Copyright (c) Rob Carnell 2026
# Nonlinear system
f <- function(X, a, b, c1, c2, c3) {
x <- X[1]
y <- X[2]
z <- X[3]
c(
x + y - x * y - c1,
x + z - x * z - c2,
a * y + b * z - c3
)
}
# Analytic Jacobian
Jac <- function(X, a, b, c1, c2, c3) {
x <- X[1]
y <- X[2]
z <- X[3]
J <- matrix(0, nrow = 3, ncol = 3)
J[1, 1] <- 1 - y
J[2, 1] <- 1 - z
J[3, 1] <- 0
J[1, 2] <- 1 - x
J[2, 2] <- 0
J[3, 2] <- a
J[1, 3] <- 0
J[2, 3] <- 1 - x
J[3, 3] <- b
J
}
test_that("Newton and Broyden converge to the closed-form solution", {
a <- 1
b <- 1
c1 <- 2
c2 <- 3
c3 <- 4
# Closed-form solution
x <- (a * c1 + b * c2 - c3) / (a + b - c3)
y <- (b * c1 - b * c2 - c1 * c3 + c3) / (-a * c1 + a - b * c2 + b)
z <- (a * (c1 - c2) + (c2 - 1) * c3) / (a * (c1 - 1) + b * (c2 - 1))
xsol <- c(x, y, z)
X.start <- c(1, 2, 3)
z1 <- nleqslv(
X.start, f, Jac,
a = a, b = b, c1 = c1, c2 = c2, c3 = c3,
method = "Newton",
control = list(trace = 0, allowSingular = TRUE)
)
z2 <- nleqslv(
X.start, f, Jac,
a = a, b = b, c1 = c1, c2 = c2, c3 = c3,
method = "Broyden",
control = list(trace = 0, allowSingular = TRUE)
)
# Both solvers should match the closed-form solution
expect_equal(z1$x, xsol, tolerance = 1e-8)
expect_equal(z2$x, xsol, tolerance = 1e-8)
# Function values should be near zero
expect_true(all(abs(z1$fvec) <= 1e-8))
expect_true(all(abs(z2$fvec) <= 1e-8))
# Ensure no catastrophic solver failure
expect_false(z1$termcd %in% c(-1, -2, -10))
expect_false(z2$termcd %in% c(-1, -2, -10))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.