View Javadoc
1   /*
2    * Copyright (C) 2017 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.geometry.refiners;
17  
18  import com.irurueta.algebra.Matrix;
19  import com.irurueta.geometry.estimators.LockedException;
20  import com.irurueta.geometry.estimators.NotReadyException;
21  
22  /**
23   * Refines an instance of type T by taking into account an initial estimation.
24   * This class can be used to find a solution that minimizes error of inliers in
25   * LMSE terms.
26   * Typically, a refiner is used by a robust estimator, however it can also be
27   * useful in some other situations.
28   * This is a base abstract class to be used by any refiner implementation.
29   *
30   * @param <T> type of instance to be refined.
31   */
32  public abstract class Refiner<T> {
33  
34      /**
35       * Indicates whether by default covariance of estimation must be kept.
36       */
37      public static final boolean DEFAULT_KEEP_COVARIANCE = false;
38  
39      /**
40       * Initial estimation.
41       */
42      protected T initialEstimation;
43  
44      /**
45       * Indicates whether covariance of estimation must be kept after refinement.
46       */
47      protected boolean keepCovariance = DEFAULT_KEEP_COVARIANCE;
48  
49      /**
50       * Estimated covariance after refinement.
51       */
52      protected Matrix covariance;
53  
54      /**
55       * Indicates if this estimator is locked because a refinement is being
56       * computed.
57       */
58      protected boolean locked;
59  
60      /**
61       * Listener in charge of attending events generated by this instance.
62       */
63      protected RefinerListener<T> listener;
64  
65      /**
66       * Constructor.
67       */
68      protected Refiner() {
69      }
70  
71      /**
72       * Constructor.
73       *
74       * @param initialEstimation initial estimation to be set.
75       * @param keepCovariance    true if covariance of estimation must be kept after
76       *                          refinement, false otherwise.
77       */
78      protected Refiner(final T initialEstimation, final boolean keepCovariance) {
79          this.initialEstimation = initialEstimation;
80          this.keepCovariance = keepCovariance;
81      }
82  
83      /**
84       * Gets listener in charge of attending events generated by this instance.
85       *
86       * @return listener in charge of attending events generated by this
87       * instance.
88       */
89      public RefinerListener<T> getListener() {
90          return listener;
91      }
92  
93      /**
94       * Sets listener in charge of attending events generated by this instance.
95       *
96       * @param listener listener in charge of attending events generated by this
97       *                 instance.
98       */
99      public void setListener(final RefinerListener<T> listener) {
100         this.listener = listener;
101     }
102 
103     /**
104      * Gets initial estimation.
105      *
106      * @return initial estimation.
107      */
108     public T getInitialEstimation() {
109         return initialEstimation;
110     }
111 
112     /**
113      * Sets initial estimation.
114      *
115      * @param initialEstimation initial estimation.
116      * @throws LockedException if estimator is locked.
117      */
118     public void setInitialEstimation(final T initialEstimation) throws LockedException {
119         if (isLocked()) {
120             throw new LockedException();
121         }
122         this.initialEstimation = initialEstimation;
123     }
124 
125     /**
126      * Indicates whether covariance of estimation must be kept after refinement
127      * or not.
128      *
129      * @return true if covariance of estimation must be kept after refinement,
130      * false otherwise.
131      */
132     public boolean isCovarianceKept() {
133         return keepCovariance;
134     }
135 
136     /**
137      * Specifies whether covariance of estimation must be kept after refinement
138      * or not.
139      *
140      * @param keepCovariance true if covariance of estimation must be kept after
141      *                       refinement, false otherwise.
142      * @throws LockedException if estimator is locked.
143      */
144     public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
145         if (isLocked()) {
146             throw new LockedException();
147         }
148         this.keepCovariance = keepCovariance;
149     }
150 
151 
152     /**
153      * Indicates if this estimator is locked because a refinement is being
154      * computed.
155      *
156      * @return true if estimator is locked, false otherwise.
157      */
158     public boolean isLocked() {
159         return locked;
160     }
161 
162     /**
163      * Gets estimated covariance after refinement.
164      *
165      * @return estimated covariance after refinement.
166      */
167     public Matrix getCovariance() {
168         return covariance;
169     }
170 
171     /**
172      * Indicates whether this refiner is ready to start refinement computation.
173      *
174      * @return true if refiner is ready, false otherwise.
175      */
176     public abstract boolean isReady();
177 
178     /**
179      * Refines provided initial estimation.
180      * Notice that implementations of this method might set a value into result
181      * even if error is not improved in LMSE terms.
182      *
183      * @param result instance where refined estimation will be stored.
184      * @return true if result improves (decreases) in LMSE terms respect to
185      * initial estimation, false if no improvement has been achieved.
186      * @throws NotReadyException if not enough input data has been provided.
187      * @throws LockedException   if estimator is locked because refinement is
188      *                           already in progress.
189      * @throws RefinerException  if refinement fails for some reason (e.g. unable
190      *                           to converge to a result).
191      */
192     public abstract boolean refine(final T result) throws NotReadyException, LockedException, RefinerException;
193 
194     /**
195      * Refines provided initial estimation.
196      *
197      * @return refined estimation.
198      * @throws NotReadyException if not enough input data has been provided.
199      * @throws LockedException   if estimator is locked because refinement is
200      *                           already in progress.
201      * @throws RefinerException  if refinement fails for some reason (e.g. unable
202      *                           to converge to a result).
203      */
204     public abstract T refine() throws NotReadyException, LockedException, RefinerException;
205 
206 }