All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ejml.dense.row.MatrixFeatures_CDRM Maven / Gradle / Ivy

Go to download

A fast and easy to use dense and sparse matrix linear algebra library written in Java.

There is a newer version: 0.43.1
Show newest version
/*
 * Copyright (c) 2020, Peter Abeles. All Rights Reserved.
 *
 * This file is part of Efficient Java Matrix Library (EJML).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ejml.dense.row;

import javax.annotation.Generated;
import org.ejml.data.*;
import org.ejml.dense.row.decompose.chol.CholeskyDecompositionInner_CDRM;
import org.ejml.dense.row.mult.VectorVectorMult_CDRM;

/**
 * 

* Functions for computing the features of complex matrices *

* * @author Peter Abeles */ @SuppressWarnings("Duplicates") @Generated("org.ejml.dense.row.MatrixFeatures_ZDRM") public class MatrixFeatures_CDRM { /** * Checks to see if the matrix is a vector or not. * * @param mat A matrix. Not modified. * @return True if it is a vector and false if it is not. */ public static boolean isVector( Matrix mat ) { return (mat.getNumCols() == 1 || mat.getNumRows() == 1); } /** *

* Checks to see if the two matrices are the negative of each other:
*
* aij = -bij *

* * @param a First matrix. Not modified. * @param b Second matrix. Not modified. * @param tol Numerical tolerance. * @return True if they are the negative of each other within tolerance. */ public static boolean isNegative( CMatrixD1 a, CMatrixD1 b, float tol ) { if (a.numRows != b.numRows || a.numCols != b.numCols) throw new IllegalArgumentException("Matrix dimensions must match"); int length = a.getNumElements()*2; for (int i = 0; i < length; i++) { if (!(Math.abs(a.data[i] + b.data[i]) <= tol)) return false; } return true; } /** * Checks to see if any element in the matrix is NaN. * * @param m A matrix. Not modified. * @return True if any element in the matrix is NaN. */ public static boolean hasNaN( CMatrixD1 m ) { int length = m.getDataLength(); for (int i = 0; i < length; i++) { if (Float.isNaN(m.data[i])) return true; } return false; } /** * Checks to see if any element in the matrix is NaN of Infinite. * * @param m A matrix. Not modified. * @return True if any element in the matrix is NaN of Infinite. */ public static boolean hasUncountable( CMatrixD1 m ) { int length = m.getDataLength(); for (int i = 0; i < length; i++) { float a = m.data[i]; if (Float.isNaN(a) || Float.isInfinite(a)) return true; } return false; } /** *

* Checks to see if each element in the two matrices are equal: * aij == bij *

* *

* NOTE: If any of the elements are NaN then false is returned. If two corresponding * elements are both positive or negative infinity then they are equal. *

* * @param a A matrix. Not modified. * @param b A matrix. Not modified. * @return true if identical and false otherwise. */ public static boolean isEquals( CMatrixD1 a, CMatrixD1 b ) { if (a.numRows != b.numRows || a.numCols != b.numCols) { return false; } final int length = a.getDataLength(); for (int i = 0; i < length; i++) { if (!(a.data[i] == b.data[i])) { return false; } } return true; } /** *

* Checks to see if each element in the two matrices are within tolerance of * each other: tol ≥ |aij - bij|. *

* *

* NOTE: If any of the elements are not countable then false is returned.
* NOTE: If a tolerance of zero is passed in this is equivalent to calling * {@link #isEquals(CMatrixD1, CMatrixD1)} *

* * @param a A matrix. Not modified. * @param b A matrix. Not modified. * @param tol How close to being identical each element needs to be. * @return true if equals and false otherwise. */ public static boolean isEquals( CMatrixD1 a, CMatrixD1 b, float tol ) { if (a.numRows != b.numRows || a.numCols != b.numCols) { return false; } if (tol == 0.0f) return isEquals(a, b); final int length = a.getDataLength(); for (int i = 0; i < length; i++) { if (!(tol >= Math.abs(a.data[i] - b.data[i]))) { return false; } } return true; } /** *

* Checks to see if each corresponding element in the two matrices are * within tolerance of each other or have the some symbolic meaning. This * can handle NaN and Infinite numbers. *

* *

* If both elements are countable then the following equality test is used:
* |aij - bij| ≤ tol.
* Otherwise both numbers must both be Float.NaN, Float.POSITIVE_INFINITY, or * Float.NEGATIVE_INFINITY to be identical. *

* * @param a A matrix. Not modified. * @param b A matrix. Not modified. * @param tol Tolerance for equality. * @return true if identical and false otherwise. */ public static boolean isIdentical( CMatrixD1 a, CMatrixD1 b, float tol ) { if (a.numRows != b.numRows || a.numCols != b.numCols) { return false; } if (tol < 0) throw new IllegalArgumentException("Tolerance must be greater than or equal to zero."); final int length = a.getDataLength(); for (int i = 0; i < length; i++) { float valA = a.data[i]; float valB = b.data[i]; // if either is negative or positive infinity the result will be positive infinity // if either is NaN the result will be NaN float diff = Math.abs(valA - valB); // diff = NaN == false // diff = infinity == false if (tol >= diff) continue; if (Float.isNaN(valA)) { return Float.isNaN(valB); } else if (Float.isInfinite(valA)) { return valA == valB; } else { return false; } } return true; } /** * Checks to see if the provided matrix is within tolerance to an identity matrix. * * @param mat Matrix being examined. Not modified. * @param tol Tolerance. * @return True if it is within tolerance to an identify matrix. */ public static boolean isIdentity( CMatrix mat, float tol ) { // see if the result is an identity matrix Complex_F32 c = new Complex_F32(); for (int i = 0; i < mat.getNumRows(); i++) { for (int j = 0; j < mat.getNumCols(); j++) { mat.get(i, j, c); if (i == j) { if (!(Math.abs(c.real - 1) <= tol)) return false; if (!(Math.abs(c.imaginary) <= tol)) return false; } else { if (!(Math.abs(c.real) <= tol)) return false; if (!(Math.abs(c.imaginary) <= tol)) return false; } } } return true; } /** *

Hermitian matrix is a square matrix with complex entries that are equal to its own conjugate transpose.

* *

a[i,j] = conj(a[j,i])

* * @param Q The matrix being tested. Not modified. * @param tol Tolerance. * @return True if it passes the test. */ public static boolean isHermitian( CMatrixRMaj Q, float tol ) { if (Q.numCols != Q.numRows) return false; Complex_F32 a = new Complex_F32(); Complex_F32 b = new Complex_F32(); for (int i = 0; i < Q.numCols; i++) { for (int j = i; j < Q.numCols; j++) { Q.get(i, j, a); Q.get(j, i, b); if (Math.abs(a.real - b.real) > tol) return false; if (Math.abs(a.imaginary + b.imaginary) > tol) return false; } } return true; } /** *

* Unitary matrices have the following properties:

* Q*QH = I *

*

* This is the complex equivalent of orthogonal matrix. *

* * @param Q The matrix being tested. Not modified. * @param tol Tolerance. * @return True if it passes the test. */ public static boolean isUnitary( CMatrixRMaj Q, float tol ) { if (Q.numRows < Q.numCols) { throw new IllegalArgumentException("The number of rows must be more than or equal to the number of columns"); } Complex_F32 prod = new Complex_F32(); CMatrixRMaj[] u = CommonOps_CDRM.columnsToVector(Q, null); for (int i = 0; i < u.length; i++) { CMatrixRMaj a = u[i]; VectorVectorMult_CDRM.innerProdH(a, a, prod); if (Math.abs(prod.real - 1) > tol) return false; if (Math.abs(prod.imaginary) > tol) return false; for (int j = i + 1; j < u.length; j++) { VectorVectorMult_CDRM.innerProdH(a, u[j], prod); if (!(prod.getMagnitude2() <= tol*tol)) return false; } } return true; } /** *

* Checks to see if the matrix is positive definite. *

*

* xT A x > 0
* for all x where x is a non-zero vector and A is a hermitian matrix. *

* * @param A square hermitian matrix. Not modified. * @return True if it is positive definite and false if it is not. */ public static boolean isPositiveDefinite( CMatrixRMaj A ) { if (A.numCols != A.numRows) return false; CholeskyDecompositionInner_CDRM chol = new CholeskyDecompositionInner_CDRM(true); if (chol.inputModified()) A = A.copy(); return chol.decompose(A); } /** *

* Checks to see if a matrix is upper triangular or Hessenberg. A Hessenberg matrix of degree N * has the following property:
*
* aij ≤ 0 for all i < j+N
*
* A triangular matrix is a Hessenberg matrix of degree 0. *

* * @param A Matrix being tested. Not modified. * @param hessenberg The degree of being hessenberg. * @param tol How close to zero the lower left elements need to be. * @return If it is an upper triangular/hessenberg matrix or not. */ public static boolean isUpperTriangle( CMatrixRMaj A, int hessenberg, float tol ) { tol *= tol; for (int i = hessenberg + 1; i < A.numRows; i++) { int maxCol = Math.min(i - hessenberg, A.numCols); for (int j = 0; j < maxCol; j++) { int index = (i*A.numCols + j)*2; float real = A.data[index]; float imag = A.data[index + 1]; float mag = real*real + imag*imag; if (!(mag <= tol)) { return false; } } } return true; } /** *

* Checks to see if a matrix is lower triangular or Hessenberg. A Hessenberg matrix of degree N * has the following property:
*
* aij ≤ 0 for all i < j+N
*
* A triangular matrix is a Hessenberg matrix of degree 0. *

* * @param A Matrix being tested. Not modified. * @param hessenberg The degree of being hessenberg. * @param tol How close to zero the lower left elements need to be. * @return If it is an upper triangular/hessenberg matrix or not. */ public static boolean isLowerTriangle( CMatrixRMaj A, int hessenberg, float tol ) { tol *= tol; for (int i = 0; i < A.numRows - hessenberg - 1; i++) { for (int j = i + hessenberg + 1; j < A.numCols; j++) { int index = (i*A.numCols + j)*2; float real = A.data[index]; float imag = A.data[index + 1]; float mag = real*real + imag*imag; if (!(mag <= tol)) { return false; } } } return true; } /** * Checks to see all the elements in the matrix are zeros * * @param m A matrix. Not modified. * @return True if all elements are zeros or false if not */ public static boolean isZeros( CMatrixD1 m, float tol ) { int length = m.getNumElements()*2; for (int i = 0; i < length; i++) { if (Math.abs(m.data[i]) > tol) return false; } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy