Commit 59c69498 authored by agebhard's avatar agebhard
Browse files

add bicubic interpolation for rectangular gridded data (TOMS 760)

parent 295100a3
Package: akima Package: akima
Version: 0.5-9 Version: 0.5-10
Date: 2013-01-19 Date: 2013-01-19
Title: Interpolation of irregularly spaced data Title: Interpolation of irregularly spaced data
Author: Fortran code by H. Akima Author: Fortran code by H. Akima
......
...@@ -9,7 +9,7 @@ Copyrighted and Licensed by ACM, ...@@ -9,7 +9,7 @@ Copyrighted and Licensed by ACM,
see http://www.acm.org/publications/policies/softwarecrnotice 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 The R interface code has been developed as work based on the
ACM licensed code, hence it is also ACM licensed, copyright ACM licensed code, hence it is also ACM licensed, copyright
......
useDynLib(akima) 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, ...@@ -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, int F77_NAME(intrpl) (int *l,double *x, double *y, int *n,
double *u, double *v, int *err); 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 @@ ...@@ -24,6 +24,20 @@
/* Fortran interface descriptions: */ /* 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] = { static R_NativePrimitiveArgType idbvip_t[13] = {
INTSXP, /* MD, */ INTSXP, /* MD, */
INTSXP, /* NCP, */ INTSXP, /* NCP, */
...@@ -124,6 +138,7 @@ static R_FortranMethodDef fortranMethods[] = { ...@@ -124,6 +138,7 @@ static R_FortranMethodDef fortranMethods[] = {
{"sdsf3p", (DL_FUNC) &F77_SUB(sdsf3p), 17, sdsf3p_t}, /* interp.new */ {"sdsf3p", (DL_FUNC) &F77_SUB(sdsf3p), 17, sdsf3p_t}, /* interp.new */
{"uvip3p", (DL_FUNC) &F77_SUB(uvip3p), 8, uvip3p_t}, /* aspline */ {"uvip3p", (DL_FUNC) &F77_SUB(uvip3p), 8, uvip3p_t}, /* aspline */
{"intrpl", (DL_FUNC) &F77_SUB(intrpl), 7, intrpl_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} {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