View Javadoc
1   /*
2    * Copyright (C) 2015 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.fitting;
17  
18  import com.irurueta.algebra.AlgebraException;
19  import com.irurueta.algebra.Matrix;
20  
21  /**
22   * Base class to fit provided multidimensional data (x1, x2, ..., y1, y2, ...)
23   * to a function made of a linear combination of functions used as a basis
24   * (i.e. f(x1, x2, ...) = a * f0(x1, x2, ...) + b * f1(x1, x2, ...) + ...).
25   * Where f0, f1, ... is the function basis which ideally should be formed by
26   * orthogonal functions.
27   */
28  public abstract class MultiDimensionLinearFitter extends MultiDimensionFitter {
29  
30      /**
31       * Evaluator of functions
32       */
33      protected LinearFitterMultiDimensionFunctionEvaluator evaluator;
34  
35      /**
36       * Array where results of function evaluations are stored
37       */
38      protected double[] afunc;
39  
40      /**
41       * Number of function basis used as a linear combination of functions being
42       * fitted
43       */
44      protected int ma;
45  
46      /**
47       * Constructor
48       */
49      MultiDimensionLinearFitter() {
50          super();
51      }
52  
53      /**
54       * Constructor
55       *
56       * @param x   input points x where a linear multidimensional function
57       *            f(x1, x2, ...) = a * f0(x1, x2, ...) + b * f1(x1, x2, ...) + ...
58       * @param y   result of evaluation of linear multidimensional function
59       *            f(x1, x2, ...) at provided x points
60       * @param sig standard deviations of each pair of points (x, y)
61       * @throws IllegalArgumentException if provided matrix rows and arrays
62       *                                  don't have the same length
63       */
64      protected MultiDimensionLinearFitter(final Matrix x, final double[] y, final double[] sig) {
65          super(x, y, sig);
66      }
67  
68      /**
69       * Constructor
70       *
71       * @param x   input points x where a linear multidimensional function
72       *            f(x1, x2, ...) = a * f0(x1, x2, ...) + b * f1(x1, x2, ...) + ...
73       * @param y   result of evaluation of linear multidimensional function
74       *            f(x1, x2, ...) at provided x points
75       * @param sig standard deviation of all pair of points assuming that
76       *            standard deviations are constant
77       * @throws IllegalArgumentException if provided matrix rows and arrays
78       *                                  don't have the same length
79       */
80      protected MultiDimensionLinearFitter(final Matrix x, final double[] y, final double sig) {
81          super(x, y, sig);
82      }
83  
84      /**
85       * Constructor
86       *
87       * @param evaluator evaluator to evaluate function at provided point and
88       *                  obtain the evaluation of function basis at such point
89       * @throws FittingException if evaluation fails
90       */
91      protected MultiDimensionLinearFitter(final LinearFitterMultiDimensionFunctionEvaluator evaluator)
92              throws FittingException {
93          super();
94          internalSetFunctionEvaluator(evaluator);
95      }
96  
97      /**
98       * Constructor
99       *
100      * @param evaluator evaluator to evaluate function at provided point and
101      *                  obtain the evaluation of function basis at such point
102      * @param x         input points x where a linear multidimensional function
103      *                  f(x1, x2, ...) = a * f0(x1, x2, ...) + b * f1(x1, x2, ...) + ...
104      * @param y         result of evaluation of linear multidimensional function
105      *                  f(x1, x2, ...) at provided x points
106      * @param sig       standard deviations of each pair of points (x, y)
107      * @throws FittingException         if evaluation fails
108      * @throws IllegalArgumentException if provided matrix rows and arrays
109      *                                  don't have the same length
110      */
111     protected MultiDimensionLinearFitter(
112             final LinearFitterMultiDimensionFunctionEvaluator evaluator, final Matrix x, final double[] y,
113             final double[] sig) throws FittingException {
114         super(x, y, sig);
115         internalSetFunctionEvaluator(evaluator);
116     }
117 
118     /**
119      * Constructor
120      *
121      * @param evaluator evaluator to evaluate function at provided point and
122      *                  obtain the evaluation of function basis at such point
123      * @param x         input points x where a linear multidimensional function
124      *                  f(x1, x2, ...) = a * f0(x1, x2, ...) + b * f1(x1, x2, ...) + ...
125      * @param y         result of evaluation of linear multidimensional function
126      *                  f(x1, x2, ...) at provided x points
127      * @param sig       standard deviation of all pair of points assuming that
128      *                  standard deviations are constant
129      * @throws FittingException         if evaluation fails
130      * @throws IllegalArgumentException if provided matrix rows and arrays
131      *                                  don't have the same length
132      */
133     protected MultiDimensionLinearFitter(
134             final LinearFitterMultiDimensionFunctionEvaluator evaluator, final Matrix x, final double[] y,
135             final double sig) throws FittingException {
136         super(x, y, sig);
137         internalSetFunctionEvaluator(evaluator);
138     }
139 
140     /**
141      * Returns function evaluator to evaluate function at a given point and
142      * obtain the evaluation of function basis at such point
143      *
144      * @return function evaluator
145      */
146     public LinearFitterMultiDimensionFunctionEvaluator getFunctionEvaluator() {
147         return evaluator;
148     }
149 
150     /**
151      * Sets function evaluator to evaluate function at a given point and obtain
152      * the evaluation of function basis at such point
153      *
154      * @param evaluator function evaluator
155      * @throws FittingException if evaluation fails
156      */
157     public void setFunctionEvaluator(
158             final LinearFitterMultiDimensionFunctionEvaluator evaluator) throws FittingException {
159         internalSetFunctionEvaluator(evaluator);
160     }
161 
162     /**
163      * Internal method to set function evaluator to evaluate function at a given
164      * point and obtain the evaluation of function basis at such point
165      *
166      * @param evaluator function evaluator
167      * @throws FittingException if evaluation fails
168      */
169     @SuppressWarnings("DuplicatedCode")
170     private void internalSetFunctionEvaluator(
171             final LinearFitterMultiDimensionFunctionEvaluator evaluator) throws FittingException {
172 
173         try {
174             this.evaluator = evaluator;
175 
176             if (evaluator != null) {
177                 afunc = evaluator.createResultArray();
178                 ma = afunc.length;
179                 a = new double[ma];
180                 covar = new Matrix(ma, ma);
181             }
182         } catch (final AlgebraException e) {
183             throw new FittingException(e);
184         }
185     }
186 
187     /**
188      * Indicates whether provided instance has enough data to start the function
189      * fitting.
190      *
191      * @return true if this instance is ready to start the function fitting,
192      * false otherwise
193      */
194     @Override
195     public boolean isReady() {
196         return evaluator != null && x != null && y != null && x.getRows() == y.length
197                 && x.getColumns() == evaluator.getNumberOfDimensions();
198     }
199 }