Vectors.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.  *      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. import org.apache.commons.geometry.core.Vector;
  19. import org.apache.commons.numbers.core.Norm;
  20. import org.apache.commons.numbers.core.Sum;

  21. /** This class consists exclusively of static vector utility methods.
  22.  */
  23. public final class Vectors {

  24.     /** Private constructor. */
  25.     private Vectors() {}

  26.     /** Returns true if the given value is real (ie, not NaN or infinite)
  27.      * and not equal to zero.
  28.      * @param value the value to test
  29.      * @return true if {@code value} is not NaN, infinite, or zero; otherwise
  30.      *      false
  31.      */
  32.     public static boolean isRealNonZero(final double value) {
  33.         return Double.isFinite(value) && value != 0.0;
  34.     }

  35.     /** Throws an {@link IllegalArgumentException} if the given norm value
  36.      * is not real (ie, not NaN or infinite) or zero. The argument is returned
  37.      * to allow this method to be called inline.
  38.      * @param norm vector norm value
  39.      * @return the validated norm value
  40.      * @throws IllegalArgumentException if the given norm value is NaN, infinite,
  41.      *      or zero
  42.      */
  43.     public static double checkedNorm(final double norm) {
  44.         if (!isRealNonZero(norm)) {
  45.             throw illegalNorm(norm);
  46.         }

  47.         return norm;
  48.     }

  49.     /** Returns the vector's norm value, throwing an {@link IllegalArgumentException} if the value
  50.      * is not real (ie, not NaN or infinite) or zero.
  51.      * @param vec vector to obtain the real, non-zero norm of
  52.      * @return the validated norm value
  53.      * @throws IllegalArgumentException if the vector norm value is NaN, infinite,
  54.      *      or zero
  55.      */
  56.     public static double checkedNorm(final Vector<?> vec) {
  57.         return checkedNorm(vec.norm());
  58.     }

  59.     /** Return an exception indicating an illegal norm value.
  60.      * @param norm illegal norm value
  61.      * @return exception indicating an illegal norm value
  62.      */
  63.     public static IllegalArgumentException illegalNorm(final double norm) {
  64.         return new IllegalArgumentException("Illegal norm: " + norm);
  65.     }

  66.     /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
  67.      * with the given components. This corresponds to the common notion of vector magnitude
  68.      * or length and is defined as the square root of the sum of the squares of all vector components.
  69.      * @param x vector component
  70.      * @return L<sub>2</sub> norm for the vector with the given components
  71.      * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
  72.      */
  73.     public static double norm(final double x) {
  74.         return Math.abs(x);
  75.     }

  76.     /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
  77.      * with the given components. This corresponds to the common notion of vector magnitude
  78.      * or length and is defined as the square root of the sum of the squares of all vector components.
  79.      * @param x1 first vector component
  80.      * @param x2 second vector component
  81.      * @return L<sub>2</sub> norm for the vector with the given components
  82.      * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
  83.      */
  84.     public static double norm(final double x1, final double x2) {
  85.         return Math.hypot(x1, x2);
  86.     }

  87.     /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector
  88.      * with the given components. This corresponds to the common notion of vector magnitude
  89.      * or length and is defined as the square root of the sum of the squares of all vector components.
  90.      * @param x1 first vector component
  91.      * @param x2 second vector component
  92.      * @param x3 third vector component
  93.      * @return L<sub>2</sub> norm for the vector with the given components
  94.      * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
  95.      */
  96.     public static double norm(final double x1, final double x2, final double x3) {
  97.         return Norm.EUCLIDEAN.of(x1, x2, x3);
  98.     }

  99.     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
  100.      * for the vector with the given components. This is equal to the sum of the squares of
  101.      * all vector components.
  102.      * @param x vector component
  103.      * @return square of the L<sub>2</sub> norm for the vector with the given components
  104.      * @see #norm(double)
  105.      */
  106.     public static double normSq(final double x) {
  107.         return x * x;
  108.     }

  109.     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
  110.      * for the vector with the given components. This is equal to the sum of the squares of
  111.      * all vector components.
  112.      * @param x1 first vector component
  113.      * @param x2 second vector component
  114.      * @return square of the L<sub>2</sub> norm for the vector with the given components
  115.      * @see #norm(double, double)
  116.      */
  117.     public static double normSq(final double x1, final double x2) {
  118.         return (x1 * x1) + (x2 * x2);
  119.     }

  120.     /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
  121.      * for the vector with the given components. This is equal to the sum of the squares of
  122.      * all vector components.
  123.      * @param x1 first vector component
  124.      * @param x2 second vector component
  125.      * @param x3 third vector component
  126.      * @return square of the L<sub>2</sub> norm for the vector with the given components
  127.      * @see #norm(double, double, double)
  128.      */
  129.     public static double normSq(final double x1, final double x2, final double x3) {
  130.         return (x1 * x1) + (x2 * x2) + (x3 * x3);
  131.     }

  132.     /** Compute the linear combination \(a_1 b_1 + a_2 b_2 \) with high accuracy.
  133.      * @param a1 first factor of the first term
  134.      * @param b1 second factor of the first term
  135.      * @param a2 first factor of the second term
  136.      * @param b2 second factor of the seconf term
  137.      * @return linear combination.
  138.      * @see Sum
  139.      */
  140.     public static double linearCombination(final double a1, final double b1,
  141.                                            final double a2, final double b2) {
  142.         return Sum.create()
  143.                 .addProduct(a1, b1)
  144.                 .addProduct(a2, b2).getAsDouble();
  145.     }

  146.     /** Compute the linear combination \(a_1 b_1 + a_2 b_2 + a_3 b_3 \) with high accuracy.
  147.      * @param a1 first factor of the first term
  148.      * @param b1 second factor of the first term
  149.      * @param a2 first factor of the second term
  150.      * @param b2 second factor of the seconf term
  151.      * @param a3 first factor of the third term
  152.      * @param b3 second factor of the third term
  153.      * @return linear combination.
  154.      * @see Sum
  155.      */
  156.     public static double linearCombination(final double a1, final double b1,
  157.                                            final double a2, final double b2,
  158.                                            final double a3, final double b3) {
  159.         return Sum.create()
  160.                 .addProduct(a1, b1)
  161.                 .addProduct(a2, b2)
  162.                 .addProduct(a3, b3).getAsDouble();
  163.     }
  164. }