1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.estimation.measurements;
18  
19  import org.orekit.time.TimeStamped;
20  
21  
22  /** Base interface for comparing measurements regardless of their type.
23   * @author Luc Maisonobe
24   * @author Evan M. Ward
25   * @since 9.2
26   */
27  public interface ComparableMeasurement extends TimeStamped, Comparable<ComparableMeasurement> {
28  
29      /** Get the observed value.
30       * <p>
31       * The observed value is the value that was measured by the instrument.
32       * </p>
33       * @return observed value
34       */
35      double[] getObservedValue();
36  
37      /** Set the observed value.
38       * <p>
39       * The observed value is the value that was measured by the instrument.
40       * </p>
41       * @param newObserved observed value
42       * @since 13.0
43       */
44      void setObservedValue(double[] newObserved);
45  
46      /**
47       * {@inheritDoc}
48       *
49       * <p>Measurements comparison is primarily chronological, but measurements with
50       * the same date are sorted based on the observed value. Even if they have
51       * the same value too, they will <em>likely</em> not be considered equal if
52       * they correspond to different instances.
53       *
54       * <p>Care should be taken before storing measurements in a
55       * {@link java.util.SortedSet SortedSet} as it may lose redundant
56       * measurements if they, by chance, have the same identity hash code.
57       *
58       * @see System#identityHashCode(Object)
59       */
60      @Override
61      default int compareTo(final ComparableMeasurement other) {
62  
63          if (this == other) {
64              // quick return for comparing a measurement to itself
65              return 0;
66          }
67  
68          // Compare date first
69          int result = getDate().compareTo(other.getDate());
70          if (result != 0) {
71              return result;
72          }
73  
74          // Simultaneous measurements, we compare the size of the measurements
75          final double[] thisV  = getObservedValue();
76          final double[] otherV = other.getObservedValue();
77          // "Bigger" measurements after "smaller" measurement
78          if (thisV.length > otherV.length) {
79              return +1;
80          } else if (thisV.length < otherV.length) {
81              return -1;
82          }
83  
84          // Measurements have same size
85          // Compare the first different value
86          // "Bigger" measurements after "smaller" measurement
87          for (int i = 0; i < thisV.length; ++i) {
88              result = Double.compare(thisV[i], otherV[i]);
89              if (result != 0) {
90                  return result;
91              }
92          }
93  
94          // Measurements have the same value,
95          // but we do not want them to appear as equal
96          // we set up an arbitrary order based on hash code
97          result = Integer.compare(this.hashCode(), other.hashCode());
98          if (result != 0) {
99              return result;
100         }
101         // next try identity hash code
102         result = Integer.compare(
103                 System.identityHashCode(this),
104                 System.identityHashCode(other));
105         // Tried all the fields to compare, and though we want an arbitrary
106         // total order, we still must obey the contract of compareTo, see #1364.
107         // So this may return zero if this==other, or for equal objects that by
108         // chance have the same identity hash code.
109         return result;
110 
111     }
112 
113 }