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