1 /*
2 * Copyright (C) 2013 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.robust;
17
18 import com.irurueta.numerical.LockedException;
19 import com.irurueta.numerical.NotReadyException;
20
21 /**
22 * Robust estimator to estimate some object in a robust manner
23 *
24 * @param <T> Object to be estimated (i.e. lines, cameras, etc)
25 */
26 public abstract class RobustEstimator<T> {
27
28 /**
29 * Default amount of progress variation before notifying a change in
30 * estimation progress. By default, this is set to 5%
31 */
32 public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
33
34 /**
35 * Minimum allowed value for progress delta
36 */
37 public static final float MIN_PROGRESS_DELTA = 0.0f;
38
39 /**
40 * Maximum allowed value for progress delta.
41 */
42 public static final float MAX_PROGRESS_DELTA = 1.0f;
43
44 /**
45 * Listener to be notified of events such as when estimation starts, ends
46 * or its progress significantly changes.
47 */
48 protected RobustEstimatorListener<T> listener;
49
50 /**
51 * Indicates if this estimator is locked because an estimation is being
52 * computed.
53 */
54 protected volatile boolean locked;
55
56 /**
57 * Amount of progress variation before notifying a progress change during
58 * estimation.
59 */
60 protected float progressDelta;
61
62 /**
63 * Constructor.
64 */
65 protected RobustEstimator() {
66 listener = null;
67 locked = false;
68 progressDelta = DEFAULT_PROGRESS_DELTA;
69 }
70
71 /**
72 * Constructor.
73 *
74 * @param listener listener to be notified of events such as when estimation
75 * starts, ends or its progress significantly changes.
76 */
77 protected RobustEstimator(final RobustEstimatorListener<T> listener) {
78 this.listener = listener;
79 locked = false;
80 progressDelta = DEFAULT_PROGRESS_DELTA;
81 }
82
83 /**
84 * Returns reference to listener to be notified of events such as when
85 * estimation starts, ends or its progress significantly changes.
86 *
87 * @return listener to be notified of events.
88 */
89 public RobustEstimatorListener<T> getListener() {
90 return listener;
91 }
92
93 /**
94 * Sets listener to be notified of events such as when estimation starts,
95 * ends or its progress significantly changes.
96 *
97 * @param listener listener to be notified of events.
98 * @throws LockedException if robust estimator is locked.
99 */
100 public void setListener(final RobustEstimatorListener<T> listener) throws LockedException {
101 if (isLocked()) {
102 throw new LockedException();
103 }
104 this.listener = listener;
105 }
106
107 /**
108 * Indicates whether listener has been provided and is available for
109 * retrieval.
110 *
111 * @return true if available, false otherwise.
112 */
113 public boolean isListenerAvailable() {
114 return listener != null;
115 }
116
117 /**
118 * Indicates if this instance is locked because estimation is being computed.
119 *
120 * @return true if locked, false otherwise.
121 */
122 public boolean isLocked() {
123 return locked;
124 }
125
126 /**
127 * Returns amount of progress variation before notifying a progress change
128 * during estimation.
129 *
130 * @return amount of progress variation before notifying a progress change
131 * during estimation.
132 */
133 public float getProgressDelta() {
134 return progressDelta;
135 }
136
137 /**
138 * Sets amount of progress variation before notifying a progress change
139 * during estimation.
140 *
141 * @param progressDelta amount of progress variation before notifying a
142 * progress change during estimation.
143 * @throws IllegalArgumentException if progress delta is less than zero or
144 * greater than 1.
145 * @throws LockedException if this estimator is locked because an estimation
146 * is being computed.
147 */
148 public void setProgressDelta(final float progressDelta) throws LockedException {
149 if (isLocked()) {
150 throw new LockedException();
151 }
152 if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
153 throw new IllegalArgumentException();
154 }
155 this.progressDelta = progressDelta;
156 }
157
158 /**
159 * Robustly estimates an instance of T.
160 *
161 * @return estimated object.
162 * @throws LockedException if robust estimator is locked.
163 * @throws NotReadyException if provided input data is not enough to start
164 * the estimation.
165 * @throws RobustEstimatorException if estimation fails for any reason
166 * (i.e. numerical instability, no solution available, etc).
167 */
168 public abstract T estimate() throws LockedException, NotReadyException, RobustEstimatorException;
169
170 /**
171 * Returns data about inliers once estimation has been done.
172 *
173 * @return data about inliers or null if estimation has not been done.
174 */
175 public abstract InliersData getInliersData();
176
177 /**
178 * Returns method being used for robust estimation.
179 *
180 * @return method being used for robust estimation.
181 */
182 public abstract RobustEstimatorMethod getMethod();
183
184 /**
185 * Indicates if estimator is ready to start the estimation process.
186 *
187 * @return true if ready, false otherwise.
188 */
189 public boolean isReady() {
190 if (listener != null) {
191 return listener.isReady();
192 } else {
193 return false;
194 }
195 }
196 }