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.core.Norm;
    21  import org.apache.commons.numbers.core.Sum;
    22
    23  /** This class consists exclusively of static vector utility methods.
    24   */
    25  public final class Vectors {
    26
    27      /** Private constructor. */
    28      private Vectors() {}
    29
    30      /** Returns true if the given value is real (ie, not NaN or infinite)
    31       * and not equal to zero.
    32       * @param value the value to test
    33       * @return true if {@code value} is not NaN, infinite, or zero; otherwise
    34       *      false
    35       */
    36      public static boolean isRealNonZero(final double value) {
    37          return Double.isFinite(value) && value != 0.0;
    38      }
    39
    40      /** Throws an {@link IllegalArgumentException} if the given norm value
    41       * is not real (ie, not NaN or infinite) or zero. The argument is returned
    42       * to allow this method to be called inline.
    43       * @param norm vector norm value
    44       * @return the validated norm value
    45       * @throws IllegalArgumentException if the given norm value is NaN, infinite,
    46       *      or zero
    47       */
    48      public static double checkedNorm(final double norm) {
    49          if (!isRealNonZero(norm)) {
    50              throw illegalNorm(norm);
    51          }
    52
    53          return norm;
    54      }
    55
    56      /** Returns the vector's norm value, throwing an {@link IllegalArgumentException} if the value
    57       * is not real (ie, not NaN or infinite) or zero.
    58       * @param vec vector to obtain the real, non-zero norm of
    59       * @return the validated norm value
    60       * @throws IllegalArgumentException if the vector norm value is NaN, infinite,
    61       *      or zero
    62       */
    63      public static double checkedNorm(final Vector<?> vec) {
    64          return checkedNorm(vec.norm());
    65      }
    66
    67      /** Return an exception indicating an illegal norm value.
    68       * @param norm illegal norm value
    69       * @return exception indicating an illegal norm value
    70       */
    71      public static IllegalArgumentException illegalNorm(final double norm) {
    72          return new IllegalArgumentException("Illegal norm: " + norm);
    73      }
    74
    75      /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    76       * with the given components. This corresponds to the common notion of vector magnitude
    77       * or length and is defined as the square root of the sum of the squares of all vector components.
    78       * @param x vector component
    79       * @return L<sub>2</sub> norm for the vector with the given components
    80       * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    81       */
    82      public static double norm(final double x) {
    83          return Math.abs(x);
    84      }
    85
    86      /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    87       * with the given components. This corresponds to the common notion of vector magnitude
    88       * or length and is defined as the square root of the sum of the squares of all vector components.
    89       * @param x1 first vector component
    90       * @param x2 second vector component
    91       * @return L<sub>2</sub> norm for the vector with the given components
    92       * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    93       */
    94      public static double norm(final double x1, final double x2) {
    95          return Math.hypot(x1, x2);
    96      }
    97
    98      /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
    99       * with the given components. This corresponds to the common notion of vector magnitude
    100      * or length and is defined as the square root of the sum of the squares of all vector components.
    101      * @param x1 first vector component
    102      * @param x2 second vector component
    103      * @param x3 third vector component
    104      * @return L<sub>2</sub> norm for the vector with the given components
    105      * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
    106      */
    107     public static double norm(final double x1, final double x2, final double x3) {
    108         return Norm.EUCLIDEAN.of(x1, x2, x3);
    109     }
    110
    111     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    112      * for the vector with the given components. This is equal to the sum of the squares of
    113      * all vector components.
    114      * @param x vector component
    115      * @return square of the L<sub>2</sub> norm for the vector with the given components
    116      * @see #norm(double)
    117      */
    118     public static double normSq(final double x) {
    119         return x * x;
    120     }
    121
    122     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    123      * for the vector with the given components. This is equal to the sum of the squares of
    124      * all vector components.
    125      * @param x1 first vector component
    126      * @param x2 second vector component
    127      * @return square of the L<sub>2</sub> norm for the vector with the given components
    128      * @see #norm(double, double)
    129      */
    130     public static double normSq(final double x1, final double x2) {
    131         return (x1 * x1) + (x2 * x2);
    132     }
    133
    134     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
    135      * for the vector with the given components. This is equal to the sum of the squares of
    136      * all vector components.
    137      * @param x1 first vector component
    138      * @param x2 second vector component
    139      * @param x3 third vector component
    140      * @return square of the L<sub>2</sub> norm for the vector with the given components
    141      * @see #norm(double, double, double)
    142      */
    143     public static double normSq(final double x1, final double x2, final double x3) {
    144         return (x1 * x1) + (x2 * x2) + (x3 * x3);
    145     }
    146
    147     /** Compute the linear combination \(a_1 b_1 + a_2 b_2 \) with high accuracy.
    148      * @param a1 first factor of the first term
    149      * @param b1 second factor of the first term
    150      * @param a2 first factor of the second term
    151      * @param b2 second factor of the seconf term
    152      * @return linear combination.
    153      * @see Sum
    154      */
    155     public static double linearCombination(final double a1, final double b1,
    156                                            final double a2, final double b2) {
    157         return Sum.create()
    158                 .addProduct(a1, b1)
    159                 .addProduct(a2, b2).getAsDouble();
    160     }
    161
    162     /** Compute the linear combination \(a_1 b_1 + a_2 b_2 + a_3 b_3 \) with high accuracy.
    163      * @param a1 first factor of the first term
    164      * @param b1 second factor of the first term
    165      * @param a2 first factor of the second term
    166      * @param b2 second factor of the seconf term
    167      * @param a3 first factor of the third term
    168      * @param b3 second factor of the third term
    169      * @return linear combination.
    170      * @see Sum
    171      */
    172     public static double linearCombination(final double a1, final double b1,
    173                                            final double a2, final double b2,
    174                                            final double a3, final double b3) {
    175         return Sum.create()
    176                 .addProduct(a1, b1)
    177                 .addProduct(a2, b2)
    178                 .addProduct(a3, b3).getAsDouble();
    179     }
    180 }