broyden.RdBroyden's method for the numerical solution of nonlinear systems of
n equations in n variables.
broyden(Ffun, x0, J0 = NULL, ...,
maxiter = 100, tol = .Machine$double.eps^(1/2))F as a function must return a vector of length n, and accept an
n-dim. vector or column vector as input. F must not be univariate,
that is n must be greater than 1.
Broyden's method computes the Jacobian and its inverse only at the first iteration, and does a rank-one update thereafter, applying the so-called Sherman-Morrison formula that computes the inverse of the sum of an invertible matrix A and the dyadic product, uv', of a column vector u and a row vector v'.
List with components: zero the best root found so far, fnorm
the square root of sum of squares of the values of f, and niter the
number of iterations needed.
Quarteroni, A., R. Sacco, and F. Saleri (2007). Numerical Mathematics. Second Edition, Springer-Verlag, Berlin Heidelberg.
Applied to a system of n linear equations it will stop in
2n steps
## Example from Quarteroni & Saleri
F1 <- function(x) c(x[1]^2 + x[2]^2 - 1, sin(pi*x[1]/2) + x[2]^3)
broyden(F1, x0 = c(1, 1))
#> $zero
#> [1] 0.4760958 -0.8793934
#>
#> $fnorm
#> [1] 9.092626e-09
#>
#> $niter
#> [1] 13
#>
# zero: 0.4760958 -0.8793934; fnorm: 9.092626e-09; niter: 13
F <- function(x) {
x1 <- x[1]; x2 <- x[2]; x3 <- x[3]
as.matrix(c(x1^2 + x2^2 + x3^2 - 1,
x1^2 + x3^2 - 0.25,
x1^2 + x2^2 - 4*x3), ncol = 1)
}
x0 <- as.matrix(c(1, 1, 1))
broyden(F, x0)
#> $zero
#> [1] 0.4407629 0.8660254 0.2360680
#>
#> $fnorm
#> [1] 1.34325e-08
#>
#> $niter
#> [1] 8
#>
# zero: 0.4407629 0.8660254 0.2360680; fnorm: 1.34325e-08; niter: 8
## Find the roots of the complex function sin(z)^2 + sqrt(z) - log(z)
F2 <- function(x) {
z <- x[1] + x[2]*1i
fz <- sin(z)^2 + sqrt(z) - log(z)
c(Re(fz), Im(fz))
}
broyden(F2, c(1, 1))
#> $zero
#> [1] 0.2555197 0.8948303
#>
#> $fnorm
#> [1] 7.284373e-10
#>
#> $niter
#> [1] 13
#>
# zero 0.2555197 0.8948303 , i.e. z0 = 0.2555 + 0.8948i
# fnorm 7.284374e-10
# niter 13
## Two more problematic examples
F3 <- function(x)
c(2*x[1] - x[2] - exp(-x[1]), -x[1] + 2*x[2] - exp(-x[2]))
broyden(F3, c(0, 0))
#> $zero
#> [1] 0.5671433 0.5671433
#>
#> $fnorm
#> [1] 4.677305e-12
#>
#> $niter
#> [1] 5
#>
# $zero 0.5671433 0.5671433 # x = exp(-x)
F4 <- function(x) # Dennis Schnabel
c(x[1]^2 + x[2]^2 - 2, exp(x[1] - 1) + x[2]^3 - 2)
broyden(F4, c(2.0, 0.5), maxiter = 100)
#> $zero
#> [1] 1 1
#>
#> $fnorm
#> [1] 1.188144e-10
#>
#> $niter
#> [1] 43
#>