Commit 59c69498 authored by agebhard's avatar agebhard

add bicubic interpolation for rectangular gridded data (TOMS 760)

parent 295100a3
Package: akima
Version: 0.5-9
Version: 0.5-10
Date: 2013-01-19
Title: Interpolation of irregularly spaced data
Author: Fortran code by H. Akima
......
......@@ -9,7 +9,7 @@ Copyrighted and Licensed by ACM,
see http://www.acm.org/publications/policies/softwarecrnotice
2. R interface (src/init.c R/*.R man/*.Rd data/*):
2. R interface (src/init.c src/akima.h R/*.R man/*.Rd data/*):
The R interface code has been developed as work based on the
ACM licensed code, hence it is also ACM licensed, copyright
......
useDynLib(akima)
export(aspline,interp,interpp,interp.old,interp.new,interp2xyz)
export(aspline,interp,interpp,interp.old,interp.new,interp2xyz,bicubic,bicubic.grid)
# R interface to Akimas regular grid spline interpolator
# (TOMS 464) improved version: TOMS 760
# http://www.netlib.org/toms/760
bicubic <- function(x,y,z,x0,y0){
nx <- length(x)
ny <- length(y)
if(dim(z)[1]!=nx)
stop("dim(z)[1] and length of x differs!")
if(dim(z)[2]!=ny)
stop("dim(z)[2] and length of y differs!")
n0 <- length(x0)
if(length(y0)!=n0)
stop("length of y0 and x0 differs!")
ret <- .Fortran("rgbi3p",
md=as.integer(1),
nxd=as.integer(nx),
nyd=as.integer(ny),
xd=as.double(x),
yd=as.double(y),
zd=as.double(z),
nip=as.integer(n0),
xi=as.double(x0),
yi=as.double(y0),
zi=double(n0),
ier=integer(1),
wk=double(3*nx*ny),
PACKAGE="akima")
list(x=x0,y=y0,z=ret$zi)
}
bicubic.grid <- function(x,y,z,xlim,ylim,dx,dy){
nx <- length(x)
ny <- length(y)
if(dim(z)[1]!=nx)
stop("dim(z)[1] and length of x differs!")
if(dim(z)[2]!=ny)
stop("dim(z)[2] and length of y differs!")
xi <- seq(xlim[1],xlim[2],by=dx)
nx <- length(xi)
yi <- seq(ylim[1],ylim[2],by=dy)
ny <- length(yi)
xmat <- matrix(rep(xi,ny),nrow=ny,ncol=nx,byrow=TRUE)
ymat <- matrix(rep(yi,nx),nrow=ny,ncol=nx,byrow=FALSE)
xy <- cbind(c(xmat),c(ymat))
n0 <- nx*ny
ret <- bicubic(x,y,z,xy[,1],xy[,2])
# return cell boundaries
list(x=xi,y=yi,z=t(matrix(ret$z,nrow=ny,ncol=nx,byrow=F)))
}
\name{bicubic}
\alias{bicubic}
\title{
Bivariate Interpolation for Data on a Rectangular grid
}
\description{
The description in the Fortran code says:
This subroutine performs interpolation of a bivariate function,
z(x,y), on a rectangular grid in the x-y plane. It is based on
the revised Akima method.
In this subroutine, the interpolating function is a piecewise
function composed of a set of bicubic (bivariate third-degree)
polynomials, each applicable to a rectangle of the input grid
in the x-y plane. Each polynomial is determined locally.
This subroutine has the accuracy of a bicubic polynomial, i.e.,
it interpolates accurately when all data points lie on a
surface of a bicubic polynomial.
The grid lines can be unevenly spaced.
}
\usage{
bicubic(x, y, z, x0, y0)
}
\arguments{
\item{x}{
a vector containing the \code{x} coordinates of the rectangular data grid.
}
\item{y}{
a vector containing the \code{y} coordinates of the rectangular data grid.
}
\item{z}{
a matrix containing the \code{z[i,j]} data values for the grid points (\code{x[i]},\code{y[j]}).
}
\item{x0}{
vector of \code{x} coordinates used to interpolate at.
}
\item{y0}{
vector of \code{y} coordinates used to interpolate at.
}
}
\details{
This functiuon is a R interface to Akima's Rectangular-Grid-Data
Fitting algorithm (TOMS 760). The algorithm has the accuracy of a bicubic
(bivariate third-degree) polynomial.
}
\value{
This function produces a list of interpolated points:
\item{x}{vector of \code{x} coordinates.}
\item{y}{vector of \code{y} coordinates.}
\item{z}{vector of interpolated data \code{z}.}
If you need an output grid, see \code{\link{bicubic.grid}}.
}
\references{
Akima, H. (1996) Rectangular-Grid-Data
Surface Fitting that Has the Accuracy of a
Bicubic Polynomial,
J. ACM \bold{22}(3), 357-361
}
\note{
Use \code{\link{interp}} for the general case of irregular gridded data!
}
\seealso{
\code{\link{interp}}, \code{\link{bicubic.grid}}
% maybe later:
% \code{\link[rgeostat]{bilinear}}
}
\examples{
data(akima760)
# interpolate at the diagonal of the grid [0,8]x[0,10]
akima.bic <- bicubic(akima760$x,akima760$y,akima760$z,
seq(0,8,length=50), seq(0,10,length=50))
plot(sqrt(akima.bic$x^2+akima.bic$y^2), akima.bic$z, type="l")
##---- Should be DIRECTLY executable !! ----
##-- ==> Define data, use random,
##-- or do help(data=index) for the standard data sets.
## The function is currently defined as
function (x, y, z, x0, y0)
{
nx <- length(x)
ny <- length(y)
if (dim(z)[1] != nx)
stop("dim(z)[1] and length of x differs!")
if (dim(z)[2] != ny)
stop("dim(z)[2] and length of y differs!")
n0 <- length(x0)
if (length(y0) != n0)
stop("length of y0 and x0 differs!")
ret <- .Fortran("rgbi3p", md = as.integer(1), nxd = as.integer(nx),
nyd = as.integer(ny), xd = as.double(x), yd = as.double(y),
zd = as.double(z), nip = as.integer(n0), xi = as.double(x0),
yi = as.double(y0), zi = double(n0), ier = integer(1),
wk = double(3 * nx * ny), PACKAGE = "akima")
list(x = x0, y = y0, z = ret$zi)
}
}
\keyword{ dplot }
\name{bicubic.grid}
\alias{bicubic.grid}
\title{
Bivariate Interpolation for Data on a Rectangular grid
}
\description{
The description in the Fortran code says:
This subroutine performs interpolation of a bivariate function,
z(x,y), on a rectangular grid in the x-y plane. It is based on
the revised Akima method.
In this subroutine, the interpolating function is a piecewise
function composed of a set of bicubic (bivariate third-degree)
polynomials, each applicable to a rectangle of the input grid
in the x-y plane. Each polynomial is determined locally.
This subroutine has the accuracy of a bicubic polynomial, i.e.,
it interpolates accurately when all data points lie on a
surface of a bicubic polynomial.
The grid lines can be unevenly spaced.
}
\usage{
bicubic.grid(x,y,z,xlim,ylim,dx,dy)
}
\arguments{
\item{x}{
a vector containing the \code{x} coordinates of the rectangular data grid.
}
\item{y}{
a vector containing the \code{y} coordinates of the rectangular data grid.
}
\item{z}{
a matrix containing the \code{z[i,j]} data values for the grid points (\code{x[i]},\code{y[j]}).
}
\item{xlim}{
vector of length 2 giving lower and upper limit for range \code{x}
coordinates used for output grid.
}
\item{ylim}{
vector of length 2 giving lower and upper limit for range of \code{y}
coordinates used for output grid.
}
\item{dx}{
output grid spacing in \code{x} direction.
}
\item{dy}{
output grid spacing in \code{y} direction.
}
}
\details{
This functiuon is a R interface to Akima's Rectangular-Grid-Data
Fitting algorithm (TOMS 760). The algorithm has the accuracy of a bicubic
(bivariate third-degree) polynomial.
}
\value{
This function produces a grid of interpolated points, feasible to be
used directly with \code{\link{image}} and \code{\link{contour}}:
\item{x}{vector of \code{x} coordinates of the output grid.}
\item{y}{vector of \code{y} coordinates of the output grid.}
\item{z}{matrix of interpolated data for the output grid.}
}
\references{
Akima, H. (1996) Rectangular-Grid-Data
Surface Fitting that Has the Accuracy of a
Bicubic Polynomial,
J. ACM \bold{22}(3), 357-361
}
\note{
Use \code{\link{interp}} for the general case of irregular gridded data!
}
\seealso{
\code{\link{interp}}, \code{\link{bicubic}}
% maybe later:
% \code{\link[rgeostat]{bilinear}}
}
\examples{
data(akima760)
# interpolate at a grid [0,8]x[0,10]
akima.bic <- bicubic.grid(akima760$x,akima760$y,akima760$z,
c(0,8),c(0,10),0.1,0.1)
image(akima.bic)
contour(akima.bic, add=TRUE)
}
\keyword{ dplot }
......@@ -28,3 +28,5 @@ int F77_NAME(uvip3p) (int *np, int *nd, double *xd, double *yd,
int F77_NAME(intrpl) (int *l,double *x, double *y, int *n,
double *u, double *v, int *err);
int F77_NAME(rgbi3p) (int *md, int *nxd, int *nyd, double *xd, double *yd, double *zd,
int *nip, double *xi, double *yi, double *zi, int *err);
......@@ -24,6 +24,20 @@
/* Fortran interface descriptions: */
static R_NativePrimitiveArgType rgbi3p_t[12] = {
INTSXP, /* MD, */
INTSXP, /* NXP, */
INTSXP, /* NYP, */
REALSXP, /* XD, */
REALSXP, /* YD, */
REALSXP, /* ZD, */
INTSXP, /* NIP, */
REALSXP, /* XI, */
REALSXP, /* YI, */
REALSXP, /* ZI, */
INTSXP, /* IER, */
REALSXP /* WK, */
};
static R_NativePrimitiveArgType idbvip_t[13] = {
INTSXP, /* MD, */
INTSXP, /* NCP, */
......@@ -124,6 +138,7 @@ static R_FortranMethodDef fortranMethods[] = {
{"sdsf3p", (DL_FUNC) &F77_SUB(sdsf3p), 17, sdsf3p_t}, /* interp.new */
{"uvip3p", (DL_FUNC) &F77_SUB(uvip3p), 8, uvip3p_t}, /* aspline */
{"intrpl", (DL_FUNC) &F77_SUB(intrpl), 7, intrpl_t}, /* aspline */
{"rgbi3p", (DL_FUNC) &F77_SUB(rgbi3p), 12, sdbi3p_t}, /* bicubic */
{NULL, NULL, 0}
};
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment