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>∞</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>∞</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 }