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 }