https://github.com/cran/fields
Tip revision: 7b2778b4ea77eab24528cc59cedaba09e3460fa7 authored by Doug Nychka on 22 April 2008, 00:00:00 UTC
version 4.3
version 4.3
Tip revision: 7b2778b
mKrig.family.R
# fields, Tools for spatial data
# Copyright 2004-2007, Institute for Mathematics Applied Geosciences
# University Corporation for Atmospheric Research
# Licensed under the GPL -- www.gpl.org/licenses/gpl.html
mKrig<- function (x,y,
weights = rep( 1, nrow( x)), lambda=0,
cov.function= "stationary.cov", m=2,
chol.args = NULL, cov.args=NULL,...)
{
# grab other arguments for covariance function
cov.args<- c( cov.args, list( ...))
# see comments in Krig.engine.fixed for algorithmic commentary
#
#
# default values for Cholesky decomposition, these are important
# for sparse matrix decompositions
if( is.null( chol.args)) {
chol.args<- list( pivot= FALSE)}
else{
chol.args<- chol.args}
# check for duplicate x's.
# stop if there are any
if( any(duplicated( cat.matrix(x))) )
stop("locations are not unique see help(mKrig) ")
# create fixed part of model as m-1 order polynomial
Tmatrix <- fields.mkpoly(x, m)
# set some dimensions
np <- nrow( x)
nt <- ncol( Tmatrix)
# covariance matrix at observation locations
# NOTE: if cov.function is a sparse constuct then tempM will be sparse.
# see e.g. wendland.cov
tempM<- do.call(
cov.function, c(cov.args, list(x1 = x, x2 = x)) )
# record sparsity of tempM
if( !is.matrix( tempM)) {
nzero<- length( tempM@entries) }
else{
nzero<- np^2}
# add diagonal matrix that is the observation error Variance
# NOTE: diag should be an overloaded function for tempM sparse.
if( lambda != 0) {
diag(tempM) <- (lambda/weights) + diag(tempM)
}
# cholesky decoposition of tempM
# do.call used to supply other arguments to the function
# especially for sparse applications.
# If chol.args is NULL then this is the same as
# Mc<-chol(tempM)
Mc<- do.call("chol",c( list( x=tempM), chol.args) )
# Efficent way to multply inverse of Mc times the Tmatrix
VT<- forwardsolve( Mc, x=Tmatrix, transpose=TRUE, upper.tri=TRUE)
qr( VT)-> qr.VT
# start linear algebra to find solution
# Note that all these expressions make sense if y is a matrix
# of several data sets and one is solving for the coefficients
# of all of these at once. In this case d.coef and c.coef are matrices
#
# now do generalized least squares for d
d.coef<- qr.coef( qr.VT,
forwardsolve( Mc, transpose=TRUE, y, upper.tri=TRUE) )
# and then find c.
# find the coefficents for the spatial part.
c.coef<- forwardsolve( Mc, transpose=TRUE,
y - Tmatrix%*% d.coef, upper.tri=TRUE)
c.coef<- backsolve( Mc,c.coef)
# return coefficients and include lambda as a check because
# results are meaningless for other values of lambda
# returned list is an "object" of class mKrig (micro Krig)
out<- list( d=(d.coef), c=(c.coef),
nt=nt,
np=np,
lambda.fixed=lambda,
x= x,
cov.function.name=cov.function, args=cov.args,m=m,
chol.args=chol.args,
call= match.call(),
nonzero.entries= nzero)
#
out$residuals<- y - predict.mKrig( out)
class(out)<- "mKrig"
return(out)
}
print.mKrig<- function(x,...){
c1 <- "Number of Observations:"
c2 <- length(x$residuals)
c1 <- c(c1, "Degree of polynomial null space ( base model):")
c2 <- c(c2, x$m - 1)
c1 <- c(c1, "Number of parameters in the null space")
c2 <- c(c2, x$nt)
c1 <- c(c1, "Smoothing parameter")
c2 <- c(c2, x$lambda.fixed)
c1 <- c(c1, "Nonzero entries in covariance")
c2 <- c(c2, x$nonzero.entries)
sum <- cbind(c1, c2)
dimnames(sum) <- list(rep("", dim(sum)[1]), rep("", dim(sum)[2]))
cat("Call:\n")
dput(x$call)
print(sum, quote = FALSE)
cat("Covariance Model:", x$cov.function, fill = TRUE)
if (x$cov.function == "stationary.cov") {
cat(" Covariance function is ", x$args$Covariance, fill = TRUE)
}
if (!is.null(x$args)) {
cat(" Names of non-default covariance arguments: ",
fill = TRUE)
cat(" ", paste(as.character(names(x$args)), collapse = ", "),
fill = TRUE)
}
invisible(x)
}
predict.mKrig<- function(object, xnew=NULL, derivative=0,...){
# the main reason to pass new args to the covariance is to increase
# the temp space size for sparse multiplications
# other optional arguments from mKrig are passed along in the
# list object$args
cov.args<- list(...)
# predict at observation locations by default
if( is.null( xnew)){
xnew<- object$x }
# fixed part of the model this a polynomial of degree m-1
# Tmatrix <- fields.mkpoly(xnew, m=object$m)
#
if( derivative==0){
temp1 <- fields.mkpoly(xnew, m=object$m) %*% object$d}
else{
temp1<- fields.derivative.poly( xnew,m=object$m, object$d)}
# add nonparametric part. Covariance basis functions
# times coefficients.
# syntax is the name of the function and then a list with
# all the arguments. This allows for different covariance functions
# that have been passed as their name.
if( derivative == 0){
# argument list are the parameters and other options from mKrig
# locations and coefficients,
temp2 <- do.call(object$cov.function.name,
c(object$args,
list(x1 = xnew, x2 = object$x, C = object$c), cov.args ) )}
else{
temp2 <- do.call(object$cov.function.name,
c(
object$args,
list(x1 = xnew, x2 = object$x, C = object$c,
derivative=derivative),
cov.args )
)}
# add two parts together and coerce to vector
return( (temp1 + temp2) )
}