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    *      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.apache.commons.geometry.euclidean.internal;
    18
    19  import org.apache.commons.geometry.core.Vector;
    20  import org.apache.commons.numbers.arrays.SafeNorm;
    21
    22  /** This class consists exclusively of static vector utility methods.
    23   */
    24  public final class Vectors {
    25
    26      /** Private constructor. */
    27      private Vectors() {}
    28
    29      /** Returns true if the given value is real (ie, not NaN or infinite)
    30       * and not equal to zero.
    31       * @param value the value to test
    32       * @return true if {@code value} is not NaN, infinite, or zero; otherwise
    33       *      false
    34       */
    35      public static boolean isRealNonZero(final double value) {
    36          return Double.isFinite(value) && value != 0.0;
    37      }
    38
    39      /** Throws an {@link IllegalArgumentException} if the given norm value
    40       * is not real (ie, not NaN or infinite) or zero. The argument is returned
    41       * to allow this method to be called inline.
    42       * @param norm vector norm value
    43       * @return the validated norm value
    44       * @throws IllegalArgumentException if the given norm value is NaN, infinite,
    45       *      or zero
    46       */
    47      public static double checkedNorm(final double norm) {
    48          if (!isRealNonZero(norm)) {
    49              throw new IllegalArgumentException("Illegal norm: " + norm);
    50          }
    51
    52          return norm;
    53      }
    54
    55      /** Returns the vector's norm value, throwing an {@link IllegalArgumentException} if the value
    56       * is not real (ie, not NaN or infinite) or zero.
    57       * @param vec vector to obtain the real, non-zero norm of
    58       * @return the validated norm value
    59       * @throws IllegalArgumentException if the vector norm value is NaN, infinite,
    60       *      or zero
    61       */
    62      public static double checkedNorm(final Vector<?> vec) {
    63          return checkedNorm(vec.norm());
    64      }
    65
    66      /** Attempt to normalize the given vector, returning null if the vector cannot be normalized
    67       * due to the norm being NaN, infinite, or null.
    68       * @param <V> Vector implementation type
    69       * @param vec the vector to attempt to normalize
    70       * @return the normalized vector if successful, otherwise null
    71       */
    72      public static <V extends Vector<V>> V tryNormalize(final V vec) {
    73          final double norm = vec.norm();
    74          if (isRealNonZero(norm)) {
    75              return vec.normalize();
    76          }
    77          return null;
    78      }
    79
    80      /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    81       * with the given components. This corresponds to the common notion of vector magnitude
    82       * or length and is defined as the square root of the sum of the squares of all vector components.
    83       * @param x vector component
    84       * @return L<sub>2</sub> norm for the vector with the given components
    85       * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    86       */
    87      public static double norm(final double x) {
    88          return Math.abs(x);
    89      }
    90
    91      /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    92       * with the given components. This corresponds to the common notion of vector magnitude
    93       * or length and is defined as the square root of the sum of the squares of all vector components.
    94       * @param x1 first vector component
    95       * @param x2 second vector component
    96       * @return L<sub>2</sub> norm for the vector with the given components
    97       * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    98       */
    99      public static double norm(final double x1, final double x2) {
    100         return Math.hypot(x1, x2);
    101     }
    102
    103     /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    104      * with the given components. This corresponds to the common notion of vector magnitude
    105      * or length and is defined as the square root of the sum of the squares of all vector components.
    106      * @param x1 first vector component
    107      * @param x2 second vector component
    108      * @param x3 third vector component
    109      * @return L<sub>2</sub> norm for the vector with the given components
    110      * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    111      */
    112     public static double norm(final double x1, final double x2, final double x3) {
    113         return SafeNorm.value(new double[] {x1, x2, x3});
    114     }
    115
    116     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    117      * for the vector with the given components. This is equal to the sum of the squares of
    118      * all vector components.
    119      * @param x vector component
    120      * @return square of the L<sub>2</sub> norm for the vector with the given components
    121      * @see #norm(double)
    122      */
    123     public static double normSq(final double x) {
    124         return x * x;
    125     }
    126
    127     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    128      * for the vector with the given components. This is equal to the sum of the squares of
    129      * all vector components.
    130      * @param x1 first vector component
    131      * @param x2 second vector component
    132      * @return square of the L<sub>2</sub> norm for the vector with the given components
    133      * @see #norm(double, double)
    134      */
    135     public static double normSq(final double x1, final double x2) {
    136         return (x1 * x1) + (x2 * x2);
    137     }
    138
    139     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    140      * for the vector with the given components. This is equal to the sum of the squares of
    141      * all vector components.
    142      * @param x1 first vector component
    143      * @param x2 second vector component
    144      * @param x3 third vector component
    145      * @return square of the L<sub>2</sub> norm for the vector with the given components
    146      * @see #norm(double, double, double)
    147      */
    148     public static double normSq(final double x1, final double x2, final double x3) {
    149         return (x1 * x1) + (x2 * x2) + (x3 * x3);
    150     }
    151 }