View Javadoc
1   /*
2    * Copyright (C) 2023 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.numerical.interpolation;
17  
18  import com.irurueta.algebra.Matrix;
19  
20  /**
21   * Interpolation in two dimensions.
22   * This is the simplest implementation.
23   */
24  public class BilinearInterpolator {
25  
26      /**
27       * Length of x1v array.
28       */
29      private final int m;
30  
31      /**
32       * Length of x2v array.
33       */
34      private final int n;
35  
36      /**
37       * Matrix of tabulated function values yij.
38       */
39      private final Matrix y;
40  
41      /**
42       * One dimensional interpolator for x1v.
43       */
44      private final LinearInterpolator x1terp;
45  
46      /**
47       * One dimensional interpolator for x2v.
48       */
49      private final LinearInterpolator x2terp;
50  
51      /**
52       * Constructor.
53       *
54       * @param x1v array of x1v.
55       * @param x2v array of x2v.
56       * @param ym matrix of tabulated function values yij.
57       */
58      @SuppressWarnings("SuspiciousNameCombination")
59      public BilinearInterpolator(final double[] x1v, final double[] x2v, final Matrix ym) {
60          m = x1v.length;
61          n = x2v.length;
62          y = ym;
63          // Construct dummy 1-dim interpolators for their locate and hunt methods
64          x1terp = new LinearInterpolator(x1v, x1v);
65          x2terp = new LinearInterpolator(x2v, x2v);
66      }
67  
68      /**
69       * Gets length of x1v array.
70       * @return length of x1v array.
71       */
72      public int getM() {
73          return m;
74      }
75  
76      /**
77       * Gets length of x2v array.
78       * @return length of x2v array.
79       */
80      public int getN() {
81          return n;
82      }
83  
84      /**
85       * Given values x1p an x2p, returns an interpolated value.
86       *
87       * @param x1p x1p value where interpolation is estimated.
88       * @param x2p x2p value where interpolation is estimated.
89       * @return interpolated value.
90       */
91      public double interpolate(final double x1p, final double x2p) {
92          final var i = x1terp.cor != 0 ? x1terp.hunt(x1p) : x1terp.locate(x1p);
93          final var j = x2terp.cor != 0 ? x2terp.hunt(x2p) : x2terp.locate(x2p);
94  
95          // Find the grid square
96          final var t = (x1p - x1terp.xx[i]) / (x1terp.xx[i + 1] - x1terp.xx[i]);
97          final var u = (x2p - x2terp.xx[j]) / (x2terp.xx[j + 1] - x2terp.xx[j]);
98  
99          // Interpolate
100         return (1. - t) * (1. - u) * y.getElementAt(i, j) + t * (1. - u) * y.getElementAt(i + 1, j)
101                 + (1. - t) * u * y.getElementAt(i, j + 1) + t * u * y.getElementAt(i + 1, j + 1);
102     }
103 
104 }