/** * <p> * Performs the following operation:<br> * <br> * B = A + αI * <p> * * @param A A square matrix. Not modified. * @param B A square matrix that the results are saved to. Modified. * @param alpha Scaling factor for the identity matrix. */ public static void addIdentity(FMatrix1Row A, FMatrix1Row B, float alpha) { if (A.numCols != A.numRows) { throw new ArgumentException("A must be square"); } if (B.numCols != A.numCols || B.numRows != A.numRows) { throw new ArgumentException("B must be the same shape as A"); } int n = A.numCols; int index = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++, index++) { if (i == j) { B.set(index, A.get(index) + alpha); } else { B.set(index, A.get(index)); } } } }
/** * <p> * Element wise p-norm:<br> * <br> * norm = {∑<sub>i=1:m</sub> ∑<sub>j=1:n</sub> { |a<sub>ij</sub>|<sup>p</sup>}}<sup>1/p</sup> * </p> * * <p> * This is not the same as the induced p-norm used on matrices, but is the same as the vector p-norm. * </p> * * @param A Matrix. Not modified. * @param p p value. * @return The norm's value. */ public static float elementP(FMatrix1Row A, float p) { if (p == 1) { return(CommonOps_FDRM.elementSumAbs(A)); } if (p == 2) { return(normF(A)); } else { float max = CommonOps_FDRM.elementMaxAbs(A); if (max == 0.0f) { return(0.0f); } float total = 0; int size = A.getNumElements(); for (int i = 0; i < size; i++) { float a = A.get(i) / max; total += (float)Math.Pow(Math.Abs(a), p); } return(max * (float)Math.Pow(total, 1.0f / p)); } }
/** * Takes a matrix and splits it into a set of row or column vectors. * * @param A original matrix. * @param column If true then column vectors will be created. * @return Set of vectors. */ public static FMatrixRMaj[] splitIntoVectors(FMatrix1Row A, bool column) { int w = column ? A.numCols : A.numRows; int M = column ? A.numRows : 1; int N = column ? 1 : A.numCols; int o = Math.Max(M, N); FMatrixRMaj[] ret = new FMatrixRMaj[w]; for (int i = 0; i < w; i++) { FMatrixRMaj a = new FMatrixRMaj(M, N); if (column) { subvector(A, 0, i, o, false, 0, a); } else { subvector(A, i, 0, o, true, 0, a); } ret[i] = a; } return(ret); }
/** * Performs a transpose across block sub-matrices. Reduces * the number of cache misses on larger matrices. * * *NOTE* If this is beneficial is highly dependent on the computer it is run on. e.g: * - Q6600 Almost twice as fast as standard. * - Pentium-M Same speed and some times a bit slower than standard. * * @param A Original matrix. Not modified. * @param A_tran Transposed matrix. Modified. * @param blockLength Length of a block. */ public static void block(FMatrix1Row A, FMatrix1Row A_tran, int blockLength) { for (int i = 0; i < A.numRows; i += blockLength) { int blockHeight = Math.Min(blockLength, A.numRows - i); int indexSrc = i * A.numCols; int indexDst = i; for (int j = 0; j < A.numCols; j += blockLength) { int blockWidth = Math.Min(blockLength, A.numCols - j); // int indexSrc = i*A.numCols + j; // int indexDst = j*A_tran.numCols + i; int indexSrcEnd = indexSrc + blockWidth; // for( int l = 0; l < blockWidth; l++ , indexSrc++ ) { for (; indexSrc < indexSrcEnd; indexSrc++) { int rowSrc = indexSrc; int rowDst = indexDst; int end = rowDst + blockHeight; // for( int k = 0; k < blockHeight; k++ , rowSrc += A.numCols ) { for (; rowDst < end; rowSrc += A.numCols) { // faster to write in sequence than to read in sequence A_tran.data[rowDst++] = A.data[rowSrc]; } indexDst += A_tran.numCols; } } } }
public static void inner_small(FMatrix1Row a, FMatrix1Row c) { for (int i = 0; i < a.numCols; i++) { for (int j = i; j < a.numCols; j++) { int indexC1 = i * c.numCols + j; int indexC2 = j * c.numCols + i; int indexA = i; int indexB = j; float sum = 0; int end = indexA + a.numRows * a.numCols; for (; indexA < end; indexA += a.numCols, indexB += a.numCols) { sum += a.data[indexA] * a.data[indexB]; } c.data[indexC1] = c.data[indexC2] = sum; } } // for( int i = 0; i < a.numCols; i++ ) { // for( int j = i; j < a.numCols; j++ ) { // float sum = 0; // for( int k = 0; k < a.numRows; k++ ) { // sum += a.get(k,i)*a.get(k,j); // } // c.set(i,j,sum); // c.set(j,i,sum); // } // } }
/** * <p> * Adds to A ∈ ℜ <sup>m × n</sup> the results of an outer product multiplication * of the two vectors. This is also known as a rank 1 update.<br> * <br> * A = A + γ x * y<sup>T</sup> * where x ∈ ℜ <sup>m</sup> and y ∈ ℜ <sup>n</sup> are vectors. * </p> * <p> * Which is equivalent to: A<sub>ij</sub> = A<sub>ij</sub> + γ x<sub>i</sub>*y<sub>j</sub> * </p> * * <p> * These functions are often used inside of highly optimized code and therefor sanity checks are * kept to a minimum. It is not recommended that any of these functions be used directly. * </p> * * @param gamma A multiplication factor for the outer product. * @param x A vector with m elements. Not modified. * @param y A vector with n elements. Not modified. * @param A A Matrix with m by n elements. Modified. */ public static void addOuterProd(float gamma, FMatrixD1 x, FMatrixD1 y, FMatrix1Row A) { int m = A.numRows; int n = A.numCols; int index = 0; if (gamma == 1.0f) { for (int i = 0; i < m; i++) { float xdat = x.get(i); for (int j = 0; j < n; j++) { A.plus(index++, xdat * y.get(j)); } } } else { for (int i = 0; i < m; i++) { float xdat = x.get(i); for (int j = 0; j < n; j++) { A.plus(index++, gamma * xdat * y.get(j)); } } } }
public static float det4(FMatrix1Row mat) { float[] data = mat.data; float a11 = data[5]; float a12 = data[6]; float a13 = data[7]; float a21 = data[9]; float a22 = data[10]; float a23 = data[11]; float a31 = data[13]; float a32 = data[14]; float a33 = data[15]; float ret = 0; ret += data[0] * (+a11 * (a22 * a33 - a23 * a32) - a12 * (a21 * a33 - a23 * a31) + a13 * (a21 * a32 - a22 * a31)); a11 = data[4]; a21 = data[8]; a31 = data[12]; ret -= data[1] * (+a11 * (a22 * a33 - a23 * a32) - a12 * (a21 * a33 - a23 * a31) + a13 * (a21 * a32 - a22 * a31)); a12 = data[5]; a22 = data[9]; a32 = data[13]; ret += data[2] * (+a11 * (a22 * a33 - a23 * a32) - a12 * (a21 * a33 - a23 * a31) + a13 * (a21 * a32 - a22 * a31)); a13 = data[6]; a23 = data[10]; a33 = data[14]; ret -= data[3] * (+a11 * (a22 * a33 - a23 * a32) - a12 * (a21 * a33 - a23 * a31) + a13 * (a21 * a32 - a22 * a31)); return(ret); }
public static void outer(FMatrix1Row a, FMatrix1Row c) { for (int i = 0; i < a.numRows; i++) { int indexC1 = i * c.numCols + i; int indexC2 = indexC1; for (int j = i; j < a.numRows; j++, indexC2 += c.numCols) { int indexA = i * a.numCols; int indexB = j * a.numCols; float sum = 0; int end = indexA + a.numCols; for (; indexA < end; indexA++, indexB++) { sum += a.data[indexA] * a.data[indexB]; } c.data[indexC2] = c.data[indexC1++] = sum; } } // for( int i = 0; i < a.numRows; i++ ) { // for( int j = 0; j < a.numRows; j++ ) { // float sum = 0; // for( int k = 0; k < a.numCols; k++ ) { // sum += a.get(i,k)*a.get(j,k); // } // c.set(i,j,sum); // } // } }
public static void invert(LinearSolverDense <FMatrixRMaj> solver, FMatrix1Row A, FMatrixRMaj A_inv) { if (A.numRows != A_inv.numRows || A.numCols != A_inv.numCols) { throw new ArgumentException("A and A_inv must have the same dimensions"); } CommonOps_FDRM.setIdentity(A_inv); solver.solve(A_inv, A_inv); }
/** * An alternative implementation of {@link #multTransA_small} that performs well on large * matrices. There is a relative performance hit when used on small matrices. * * @param A A matrix that is m by n. Not modified. * @param B A Vector that has length m. Not modified. * @param C A column vector that has length n. Modified. */ public static void multTransA_reorder(FMatrix1Row A, FMatrixD1 B, FMatrixD1 C) { if (C.numCols != 1) { throw new MatrixDimensionException("C is not a column vector"); } else if (C.numRows != A.numCols) { throw new MatrixDimensionException("C is not the expected length"); } if (B.numRows == 1) { if (A.numRows != B.numCols) { throw new MatrixDimensionException("A and B are not compatible"); } } else if (B.numCols == 1) { if (A.numRows != B.numRows) { throw new MatrixDimensionException("A and B are not compatible"); } } else { throw new MatrixDimensionException("B is not a vector"); } if (A.numRows == 0) { CommonOps_FDRM.fill(C, 0); return; } float B_val = B.get(0); for (int i = 0; i < A.numCols; i++) { C.set(i, A.get(i) * B_val); } int indexA = A.numCols; for (int i = 1; i < A.numRows; i++) { B_val = B.get(i); for (int j = 0; j < A.numCols; j++) { C.plus(j, A.get(indexA++) * B_val); } } }
/** * Computes the product of the diagonal elements. For a diagonal or triangular * matrix this is the determinant. * * @param T A matrix. * @return product of the diagonal elements. */ public static float diagProd(FMatrix1Row T) { float prod = 1.0f; int N = Math.Min(T.numRows, T.numCols); for (int i = 0; i < N; i++) { prod *= T.unsafe_get(i, i); } return(prod); }
/** * <p> * Performs a matrix vector multiply.<br> * <br> * c = A * b <br> * and<br> * c = A * b<sup>T</sup> <br> * <br> * c<sub>i</sub> = Sum{ j=1:n, a<sub>ij</sub> * b<sub>j</sub>}<br> * <br> * where A is a matrix, b is a column or transposed row vector, and c is a column vector. * </p> * * @param A A matrix that is m by n. Not modified. * @param B A vector that has length n. Not modified. * @param C A column vector that has length m. Modified. */ public static void mult(FMatrix1Row A, FMatrixD1 B, FMatrixD1 C) { if (C.numCols != 1) { throw new MatrixDimensionException("C is not a column vector"); } else if (C.numRows != A.numRows) { throw new MatrixDimensionException("C is not the expected length"); } if (B.numRows == 1) { if (A.numCols != B.numCols) { throw new MatrixDimensionException("A and B are not compatible"); } } else if (B.numCols == 1) { if (A.numCols != B.numRows) { throw new MatrixDimensionException("A and B are not compatible"); } } else { throw new MatrixDimensionException("B is not a vector"); } if (A.numCols == 0) { CommonOps_FDRM.fill(C, 0); return; } int indexA = 0; int cIndex = 0; float b0 = B.get(0); for (int i = 0; i < A.numRows; i++) { float total = A.get(indexA++) * b0; for (int j = 1; j < A.numCols; j++) { total += A.get(indexA++) * B.get(j); } C.set(cIndex++, total); } }
public static void setSubMatrix(FMatrix1Row src, FMatrix1Row dst, int srcRow, int srcCol, int dstRow, int dstCol, int numSubRows, int numSubCols) { for (int i = 0; i < numSubRows; i++) { for (int j = 0; j < numSubCols; j++) { float val = src.get(i + srcRow, j + srcCol); dst.set(i + dstRow, j + dstCol, val); } } }
/** * A straight forward transpose. Good for small non-square matrices. * * @param A Original matrix. Not modified. * @param A_tran Transposed matrix. Modified. */ public static void standard(FMatrix1Row A, FMatrix1Row A_tran) { int index = 0; for (int i = 0; i < A_tran.numRows; i++) { int index2 = i; int end = index + A_tran.numCols; while (index < end) { A_tran.data[index++] = A.data[index2]; index2 += A.numCols; } } }
/** * <p> * Sets A ∈ ℜ <sup>m × n</sup> equal to an outer product multiplication of the two * vectors. This is also known as a rank-1 operation.<br> * <br> * A = x * y' * where x ∈ ℜ <sup>m</sup> and y ∈ ℜ <sup>n</sup> are vectors. * </p> * <p> * Which is equivalent to: A<sub>ij</sub> = x<sub>i</sub>*y<sub>j</sub> * </p> * * <p> * These functions are often used inside of highly optimized code and therefor sanity checks are * kept to a minimum. It is not recommended that any of these functions be used directly. * </p> * * @param x A vector with m elements. Not modified. * @param y A vector with n elements. Not modified. * @param A A Matrix with m by n elements. Modified. */ public static void outerProd(FMatrixD1 x, FMatrixD1 y, FMatrix1Row A) { int m = A.numRows; int n = A.numCols; int index = 0; for (int i = 0; i < m; i++) { float xdat = x.get(i); for (int j = 0; j < n; j++) { A.set(index++, xdat * y.get(j)); } } }
/** * <p> * Creates a reflector from the provided vector.<br> * <br> * Q = I - γ u u<sup>T</sup><br> * γ = 2/||u||<sup>2</sup> * </p> * * <p> * In practice {@link VectorVectorMult_FDRM#householder(float, FMatrixD1, FMatrixD1, FMatrixD1)} multHouseholder} * should be used for performance reasons since there is no need to calculate Q explicitly. * </p> * * @param u A vector. Not modified. * @return An orthogonal reflector. */ public static FMatrixRMaj createReflector(FMatrix1Row u) { if (!MatrixFeatures_FDRM.isVector(u)) { throw new ArgumentException("u must be a vector"); } float norm = NormOps_FDRM.fastNormF(u); float gamma = -2.0f / (norm * norm); FMatrixRMaj Q = CommonOps_FDRM.identity(u.getNumElements()); CommonOps_FDRM.multAddTransB(gamma, u, u, Q); return(Q); }
public static float det(FMatrix1Row mat) { switch (mat.numRows) { case 2: return(det2(mat)); case 3: return(det3(mat)); case 4: return(det4(mat)); case 5: return(det5(mat)); case 6: return(det6(mat)); default: throw new ArgumentException("Not supported"); } }
/** * <p> * Performs a matrix vector multiply.<br> * <br> * C = C + A<sup>T</sup> * B <br> * or<br> * C = C<sup>T</sup> + A<sup>T</sup> * B<sup>T</sup> <br> * <br> * c<sub>i</sub> = Sum{ j=1:n, c<sub>i</sub> + a<sub>ji</sub> * b<sub>j</sub>}<br> * <br> * where A is a matrix, B is a column or transposed row vector, and C is a column vector. * </p> * <p> * This implementation is optimal for small matrices. There is a huge performance hit when * used on large matrices due to CPU cache issues. * </p> * * @param A A matrix that is m by n. Not modified. * @param B A vector that has length m. Not modified. * @param C A column vector that has length n. Modified. */ public static void multAddTransA_small(FMatrix1Row A, FMatrixD1 B, FMatrixD1 C) { if (C.numCols != 1) { throw new MatrixDimensionException("C is not a column vector"); } else if (C.numRows != A.numCols) { throw new MatrixDimensionException("C is not the expected length"); } if (B.numRows == 1) { if (A.numRows != B.numCols) { throw new MatrixDimensionException("A and B are not compatible"); } } else if (B.numCols == 1) { if (A.numRows != B.numRows) { throw new MatrixDimensionException("A and B are not compatible"); } } else { throw new MatrixDimensionException("B is not a vector"); } int cIndex = 0; for (int i = 0; i < A.numCols; i++) { float total = 0.0f; int indexA = i; for (int j = 0; j < A.numRows; j++) { total += A.get(indexA) * B.get(j); indexA += A.numCols; } C.plus(cIndex++, total); } }
public static void inner_reorder(FMatrix1Row a, FMatrix1Row c) { for (int i = 0; i < a.numCols; i++) { int indexC = i * c.numCols + i; float valAi = a.data[i]; for (int j = i; j < a.numCols; j++) { c.data[indexC++] = valAi * a.data[j]; } for (int k = 1; k < a.numRows; k++) { indexC = i * c.numCols + i; int indexB = k * a.numCols + i; valAi = a.data[indexB]; for (int j = i; j < a.numCols; j++) { c.data[indexC++] += valAi * a.data[indexB++]; } } indexC = i * c.numCols + i; int indexC2 = indexC; for (int j = i; j < a.numCols; j++, indexC2 += c.numCols) { c.data[indexC2] = c.data[indexC++]; } } // for( int i = 0; i < a.numCols; i++ ) { // for( int j = i; j < a.numCols; j++ ) { // c.set(i,j,a.get(0,i)*a.get(0,j)); // } // // for( int k = 1; k < a.numRows; k++ ) { // for( int j = i; j < a.numCols; j++ ) { // c.set(i,j, c.get(i,j)+ a.get(k,i)*a.get(k,j)); // } // } // for( int j = i; j < a.numCols; j++ ) { // c.set(j,i,c.get(i,j)); // } // } }
/** * In-place transpose for a square matrix. On most architectures it is faster than the standard transpose * algorithm, but on most modern computers it's slower than block transpose. * * @param mat The matrix that is transposed in-place. Modified. */ public static void square(FMatrix1Row mat) { int index = 1; int indexEnd = mat.numCols; for (int i = 0; i < mat.numRows; i++, index += i + 1, indexEnd += mat.numCols) { int indexOther = (i + 1) * mat.numCols + i; for (; index < indexEnd; index++, indexOther += mat.numCols) { float val = mat.data[index]; mat.data[index] = mat.data[indexOther]; mat.data[indexOther] = val; } } }
/** * <p> * Extracts a row or column vector from matrix A. The first element in the matrix is at element (rowA,colA). * The next 'length' elements are extracted along a row or column. The results are put into vector 'v' * start at its element v0. * </p> * * @param A Matrix that the vector is being extracted from. Not modified. * @param rowA Row of the first element that is extracted. * @param colA Column of the first element that is extracted. * @param length Length of the extracted vector. * @param row If true a row vector is extracted, otherwise a column vector is extracted. * @param offsetV First element in 'v' where the results are extracted to. * @param v Vector where the results are written to. Modified. */ public static void subvector(FMatrix1Row A, int rowA, int colA, int length, bool row, int offsetV, FMatrix1Row v) { if (row) { for (int i = 0; i < length; i++) { v.set(offsetV + i, A.get(rowA, colA + i)); } } else { for (int i = 0; i < length; i++) { v.set(offsetV + i, A.get(rowA + i, colA)); } } }
private void createMinor(FMatrix1Row mat) { int w = minWidth - 1; int firstRow = (width - w) * width; for (int i = 0; i < numOpen; i++) { int col = open[i]; int srcIndex = firstRow + col; int dstIndex = i; for (int j = 0; j < w; j++) { tempMat.set(dstIndex, mat.get(srcIndex)); dstIndex += w; srcIndex += width; } } }
public static float det3(FMatrix1Row mat) { float[] m = mat.data; float a11 = m[0]; float a12 = m[1]; float a13 = m[2]; float a21 = m[3]; float a22 = m[4]; float a23 = m[5]; float a31 = m[6]; float a32 = m[7]; float a33 = m[8]; float a = a11 * (a22 * a33 - a23 * a32); float b = a12 * (a21 * a33 - a23 * a31); float c = a13 * (a21 * a32 - a31 * a22); return(a - b + c); }
public static void inner_reorder_upper(FMatrix1Row a, FMatrix1Row c) { for (int i = 0; i < a.numCols; i++) { int indexC = i * c.numCols + i; float valAi = a.data[i]; for (int j = i; j < a.numCols; j++) { c.data[indexC++] = valAi * a.data[j]; } for (int k = 1; k < a.numRows; k++) { indexC = i * c.numCols + i; int indexB = k * a.numCols + i; valAi = a.data[indexB]; for (int j = i; j < a.numCols; j++) { c.data[indexC++] += valAi * a.data[indexB++]; } } } }
public static float det2(FMatrix1Row mat) { float[] m = mat.data; return(m[0] * m[3] - m[1] * m[2]); }
public static float det5(FMatrix1Row mat) { float[] data = mat.data; float a11 = data[6]; float a12 = data[7]; float a13 = data[8]; float a14 = data[9]; float a21 = data[11]; float a22 = data[12]; float a23 = data[13]; float a24 = data[14]; float a31 = data[16]; float a32 = data[17]; float a33 = data[18]; float a34 = data[19]; float a41 = data[21]; float a42 = data[22]; float a43 = data[23]; float a44 = data[24]; float ret = 0; ret += data[0] * (+a11 * (+a22 * (a33 * a44 - a34 * a43) - a23 * (a32 * a44 - a34 * a42) + a24 * (a32 * a43 - a33 * a42)) - a12 * (+a21 * (a33 * a44 - a34 * a43) - a23 * (a31 * a44 - a34 * a41) + a24 * (a31 * a43 - a33 * a41)) + a13 * (+a21 * (a32 * a44 - a34 * a42) - a22 * (a31 * a44 - a34 * a41) + a24 * (a31 * a42 - a32 * a41)) - a14 * (+a21 * (a32 * a43 - a33 * a42) - a22 * (a31 * a43 - a33 * a41) + a23 * (a31 * a42 - a32 * a41))); a11 = data[5]; a21 = data[10]; a31 = data[15]; a41 = data[20]; ret -= data[1] * (+a11 * (+a22 * (a33 * a44 - a34 * a43) - a23 * (a32 * a44 - a34 * a42) + a24 * (a32 * a43 - a33 * a42)) - a12 * (+a21 * (a33 * a44 - a34 * a43) - a23 * (a31 * a44 - a34 * a41) + a24 * (a31 * a43 - a33 * a41)) + a13 * (+a21 * (a32 * a44 - a34 * a42) - a22 * (a31 * a44 - a34 * a41) + a24 * (a31 * a42 - a32 * a41)) - a14 * (+a21 * (a32 * a43 - a33 * a42) - a22 * (a31 * a43 - a33 * a41) + a23 * (a31 * a42 - a32 * a41))); a12 = data[6]; a22 = data[11]; a32 = data[16]; a42 = data[21]; ret += data[2] * (+a11 * (+a22 * (a33 * a44 - a34 * a43) - a23 * (a32 * a44 - a34 * a42) + a24 * (a32 * a43 - a33 * a42)) - a12 * (+a21 * (a33 * a44 - a34 * a43) - a23 * (a31 * a44 - a34 * a41) + a24 * (a31 * a43 - a33 * a41)) + a13 * (+a21 * (a32 * a44 - a34 * a42) - a22 * (a31 * a44 - a34 * a41) + a24 * (a31 * a42 - a32 * a41)) - a14 * (+a21 * (a32 * a43 - a33 * a42) - a22 * (a31 * a43 - a33 * a41) + a23 * (a31 * a42 - a32 * a41))); a13 = data[7]; a23 = data[12]; a33 = data[17]; a43 = data[22]; ret -= data[3] * (+a11 * (+a22 * (a33 * a44 - a34 * a43) - a23 * (a32 * a44 - a34 * a42) + a24 * (a32 * a43 - a33 * a42)) - a12 * (+a21 * (a33 * a44 - a34 * a43) - a23 * (a31 * a44 - a34 * a41) + a24 * (a31 * a43 - a33 * a41)) + a13 * (+a21 * (a32 * a44 - a34 * a42) - a22 * (a31 * a44 - a34 * a41) + a24 * (a31 * a42 - a32 * a41)) - a14 * (+a21 * (a32 * a43 - a33 * a42) - a22 * (a31 * a43 - a33 * a41) + a23 * (a31 * a42 - a32 * a41))); a14 = data[8]; a24 = data[13]; a34 = data[18]; a44 = data[23]; ret += data[4] * (+a11 * (+a22 * (a33 * a44 - a34 * a43) - a23 * (a32 * a44 - a34 * a42) + a24 * (a32 * a43 - a33 * a42)) - a12 * (+a21 * (a33 * a44 - a34 * a43) - a23 * (a31 * a44 - a34 * a41) + a24 * (a31 * a43 - a33 * a41)) + a13 * (+a21 * (a32 * a44 - a34 * a42) - a22 * (a31 * a44 - a34 * a41) + a24 * (a31 * a42 - a32 * a41)) - a14 * (+a21 * (a32 * a43 - a33 * a42) - a22 * (a31 * a43 - a33 * a41) + a23 * (a31 * a42 - a32 * a41))); return(ret); }
/** * Computes the determinant for the specified matrix. It must be square and have * the same width and height as what was specified in the constructor. * * @param mat The matrix whose determinant is to be computed. * @return The determinant. */ public float compute(FMatrix1Row mat) { if (width != mat.numCols || width != mat.numRows) { throw new InvalidOperationException("Unexpected matrix dimension"); } // make sure everything is in the proper state before it starts initStructures(); // Array.Copy(mat.data,0,minorMatrix[0],0,mat.data.Length); int level = 0; while (true) { int levelWidth = width - level; int levelIndex = levelIndexes[level]; if (levelIndex == levelWidth) { if (level == 0) { return(levelResults[0]); } int prevLevelIndex = levelIndexes[level - 1]++; float val = mat.get((level - 1) * width + levelRemoved[level - 1]); if (prevLevelIndex % 2 == 0) { levelResults[level - 1] += val * levelResults[level]; } else { levelResults[level - 1] -= val * levelResults[level]; } putIntoOpen(level - 1); levelResults[level] = 0; levelIndexes[level] = 0; level--; } else { int excluded = openRemove(levelIndex); levelRemoved[level] = excluded; if (levelWidth == minWidth) { createMinor(mat); float subresult = mat.get(level * width + levelRemoved[level]); subresult *= UnrolledDeterminantFromMinor_FDRM.det(tempMat); if (levelIndex % 2 == 0) { levelResults[level] += subresult; } else { levelResults[level] -= subresult; } // put it back into the list putIntoOpen(level); levelIndexes[level]++; } else { level++; } } } }
public static float det6(FMatrix1Row mat) { float[] data = mat.data; float a11 = data[7]; float a12 = data[8]; float a13 = data[9]; float a14 = data[10]; float a15 = data[11]; float a21 = data[13]; float a22 = data[14]; float a23 = data[15]; float a24 = data[16]; float a25 = data[17]; float a31 = data[19]; float a32 = data[20]; float a33 = data[21]; float a34 = data[22]; float a35 = data[23]; float a41 = data[25]; float a42 = data[26]; float a43 = data[27]; float a44 = data[28]; float a45 = data[29]; float a51 = data[31]; float a52 = data[32]; float a53 = data[33]; float a54 = data[34]; float a55 = data[35]; float ret = 0; ret += data[0] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); a11 = data[6]; a21 = data[12]; a31 = data[18]; a41 = data[24]; a51 = data[30]; ret -= data[1] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); a12 = data[7]; a22 = data[13]; a32 = data[19]; a42 = data[25]; a52 = data[31]; ret += data[2] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); a13 = data[8]; a23 = data[14]; a33 = data[20]; a43 = data[26]; a53 = data[32]; ret -= data[3] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); a14 = data[9]; a24 = data[15]; a34 = data[21]; a44 = data[27]; a54 = data[33]; ret += data[4] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); a15 = data[10]; a25 = data[16]; a35 = data[22]; a45 = data[28]; a55 = data[34]; ret -= data[5] * ( +a11 * (+a22 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) + a24 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a25 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52))) - a12 * (+a21 * (+a33 * (a44 * a55 - a45 * a54) - a34 * (a43 * a55 - a45 * a53) + a35 * (a43 * a54 - a44 * a53)) - a23 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) - a25 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51))) + a13 * (+a21 * (+a32 * (a44 * a55 - a45 * a54) - a34 * (a42 * a55 - a45 * a52) + a35 * (a42 * a54 - a44 * a52)) - a22 * (+a31 * (a44 * a55 - a45 * a54) - a34 * (a41 * a55 - a45 * a51) + a35 * (a41 * a54 - a44 * a51)) + a24 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51))) - a14 * (+a21 * (+a32 * (a43 * a55 - a45 * a53) - a33 * (a42 * a55 - a45 * a52) + a35 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a55 - a45 * a53) - a33 * (a41 * a55 - a45 * a51) + a35 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a55 - a45 * a52) - a32 * (a41 * a55 - a45 * a51) + a35 * (a41 * a52 - a42 * a51)) - a25 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51))) + a15 * (+a21 * (+a32 * (a43 * a54 - a44 * a53) - a33 * (a42 * a54 - a44 * a52) + a34 * (a42 * a53 - a43 * a52)) - a22 * (+a31 * (a43 * a54 - a44 * a53) - a33 * (a41 * a54 - a44 * a51) + a34 * (a41 * a53 - a43 * a51)) + a23 * (+a31 * (a42 * a54 - a44 * a52) - a32 * (a41 * a54 - a44 * a51) + a34 * (a41 * a52 - a42 * a51)) - a24 * (+a31 * (a42 * a53 - a43 * a52) - a32 * (a41 * a53 - a43 * a51) + a33 * (a41 * a52 - a42 * a51)))); return(ret); }