001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.geometry.euclidean.internal; 018 019/** This class consists exclusively of static matrix utility methods. 020 */ 021public final class Matrices { 022 023 /** Private constructor. */ 024 private Matrices() {} 025 026 /** Compute the determinant of the 2x2 matrix represented by the given values. 027 * The values are listed in row-major order. 028 * @param a00 matrix entry <code>a<sub>0,0</sub></code> 029 * @param a01 matrix entry <code>a<sub>0,1</sub></code> 030 * @param a10 matrix entry <code>a<sub>1,0</sub></code> 031 * @param a11 matrix entry <code>a<sub>1,1</sub></code> 032 * @return computed 2x2 matrix determinant 033 */ 034 public static double determinant( 035 final double a00, final double a01, 036 final double a10, final double a11) { 037 038 return (a00 * a11) - (a01 * a10); 039 } 040 041 /** Compute the determinant of the 3x3 matrix represented by the given values. 042 * The values are listed in row-major order. 043 * @param a00 matrix entry <code>a<sub>0,0</sub></code> 044 * @param a01 matrix entry <code>a<sub>0,1</sub></code> 045 * @param a02 matrix entry <code>a<sub>0,2</sub></code> 046 * @param a10 matrix entry <code>a<sub>1,0</sub></code> 047 * @param a11 matrix entry <code>a<sub>1,1</sub></code> 048 * @param a12 matrix entry <code>a<sub>1,2</sub></code> 049 * @param a20 matrix entry <code>a<sub>2,0</sub></code> 050 * @param a21 matrix entry <code>a<sub>2,1</sub></code> 051 * @param a22 matrix entry <code>a<sub>2,2</sub></code> 052 * @return computed 3x3 matrix determinant 053 */ 054 public static double determinant( 055 final double a00, final double a01, final double a02, 056 final double a10, final double a11, final double a12, 057 final double a20, final double a21, final double a22) { 058 059 return ((a00 * a11 * a22) + (a01 * a12 * a20) + (a02 * a10 * a21)) - 060 ((a00 * a12 * a21) + (a01 * a10 * a22) + (a02 * a11 * a20)); 061 } 062 063 /** Check that the given determinant is valid for use in calculating a matrix 064 * inverse. An {@link IllegalStateException} is thrown if the determinant is 065 * NaN, infinite, or zero. 066 * @param det the determinant to check 067 * @return the checked determinant 068 * @throws IllegalStateException if the matrix determinant value is NaN, infinite, 069 * or zero 070 */ 071 public static double checkDeterminantForInverse(final double det) { 072 if (!Vectors.isRealNonZero(det)) { 073 throw nonInvertibleTransform("matrix determinant is " + det); 074 } 075 return det; 076 } 077 078 /** Check that the given matrix element is valid for use in calculation of 079 * a matrix inverse, throwing an {@link IllegalStateException} if not. 080 * @param element matrix entry to check 081 * @return the checked element 082 * @throws IllegalStateException if the element is not valid for use 083 * in calculating a matrix inverse, ie if it is NaN or infinite. 084 */ 085 public static double checkElementForInverse(final double element) { 086 if (!Double.isFinite(element)) { 087 throw nonInvertibleTransform("invalid matrix element: " + element); 088 } 089 090 return element; 091 } 092 093 /** Create an exception indicating that a matrix is not able to be inverted. 094 * @param msg message containing the specific reason that the matrix cannot 095 * be inverted 096 * @return IllegalStateException containing the given error message 097 */ 098 private static IllegalStateException nonInvertibleTransform(final String msg) { 099 return new IllegalStateException("Matrix is not invertible; " + msg); 100 } 101}