View Javadoc
1   /*
2    * Copyright (C) 2019 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.navigation.indoor.radiosource;
17  
18  import com.irurueta.geometry.Point3D;
19  import com.irurueta.navigation.LockedException;
20  import com.irurueta.navigation.NavigationException;
21  import com.irurueta.navigation.indoor.Beacon;
22  import com.irurueta.navigation.indoor.BeaconWithPowerAndLocated3D;
23  import com.irurueta.navigation.indoor.RadioSource;
24  import com.irurueta.navigation.indoor.RadioSourceWithPowerAndLocated;
25  import com.irurueta.navigation.indoor.RangingAndRssiReadingLocated;
26  import com.irurueta.navigation.indoor.WifiAccessPoint;
27  import com.irurueta.navigation.indoor.WifiAccessPointWithPowerAndLocated3D;
28  import com.irurueta.numerical.robust.RobustEstimatorMethod;
29  
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  /**
34   * This is an abstract class to robustly estimate 3D position, transmitted power and path-loss
35   * exponent of a radio source (e.g. Wi-Fi access point or bluetooth beacon), by discarding
36   * outliers and assuming that the ranging data is available to obtain position with
37   * greater accuracy and that the radio source emits isotropically following the
38   * expression below:
39   * Pr = Pt*Gt*Gr*lambda^2 / (4*pi*d)^2,
40   * where Pr is the received power (expressed in mW),
41   * Gt is the Gain of the transmission antenna
42   * Gr is the Gain of the receiver antenna
43   * d is the distance between emitter and receiver
44   * and lambda is the wavelength and is equal to: lambda = c / f,
45   * where c is the speed of light
46   * and f is the carrier frequency of the radio signal.
47   * Because usually information about the antenna of the radio source cannot be
48   * retrieved (because many measurements are made on unknown devices where
49   * physical access is not possible), this implementation will estimate the
50   * equivalent transmitted power as: Pte = Pt * Gt * Gr.
51   * If Readings contain RSSI standard deviations, those values will be used,
52   * otherwise it will be assumed an RSSI standard deviation of 1 dB.
53   * <p>
54   * Although RobustRssiRadioSourceEstimator can estimate the same parameters of a radio
55   * source, when ranging measures are available along with RSSI measurements,
56   * implementations of this class should be preferred instead as they can provide
57   * greater accuracy.
58   *
59   * @param <S> a {@link RadioSource} type.
60   */
61  public abstract class RobustRangingAndRssiRadioSourceEstimator3D<S extends RadioSource> extends
62          RobustRangingAndRssiRadioSourceEstimator<S, Point3D> {
63  
64      /**
65       * Radio source estimator used internally.
66       */
67      protected final RangingAndRssiRadioSourceEstimator3D<S> innerEstimator =
68              new RangingAndRssiRadioSourceEstimator3D<>();
69  
70      /**
71       * Subset of readings used by inner estimator.
72       */
73      private final List<RangingAndRssiReadingLocated<S, Point3D>> innerReadings = new ArrayList<>();
74  
75      /**
76       * Constructor.
77       */
78      protected RobustRangingAndRssiRadioSourceEstimator3D() {
79          super();
80          preliminarySubsetSize = getMinReadings();
81      }
82  
83      /**
84       * Constructor.
85       * Sets signal readings belonging to the same radio source.
86       *
87       * @param readings signal readings belonging to the same radio source.
88       * @throws IllegalArgumentException if readings are not valid.
89       */
90      protected RobustRangingAndRssiRadioSourceEstimator3D(
91              final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings) {
92          super(readings);
93          preliminarySubsetSize = getMinReadings();
94      }
95  
96      /**
97       * Constructor.
98       *
99       * @param listener listener in charge of attending events raised by this instance.
100      */
101     protected RobustRangingAndRssiRadioSourceEstimator3D(
102             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
103         super(listener);
104         preliminarySubsetSize = getMinReadings();
105     }
106 
107     /**
108      * Constructor.
109      * Sets signal readings belonging to the same radio source.
110      *
111      * @param readings signal readings belonging to the same radio source.
112      * @param listener listener in charge of attending events raised by this instance.
113      * @throws IllegalArgumentException if readings are not valid.
114      */
115     protected RobustRangingAndRssiRadioSourceEstimator3D(
116             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
117             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
118         super(readings, listener);
119         preliminarySubsetSize = getMinReadings();
120     }
121 
122     /**
123      * Constructor.
124      * Sets signal readings belonging to the same radio source.
125      *
126      * @param readings        signal readings belonging to the same radio source.
127      * @param initialPosition initial position to start the estimation of radio
128      *                        source position.
129      * @throws IllegalArgumentException if readings are not valid.
130      */
131     protected RobustRangingAndRssiRadioSourceEstimator3D(
132             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition) {
133         super(readings, initialPosition);
134         preliminarySubsetSize = getMinReadings();
135     }
136 
137     /**
138      * Constructor.
139      *
140      * @param initialPosition initial position to start the estimation of radio
141      *                        source position.
142      */
143     protected RobustRangingAndRssiRadioSourceEstimator3D(final Point3D initialPosition) {
144         super(initialPosition);
145         preliminarySubsetSize = getMinReadings();
146     }
147 
148     /**
149      * Constructor.
150      *
151      * @param initialPosition initial position to start the estimation of radio
152      *                        source position.
153      * @param listener        listener in charge of attending events raised by this instance.
154      */
155     protected RobustRangingAndRssiRadioSourceEstimator3D(
156             final Point3D initialPosition,
157             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
158         super(initialPosition, listener);
159         preliminarySubsetSize = getMinReadings();
160     }
161 
162     /**
163      * Constructor.
164      * Sets signal readings belonging to the same radio source.
165      *
166      * @param readings        signal readings belonging to the same radio source.
167      * @param initialPosition initial position to start the estimation of radio
168      *                        source position.
169      * @param listener        listener in charge of attending events raised by this instance.
170      * @throws IllegalArgumentException if readings are not valid.
171      */
172     protected RobustRangingAndRssiRadioSourceEstimator3D(
173             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
174             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
175         super(readings, initialPosition, listener);
176         preliminarySubsetSize = getMinReadings();
177     }
178 
179     /**
180      * Constructor.
181      *
182      * @param initialTransmittedPowerdBm initial transmitted power to start the
183      *                                   estimation of radio source transmitted power
184      *                                   (expressed in dBm's)
185      */
186     protected RobustRangingAndRssiRadioSourceEstimator3D(final Double initialTransmittedPowerdBm) {
187         super(initialTransmittedPowerdBm);
188         preliminarySubsetSize = getMinReadings();
189     }
190 
191     /**
192      * Constructor.
193      * Sets signal readings belonging to the same radio source.
194      *
195      * @param readings                   Wi-Fi signal readings belonging to the same radio source.
196      * @param initialTransmittedPowerdBm initial transmitted power to start the
197      *                                   estimation of radio source transmitted power
198      *                                   (expressed in dBm's)
199      * @throws IllegalArgumentException if readings are not valid.
200      */
201     protected RobustRangingAndRssiRadioSourceEstimator3D(
202             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
203             final Double initialTransmittedPowerdBm) {
204         super(readings, initialTransmittedPowerdBm);
205         preliminarySubsetSize = getMinReadings();
206     }
207 
208     /**
209      * Constructor.
210      *
211      * @param initialTransmittedPowerdBm initial transmitted power to start the
212      *                                   estimation of radio source transmitted power
213      *                                   (expressed in dBm's)
214      * @param listener                   listener in charge of attending events raised by this instance.
215      */
216     protected RobustRangingAndRssiRadioSourceEstimator3D(
217             final Double initialTransmittedPowerdBm,
218             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
219         super(initialTransmittedPowerdBm, listener);
220         preliminarySubsetSize = getMinReadings();
221     }
222 
223     /**
224      * Constructor.
225      * Sets signal readings belonging to the same radio source.
226      *
227      * @param readings                   Wi-Fi signal readings belonging to the radio source point.
228      * @param initialTransmittedPowerdBm initial transmitted power to start the
229      *                                   estimation of radio source transmitted power
230      *                                   (expressed in dBm's)
231      * @param listener                   listener in charge of attending events raised by this instance.
232      * @throws IllegalArgumentException if readings are not valid.
233      */
234     protected RobustRangingAndRssiRadioSourceEstimator3D(
235             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
236             final Double initialTransmittedPowerdBm,
237             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
238         super(readings, initialTransmittedPowerdBm, listener);
239         preliminarySubsetSize = getMinReadings();
240     }
241 
242     /**
243      * Constructor.
244      * Sets signal readings belonging to the same radio source.
245      *
246      * @param readings                   signal readings belonging to the same radio source.
247      * @param initialPosition            initial position to start the estimation of radio
248      *                                   source position.
249      * @param initialTransmittedPowerdBm initial transmitted power to start the
250      *                                   estimation of radio source transmitted power
251      *                                   (expressed in dBm's).
252      * @throws IllegalArgumentException if readings are not valid.
253      */
254     protected RobustRangingAndRssiRadioSourceEstimator3D(
255             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
256             final Double initialTransmittedPowerdBm) {
257         super(readings, initialPosition, initialTransmittedPowerdBm);
258         preliminarySubsetSize = getMinReadings();
259     }
260 
261     /**
262      * Constructor.
263      *
264      * @param initialPosition            initial position to start the estimation of radio
265      *                                   source position.
266      * @param initialTransmittedPowerdBm initial transmitted power to start the
267      *                                   estimation of radio source transmitted power
268      *                                   (expressed in dBm's).
269      */
270     protected RobustRangingAndRssiRadioSourceEstimator3D(
271             final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
272         super(initialPosition, initialTransmittedPowerdBm);
273         preliminarySubsetSize = getMinReadings();
274     }
275 
276     /**
277      * Constructor.
278      *
279      * @param initialPosition            initial position to start the estimation of radio
280      *                                   source position.
281      * @param initialTransmittedPowerdBm initial transmitted power to start the
282      *                                   estimation of radio source transmitted power
283      *                                   (expressed in dBm's).
284      * @param listener                   listener in charge of attending events raised by this instance.
285      */
286     protected RobustRangingAndRssiRadioSourceEstimator3D(
287             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
288             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
289         super(initialPosition, initialTransmittedPowerdBm, listener);
290         preliminarySubsetSize = getMinReadings();
291     }
292 
293     /**
294      * Constructor.
295      * Sets signal readings belonging to the same radio source.
296      *
297      * @param readings                   signal readings belonging to the same radio source.
298      * @param initialPosition            initial position to start the estimation of radio
299      *                                   source position.
300      * @param initialTransmittedPowerdBm initial transmitted power to start the
301      *                                   estimation of radio source transmitted power
302      *                                   (expressed in dBm's).
303      * @param listener                   listener in charge of attending events raised by this instance.
304      * @throws IllegalArgumentException if readings are not valid.
305      */
306     protected RobustRangingAndRssiRadioSourceEstimator3D(
307             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
308             final Double initialTransmittedPowerdBm,
309             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
310         super(readings, initialPosition, initialTransmittedPowerdBm, listener);
311         preliminarySubsetSize = getMinReadings();
312     }
313 
314     /**
315      * Constructor.
316      * Sets signal readings belonging to the same radio source.
317      *
318      * @param readings                   signal readings belonging to the same radio source.
319      * @param initialPosition            initial position to start the estimation of radio
320      *                                   source position.
321      * @param initialTransmittedPowerdBm initial transmitted power to start the
322      *                                   estimation of radio source transmitted power
323      *                                   (expressed in dBm's).
324      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
325      * @throws IllegalArgumentException if readings are not valid.
326      */
327     protected RobustRangingAndRssiRadioSourceEstimator3D(
328             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
329             final Double initialTransmittedPowerdBm, final double initialPathLossExponent) {
330         super(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
331         preliminarySubsetSize = getMinReadings();
332     }
333 
334     /**
335      * Constructor.
336      *
337      * @param initialPosition            initial position to start the estimation of radio
338      *                                   source position.
339      * @param initialTransmittedPowerdBm initial transmitted power to start the
340      *                                   estimation of radio source transmitted power
341      *                                   (expressed in dBm's).
342      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
343      */
344     protected RobustRangingAndRssiRadioSourceEstimator3D(
345             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
346             final double initialPathLossExponent) {
347         super(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
348         preliminarySubsetSize = getMinReadings();
349     }
350 
351     /**
352      * Constructor.
353      *
354      * @param initialPosition            initial position to start the estimation of radio
355      *                                   source position.
356      * @param initialTransmittedPowerdBm initial transmitted power to start the
357      *                                   estimation of radio source transmitted power
358      *                                   (expressed in dBm's).
359      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
360      * @param listener                   listener in charge of attending events raised by this instance.
361      */
362     protected RobustRangingAndRssiRadioSourceEstimator3D(
363             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
364             final double initialPathLossExponent,
365             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
366         super(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
367         preliminarySubsetSize = getMinReadings();
368     }
369 
370     /**
371      * Constructor.
372      * Sets signal readings belonging to the same radio source.
373      *
374      * @param readings                   signal readings belonging to the same radio source.
375      * @param initialPosition            initial position to start the estimation of radio
376      *                                   source position.
377      * @param initialTransmittedPowerdBm initial transmitted power to start the
378      *                                   estimation of radio source transmitted power
379      *                                   (expressed in dBm's).
380      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
381      * @param listener                   listener in charge of attending events raised by this instance.
382      * @throws IllegalArgumentException if readings are not valid.
383      */
384     protected RobustRangingAndRssiRadioSourceEstimator3D(
385             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
386             final Double initialTransmittedPowerdBm, final double initialPathLossExponent,
387             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
388         super(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
389         preliminarySubsetSize = getMinReadings();
390     }
391 
392     /**
393      * Creates a robust 3D position radio source estimator.
394      *
395      * @param method robust estimator method.
396      * @param <S>    a {@link RadioSource} type.
397      * @return a new robust 3D position radio source estimator.
398      */
399     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
400             final RobustEstimatorMethod method) {
401         return switch (method) {
402             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>();
403             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>();
404             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>();
405             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>();
406             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>();
407         };
408     }
409 
410     /**
411      * Creates a robust 3D position radio source estimator.
412      *
413      * @param readings signal readings belonging to the same radio source.
414      * @param method   robust estimator method.
415      * @param <S>      a {@link RadioSource} type.
416      * @return a new robust 3D position radio source estimator.
417      * @throws IllegalArgumentException if readings are not valid.
418      */
419     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
420             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
421             final RobustEstimatorMethod method) {
422         return switch (method) {
423             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
424             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
425             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
426             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
427             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
428         };
429     }
430 
431     /**
432      * Creates a robust 3D position radio source estimator.
433      *
434      * @param listener listener in charge of attending events raised by this instance.
435      * @param method   robust estimator method.
436      * @param <S>      a {@link RadioSource} type.
437      * @return a new robust 3D position radio source estimator.
438      */
439     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
440             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
441             final RobustEstimatorMethod method) {
442         return switch (method) {
443             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
444             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
445             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
446             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
447             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
448         };
449     }
450 
451     /**
452      * Creates a robust 3D position radio source estimator.
453      *
454      * @param readings signal readings belonging to the same radio source.
455      * @param listener listener in charge of attending events raised by this instance.
456      * @param method   robust estimator method.
457      * @param <S>      a {@link RadioSource} type.
458      * @return a new robust 3D position radio source estimator.
459      * @throws IllegalArgumentException if readings are not valid.
460      */
461     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
462             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
463             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
464             final RobustEstimatorMethod method) {
465         return switch (method) {
466             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
467             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
468             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
469             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
470             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
471         };
472     }
473 
474     /**
475      * Creates a robust 3D position radio source estimator.
476      *
477      * @param readings        signal readings belonging to the same radio source.
478      * @param initialPosition initial position to start the estimation of radio
479      *                        source position.
480      * @param method          robust estimator method.
481      * @param <S>             a {@link RadioSource} type.
482      * @return a new robust 3D position radio source estimator.
483      * @throws IllegalArgumentException if readings are not valid.
484      */
485     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
486             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
487             final RobustEstimatorMethod method) {
488         return switch (method) {
489             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
490             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
491             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
492             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
493             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
494         };
495     }
496 
497     /**
498      * Creates a robust 3D position radio source estimator.
499      *
500      * @param initialPosition initial position to start the estimation of radio
501      *                        source position.
502      * @param method          robust estimator method.
503      * @param <S>             a {@link RadioSource} type.
504      * @return a new robust 3D position radio source estimator.
505      */
506     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
507             final Point3D initialPosition, final RobustEstimatorMethod method) {
508         return switch (method) {
509             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
510             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
511             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
512             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
513             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
514         };
515     }
516 
517     /**
518      * Creates a robust 3D position radio source estimator.
519      *
520      * @param initialPosition initial position to start the estimation of radio
521      *                        source position.
522      * @param listener        listener in charge of attending events raised by this instance.
523      * @param method          robust estimator method.
524      * @param <S>             a {@link RadioSource} type.
525      * @return a new robust 3D position radio source estimator.
526      */
527     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
528             final Point3D initialPosition, final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
529             final RobustEstimatorMethod method) {
530         return switch (method) {
531             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
532             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
533             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
534             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
535             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
536         };
537     }
538 
539     /**
540      * Creates a robust 3D position radio source estimator.
541      *
542      * @param readings        signal readings belonging to the same radio source.
543      * @param initialPosition initial position to start the estimation of radio
544      *                        source position.
545      * @param listener        listener in charge of attending events raised by this instance
546      * @param method          robust estimator method.
547      * @param <S>             a {@link RadioSource} type.
548      * @return a new robust 3D position radio source estimator.
549      * @throws IllegalArgumentException if readings are not valid.
550      */
551     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
552             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
553             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
554             final RobustEstimatorMethod method) {
555         return switch (method) {
556             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
557             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
558             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
559             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
560             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
561         };
562     }
563 
564     /**
565      * Creates a robust 3D position radio source estimator.
566      *
567      * @param initialTransmittedPowerdBm initial transmitted power to start the
568      *                                   estimation of radio source transmitted power
569      *                                   (expressed in dBm's).
570      * @param method                     robust estimator method.
571      * @param <S>                        a {@link RadioSource} type.
572      * @return a new robust 3D position radio source estimator.
573      */
574     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
575             final Double initialTransmittedPowerdBm, final RobustEstimatorMethod method) {
576         return switch (method) {
577             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
578             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
579             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
580             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
581             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
582         };
583     }
584 
585     /**
586      * Creates a robust 3D position radio source estimator.
587      *
588      * @param readings                   signal readings belonging to the same radio source.
589      * @param initialTransmittedPowerdBm initial transmitted power to start the
590      *                                   estimation of radio source transmitted power
591      *                                   (expressed in dBm's).
592      * @param method                     robust estimator method.
593      * @param <S>                        a {@link RadioSource} type.
594      * @return a new robust 3D position radio source estimator.
595      * @throws IllegalArgumentException if readings are not valid.
596      */
597     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
598             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
599             final Double initialTransmittedPowerdBm, final RobustEstimatorMethod method) {
600         return switch (method) {
601             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
602             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
603             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
604             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
605             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
606         };
607     }
608 
609     /**
610      * Creates a robust 3D position radio source estimator.
611      *
612      * @param initialTransmittedPowerdBm initial transmitted power to start the
613      *                                   estimation of radio source transmitted power
614      *                                   (expressed in dBm's)
615      * @param listener                   listener in charge of attending events raised by this instance.
616      * @param method                     robust estimator method.
617      * @param <S>                        a {@link RadioSource} type.
618      * @return a new robust 3D position radio source estimator.
619      */
620     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
621             final Double initialTransmittedPowerdBm,
622             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
623             final RobustEstimatorMethod method) {
624         return switch (method) {
625             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
626             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
627             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
628             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
629             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
630         };
631     }
632 
633     /**
634      * Creates a robust 3D position radio source estimator.
635      *
636      * @param readings                   signal readings belonging to the same radio source.
637      * @param initialTransmittedPowerdBm initial transmitted power to start the
638      *                                   estimation of radio source transmitted power
639      *                                   (expressed in dBm's)
640      * @param listener                   listener in charge of attending events raised by this instance.
641      * @param method                     robust estimator method.
642      * @param <S>                        a {@link RadioSource} type.
643      * @return a new robust 3D radio source power and position estimator.
644      * @throws IllegalArgumentException if readings are not valid.
645      */
646     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
647             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
648             final Double initialTransmittedPowerdBm,
649             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
650             final RobustEstimatorMethod method) {
651         return switch (method) {
652             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
653                     listener);
654             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
655                     listener);
656             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
657                     listener);
658             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
659                     listener);
660             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
661                     listener);
662         };
663     }
664 
665     /**
666      * Creates a robust 3D position radio source estimator.
667      *
668      * @param readings                   signal readings belonging to the same radio source.
669      * @param initialPosition            initial position to start the estimation of radio
670      *                                   source position.
671      * @param initialTransmittedPowerdBm initial transmitted power to start the
672      *                                   estimation of radio source transmitted power
673      *                                   (expressed in dBm's).
674      * @param method                     robust estimator method.
675      * @param <S>                        a {@link RadioSource} type.
676      * @return a new robust 3D radio source power and position estimator.
677      * @throws IllegalArgumentException if readings are not valid.
678      */
679     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
680             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
681             final Double initialTransmittedPowerdBm, final RobustEstimatorMethod method) {
682         return switch (method) {
683             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
684                     initialTransmittedPowerdBm);
685             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
686                     initialTransmittedPowerdBm);
687             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
688                     initialTransmittedPowerdBm);
689             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
690                     initialTransmittedPowerdBm);
691             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
692                     initialTransmittedPowerdBm);
693         };
694     }
695 
696     /**
697      * Creates a robust 3D position radio source estimator.
698      *
699      * @param initialPosition            initial position to start the estimation of radio
700      *                                   source position.
701      * @param initialTransmittedPowerdBm initial transmitted power to start the
702      *                                   estimation of radio source transmitted power
703      *                                   (expressed in dBm's).
704      * @param method                     robust estimator method.
705      * @param <S>                        a {@link RadioSource} type.
706      * @return a new robust 3D position radio source estimator.
707      */
708     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
709             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
710             final RobustEstimatorMethod method) {
711         return switch (method) {
712             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
713                     initialTransmittedPowerdBm);
714             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
715                     initialTransmittedPowerdBm);
716             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
717                     initialTransmittedPowerdBm);
718             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
719                     initialTransmittedPowerdBm);
720             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
721                     initialTransmittedPowerdBm);
722         };
723     }
724 
725     /**
726      * Creates a robust 3D position radio source estimator.
727      *
728      * @param initialPosition            initial position to start the estimation of radio
729      *                                   source position.
730      * @param initialTransmittedPowerdBm initial transmitted power to start the
731      *                                   estimation of radio source transmitted power
732      *                                   (expressed in dBm's).
733      * @param listener                   listener in charge of attending events raised by this instance.
734      * @param method                     robust estimator method.
735      * @param <S>                        a {@link RadioSource} type.
736      * @return a new robust 3D position radio source estimator.
737      */
738     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
739             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
740             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
741             final RobustEstimatorMethod method) {
742         return switch (method) {
743             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
744                     initialTransmittedPowerdBm, listener);
745             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
746                     initialTransmittedPowerdBm, listener);
747             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
748                     initialTransmittedPowerdBm, listener);
749             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
750                     initialTransmittedPowerdBm, listener);
751             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
752                     initialTransmittedPowerdBm, listener);
753         };
754     }
755 
756     /**
757      * Creates a robust 3D position radio source estimator.
758      *
759      * @param readings                   signal readings belonging to the same radio source.
760      * @param initialPosition            initial position to start the estimation of radio
761      *                                   source position.
762      * @param initialTransmittedPowerdBm initial transmitted power to start the
763      *                                   estimation of radio source transmitted power
764      *                                   (expressed in dBm's).
765      * @param listener                   listener in charge of attending events raised by this instance.
766      * @param method                     robust estimator method.
767      * @param <S>                        a {@link RadioSource} type.
768      * @return a new robust 3D position radio source estimator.
769      * @throws IllegalArgumentException if readings are not valid.
770      */
771     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
772             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
773             final Double initialTransmittedPowerdBm,
774             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
775             final RobustEstimatorMethod method) {
776         return switch (method) {
777             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
778                     initialTransmittedPowerdBm, listener);
779             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
780                     initialTransmittedPowerdBm, listener);
781             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
782                     initialTransmittedPowerdBm, listener);
783             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
784                     initialTransmittedPowerdBm, listener);
785             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
786                     initialTransmittedPowerdBm, listener);
787         };
788     }
789 
790     /**
791      * Creates a robust 3D position radio source estimator.
792      *
793      * @param readings                   signal readings belonging to the same radio source.
794      * @param initialPosition            initial position to start the estimation of radio
795      *                                   source position.
796      * @param initialTransmittedPowerdBm initial transmitted power to start the
797      *                                   estimation of radio source transmitted power
798      *                                   (expressed in dBm's).
799      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
800      * @param method                     robust estimator method.
801      * @param <S>                        a {@link RadioSource} type.
802      * @return a new robust 3D position radio source estimator.
803      * @throws IllegalArgumentException if readings are not valid.
804      */
805     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
806             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
807             final Double initialTransmittedPowerdBm, final double initialPathLossExponent,
808             final RobustEstimatorMethod method) {
809         return switch (method) {
810             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
811                     initialTransmittedPowerdBm, initialPathLossExponent);
812             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
813                     initialTransmittedPowerdBm, initialPathLossExponent);
814             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
815                     initialTransmittedPowerdBm, initialPathLossExponent);
816             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
817                     initialTransmittedPowerdBm, initialPathLossExponent);
818             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
819                     initialTransmittedPowerdBm, initialPathLossExponent);
820         };
821     }
822 
823     /**
824      * Creates a robust 3D position radio source estimator.
825      *
826      * @param initialPosition            initial position to start the estimation of radio
827      *                                   source position.
828      * @param initialTransmittedPowerdBm initial transmitted power to start the
829      *                                   estimation of radio source transmitted power
830      *                                   (expressed in dBm's).
831      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
832      * @param method                     robust estimator method.
833      * @param <S>                        a {@link RadioSource} type.
834      * @return a new robust 3D position radio source estimator.
835      */
836     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
837             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
838             final double initialPathLossExponent, final RobustEstimatorMethod method) {
839         return switch (method) {
840             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
841                     initialTransmittedPowerdBm, initialPathLossExponent);
842             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
843                     initialTransmittedPowerdBm, initialPathLossExponent);
844             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
845                     initialTransmittedPowerdBm, initialPathLossExponent);
846             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
847                     initialTransmittedPowerdBm, initialPathLossExponent);
848             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
849                     initialTransmittedPowerdBm, initialPathLossExponent);
850         };
851     }
852 
853     /**
854      * Creates a robust 3D position radio source estimator.
855      *
856      * @param initialPosition            initial position to start the estimation of radio
857      *                                   source position.
858      * @param initialTransmittedPowerdBm initial transmitted power to start the
859      *                                   estimation of radio source transmitted power
860      *                                   (expressed in dBm's).
861      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
862      * @param listener                   listener in charge of attending events raised by this instance.
863      * @param method                     robust estimator method.
864      * @param <S>                        a {@link RadioSource} type.
865      * @return a new robust 3D position radio source estimator.
866      */
867     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
868             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
869             final double initialPathLossExponent,
870             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
871             final RobustEstimatorMethod method) {
872         return switch (method) {
873             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
874                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
875             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
876                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
877             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
878                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
879             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
880                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
881             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
882                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
883         };
884     }
885 
886     /**
887      * Creates a robust 3D position radio source estimator.
888      *
889      * @param readings                   signal readings belonging to the same radio source.
890      * @param initialPosition            initial position to start the estimation of radio
891      *                                   source position.
892      * @param initialTransmittedPowerdBm initial transmitted power to start the
893      *                                   estimation of radio source transmitted power
894      *                                   (expressed in dBm's).
895      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
896      * @param listener                   listener in charge of attending events raised by this instance.
897      * @param method                     robust estimator method.
898      * @param <S>                        a {@link RadioSource} type.
899      * @return a new robust 3D position radio source estimator.
900      * @throws IllegalArgumentException if readings are not valid.
901      */
902     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
903             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
904             final Double initialTransmittedPowerdBm, final double initialPathLossExponent,
905             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
906             final RobustEstimatorMethod method) {
907         return switch (method) {
908             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
909                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
910             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
911                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
912             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
913                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
914             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
915                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
916             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
917                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
918         };
919     }
920 
921     /**
922      * Creates a robust 3D position radio source estimator.
923      *
924      * @param qualityScores quality scores corresponding to each provided
925      *                      sample. The larger the score value the better
926      *                      the quality of the sample.
927      * @param method        robust estimator method.
928      * @param <S>           a {@link RadioSource} type.
929      * @return a new robust 3D position radio source estimator.
930      */
931     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
932             final double[] qualityScores, final RobustEstimatorMethod method) {
933         return switch (method) {
934             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>();
935             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>();
936             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>();
937             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores);
938             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores);
939         };
940     }
941 
942     /**
943      * Creates a robust 3D position radio source estimator.
944      *
945      * @param qualityScores quality scores corresponding to each provided
946      *                      sample. The larger the score value the better
947      *                      the quality of the sample.
948      * @param readings      signal readings belonging to the same radio source.
949      * @param method        robust estimator method.
950      * @param <S>           a {@link RadioSource} type.
951      * @return a new robust 3D position radio source estimator.
952      * @throws IllegalArgumentException if readings are not valid.
953      */
954     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
955             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
956             final RobustEstimatorMethod method) {
957         return switch (method) {
958             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
959             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
960             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings);
961             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings);
962             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings);
963         };
964     }
965 
966     /**
967      * Creates a robust 3D position radio source estimator.
968      *
969      * @param qualityScores quality scores corresponding to each provided
970      *                      sample. The larger the score value the better
971      *                      the quality of the sample.
972      * @param listener      listener in charge of attending events raised by this instance.
973      * @param method        robust estimator method.
974      * @param <S>           a {@link RadioSource} type.
975      * @return a new robust 3D position radio source estimator.
976      */
977     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
978             final double[] qualityScores, final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
979             final RobustEstimatorMethod method) {
980         return switch (method) {
981             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
982             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
983             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(listener);
984             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, listener);
985             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, listener);
986         };
987     }
988 
989     /**
990      * Creates a robust 3D position radio source estimator.
991      *
992      * @param qualityScores quality scores corresponding to each provided
993      *                      sample. The larger the score value the better
994      *                      the quality of the sample.
995      * @param readings      signal readings belonging to the same radio source.
996      * @param listener      listener in charge of attending events raised by this instance.
997      * @param method        robust estimator method.
998      * @param <S>           a {@link RadioSource} type.
999      * @return a new robust 3D position radio source estimator.
1000      * @throws IllegalArgumentException if readings are not valid.
1001      */
1002     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1003             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1004             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1005             final RobustEstimatorMethod method) {
1006         return switch (method) {
1007             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
1008             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
1009             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, listener);
1010             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings, listener);
1011             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings, listener);
1012         };
1013     }
1014 
1015     /**
1016      * Creates a robust 3D position radio source estimator.
1017      *
1018      * @param qualityScores   quality scores corresponding to each provided
1019      *                        sample. The larger the score value the better
1020      *                        the quality of the sample.
1021      * @param readings        signal readings belonging to the same radio source.
1022      * @param initialPosition initial position to start the estimation of radio
1023      *                        source position.
1024      * @param method          robust estimator method.
1025      * @param <S>             a {@link RadioSource} type.
1026      * @return a new robust 3D position radio source estimator.
1027      * @throws IllegalArgumentException if readings are not valid.
1028      */
1029     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1030             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1031             final Point3D initialPosition, final RobustEstimatorMethod method) {
1032         return switch (method) {
1033             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
1034             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
1035             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition);
1036             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1037                     initialPosition);
1038             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1039                     initialPosition);
1040         };
1041     }
1042 
1043     /**
1044      * Creates a robust 3D position radio source estimator.
1045      *
1046      * @param qualityScores   quality scores corresponding to each provided
1047      *                        sample. The larger the score value the better
1048      *                        the quality of the sample.
1049      * @param initialPosition initial position to start the estimation of radio
1050      *                        source position.
1051      * @param method          robust estimator method.
1052      * @param <S>             a {@link RadioSource} type.
1053      * @return a new robust 3D position radio source estimator.
1054      */
1055     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1056             final double[] qualityScores, final Point3D initialPosition, final RobustEstimatorMethod method) {
1057         return switch (method) {
1058             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
1059             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
1060             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition);
1061             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition);
1062             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition);
1063         };
1064     }
1065 
1066     /**
1067      * Creates a robust 3D position radio source estimator.
1068      *
1069      * @param qualityScores   quality scores corresponding to each provided
1070      *                        sample. The larger the score value the better
1071      *                        the quality of the sample.
1072      * @param initialPosition initial position to start the estimation of radio
1073      *                        source position.
1074      * @param listener        listener in charge of attending events raised by this instance.
1075      * @param method          robust estimator method.
1076      * @param <S>             a {@link RadioSource} type.
1077      * @return a new robust 3D position radio source estimator.
1078      */
1079     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1080             final double[] qualityScores, final Point3D initialPosition,
1081             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1082             final RobustEstimatorMethod method) {
1083         return switch (method) {
1084             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
1085             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
1086             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition, listener);
1087             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1088                     listener);
1089             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1090                     listener);
1091         };
1092     }
1093 
1094     /**
1095      * Creates a robust 3D position radio source estimator.
1096      *
1097      * @param qualityScores   quality scores corresponding to each provided
1098      *                        sample. The larger the score value the better
1099      *                        the quality of the sample.
1100      * @param readings        signal readings belonging to the same radio source.
1101      * @param initialPosition initial position to start the estimation of radio
1102      *                        source position.
1103      * @param listener        listener in charge of attending events raised by this instance
1104      * @param method          robust estimator method.
1105      * @param <S>             a {@link RadioSource} type.
1106      * @return a new robust 3D position radio source estimator.
1107      * @throws IllegalArgumentException if readings are not valid.
1108      */
1109     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1110             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1111             final Point3D initialPosition, final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1112             final RobustEstimatorMethod method) {
1113         return switch (method) {
1114             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
1115             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
1116             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition, listener);
1117             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1118                     initialPosition, listener);
1119             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1120                     initialPosition, listener);
1121         };
1122     }
1123 
1124     /**
1125      * Creates a robust 3D position radio source estimator.
1126      *
1127      * @param qualityScores              quality scores corresponding to each provided
1128      *                                   sample. The larger the score value the better
1129      *                                   the quality of the sample.
1130      * @param initialTransmittedPowerdBm initial transmitted power to start the
1131      *                                   estimation of access point transmitted power
1132      *                                   (expressed in dBm's).
1133      * @param method                     robust estimator method.
1134      * @param <S>                        a {@link RadioSource} type.
1135      * @return a new robust 3D position radio source estimator.
1136      */
1137     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1138             final double[] qualityScores, final Double initialTransmittedPowerdBm, final RobustEstimatorMethod method) {
1139         return switch (method) {
1140             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
1141             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
1142             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm);
1143             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores,
1144                     initialTransmittedPowerdBm);
1145             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores,
1146                     initialTransmittedPowerdBm);
1147         };
1148     }
1149 
1150     /**
1151      * Creates a robust 3D position radio source estimator.
1152      *
1153      * @param qualityScores              quality scores corresponding to each provided
1154      *                                   sample. The larger the score value the better
1155      *                                   the quality of the sample.
1156      * @param readings                   signal readings belonging to the same radio source.
1157      * @param initialTransmittedPowerdBm initial transmitted power to start the
1158      *                                   estimation of radio source transmitted power
1159      *                                   (expressed in dBm's).
1160      * @param method                     robust estimator method.
1161      * @param <S>                        a {@link RadioSource} type.
1162      * @return a new robust 3D position radio source estimator.
1163      * @throws IllegalArgumentException if readings are not valid.
1164      */
1165     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1166             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1167             final Double initialTransmittedPowerdBm, final RobustEstimatorMethod method) {
1168         return switch (method) {
1169             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
1170             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
1171             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm);
1172             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1173                     initialTransmittedPowerdBm);
1174             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1175                     initialTransmittedPowerdBm);
1176         };
1177     }
1178 
1179     /**
1180      * Creates a robust 3D position radio source estimator.
1181      *
1182      * @param qualityScores              quality scores corresponding to each provided
1183      *                                   sample. The larger the score value the better
1184      *                                   the quality of the sample.
1185      * @param initialTransmittedPowerdBm initial transmitted power to start the
1186      *                                   estimation of radio source transmitted power
1187      *                                   (expressed in dBm's)
1188      * @param listener                   listener in charge of attending events raised by this instance.
1189      * @param method                     robust estimator method.
1190      * @param <S>                        a {@link RadioSource} type.
1191      * @return a new robust 3D position radio source estimator.
1192      */
1193     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1194             final double[] qualityScores, final Double initialTransmittedPowerdBm,
1195             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1196             final RobustEstimatorMethod method) {
1197         return switch (method) {
1198             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
1199             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
1200             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialTransmittedPowerdBm, listener);
1201             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores,
1202                     initialTransmittedPowerdBm, listener);
1203             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores,
1204                     initialTransmittedPowerdBm, listener);
1205         };
1206     }
1207 
1208     /**
1209      * Creates a robust 3D position radio source estimator.
1210      *
1211      * @param qualityScores              quality scores corresponding to each provided
1212      *                                   sample. The larger the score value the better
1213      *                                   the quality of the sample.
1214      * @param readings                   signal readings belonging to the same radio source.
1215      * @param initialTransmittedPowerdBm initial transmitted power to start the
1216      *                                   estimation of radio source transmitted power
1217      *                                   (expressed in dBm's)
1218      * @param listener                   listener in charge of attending events raised by this instance.
1219      * @param method                     robust estimator method.
1220      * @param <S>                        a {@link RadioSource} type.
1221      * @return a new robust 3D position radio source estimator.
1222      * @throws IllegalArgumentException if readings are not valid.
1223      */
1224     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1225             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1226             final Double initialTransmittedPowerdBm,
1227             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1228             final RobustEstimatorMethod method) {
1229         return switch (method) {
1230             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
1231                     listener);
1232             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
1233                     listener);
1234             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialTransmittedPowerdBm,
1235                     listener);
1236             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1237                     initialTransmittedPowerdBm, listener);
1238             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1239                     initialTransmittedPowerdBm, listener);
1240         };
1241     }
1242 
1243     /**
1244      * Creates a robust 3D position radio source estimator.
1245      *
1246      * @param qualityScores              quality scores corresponding to each provided
1247      *                                   sample. The larger the score value the better
1248      *                                   the quality of the sample.
1249      * @param readings                   signal readings belonging to the same radio source.
1250      * @param initialPosition            initial position to start the estimation of radio
1251      *                                   source position.
1252      * @param initialTransmittedPowerdBm initial transmitted power to start the
1253      *                                   estimation of radio source transmitted power
1254      *                                   (expressed in dBm's).
1255      * @param method                     robust estimator method.
1256      * @param <S>                        a {@link RadioSource} type.
1257      * @return a new robust 3D position radio source estimator.
1258      * @throws IllegalArgumentException if readings are not valid.
1259      */
1260     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1261             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1262             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1263             final RobustEstimatorMethod method) {
1264         return switch (method) {
1265             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1266                     initialTransmittedPowerdBm);
1267             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1268                     initialTransmittedPowerdBm);
1269             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1270                     initialTransmittedPowerdBm);
1271             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1272                     initialPosition, initialTransmittedPowerdBm);
1273             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings, initialPosition,
1274                     initialTransmittedPowerdBm);
1275         };
1276     }
1277 
1278     /**
1279      * Creates a robust 3D position radio source estimator.
1280      *
1281      * @param qualityScores              quality scores corresponding to each provided
1282      *                                   sample. The larger the score value the better
1283      *                                   the quality of the sample.
1284      * @param initialPosition            initial position to start the estimation of radio
1285      *                                   source position.
1286      * @param initialTransmittedPowerdBm initial transmitted power to start the
1287      *                                   estimation of radio source transmitted power
1288      *                                   (expressed in dBm's).
1289      * @param method                     robust estimator method.
1290      * @param <S>                        a {@link RadioSource} type.
1291      * @return a new robust 3D position radio source estimator.
1292      */
1293     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1294             final double[] qualityScores, final Point3D initialPosition,
1295             final Double initialTransmittedPowerdBm, RobustEstimatorMethod method) {
1296         return switch (method) {
1297             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1298                     initialTransmittedPowerdBm);
1299             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1300                     initialTransmittedPowerdBm);
1301             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1302                     initialTransmittedPowerdBm);
1303             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1304                     initialTransmittedPowerdBm);
1305             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1306                     initialTransmittedPowerdBm);
1307         };
1308     }
1309 
1310     /**
1311      * Creates a robust 3D position radio source estimator.
1312      *
1313      * @param qualityScores              quality scores corresponding to each provided
1314      *                                   sample. The larger the score value the better
1315      *                                   the quality of the sample.
1316      * @param initialPosition            initial position to start the estimation of radio
1317      *                                   source position.
1318      * @param initialTransmittedPowerdBm initial transmitted power to start the
1319      *                                   estimation of radio source transmitted power
1320      *                                   (expressed in dBm's).
1321      * @param listener                   listener in charge of attending events raised by this instance.
1322      * @param method                     robust estimator method.
1323      * @param <S>                        a {@link RadioSource} type.
1324      * @return a new robust 3D position radio source estimator.
1325      */
1326     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1327             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1328             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1329             final RobustEstimatorMethod method) {
1330         return switch (method) {
1331             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1332                     initialTransmittedPowerdBm, listener);
1333             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1334                     initialTransmittedPowerdBm, listener);
1335             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1336                     initialTransmittedPowerdBm, listener);
1337             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1338                     initialTransmittedPowerdBm, listener);
1339             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1340                     initialTransmittedPowerdBm, listener);
1341         };
1342     }
1343 
1344     /**
1345      * Creates a robust 3D position radio source estimator.
1346      *
1347      * @param qualityScores              quality scores corresponding to each provided
1348      *                                   sample. The larger the score value the better
1349      *                                   the quality of the sample.
1350      * @param readings                   signal readings belonging to the same radio source.
1351      * @param initialPosition            initial position to start the estimation of radio
1352      *                                   source position.
1353      * @param initialTransmittedPowerdBm initial transmitted power to start the
1354      *                                   estimation of radio source transmitted power
1355      *                                   (expressed in dBm's).
1356      * @param listener                   listener in charge of attending events raised by this instance.
1357      * @param method                     robust estimator method.
1358      * @param <S>                        a {@link RadioSource} type.
1359      * @return a new robust 3D position radio source estimator.
1360      * @throws IllegalArgumentException if readings are not valid.
1361      */
1362     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1363             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1364             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1365             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1366             final RobustEstimatorMethod method) {
1367         return switch (method) {
1368             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1369                     initialTransmittedPowerdBm, listener);
1370             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1371                     initialTransmittedPowerdBm, listener);
1372             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1373                     initialTransmittedPowerdBm, listener);
1374             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1375                     initialPosition, initialTransmittedPowerdBm, listener);
1376             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1377                     initialPosition, initialTransmittedPowerdBm, listener);
1378         };
1379     }
1380 
1381     /**
1382      * Creates a robust 3D position radio source estimator.
1383      *
1384      * @param qualityScores              quality scores corresponding to each provided
1385      *                                   sample. The larger the score value the better
1386      *                                   the quality of the sample.
1387      * @param readings                   signal readings belonging to the same radio source.
1388      * @param initialPosition            initial position to start the estimation of radio
1389      *                                   source position.
1390      * @param initialTransmittedPowerdBm initial transmitted power to start the
1391      *                                   estimation of radio source transmitted power
1392      *                                   (expressed in dBm's).
1393      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1394      * @param method                     robust estimator method.
1395      * @param <S>                        a {@link RadioSource} type.
1396      * @return a new robust 3D position radio source estimator.
1397      * @throws IllegalArgumentException if readings are not valid.
1398      */
1399     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1400             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1401             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1402             final double initialPathLossExponent, final RobustEstimatorMethod method) {
1403         return switch (method) {
1404             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1405                     initialTransmittedPowerdBm, initialPathLossExponent);
1406             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1407                     initialTransmittedPowerdBm, initialPathLossExponent);
1408             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1409                     initialTransmittedPowerdBm, initialPathLossExponent);
1410             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1411                     initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
1412             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings, initialPosition,
1413                     initialTransmittedPowerdBm, initialPathLossExponent);
1414         };
1415     }
1416 
1417     /**
1418      * Creates a robust 3D position radio source estimator.
1419      *
1420      * @param qualityScores              quality scores corresponding to each provided
1421      *                                   sample. The larger the score value the better
1422      *                                   the quality of the sample.
1423      * @param initialPosition            initial position to start the estimation of radio
1424      *                                   source position.
1425      * @param initialTransmittedPowerdBm initial transmitted power to start the
1426      *                                   estimation of radio source transmitted power
1427      *                                   (expressed in dBm's).
1428      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1429      * @param method                     robust estimator method.
1430      * @param <S>                        a {@link RadioSource} type.
1431      * @return a new robust 3D position radio source estimator.
1432      */
1433     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1434             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1435             final double initialPathLossExponent, final RobustEstimatorMethod method) {
1436         return switch (method) {
1437             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1438                     initialTransmittedPowerdBm, initialPathLossExponent);
1439             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1440                     initialTransmittedPowerdBm, initialPathLossExponent);
1441             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1442                     initialTransmittedPowerdBm, initialPathLossExponent);
1443             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1444                     initialTransmittedPowerdBm, initialPathLossExponent);
1445             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1446                     initialTransmittedPowerdBm, initialPathLossExponent);
1447         };
1448     }
1449 
1450     /**
1451      * Creates a robust 3D position radio source estimator.
1452      *
1453      * @param qualityScores              quality scores corresponding to each provided
1454      *                                   sample. The larger the score value the better
1455      *                                   the quality of the sample.
1456      * @param initialPosition            initial position to start the estimation of radio
1457      *                                   source position.
1458      * @param initialTransmittedPowerdBm initial transmitted power to start the
1459      *                                   estimation of radio source transmitted power
1460      *                                   (expressed in dBm's).
1461      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1462      * @param listener                   listener in charge of attending events raised by this instance.
1463      * @param method                     robust estimator method.
1464      * @param <S>                        a {@link RadioSource} type.
1465      * @return a new robust 3D position radio source estimator.
1466      */
1467     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1468             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1469             final double initialPathLossExponent,
1470             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1471             final RobustEstimatorMethod method) {
1472         return switch (method) {
1473             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1474                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1475             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1476                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1477             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(initialPosition,
1478                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1479             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1480                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1481             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, initialPosition,
1482                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1483         };
1484     }
1485 
1486     /**
1487      * Creates a robust 3D position radio source estimator.
1488      *
1489      * @param qualityScores              quality scores corresponding to each provided
1490      *                                   sample. The larger the score value the better
1491      *                                   the quality of the sample.
1492      * @param readings                   signal readings belonging to the same radio source.
1493      * @param initialPosition            initial position to start the estimation of radio
1494      *                                   source position.
1495      * @param initialTransmittedPowerdBm initial transmitted power to start the
1496      *                                   estimation of radio source transmitted power
1497      *                                   (expressed in dBm's).
1498      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1499      * @param listener                   listener in charge of attending events raised by this instance.
1500      * @param method                     robust estimator method.
1501      * @param <S>                        a {@link RadioSource} type.
1502      * @return a new robust 3D position radio source estimator.
1503      * @throws IllegalArgumentException if readings are not valid.
1504      */
1505     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1506             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1507             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1508             final double initialPathLossExponent,
1509             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener,
1510             final RobustEstimatorMethod method) {
1511         return switch (method) {
1512             case RANSAC -> new RANSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1513                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1514             case LMEDS -> new LMedSRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1515                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1516             case MSAC -> new MSACRobustRangingAndRssiRadioSourceEstimator3D<>(readings, initialPosition,
1517                     initialTransmittedPowerdBm, initialPathLossExponent, listener);
1518             case PROSAC -> new PROSACRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1519                     initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
1520             default -> new PROMedSRobustRangingAndRssiRadioSourceEstimator3D<>(qualityScores, readings,
1521                     initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
1522         };
1523     }
1524 
1525     /**
1526      * Creates a robust 3D position radio source estimator using
1527      * default method.
1528      *
1529      * @param <S> a {@link RadioSource} type.
1530      * @return a new robust 3D position radio source estimator.
1531      */
1532     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create() {
1533         return create(DEFAULT_ROBUST_METHOD);
1534     }
1535 
1536     /**
1537      * Creates a robust 3D position radio source estimator using
1538      * default method.
1539      *
1540      * @param readings signal readings belonging to the same radio source.
1541      * @param <S>      a {@link RadioSource} type.
1542      * @return a new robust 3D position radio source estimator.
1543      * @throws IllegalArgumentException if readings are not valid.
1544      */
1545     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1546             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings) {
1547         return create(readings, DEFAULT_ROBUST_METHOD);
1548     }
1549 
1550     /**
1551      * Creates a robust 3D position radio source estimator using
1552      * default method.
1553      *
1554      * @param listener listener in charge of attending events raised by this instance.
1555      * @param <S>      a {@link RadioSource} type.
1556      * @return a new robust 3D position radio source estimator.
1557      */
1558     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1559             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1560         return create(listener, DEFAULT_ROBUST_METHOD);
1561     }
1562 
1563     /**
1564      * Creates a robust 3D position radio source estimator using
1565      * default method.
1566      *
1567      * @param readings signal readings belonging to the same radio source.
1568      * @param listener listener in charge of attending events raised by this instance.
1569      * @param <S>      a {@link RadioSource} type.
1570      * @return a new robust 3D position radio source estimator.
1571      * @throws IllegalArgumentException if readings are not valid.
1572      */
1573     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1574             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1575             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1576         return create(readings, listener, DEFAULT_ROBUST_METHOD);
1577     }
1578 
1579     /**
1580      * Creates a robust 3D position radio source estimator using
1581      * default method.
1582      *
1583      * @param readings        signal readings belonging to the same radio source.
1584      * @param initialPosition initial position to start the estimation of radio
1585      *                        source position.
1586      * @param <S>             a {@link RadioSource} type.
1587      * @return a new robust 3D position radio source estimator.
1588      * @throws IllegalArgumentException if readings are not valid.
1589      */
1590     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1591             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition) {
1592         return create(readings, initialPosition, DEFAULT_ROBUST_METHOD);
1593     }
1594 
1595     /**
1596      * Creates a robust 3D position radio source estimator using
1597      * default method.
1598      *
1599      * @param initialPosition initial position to start the estimation of radio
1600      *                        source position.
1601      * @param <S>             a {@link RadioSource} type.
1602      * @return a new robust 3D position radio source estimator.
1603      */
1604     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1605             final Point3D initialPosition) {
1606         return create(initialPosition, DEFAULT_ROBUST_METHOD);
1607     }
1608 
1609     /**
1610      * Creates a robust 3D position radio source estimator using
1611      * default method.
1612      *
1613      * @param initialPosition initial position to start the estimation of radio
1614      *                        source position.
1615      * @param listener        listener in charge of attending events raised by this instance.
1616      * @param <S>             a {@link RadioSource} type.
1617      * @return a new robust 3D position radio source estimator.
1618      */
1619     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1620             final Point3D initialPosition,
1621             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1622         return create(initialPosition, listener, DEFAULT_ROBUST_METHOD);
1623     }
1624 
1625     /**
1626      * Creates a robust 3D position radio source estimator using
1627      * default method.
1628      *
1629      * @param readings        signal readings belonging to the same radio source.
1630      * @param initialPosition initial position to start the estimation of radio
1631      *                        source position.
1632      * @param listener        listener in charge of attending events raised by this instance
1633      * @param <S>             a {@link RadioSource} type.
1634      * @return a new robust 3D position radio source estimator.
1635      * @throws IllegalArgumentException if readings are not valid.
1636      */
1637     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1638             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
1639             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1640         return create(readings, initialPosition, listener, DEFAULT_ROBUST_METHOD);
1641     }
1642 
1643     /**
1644      * Creates a robust 3D position radio source estimator using
1645      * default method.
1646      *
1647      * @param initialTransmittedPowerdBm initial transmitted power to start the
1648      *                                   estimation of radio source transmitted power
1649      *                                   (expressed in dBm's).
1650      * @param <S>                        a {@link RadioSource} type.
1651      * @return a new robust 3D position radio source estimator.
1652      */
1653     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1654             final Double initialTransmittedPowerdBm) {
1655         return create(initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
1656     }
1657 
1658     /**
1659      * Creates a robust 3D position radio source estimator using
1660      * default method.
1661      *
1662      * @param readings                   signal readings belonging to the same radio source.
1663      * @param initialTransmittedPowerdBm initial transmitted power to start the
1664      *                                   estimation of radio source transmitted power
1665      *                                   (expressed in dBm's).
1666      * @param <S>                        a {@link RadioSource} type.
1667      * @return a new robust 3D position radio source estimator.
1668      * @throws IllegalArgumentException if readings are not valid.
1669      */
1670     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1671             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1672             final Double initialTransmittedPowerdBm) {
1673         return create(readings, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
1674     }
1675 
1676     /**
1677      * Creates a robust 3D position radio source estimator using
1678      * default method.
1679      *
1680      * @param initialTransmittedPowerdBm initial transmitted power to start the
1681      *                                   estimation of radio source transmitted power
1682      *                                   (expressed in dBm's)
1683      * @param listener                   listener in charge of attending events raised by this instance.
1684      * @param <S>                        a {@link RadioSource} type.
1685      * @return a new robust 3D position radio source estimator.
1686      */
1687     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1688             final Double initialTransmittedPowerdBm,
1689             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1690         return create(initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
1691     }
1692 
1693     /**
1694      * Creates a robust 3D position radio source estimator using
1695      * default method.
1696      *
1697      * @param readings                   signal readings belonging to the same radio source.
1698      * @param initialTransmittedPowerdBm initial transmitted power to start the
1699      *                                   estimation of radio source transmitted power
1700      *                                   (expressed in dBm's)
1701      * @param listener                   listener in charge of attending events raised by this instance.
1702      * @param <S>                        a {@link RadioSource} type.
1703      * @return a new robust 3D position radio source estimator.
1704      * @throws IllegalArgumentException if readings are not valid.
1705      */
1706     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1707             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1708             final Double initialTransmittedPowerdBm,
1709             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1710         return create(readings, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
1711     }
1712 
1713     /**
1714      * Creates a robust 3D position radio source estimator using
1715      * default method.
1716      *
1717      * @param readings                   signal readings belonging to the same radio source.
1718      * @param initialPosition            initial position to start the estimation of radio
1719      *                                   source position.
1720      * @param initialTransmittedPowerdBm initial transmitted power to start the
1721      *                                   estimation of radio source transmitted power
1722      *                                   (expressed in dBm's).
1723      * @param <S>                        a {@link RadioSource} type.
1724      * @return a new robust 3D position radio source estimator.
1725      * @throws IllegalArgumentException if readings are not valid.
1726      */
1727     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1728             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
1729             final Double initialTransmittedPowerdBm) {
1730         return create(readings, initialPosition, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
1731     }
1732 
1733     /**
1734      * Creates a robust 3D position radio source estimator using
1735      * default method.
1736      *
1737      * @param initialPosition            initial position to start the estimation of radio
1738      *                                   source position.
1739      * @param initialTransmittedPowerdBm initial transmitted power to start the
1740      *                                   estimation of radio source transmitted power
1741      *                                   (expressed in dBm's).
1742      * @param <S>                        a {@link RadioSource} type.
1743      * @return a new robust 3D position radio source estimator.
1744      */
1745     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1746             final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
1747         return create(initialPosition, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
1748     }
1749 
1750     /**
1751      * Creates a robust 3D position radio source estimator using
1752      * default method.
1753      *
1754      * @param initialPosition            initial position to start the estimation of radio
1755      *                                   source position.
1756      * @param initialTransmittedPowerdBm initial transmitted power to start the
1757      *                                   estimation of radio source transmitted power
1758      *                                   (expressed in dBm's).
1759      * @param listener                   listener in charge of attending events raised by this instance.
1760      * @param <S>                        a {@link RadioSource} type.
1761      * @return a new robust 3D position radio source estimator.
1762      */
1763     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1764             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1765             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1766         return create(initialPosition, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
1767     }
1768 
1769     /**
1770      * Creates a robust 3D position radio source estimator using
1771      * default method.
1772      *
1773      * @param readings                   signal readings belonging to the same radio source.
1774      * @param initialPosition            initial position to start the estimation of radio
1775      *                                   source position.
1776      * @param initialTransmittedPowerdBm initial transmitted power to start the
1777      *                                   estimation of radio source transmitted power
1778      *                                   (expressed in dBm's).
1779      * @param listener                   listener in charge of attending events raised by this instance.
1780      * @param <S>                        a {@link RadioSource} type.
1781      * @return a new robust 3D position radio source estimator.
1782      * @throws IllegalArgumentException if readings are not valid.
1783      */
1784     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1785             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
1786             final Double initialTransmittedPowerdBm,
1787             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1788         return create(readings, initialPosition, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
1789     }
1790 
1791     /**
1792      * Creates a robust 3D position radio source estimator using
1793      * default method.
1794      *
1795      * @param readings                   signal readings belonging to the same radio source.
1796      * @param initialPosition            initial position to start the estimation of radio
1797      *                                   source position.
1798      * @param initialTransmittedPowerdBm initial transmitted power to start the
1799      *                                   estimation of radio source transmitted power
1800      *                                   (expressed in dBm's).
1801      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1802      * @param <S>                        a {@link RadioSource} type.
1803      * @return a new robust 3D position radio source estimator.
1804      * @throws IllegalArgumentException if readings are not valid.
1805      */
1806     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1807             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
1808             final Double initialTransmittedPowerdBm, final double initialPathLossExponent) {
1809         return create(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent,
1810                 DEFAULT_ROBUST_METHOD);
1811     }
1812 
1813     /**
1814      * Creates a robust 3D position radio source estimator using
1815      * default method.
1816      *
1817      * @param initialPosition            initial position to start the estimation of radio
1818      *                                   source position.
1819      * @param initialTransmittedPowerdBm initial transmitted power to start the
1820      *                                   estimation of radio source transmitted power
1821      *                                   (expressed in dBm's).
1822      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1823      * @param <S>                        a {@link RadioSource} type.
1824      * @return a new robust 3D position radio source estimator.
1825      */
1826     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1827             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1828             final double initialPathLossExponent) {
1829         return create(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, DEFAULT_ROBUST_METHOD);
1830     }
1831 
1832     /**
1833      * Creates a robust 3D position radio source estimator using
1834      * default method.
1835      *
1836      * @param initialPosition            initial position to start the estimation of radio
1837      *                                   source position.
1838      * @param initialTransmittedPowerdBm initial transmitted power to start the
1839      *                                   estimation of radio source transmitted power
1840      *                                   (expressed in dBm's).
1841      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1842      * @param listener                   listener in charge of attending events raised by this instance.
1843      * @param <S>                        a {@link RadioSource} type.
1844      * @return a new robust 3D position radio source estimator.
1845      */
1846     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1847             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
1848             final double initialPathLossExponent,
1849             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1850         return create(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener,
1851                 DEFAULT_ROBUST_METHOD);
1852     }
1853 
1854     /**
1855      * Creates a robust 3D position radio source estimator using
1856      * default method.
1857      *
1858      * @param readings                   signal readings belonging to the same radio source.
1859      * @param initialPosition            initial position to start the estimation of radio
1860      *                                   source position.
1861      * @param initialTransmittedPowerdBm initial transmitted power to start the
1862      *                                   estimation of radio source transmitted power
1863      *                                   (expressed in dBm's).
1864      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
1865      * @param listener                   listener in charge of attending events raised by this instance.
1866      * @param <S>                        a {@link RadioSource} type.
1867      * @return a new robust 3D position radio source estimator.
1868      * @throws IllegalArgumentException if readings are not valid.
1869      */
1870     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1871             final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings, final Point3D initialPosition,
1872             final Double initialTransmittedPowerdBm, final double initialPathLossExponent,
1873             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1874         return create(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener,
1875                 DEFAULT_ROBUST_METHOD);
1876     }
1877 
1878     /**
1879      * Creates a robust 3D position radio source estimator using
1880      * default method.
1881      *
1882      * @param qualityScores quality scores corresponding to each provided
1883      *                      sample. The larger the score value the better
1884      *                      the quality of the sample.
1885      * @param <S>           a {@link RadioSource} type.
1886      * @return a new robust 3D position radio source estimator.
1887      */
1888     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1889             final double[] qualityScores) {
1890         return create(qualityScores, DEFAULT_ROBUST_METHOD);
1891     }
1892 
1893     /**
1894      * Creates a robust 3D position radio source estimator using
1895      * default method.
1896      *
1897      * @param qualityScores quality scores corresponding to each provided
1898      *                      sample. The larger the score value the better
1899      *                      the quality of the sample.
1900      * @param readings      signal readings belonging to the same radio source.
1901      * @param <S>           a {@link RadioSource} type.
1902      * @return a new robust 3D position radio source estimator.
1903      * @throws IllegalArgumentException if readings are not valid.
1904      */
1905     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1906             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings) {
1907         return create(qualityScores, readings, DEFAULT_ROBUST_METHOD);
1908     }
1909 
1910     /**
1911      * Creates a robust 3D position radio source estimator using
1912      * default method.
1913      *
1914      * @param qualityScores quality scores corresponding to each provided
1915      *                      sample. The larger the score value the better
1916      *                      the quality of the sample.
1917      * @param listener      listener in charge of attending events raised by this instance.
1918      * @param <S>           a {@link RadioSource} type.
1919      * @return a new robust 3D position radio source estimator.
1920      */
1921     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1922             final double[] qualityScores, final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1923         return create(qualityScores, listener, DEFAULT_ROBUST_METHOD);
1924     }
1925 
1926     /**
1927      * Creates a robust 3D position radio source estimator using
1928      * default method.
1929      *
1930      * @param qualityScores quality scores corresponding to each provided
1931      *                      sample. The larger the score value the better
1932      *                      the quality of the sample.
1933      * @param readings      signal readings belonging to the same radio source.
1934      * @param listener      listener in charge of attending events raised by this instance.
1935      * @param <S>           a {@link RadioSource} type.
1936      * @return a new robust 3D position radio source estimator.
1937      * @throws IllegalArgumentException if readings are not valid.
1938      */
1939     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1940             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1941             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1942         return create(qualityScores, readings, listener, DEFAULT_ROBUST_METHOD);
1943     }
1944 
1945     /**
1946      * Creates a robust 3D position radio source estimator using
1947      * default method.
1948      *
1949      * @param qualityScores   quality scores corresponding to each provided
1950      *                        sample. The larger the score value the better
1951      *                        the quality of the sample.
1952      * @param readings        signal readings belonging to the same radio source.
1953      * @param initialPosition initial position to start the estimation of radio
1954      *                        source position.
1955      * @param <S>             a {@link RadioSource} type.
1956      * @return a new robust 3D position radio source estimator.
1957      * @throws IllegalArgumentException if readings are not valid.
1958      */
1959     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1960             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
1961             final Point3D initialPosition) {
1962         return create(qualityScores, readings, initialPosition, DEFAULT_ROBUST_METHOD);
1963     }
1964 
1965     /**
1966      * Creates a robust 3D position radio source estimator using
1967      * default method.
1968      *
1969      * @param qualityScores   quality scores corresponding to each provided
1970      *                        sample. The larger the score value the better
1971      *                        the quality of the sample.
1972      * @param initialPosition initial position to start the estimation of radio
1973      *                        source position.
1974      * @param <S>             a {@link RadioSource} type.
1975      * @return a new robust 3D position radio source estimator.
1976      */
1977     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1978             final double[] qualityScores, final Point3D initialPosition) {
1979         return create(qualityScores, initialPosition, DEFAULT_ROBUST_METHOD);
1980     }
1981 
1982     /**
1983      * Creates a robust 3D position radio source estimator using
1984      * default method.
1985      *
1986      * @param qualityScores   quality scores corresponding to each provided
1987      *                        sample. The larger the score value the better
1988      *                        the quality of the sample.
1989      * @param initialPosition initial position to start the estimation of radio
1990      *                        source position.
1991      * @param listener        listener in charge of attending events raised by this instance.
1992      * @param <S>             a {@link RadioSource} type.
1993      * @return a new robust 3D position radio source estimator.
1994      */
1995     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
1996             final double[] qualityScores, final Point3D initialPosition,
1997             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
1998         return create(qualityScores, initialPosition, listener, DEFAULT_ROBUST_METHOD);
1999     }
2000 
2001     /**
2002      * Creates a robust 3D position radio source estimator using
2003      * default method.
2004      *
2005      * @param qualityScores   quality scores corresponding to each provided
2006      *                        sample. The larger the score value the better
2007      *                        the quality of the sample.
2008      * @param readings        signal readings belonging to the same radio source.
2009      * @param initialPosition initial position to start the estimation of radio
2010      *                        source position.
2011      * @param listener        listener in charge of attending events raised by this instance
2012      * @param <S>             a {@link RadioSource} type.
2013      * @return a new robust 3D position radio source estimator.
2014      * @throws IllegalArgumentException if readings are not valid.
2015      */
2016     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2017             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2018             final Point3D initialPosition,
2019             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2020         return create(qualityScores, readings, initialPosition, listener, DEFAULT_ROBUST_METHOD);
2021     }
2022 
2023     /**
2024      * Creates a robust 3D position radio source estimator using
2025      * default method.
2026      *
2027      * @param qualityScores              quality scores corresponding to each provided
2028      *                                   sample. The larger the score value the better
2029      *                                   the quality of the sample.
2030      * @param initialTransmittedPowerdBm initial transmitted power to start the
2031      *                                   estimation of radio source transmitted power
2032      *                                   (expressed in dBm's).
2033      * @param <S>                        a {@link RadioSource} type.
2034      * @return a new robust 3D position radio source estimator.
2035      */
2036     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2037             final double[] qualityScores, final Double initialTransmittedPowerdBm) {
2038         return create(qualityScores, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
2039     }
2040 
2041     /**
2042      * Creates a robust 3D position radio source estimator using
2043      * default method.
2044      *
2045      * @param qualityScores              quality scores corresponding to each provided
2046      *                                   sample. The larger the score value the better
2047      *                                   the quality of the sample.
2048      * @param readings                   signal readings belonging to the same radio source.
2049      * @param initialTransmittedPowerdBm initial transmitted power to start the
2050      *                                   estimation of radio source transmitted power
2051      *                                   (expressed in dBm's).
2052      * @param <S>                        a {@link RadioSource} type.
2053      * @return a new robust 3D position radio source estimator.
2054      * @throws IllegalArgumentException if readings are not valid.
2055      */
2056     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2057             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2058             final Double initialTransmittedPowerdBm) {
2059         return create(qualityScores, readings, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
2060     }
2061 
2062     /**
2063      * Creates a robust 3D position radio source estimator using
2064      * default method.
2065      *
2066      * @param qualityScores              quality scores corresponding to each provided
2067      *                                   sample. The larger the score value the better
2068      *                                   the quality of the sample.
2069      * @param initialTransmittedPowerdBm initial transmitted power to start the
2070      *                                   estimation of radio source transmitted power
2071      *                                   (expressed in dBm's)
2072      * @param listener                   listener in charge of attending events raised by this instance.
2073      * @param <S>                        a {@link RadioSource} type.
2074      * @return a new robust 3D position radio source estimator.
2075      */
2076     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2077             final double[] qualityScores, final Double initialTransmittedPowerdBm,
2078             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2079         return create(qualityScores, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
2080     }
2081 
2082     /**
2083      * Creates a robust 3D position radio source estimator using
2084      * default method.
2085      *
2086      * @param qualityScores              quality scores corresponding to each provided
2087      *                                   sample. The larger the score value the better
2088      *                                   the quality of the sample.
2089      * @param readings                   signal readings belonging to the same radio source.
2090      * @param initialTransmittedPowerdBm initial transmitted power to start the
2091      *                                   estimation of radio source transmitted power
2092      *                                   (expressed in dBm's)
2093      * @param listener                   listener in charge of attending events raised by this instance.
2094      * @param <S>                        a {@link RadioSource} type.
2095      * @return a new robust 3D position radio source estimator.
2096      * @throws IllegalArgumentException if readings are not valid.
2097      */
2098     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2099             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2100             final Double initialTransmittedPowerdBm,
2101             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2102         return create(qualityScores, readings, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
2103     }
2104 
2105     /**
2106      * Creates a robust 3D position radio source estimator using
2107      * default method.
2108      *
2109      * @param qualityScores              quality scores corresponding to each provided
2110      *                                   sample. The larger the score value the better
2111      *                                   the quality of the sample.
2112      * @param readings                   signal readings belonging to the same radio source.
2113      * @param initialPosition            initial position to start the estimation of radio
2114      *                                   source position.
2115      * @param initialTransmittedPowerdBm initial transmitted power to start the
2116      *                                   estimation of radio source transmitted power
2117      *                                   (expressed in dBm's).
2118      * @param <S>                        a {@link RadioSource} type.
2119      * @return a new robust 3D position radio source estimator.
2120      * @throws IllegalArgumentException if readings are not valid.
2121      */
2122     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2123             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2124             final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
2125         return create(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
2126     }
2127 
2128     /**
2129      * Creates a robust 3D position radio source estimator using
2130      * default method.
2131      *
2132      * @param qualityScores              quality scores corresponding to each provided
2133      *                                   sample. The larger the score value the better
2134      *                                   the quality of the sample.
2135      * @param initialPosition            initial position to start the estimation of radio
2136      *                                   source position.
2137      * @param initialTransmittedPowerdBm initial transmitted power to start the
2138      *                                   estimation of radio source transmitted power
2139      *                                   (expressed in dBm's).
2140      * @param <S>                        a {@link RadioSource} type.
2141      * @return a new robust 3D position radio source estimator.
2142      */
2143     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2144             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
2145         return create(qualityScores, initialPosition, initialTransmittedPowerdBm, DEFAULT_ROBUST_METHOD);
2146     }
2147 
2148     /**
2149      * Creates a robust 3D position radio source estimator using
2150      * default method.
2151      *
2152      * @param qualityScores              quality scores corresponding to each provided
2153      *                                   sample. The larger the score value the better
2154      *                                   the quality of the sample.
2155      * @param initialPosition            initial position to start the estimation of radio
2156      *                                   source position.
2157      * @param initialTransmittedPowerdBm initial transmitted power to start the
2158      *                                   estimation of radio source transmitted power
2159      *                                   (expressed in dBm's).
2160      * @param listener                   listener in charge of attending events raised by this instance.
2161      * @param <S>                        a {@link RadioSource} type.
2162      * @return a new robust 3D position radio source estimator.
2163      */
2164     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2165             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2166             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2167         return create(qualityScores, initialPosition, initialTransmittedPowerdBm, listener, DEFAULT_ROBUST_METHOD);
2168     }
2169 
2170     /**
2171      * Creates a robust 3D position radio source estimator using
2172      * default method.
2173      *
2174      * @param qualityScores              quality scores corresponding to each provided
2175      *                                   sample. The larger the score value the better
2176      *                                   the quality of the sample.
2177      * @param readings                   signal readings belonging to the same radio source.
2178      * @param initialPosition            initial position to start the estimation of radio
2179      *                                   source position.
2180      * @param initialTransmittedPowerdBm initial transmitted power to start the
2181      *                                   estimation of radio source transmitted power
2182      *                                   (expressed in dBm's).
2183      * @param listener                   listener in charge of attending events raised by this instance.
2184      * @param <S>                        a {@link RadioSource} type.
2185      * @return a new robust 3D position radio source estimator.
2186      * @throws IllegalArgumentException if readings are not valid.
2187      */
2188     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2189             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2190             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2191             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2192         return create(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, listener,
2193                 DEFAULT_ROBUST_METHOD);
2194     }
2195 
2196     /**
2197      * Creates a robust 3D position radio source estimator using
2198      * default method.
2199      *
2200      * @param qualityScores              quality scores corresponding to each provided
2201      *                                   sample. The larger the score value the better
2202      *                                   the quality of the sample.
2203      * @param readings                   signal readings belonging to the same radio source.
2204      * @param initialPosition            initial position to start the estimation of radio
2205      *                                   source position.
2206      * @param initialTransmittedPowerdBm initial transmitted power to start the
2207      *                                   estimation of radio source transmitted power
2208      *                                   (expressed in dBm's).
2209      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
2210      * @param <S>                        a {@link RadioSource} type.
2211      * @return a new robust 3D position radio source estimator.
2212      * @throws IllegalArgumentException if readings are not valid.
2213      */
2214     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2215             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2216             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2217             final double initialPathLossExponent) {
2218         return create(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent,
2219                 DEFAULT_ROBUST_METHOD);
2220     }
2221 
2222     /**
2223      * Creates a robust 3D position radio source estimator using
2224      * default method.
2225      *
2226      * @param qualityScores              quality scores corresponding to each provided
2227      *                                   sample. The larger the score value the better
2228      *                                   the quality of the sample.
2229      * @param initialPosition            initial position to start the estimation of radio
2230      *                                   source position.
2231      * @param initialTransmittedPowerdBm initial transmitted power to start the
2232      *                                   estimation of radio source transmitted power
2233      *                                   (expressed in dBm's).
2234      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
2235      * @param <S>                        a {@link RadioSource} type.
2236      * @return a new robust 3D position radio source estimator.
2237      */
2238     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2239             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2240             final double initialPathLossExponent) {
2241         return create(qualityScores, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent,
2242                 DEFAULT_ROBUST_METHOD);
2243     }
2244 
2245     /**
2246      * Creates a robust 3D position radio source estimator using
2247      * default method.
2248      *
2249      * @param qualityScores              quality scores corresponding to each provided
2250      *                                   sample. The larger the score value the better
2251      *                                   the quality of the sample.
2252      * @param initialPosition            initial position to start the estimation of radio
2253      *                                   source position.
2254      * @param initialTransmittedPowerdBm initial transmitted power to start the
2255      *                                   estimation of radio source transmitted power
2256      *                                   (expressed in dBm's).
2257      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
2258      * @param listener                   listener in charge of attending events raised by this instance.
2259      * @param <S>                        a {@link RadioSource} type.
2260      * @return a new robust 3D position radio source estimator.
2261      */
2262     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2263             final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2264             final double initialPathLossExponent,
2265             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2266         return create(qualityScores, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener,
2267                 DEFAULT_ROBUST_METHOD);
2268     }
2269 
2270     /**
2271      * Creates a robust 3D position radio source estimator using
2272      * default method.
2273      *
2274      * @param qualityScores              quality scores corresponding to each provided
2275      *                                   sample. The larger the score value the better
2276      *                                   the quality of the sample.
2277      * @param readings                   signal readings belonging to the same radio source.
2278      * @param initialPosition            initial position to start the estimation of radio
2279      *                                   source position.
2280      * @param initialTransmittedPowerdBm initial transmitted power to start the
2281      *                                   estimation of radio source transmitted power
2282      *                                   (expressed in dBm's).
2283      * @param initialPathLossExponent    initial path loss exponent. A typical value is 2.0.
2284      * @param listener                   listener in charge of attending events raised by this instance.
2285      * @param <S>                        a {@link RadioSource} type.
2286      * @return a new robust 3D position radio source estimator.
2287      * @throws IllegalArgumentException if readings are not valid.
2288      */
2289     public static <S extends RadioSource> RobustRangingAndRssiRadioSourceEstimator3D<S> create(
2290             final double[] qualityScores, final List<? extends RangingAndRssiReadingLocated<S, Point3D>> readings,
2291             final Point3D initialPosition, final Double initialTransmittedPowerdBm,
2292             final double initialPathLossExponent,
2293             final RobustRangingAndRssiRadioSourceEstimatorListener<S, Point3D> listener) {
2294         return create(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent,
2295                 listener, DEFAULT_ROBUST_METHOD);
2296     }
2297 
2298     /**
2299      * Indicates whether an homogeneous linear solver is used to estimate an initial
2300      * position for the internal ranging radio source estimator.
2301      *
2302      * @return true if homogeneous linear solver is used, false if an inhomogeneous linear
2303      * one is used instead.
2304      */
2305     @Override
2306     public boolean isHomogeneousRangingLinearSolverUsed() {
2307         return innerEstimator.isHomogeneousRangingLinearSolverUsed();
2308     }
2309 
2310     /**
2311      * Specifies whether an homogeneous linear solver is used to estimate an initial
2312      * position for the internal ranging radio source estimator.
2313      *
2314      * @param useHomogeneousLinearSolver true if homogeneous linear solver is used, false
2315      *                                   if an inhomogeneous linear one is used instead.
2316      * @throws LockedException if estimator is locked.
2317      */
2318     @Override
2319     public void setHomogeneousRangingLinearSolverUsed(final boolean useHomogeneousLinearSolver) throws LockedException {
2320         if (isLocked()) {
2321             throw new LockedException();
2322         }
2323 
2324         innerEstimator.setHomogeneousRangingLinearSolverUsed(useHomogeneousLinearSolver);
2325     }
2326 
2327     /**
2328      * Gets minimum required number of readings to estimate
2329      * power, position and path-loss exponent.
2330      * This value depends on the number of parameters to
2331      * be estimated, but for position only, this is 3
2332      * readings.
2333      *
2334      * @return minimum required number of readings.
2335      */
2336     @Override
2337     public int getMinReadings() {
2338         var minReadings = Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;
2339         if (isTransmittedPowerEstimationEnabled()) {
2340             minReadings++;
2341         }
2342         if (isPathLossEstimationEnabled()) {
2343             minReadings++;
2344         }
2345         return ++minReadings;
2346     }
2347 
2348     /**
2349      * Gets number of dimensions of position points.
2350      *
2351      * @return always returns 2 dimensions.
2352      */
2353     @Override
2354     public int getNumberOfDimensions() {
2355         return innerEstimator.getNumberOfDimensions();
2356     }
2357 
2358     /**
2359      * Gets estimated located radio source with estimated transmitted power.
2360      *
2361      * @return estimated located radio source with estimated transmitted power or null.
2362      */
2363     @Override
2364     @SuppressWarnings("unchecked")
2365     public RadioSourceWithPowerAndLocated<Point3D> getEstimatedRadioSource() {
2366         final var readings = getReadings();
2367         if (readings == null || readings.isEmpty()) {
2368             return null;
2369         }
2370         final var source = readings.get(0).getSource();
2371 
2372         final var estimatedPosition = getEstimatedPosition();
2373         if (estimatedPosition == null) {
2374             return null;
2375         }
2376 
2377         final var estimatedPositionCovariance = getEstimatedPositionCovariance();
2378 
2379         final var transmittedPowerVariance = getEstimatedTransmittedPowerVariance();
2380         final var transmittedPowerStandardDeviation = transmittedPowerVariance != null
2381                 ? Math.sqrt(transmittedPowerVariance) : null;
2382 
2383         final var pathlossExponentVariance = getEstimatedPathLossExponentVariance();
2384         final var pathlossExponentStandardDeviation = pathlossExponentVariance != null
2385                 ? Math.sqrt(pathlossExponentVariance) : null;
2386 
2387         if (source instanceof WifiAccessPoint accessPoint) {
2388             return new WifiAccessPointWithPowerAndLocated3D(accessPoint.getBssid(), source.getFrequency(),
2389                     accessPoint.getSsid(), getEstimatedTransmittedPowerdBm(), transmittedPowerStandardDeviation,
2390                     getEstimatedPathLossExponent(), pathlossExponentStandardDeviation, estimatedPosition,
2391                     estimatedPositionCovariance);
2392         } else if (source instanceof Beacon beacon) {
2393             return new BeaconWithPowerAndLocated3D(beacon.getIdentifiers(), getEstimatedTransmittedPowerdBm(),
2394                     beacon.getFrequency(), beacon.getBluetoothAddress(), beacon.getBeaconTypeCode(),
2395                     beacon.getManufacturer(), beacon.getServiceUuid(), beacon.getBluetoothName(),
2396                     getEstimatedPathLossExponent(), transmittedPowerStandardDeviation,
2397                     pathlossExponentStandardDeviation, estimatedPosition, estimatedPositionCovariance);
2398         } else {
2399             return null;
2400         }
2401     }
2402 
2403     /**
2404      * Solves preliminary solution for a subset of samples.
2405      *
2406      * @param samplesIndices indices of subset samples.
2407      * @param solutions      instance where solution will be stored.
2408      */
2409     @Override
2410     protected void solvePreliminarySolutions(final int[] samplesIndices, final List<Solution<Point3D>> solutions) {
2411 
2412         try {
2413             innerReadings.clear();
2414             for (final var samplesIndex : samplesIndices) {
2415                 innerReadings.add(readings.get(samplesIndex));
2416             }
2417 
2418             // initial transmitted power and position might or might not be available
2419             innerEstimator.setInitialTransmittedPowerdBm(initialTransmittedPowerdBm);
2420             innerEstimator.setInitialPosition(initialPosition);
2421             innerEstimator.setInitialPathLossExponent(initialPathLossExponent);
2422 
2423             innerEstimator.setTransmittedPowerEstimationEnabled(transmittedPowerEstimationEnabled);
2424             innerEstimator.setPathLossEstimationEnabled(pathLossEstimationEnabled);
2425 
2426             innerEstimator.setReadings(innerReadings);
2427 
2428             // indicates whether readings position covariances must be taken into account
2429             innerEstimator.setUseReadingPositionCovariances(useReadingPositionCovariances);
2430 
2431             innerEstimator.estimate();
2432 
2433             final var estimatedPosition = innerEstimator.getEstimatedPosition();
2434             final var estimatedTransmittedPowerdBm = innerEstimator.getEstimatedTransmittedPowerdBm();
2435             final var estimatedPathLossExponent = innerEstimator.getEstimatedPathLossExponent();
2436             solutions.add(new Solution<>(estimatedPosition, estimatedTransmittedPowerdBm, estimatedPathLossExponent));
2437         } catch (final NavigationException ignore) {
2438             // if anything fails, no solution is added
2439         }
2440     }
2441 
2442     /**
2443      * Attempts to refine estimated position and transmitted power contained in
2444      * provided solution if refinement is requested.
2445      * This method sets a refined result and transmitted power or provided input
2446      * result if refinement is not requested or has failed.
2447      * If refinement is enabled, and it is requested to keep covariance, this method
2448      * will also keep covariance of refined result.
2449      * solution if not requested or refinement failed.
2450      *
2451      * @param result result to be refined.
2452      */
2453     protected void attemptRefine(final Solution<Point3D> result) {
2454         final var initialPosition = result.getEstimatedPosition();
2455         final var initialTransmittedPowerdBm = result.getEstimatedTransmittedPowerdBm();
2456         final var initialPathLossExponent = result.getEstimatedPathLossExponent();
2457 
2458         if (refineResult && inliersData != null) {
2459             final var inliers = inliersData.getInliers();
2460             final var nSamples = readings.size();
2461 
2462             innerReadings.clear();
2463 
2464             for (var i = 0; i < nSamples; i++) {
2465                 if (inliers.get(i)) {
2466                     // sample is inlier
2467                     innerReadings.add(readings.get(i));
2468                 }
2469             }
2470 
2471             try {
2472                 innerEstimator.setInitialPosition(initialPosition);
2473                 innerEstimator.setInitialTransmittedPowerdBm(initialTransmittedPowerdBm);
2474                 innerEstimator.setInitialPathLossExponent(initialPathLossExponent);
2475                 innerEstimator.setTransmittedPowerEstimationEnabled(transmittedPowerEstimationEnabled);
2476                 innerEstimator.setPathLossEstimationEnabled(pathLossEstimationEnabled);
2477                 innerEstimator.setReadings(innerReadings);
2478                 innerEstimator.setUseReadingPositionCovariances(useReadingPositionCovariances);
2479 
2480                 innerEstimator.estimate();
2481 
2482                 final var cov = innerEstimator.getEstimatedCovariance();
2483                 if (keepCovariance && cov != null) {
2484                     // keep covariance
2485                     covariance = cov;
2486 
2487                     final var dims = getNumberOfDimensions();
2488                     var pos = 0;
2489 
2490                     final var d = dims - 1;
2491                     if (estimatedPositionCovariance == null) {
2492                         estimatedPositionCovariance = covariance.getSubmatrix(0, 0, d, d);
2493                     } else {
2494                         covariance.getSubmatrix(0, 0, d, d, estimatedPositionCovariance);
2495                     }
2496                     pos += dims;
2497 
2498                     if (transmittedPowerEstimationEnabled) {
2499                         // transmitted power estimation enabled
2500                         estimatedTransmittedPowerVariance = covariance.getElementAt(pos, pos);
2501                         pos++;
2502                     } else {
2503                         // transmitted power estimation disabled
2504                         estimatedTransmittedPowerVariance = null;
2505                     }
2506 
2507                     if (pathLossEstimationEnabled) {
2508                         // path-loss exponent estimation enabled
2509                         estimatedPathLossExponentVariance = covariance.getElementAt(pos, pos);
2510                     } else {
2511                         // path-loss exponent estimation disabled
2512                         estimatedPathLossExponentVariance = null;
2513                     }
2514                 } else {
2515                     covariance = null;
2516                     estimatedPositionCovariance = null;
2517                     estimatedTransmittedPowerVariance = null;
2518                     estimatedPathLossExponentVariance = null;
2519                 }
2520 
2521                 estimatedPosition = innerEstimator.getEstimatedPosition();
2522                 estimatedTransmittedPowerdBm = innerEstimator.getEstimatedTransmittedPowerdBm();
2523                 estimatedPathLossExponent = innerEstimator.getEstimatedPathLossExponent();
2524             } catch (final Exception e) {
2525                 // refinement failed, so we return input value, and covariance
2526                 // becomes unavailable
2527                 covariance = null;
2528                 estimatedPositionCovariance = null;
2529                 estimatedTransmittedPowerVariance = null;
2530                 estimatedPathLossExponentVariance = null;
2531 
2532                 estimatedPosition = initialPosition;
2533                 estimatedTransmittedPowerdBm = initialTransmittedPowerdBm;
2534                 estimatedPathLossExponent = initialPathLossExponent;
2535             }
2536         } else {
2537             covariance = null;
2538             estimatedPositionCovariance = null;
2539             estimatedTransmittedPowerVariance = null;
2540             estimatedPathLossExponentVariance = null;
2541 
2542             estimatedPosition = initialPosition;
2543             estimatedTransmittedPowerdBm = initialTransmittedPowerdBm;
2544             estimatedPathLossExponent = initialPathLossExponent;
2545         }
2546     }
2547 }