Nothing
##
## g m r e s . R Generalized Linear equation solver
##
gmres <- function(A, b, x0 = rep(0, length(b)),
errtol = 1e-6, kmax = length(b)+1, reorth = 1) {
stopifnot(is.numeric(A), is.numeric(b), is.matrix(A))
b <- as.matrix(b)
n <- length(b)
if (nrow(A) != n || ncol(A) != n)
stop("Matrix 'A' must be square and compatible with 'b'.")
# initialization
h <- zeros(kmax)
v <- zeros(n, kmax)
c <- zeros(kmax+1, 1)
s <- zeros(kmax+1, 1)
normF <- function(x) norm(as.matrix(x), type = 'F')
x <- as.matrix(x0)
if (norm(x, 'F') != 0) {
r <- b - A %*% x
} else {
r <- b
}
rho <- norm(r, 'F')
g <- rho*eye(kmax+1, 1)
errtol <- errtol * norm(b, 'F')
error <- c()
# test for termination on entry
error <- c(error, rho)
niter <- 0
if(rho < errtol)
return(list(x = x, error = error, niter = niter))
v[, 1] <- r/rho
beta <- rho
# GMRES iteration
k <- 0
while (rho > errtol && k < kmax) {
k <- k + 1
v[, k+1] <- A %*% v[, k]
normav <- normF(v[, k+1])
# modified Gram-Schmidt
for (j in 1:k) {
h[j, k] <- t(v[, j]) %*% v[, k+1]
v[, k+1] <- v[, k+1] - h[j,k] * v[, j]
}
h[k+1, k] <- normF(v[, k+1])
normav2 <- h[k+1, k]
# reorthogonalize
if ((reorth == 1 && normav + 0.001*normav2 == normav) || reorth == 3) {
for (j in 1:k) {
hr <- t(v[, j]) %*% v[, k+1]
h[j, k] <- h[j, k] + hr
v[, k+1] = v[, k+1] - hr*v[, j]
}
h[k+1, k] <- normF(v[, k+1])
}
# watch out for happy breakdown
if (h[k+1, k] != 0)
v[, k+1] <- v[, k+1] / h[k+1, k]
# form and store the information for the new Givens rotation
if (k > 1)
h[1:k, k] <- .givapp(c[1:(k-1)], s[1:(k-1)], h[1:k, k], k-1)
nu <- normF(h[k:(k+1), k])
if (nu != 0) {
c[k] <- Conj(h[k, k] / nu)
s[k] <- -h[k+1, k] / nu
h[k, k] <- c[k] * h[k, k] - s[k] * h[k+1, k]
h[k+1, k] <- 0
g[k:(k+1)] <- .givapp(c[k], s[k], g[k:(k+1)], 1)
}
# update the residual norm
rho <- abs(g[k+1])
error <- c(error,rho)
}
# at this point either k > kmax or rho < errtol
y <- qr.solve(h[1:k, 1:k], g[1:k])
x <- x0 + v[1:n, 1:k] %*% y
return(list(x = x, error = error, niter = k))
}
.givapp <- function(c, s, v_in, k) {
v_rot <- v_in
for (i in 1:k) {
w1 <- c[i] * v_rot[i] - s[i] * v_rot[i+1]
w2 <- s[i] * v_rot[i] + Conj(c[i]) * v_rot[i+1]
v_rot[i:(i+1)] <- c(w1, w2)
}
v_rot
}
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.