View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF 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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.geometry.euclidean.oned;
23  
24  import java.text.NumberFormat;
25  
26  import org.hipparchus.geometry.Point;
27  import org.hipparchus.geometry.Space;
28  import org.hipparchus.geometry.Vector;
29  import org.hipparchus.util.FastMath;
30  import org.hipparchus.util.MathUtils;
31  
32  /** This class represents a 1D vector.
33   * <p>Instances of this class are guaranteed to be immutable.</p>
34   */
35  public class Vector1D implements Vector<Euclidean1D, Vector1D> {
36  
37      /** Origin (coordinates: 0). */
38      public static final Vector1D ZERO = new Vector1D(0.0);
39  
40      /** Unit (coordinates: 1). */
41      public static final Vector1D ONE  = new Vector1D(1.0);
42  
43      // CHECKSTYLE: stop ConstantName
44      /** A vector with all coordinates set to NaN. */
45      public static final Vector1D NaN = new Vector1D(Double.NaN);
46      // CHECKSTYLE: resume ConstantName
47  
48      /** A vector with all coordinates set to positive infinity. */
49      public static final Vector1D POSITIVE_INFINITY =
50          new Vector1D(Double.POSITIVE_INFINITY);
51  
52      /** A vector with all coordinates set to negative infinity. */
53      public static final Vector1D NEGATIVE_INFINITY =
54          new Vector1D(Double.NEGATIVE_INFINITY);
55  
56      /** Serializable UID. */
57      private static final long serialVersionUID = 7556674948671647925L;
58  
59      /** Abscissa. */
60      private final double x;
61  
62      /** Simple constructor.
63       * Build a vector from its coordinates
64       * @param x abscissa
65       * @see #getX()
66       */
67      public Vector1D(double x) {
68          this.x = x;
69      }
70  
71      /** Multiplicative constructor
72       * Build a vector from another one and a scale factor.
73       * The vector built will be a * u
74       * @param a scale factor
75       * @param u base (unscaled) vector
76       */
77      public Vector1D(double a, Vector1D u) {
78          this.x = a * u.x;
79      }
80  
81      /** Linear constructor
82       * Build a vector from two other ones and corresponding scale factors.
83       * The vector built will be a1 * u1 + a2 * u2
84       * @param a1 first scale factor
85       * @param u1 first base (unscaled) vector
86       * @param a2 second scale factor
87       * @param u2 second base (unscaled) vector
88       */
89      public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2) {
90          this.x = a1 * u1.x + a2 * u2.x;
91      }
92  
93      /** Linear constructor
94       * Build a vector from three other ones and corresponding scale factors.
95       * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
96       * @param a1 first scale factor
97       * @param u1 first base (unscaled) vector
98       * @param a2 second scale factor
99       * @param u2 second base (unscaled) vector
100      * @param a3 third scale factor
101      * @param u3 third base (unscaled) vector
102      */
103     public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
104                    double a3, Vector1D u3) {
105         this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
106     }
107 
108     /** Linear constructor
109      * Build a vector from four other ones and corresponding scale factors.
110      * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
111      * @param a1 first scale factor
112      * @param u1 first base (unscaled) vector
113      * @param a2 second scale factor
114      * @param u2 second base (unscaled) vector
115      * @param a3 third scale factor
116      * @param u3 third base (unscaled) vector
117      * @param a4 fourth scale factor
118      * @param u4 fourth base (unscaled) vector
119      */
120     public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
121                    double a3, Vector1D u3, double a4, Vector1D u4) {
122         this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
123     }
124 
125     /** Get the abscissa of the vector.
126      * @return abscissa of the vector
127      * @see #Vector1D(double)
128      */
129     public double getX() {
130         return x;
131     }
132 
133     /** {@inheritDoc} */
134     @Override
135     public Space getSpace() {
136         return Euclidean1D.getInstance();
137     }
138 
139     /** {@inheritDoc} */
140     @Override
141     public Vector1D getZero() {
142         return ZERO;
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     public double getNorm1() {
148         return FastMath.abs(x);
149     }
150 
151     /** {@inheritDoc} */
152     @Override
153     public double getNorm() {
154         return FastMath.abs(x);
155     }
156 
157     /** {@inheritDoc} */
158     @Override
159     public double getNormSq() {
160         return x * x;
161     }
162 
163     /** {@inheritDoc} */
164     @Override
165     public double getNormInf() {
166         return FastMath.abs(x);
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     public Vector1D add(Vector<Euclidean1D, Vector1D> v) {
172         Vector1D v1 = (Vector1D) v;
173         return new Vector1D(x + v1.getX());
174     }
175 
176     /** {@inheritDoc} */
177     @Override
178     public Vector1D add(double factor, Vector<Euclidean1D, Vector1D> v) {
179         Vector1D v1 = (Vector1D) v;
180         return new Vector1D(x + factor * v1.getX());
181     }
182 
183     /** {@inheritDoc} */
184     @Override
185     public Vector1D subtract(Vector<Euclidean1D, Vector1D> p) {
186         Vector1D p3 = (Vector1D) p;
187         return new Vector1D(x - p3.x);
188     }
189 
190     /** {@inheritDoc} */
191     @Override
192     public Vector1D subtract(double factor, Vector<Euclidean1D, Vector1D> v) {
193         Vector1D v1 = (Vector1D) v;
194         return new Vector1D(x - factor * v1.getX());
195     }
196 
197     /** {@inheritDoc} */
198     @Override
199     public Vector1D negate() {
200         return new Vector1D(-x);
201     }
202 
203     /** {@inheritDoc} */
204     @Override
205     public Vector1D scalarMultiply(double a) {
206         return new Vector1D(a * x);
207     }
208 
209     /** {@inheritDoc} */
210     @Override
211     public boolean isNaN() {
212         return Double.isNaN(x);
213     }
214 
215     /** {@inheritDoc} */
216     @Override
217     public boolean isInfinite() {
218         return !isNaN() && Double.isInfinite(x);
219     }
220 
221     /** {@inheritDoc} */
222     @Override
223     public double distance1(Vector<Euclidean1D, Vector1D> p) {
224         Vector1D p3 = (Vector1D) p;
225         return FastMath.abs(p3.x - x);
226     }
227 
228     /** {@inheritDoc} */
229     @Override
230     public double distance(Point<Euclidean1D> p) {
231         Vector1D p3 = (Vector1D) p;
232         return FastMath.abs(p3.x - x);
233     }
234 
235     /** {@inheritDoc} */
236     @Override
237     public double distanceInf(Vector<Euclidean1D, Vector1D> p) {
238         Vector1D p3 = (Vector1D) p;
239         return FastMath.abs(p3.x - x);
240     }
241 
242     /** {@inheritDoc} */
243     @Override
244     public double distanceSq(Vector<Euclidean1D, Vector1D> p) {
245         Vector1D p3 = (Vector1D) p;
246         final double dx = p3.x - x;
247         return dx * dx;
248     }
249 
250     /** {@inheritDoc} */
251     @Override
252     public double dotProduct(final Vector<Euclidean1D, Vector1D> v) {
253         final Vector1D v1 = (Vector1D) v;
254         return x * v1.x;
255     }
256 
257     /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
258      * <p>Calling this method is equivalent to calling:
259      * <code>p1.subtract(p2).getNorm()</code> except that no intermediate
260      * vector is built</p>
261      * @param p1 first vector
262      * @param p2 second vector
263      * @return the distance between p1 and p2 according to the L<sub>2</sub> norm
264      */
265     public static double distance(Vector1D p1, Vector1D p2) {
266         return p1.distance(p2);
267     }
268 
269     /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
270      * <p>Calling this method is equivalent to calling:
271      * <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
272      * vector is built</p>
273      * @param p1 first vector
274      * @param p2 second vector
275      * @return the distance between p1 and p2 according to the L<sub>&infin;</sub> norm
276      */
277     public static double distanceInf(Vector1D p1, Vector1D p2) {
278         return p1.distanceInf(p2);
279     }
280 
281     /** Compute the square of the distance between two vectors.
282      * <p>Calling this method is equivalent to calling:
283      * <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
284      * vector is built</p>
285      * @param p1 first vector
286      * @param p2 second vector
287      * @return the square of the distance between p1 and p2
288      */
289     public static double distanceSq(Vector1D p1, Vector1D p2) {
290         return p1.distanceSq(p2);
291     }
292 
293     /**
294      * Test for the equality of two 1D vectors.
295      * <p>
296      * If all coordinates of two 1D vectors are exactly the same, and none are
297      * {@code Double.NaN}, the two 1D vectors are considered to be equal.
298      * </p>
299      * <p>
300      * {@code NaN} coordinates are considered to affect globally the vector
301      * and be equals to each other - i.e, if either (or all) coordinates of the
302      * 1D vector are equal to {@code Double.NaN}, the 1D vector is equal to
303      * {@link #NaN}.
304      * </p>
305      *
306      * @param other Object to test for equality to this
307      * @return true if two 1D vector objects are equal, false if
308      *         object is null, not an instance of Vector1D, or
309      *         not equal to this Vector1D instance
310      */
311     @Override
312     public boolean equals(Object other) {
313 
314         if (this == other) {
315             return true;
316         }
317 
318         if (other instanceof Vector1D) {
319             final Vector1D rhs = (Vector1D) other;
320             return x == rhs.x || isNaN() && rhs.isNaN();
321         }
322 
323         return false;
324 
325     }
326 
327     /**
328      * Test for the equality of two 1D vectors.
329      * <p>
330      * If all coordinates of two 1D vectors are exactly the same, and none are
331      * {@code NaN}, the two 1D vectors are considered to be equal.
332      * </p>
333      * <p>
334      * In compliance with IEEE754 handling, if any coordinates of any of the
335      * two vectors are {@code NaN}, then the vectors are considered different.
336      * This implies that {@link #NaN Vector1D.NaN}.equals({@link #NaN Vector1D.NaN})
337      * returns {@code false} despite the instance is checked against itself.
338      * </p>
339      *
340      * @param other Object to test for equality to this
341      * @return true if two 1D vector objects are equal, false if
342      *         object is null, not an instance of Vector1D, or
343      *         not equal to this Vector1D instance
344      *
345      * @since 2.1
346      */
347     public boolean equalsIeee754(Object other) {
348 
349         if (this == other && !isNaN()) {
350             return true;
351         }
352 
353         if (other instanceof Vector1D) {
354             final Vector1D rhs = (Vector1D) other;
355             return x == rhs.x;
356         }
357 
358         return false;
359 
360     }
361 
362     /**
363      * Get a hashCode for the 1D vector.
364      * <p>
365      * All NaN values have the same hash code.</p>
366      *
367      * @return a hash code value for this object
368      */
369     @Override
370     public int hashCode() {
371         if (isNaN()) {
372             return 7785;
373         }
374         return 997 * MathUtils.hash(x);
375     }
376 
377     /** Get a string representation of this vector.
378      * @return a string representation of this vector
379      */
380     @Override
381     public String toString() {
382         return Vector1DFormat.getVector1DFormat().format(this);
383     }
384 
385     /** {@inheritDoc} */
386     @Override
387     public String toString(final NumberFormat format) {
388         return new Vector1DFormat(format).format(this);
389     }
390 
391 }