1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Library General Public
3# License as published by the Free Software Foundation; either
4# version 2 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU Library General Public License for more details.
10#
11# You should have received A copy of the GNU Library General
12# Public License along with this library; if not, write to the
13# Free Foundation, Inc., 59 Temple Place, Suite 330, Boston,
14# MA  02111-1307  USA
15
16
17################################################################################
18# FUNCTION:                 BIVARIATE GRIDDED INTERPOLATION:
19#  linearInterp             Interpolates linearly irregularly spaced data points
20#  linearInterpp            Interpolates linearly pointwise
21################################################################################
22
23
24linearInterp <-
25  function(x, y = NULL, z = NULL, gridPoints = 21,
26           xo = seq(min(x), max(x), length = gridPoints),
27           yo = seq(min(y), max(y), length = gridPoints))
28  {
29    # A function implemented by Diethelm Wuertz
30
31    # Description:
32    #   Interpolates Linearly Irregularly Distributed Data Points
33
34    # Arguments:
35    #   x, y, z - either three numeric vectors of equal length or if
36    #       y and z are NULL, a list with entries x, y, a, or named
37    #       data.frame with x in the first, y in the second, and z in
38    #       the third column.
39    #   gridPoints - number of grid points in x and y direction.
40    #   xo, yo, a sequence of data points spanning the grid
41
42    # Note:
43    #   Extrapolation is not possible in the case of linear interpolation.
44
45    # Value:
46    #   A list with three elements, $x and $y which are vectors of length
47    #   'gridPoints' and $z which is a matrix of size 'gridPoints^2'.
48
49    # Requirements:
50    #   akima Builtin Fortran Code.
51
52    # Example:
53    #   set.seed(1953)
54    #   x = runif(999)-0.5; y = runif(999)-0.5; z = cos(2*pi*(x^2+y^2))
55    #   ans = linearInterp(x, y, z)
56    #   persp(ans, theta = -50, phi = 30, col = "steelblue")
57
58    # Note:
59    #   Uses Fortran akima Builtin
60
61    # FUNCTION:
62
63    if (!requireNamespace("akima", quietly = TRUE))
64      stop("Needs Package 'akima' which is not auto-installed because of a different licence\n")
65
66    # Arguments:
67    if (is.data.frame(x))
68      x <- as.matrix.data.frame(x)
69    else if (is.list(x))
70      x <- matrix(unlist(x), ncol = 3)
71    if (is.matrix(x)) {
72      z = x[, 3]
73      y = x[, 2]
74      x = x[, 1]
75    }
76
77    # Interpolation:
78    ans <- akima::interp(x, y, z, xo, yo, linear = TRUE, extrap = FALSE,
79                         duplicate = "median", dupfun = NULL)
80    colnames(ans$z) <- as.character(signif(ans$x, round(log(gridPoints), 0)))
81    rownames(ans$z) <- as.character(signif(ans$y, round(log(gridPoints), 0)))
82    class(ans) <- "gridData"
83
84    # Return Value:
85    ans
86  }
87
88
89# ------------------------------------------------------------------------------
90
91
92linearInterpp <-
93  function(x, y = NULL, z = NULL, xo, yo)
94  {
95    # A function implemented by Diethelm Wuertz
96
97    # Description:
98    #   Interpolates Linearly Irregularly Distributed Data Points
99
100    # Arguments:
101    #   x, y, z - either three numeric vectors of equal length or if
102    #       y and z are NULL, a list with entries x, y, a, or named
103    #       data.frame with x in the first, y in the second, and z in
104    #       the third column.
105    #   gridPoints - number of grid points in x and y direction.
106    #   xo, yo, a sequence of data points for pointwise interpolation
107
108    # Note:
109    #   Extrapolation is not possible in the case of linear interpolation.
110
111    # Value:
112    #   A list with three elements, $x and $y which are vectors of length
113    #   'gridPoints' and $z which is a matrix of size 'gridPoints^2'.
114
115    # Requirements:
116    #   akima Builtin Fortran Code.
117
118    # Example:
119    #   set.seed(1953)
120    #   x = runif(999)-0.5; y = runif(999)-0.5; z = cos(2*pi*(x^2+y^2))
121    #   ans = linearInterpp(x, y, z, c(mean(x), 0, 100), c(mean(y), 0, 100))
122    #   persp(ans, theta = -50, phi = 30, col = "steelblue")
123
124    # Note:
125    #   Uses Fortran akima Builtin
126
127    # FUNCTION:
128
129    if (!requireNamespace("akima", quietly = TRUE))
130      stop("Needs Package 'akima' which is not auto-installed because of a different licence\n")
131
132    # Arguments:
133    if (is.data.frame(x))
134      x <- as.matrix.data.frame(x)
135    else if (is.list(x))
136      x <- matrix(unlist(x), ncol = 3)
137    if (is.matrix(x)) {
138      z = x[, 3]
139      y = x[, 2]
140      x = x[, 1]
141    }
142
143    # Interpolation:
144    interpp <- eval(parse(text=paste0("akima",":::","interpp")))
145    ans <- interpp(x, y, z, xo, yo, linear = TRUE, extrap = FALSE,
146                   duplicate = "median", dupfun = NULL)
147    ## Return
148    data.frame(x = ans$x, y = ans$y, z = ans$z)
149  }
150
151
152################################################################################
153