Vector1D.java

  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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.geometry.euclidean.oned;

  22. import java.text.NumberFormat;

  23. import org.hipparchus.geometry.Space;
  24. import org.hipparchus.geometry.Vector;
  25. import org.hipparchus.util.FastMath;
  26. import org.hipparchus.util.MathUtils;

  27. /** This class represents a 1D vector.
  28.  * <p>Instances of this class are guaranteed to be immutable.</p>
  29.  */
  30. public class Vector1D implements Vector<Euclidean1D, Vector1D> {

  31.     /** Origin (coordinates: 0). */
  32.     public static final Vector1D ZERO = new Vector1D(0.0);

  33.     /** Unit (coordinates: 1). */
  34.     public static final Vector1D ONE  = new Vector1D(1.0);

  35.     // CHECKSTYLE: stop ConstantName
  36.     /** A vector with all coordinates set to NaN. */
  37.     public static final Vector1D NaN = new Vector1D(Double.NaN);
  38.     // CHECKSTYLE: resume ConstantName

  39.     /** A vector with all coordinates set to positive infinity. */
  40.     public static final Vector1D POSITIVE_INFINITY =
  41.         new Vector1D(Double.POSITIVE_INFINITY);

  42.     /** A vector with all coordinates set to negative infinity. */
  43.     public static final Vector1D NEGATIVE_INFINITY =
  44.         new Vector1D(Double.NEGATIVE_INFINITY);

  45.     /** Serializable UID. */
  46.     private static final long serialVersionUID = 7556674948671647925L;

  47.     /** Abscissa. */
  48.     private final double x;

  49.     /** Simple constructor.
  50.      * Build a vector from its coordinates
  51.      * @param x abscissa
  52.      * @see #getX()
  53.      */
  54.     public Vector1D(double x) {
  55.         this.x = x;
  56.     }

  57.     /** Multiplicative constructor
  58.      * Build a vector from another one and a scale factor.
  59.      * The vector built will be a * u
  60.      * @param a scale factor
  61.      * @param u base (unscaled) vector
  62.      */
  63.     public Vector1D(double a, Vector1D u) {
  64.         this.x = a * u.x;
  65.     }

  66.     /** Linear constructor
  67.      * Build a vector from two other ones and corresponding scale factors.
  68.      * The vector built will be a1 * u1 + a2 * u2
  69.      * @param a1 first scale factor
  70.      * @param u1 first base (unscaled) vector
  71.      * @param a2 second scale factor
  72.      * @param u2 second base (unscaled) vector
  73.      */
  74.     public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2) {
  75.         this.x = a1 * u1.x + a2 * u2.x;
  76.     }

  77.     /** Linear constructor
  78.      * Build a vector from three other ones and corresponding scale factors.
  79.      * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
  80.      * @param a1 first scale factor
  81.      * @param u1 first base (unscaled) vector
  82.      * @param a2 second scale factor
  83.      * @param u2 second base (unscaled) vector
  84.      * @param a3 third scale factor
  85.      * @param u3 third base (unscaled) vector
  86.      */
  87.     public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
  88.                    double a3, Vector1D u3) {
  89.         this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
  90.     }

  91.     /** Linear constructor
  92.      * Build a vector from four other ones and corresponding scale factors.
  93.      * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
  94.      * @param a1 first scale factor
  95.      * @param u1 first base (unscaled) vector
  96.      * @param a2 second scale factor
  97.      * @param u2 second base (unscaled) vector
  98.      * @param a3 third scale factor
  99.      * @param u3 third base (unscaled) vector
  100.      * @param a4 fourth scale factor
  101.      * @param u4 fourth base (unscaled) vector
  102.      */
  103.     public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
  104.                    double a3, Vector1D u3, double a4, Vector1D u4) {
  105.         this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
  106.     }

  107.     /** Get the abscissa of the vector.
  108.      * @return abscissa of the vector
  109.      * @see #Vector1D(double)
  110.      */
  111.     public double getX() {
  112.         return x;
  113.     }

  114.     /** {@inheritDoc} */
  115.     @Override
  116.     public Space getSpace() {
  117.         return Euclidean1D.getInstance();
  118.     }

  119.     /** {@inheritDoc} */
  120.     @Override
  121.     public Vector1D getZero() {
  122.         return ZERO;
  123.     }

  124.     /** {@inheritDoc} */
  125.     @Override
  126.     public double getNorm1() {
  127.         return FastMath.abs(x);
  128.     }

  129.     /** {@inheritDoc} */
  130.     @Override
  131.     public double getNorm() {
  132.         return FastMath.abs(x);
  133.     }

  134.     /** {@inheritDoc} */
  135.     @Override
  136.     public double getNormSq() {
  137.         return x * x;
  138.     }

  139.     /** {@inheritDoc} */
  140.     @Override
  141.     public double getNormInf() {
  142.         return FastMath.abs(x);
  143.     }

  144.     /** {@inheritDoc} */
  145.     @Override
  146.     public Vector1D add(Vector1D v) {
  147.         return new Vector1D(x + v.getX());
  148.     }

  149.     /** {@inheritDoc} */
  150.     @Override
  151.     public Vector1D add(double factor, Vector1D v) {
  152.         return new Vector1D(x + factor * v.getX());
  153.     }

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     public Vector1D subtract(Vector1D p) {
  157.         return new Vector1D(x - p.x);
  158.     }

  159.     /** {@inheritDoc} */
  160.     @Override
  161.     public Vector1D subtract(double factor, Vector1D v) {
  162.         return new Vector1D(x - factor * v.getX());
  163.     }

  164.     /** {@inheritDoc} */
  165.     @Override
  166.     public Vector1D negate() {
  167.         return new Vector1D(-x);
  168.     }

  169.     /** {@inheritDoc} */
  170.     @Override
  171.     public Vector1D scalarMultiply(double a) {
  172.         return new Vector1D(a * x);
  173.     }

  174.     /** {@inheritDoc} */
  175.     @Override
  176.     public boolean isNaN() {
  177.         return Double.isNaN(x);
  178.     }

  179.     /** {@inheritDoc} */
  180.     @Override
  181.     public boolean isInfinite() {
  182.         return !isNaN() && Double.isInfinite(x);
  183.     }

  184.     /** {@inheritDoc} */
  185.     @Override
  186.     public double distance1(Vector1D p) {
  187.         return FastMath.abs(p.x - x);
  188.     }

  189.     /** {@inheritDoc} */
  190.     @Override
  191.     public double distance(Vector1D p) {
  192.         return FastMath.abs(p.x - x);
  193.     }

  194.     /** {@inheritDoc} */
  195.     @Override
  196.     public double distanceInf(Vector1D p) {
  197.         return FastMath.abs(p.x - x);
  198.     }

  199.     /** {@inheritDoc} */
  200.     @Override
  201.     public double distanceSq(Vector1D p) {
  202.         final double dx = p.x - x;
  203.         return dx * dx;
  204.     }

  205.     /** {@inheritDoc} */
  206.     @Override
  207.     public double dotProduct(final Vector1D v) {
  208.         return x * v.x;
  209.     }

  210.     /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
  211.      * <p>Calling this method is equivalent to calling:
  212.      * <code>p1.subtract(p2).getNorm()</code> except that no intermediate
  213.      * vector is built</p>
  214.      * @param p1 first vector
  215.      * @param p2 second vector
  216.      * @return the distance between p1 and p2 according to the L<sub>2</sub> norm
  217.      */
  218.     public static double distance(Vector1D p1, Vector1D p2) {
  219.         return p1.distance(p2);
  220.     }

  221.     /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
  222.      * <p>Calling this method is equivalent to calling:
  223.      * <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
  224.      * vector is built</p>
  225.      * @param p1 first vector
  226.      * @param p2 second vector
  227.      * @return the distance between p1 and p2 according to the L<sub>&infin;</sub> norm
  228.      */
  229.     public static double distanceInf(Vector1D p1, Vector1D p2) {
  230.         return p1.distanceInf(p2);
  231.     }

  232.     /** Compute the square of the distance between two vectors.
  233.      * <p>Calling this method is equivalent to calling:
  234.      * <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
  235.      * vector is built</p>
  236.      * @param p1 first vector
  237.      * @param p2 second vector
  238.      * @return the square of the distance between p1 and p2
  239.      */
  240.     public static double distanceSq(Vector1D p1, Vector1D p2) {
  241.         return p1.distanceSq(p2);
  242.     }

  243.     /** {@inheritDoc} */
  244.     @Override
  245.     public Vector1D moveTowards(final Vector1D other, final double ratio) {
  246.         return new Vector1D(x + ratio * (other.x - x));
  247.     }

  248.     /**
  249.      * Test for the equality of two 1D vectors.
  250.      * <p>
  251.      * If all coordinates of two 1D vectors are exactly the same, and none are
  252.      * {@code Double.NaN}, the two 1D vectors are considered to be equal.
  253.      * </p>
  254.      * <p>
  255.      * {@code NaN} coordinates are considered to affect globally the vector
  256.      * and be equals to each other - i.e, if either (or all) coordinates of the
  257.      * 1D vector are equal to {@code Double.NaN}, the 1D vector is equal to
  258.      * {@link #NaN}.
  259.      * </p>
  260.      *
  261.      * @param other Object to test for equality to this
  262.      * @return true if two 1D vector objects are equal, false if
  263.      *         object is null, not an instance of Vector1D, or
  264.      *         not equal to this Vector1D instance
  265.      */
  266.     @Override
  267.     public boolean equals(Object other) {

  268.         if (this == other) {
  269.             return true;
  270.         }

  271.         if (other instanceof Vector1D) {
  272.             final Vector1D rhs = (Vector1D) other;
  273.             return x == rhs.x || isNaN() && rhs.isNaN();
  274.         }

  275.         return false;

  276.     }

  277.     /**
  278.      * Test for the equality of two 1D vectors.
  279.      * <p>
  280.      * If all coordinates of two 1D vectors are exactly the same, and none are
  281.      * {@code NaN}, the two 1D vectors are considered to be equal.
  282.      * </p>
  283.      * <p>
  284.      * In compliance with IEEE754 handling, if any coordinates of any of the
  285.      * two vectors are {@code NaN}, then the vectors are considered different.
  286.      * This implies that {@link #NaN Vector1D.NaN}.equals({@link #NaN Vector1D.NaN})
  287.      * returns {@code false} despite the instance is checked against itself.
  288.      * </p>
  289.      *
  290.      * @param other Object to test for equality to this
  291.      * @return true if two 1D vector objects are equal, false if
  292.      *         object is null, not an instance of Vector1D, or
  293.      *         not equal to this Vector1D instance
  294.      *
  295.      * @since 2.1
  296.      */
  297.     public boolean equalsIeee754(Object other) {

  298.         if (this == other && !isNaN()) {
  299.             return true;
  300.         }

  301.         if (other instanceof Vector1D) {
  302.             final Vector1D rhs = (Vector1D) other;
  303.             return x == rhs.x;
  304.         }

  305.         return false;

  306.     }

  307.     /**
  308.      * Get a hashCode for the 1D vector.
  309.      * <p>
  310.      * All NaN values have the same hash code.</p>
  311.      *
  312.      * @return a hash code value for this object
  313.      */
  314.     @Override
  315.     public int hashCode() {
  316.         if (isNaN()) {
  317.             return 7785;
  318.         }
  319.         return 997 * MathUtils.hash(x);
  320.     }

  321.     /** Get a string representation of this vector.
  322.      * @return a string representation of this vector
  323.      */
  324.     @Override
  325.     public String toString() {
  326.         return Vector1DFormat.getVector1DFormat().format(this);
  327.     }

  328.     /** {@inheritDoc} */
  329.     @Override
  330.     public String toString(final NumberFormat format) {
  331.         return new Vector1DFormat(format).format(this);
  332.     }

  333. }