diff --git a/docs/flag4j/org/flag4j/linalg/operations/dense/real/RealDenseMatrixMultTranspose.html b/docs/flag4j/org/flag4j/linalg/operations/dense/real/RealDenseMatrixMultTranspose.html index 3b64e931f..51a016244 100644 --- a/docs/flag4j/org/flag4j/linalg/operations/dense/real/RealDenseMatrixMultTranspose.html +++ b/docs/flag4j/org/flag4j/linalg/operations/dense/real/RealDenseMatrixMultTranspose.html @@ -86,7 +86,7 @@
A sparse matrix stored in coordinate list (COO) format. The {@link #data} of this COO vector are - * elements of a {@link Field}. - * - *
The {@link #data non-zero data} and non-zero indices of a COO matrix are mutable but the {@link #shape} - * and total number of non-zero data is fixed. - * - *
Sparse matrices allow for the efficient storage of and ops on matrices that contain many zero values. - * - *
COO matrices are optimized for hyper-sparse matrices (i.e. matrices which contain almost all zeros relative to the size of the - * matrix). - * - *
Note: many ops assume that the data of the COO matrix are sorted lexicographically by the row and column indices. - * (i.e.) by row indices first then column indices. However, this is not explicitly verified but any ops implemented in this - * class will preserve the lexicographical sorting. - * - *
If indices need to be sorted, call {@link #sortIndices()}.
- *
- * @param Computes the trace of this matrix. That is, the sum of elements along the principle diagonal of this matrix.
- *
- * Same as {@link #trace()}.
- *
- * @return The trace of this matrix.
- *
- * @throws IllegalArgumentException If this matrix is not square.
- */
- @Override
- public W tr() {
- W trace = getZeroElement();
-
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i]==colIndices[i]) trace = trace.add(data[i]); // Then entry is on the diagonal.
-
- return trace;
- }
-
-
- /**
- * Checks if this matrix is upper triangular.
- *
- * @return {@code true} is this matrix is upper triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriL()
- * @see #isDiag()
- */
- @Override
- public boolean isTriU() {
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i] > colIndices[i] && !data[i].isZero()) return false; // Then non-zero entry is not in upper triangle.
-
- return true;
- }
-
-
- /**
- * Checks if this matrix is lower triangular.
- *
- * @return {@code true} is this matrix is lower triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriU()
- * @see #isDiag()
- */
- @Override
- public boolean isTriL() {
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i] < colIndices[i] && !data[i].isZero()) return false; // Then non-zero entry is not in lower triangle.
-
- return true;
- }
-
-
- /**
- * Checks if this matrix is the identity matrix. That is, checks if this matrix is square and contains
- * only ones along the principle diagonal and zeros everywhere else.
- *
- * @return {@code true} if this matrix is the identity matrix; {@code false} otherwise.
- */
- @Override
- public boolean isI() {
- return CooSemiringMatrixProperties.isIdentity(shape, data, rowIndices, colIndices);
- }
-
-
- /**
- * Computes the matrix multiplication between two matrices.
- *
- * @param b Second matrix in the matrix multiplication.
- *
- * @return The result of matrix multiplying this matrix with matrix {@code b}.
- *
- * @throws LinearAlgebraException If the number of columns in this matrix do not equal the number
- * of rows in matrix {@code b}.
- */
- @Override
- public U mult(T b) {
- ValidateParameters.ensureMatMultShapes(shape, b.shape);
- W[] dest = makeEmptyDataArray(numRows*b.numCols);
- CooSemiringMatMult.standard(
- data, rowIndices, colIndices, shape,
- b.data, b.rowIndices, b.colIndices, b.shape, dest);
-
- return makeLikeDenseTensor(new Shape(numRows, b.numCols), dest);
- }
-
- // TODO: Add mult2Sparse methods for all COO matrices.
-
- /**
- * Multiplies this matrix with the transpose of the {@code b} tensor as if by
- * {@code this.mult(b.H())}.
- * For large matrices, this method may
- * be significantly faster than directly computing the Hermitian transpose followed by the multiplication as
- * {@code this.mult(b.H())}.
- *
- * @param b The second matrix in the multiplication and the matrix to transpose.
- *
- * @return The result of multiplying this matrix with the Hermitian transpose of {@code b}.
- */
- @Override
- public U multTranspose(T b) {
- // TODO: MAke sure all complex and field matrices use the hermitian transpose for this method.
- ValidateParameters.ensureEquals(numCols, b.numCols);
- return mult(b.H());
- }
-
-
- /**
- * Stacks matrices along columns. A sparse matrix stored in coordinate list (COO) format. The {@link #data} of this COO vector are
+ * elements of a {@link Field}.
+ *
+ * The {@link #data non-zero data} and non-zero indices of a COO matrix are mutable but the {@link #shape}
+ * and total number of non-zero data is fixed.
+ *
+ * Sparse matrices allow for the efficient storage of and ops on matrices that contain many zero values.
+ *
+ * COO matrices are optimized for hyper-sparse matrices (i.e. matrices which contain almost all zeros relative to the size of the
+ * matrix).
+ *
+ * Note: many ops assume that the data of the COO matrix are sorted lexicographically by the row and column indices.
+ * (i.e.) by row indices first then column indices. However, this is not explicitly verified but any ops implemented in this
+ * class will preserve the lexicographical sorting.
+ *
+ * If indices need to be sorted, call {@link #sortIndices()}.
+ *
+ * @param Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- ValidateParameters.ensureNotEquals(axis1, axis2);
- ValidateParameters.ensureValidAxes(shape, axis1, axis2);
- // TODO: Investigate if this cast (W[]) is safe for example for Complex128[].
- return makeLikeTensor(new Shape(1, 1), (W[]) new Field[]{tr()}, new int[]{0}, new int[]{0});
- }
-
-
- /**
- * Sorts the indices of this tensor in lexicographical order while maintaining the associated value for each index.
- */
- public void sortIndices() {
- CooDataSorter.wrap(data, rowIndices, colIndices).sparseSort().unwrap(data, rowIndices, colIndices);
- }
-
-
- /**
- * Converts this sparse COO matrix to an equivalent dense matrix.
- * @return A dense matrix equivalent to this sparse COO matrix.
- */
- public U toDense() {
- W[] dense = makeEmptyDataArray(shape.totalEntriesIntValueExact());
- Arrays.fill(dense, zeroElement);
-
- for(int i = 0; i Computes the element-wise quotient between two tensors.
* WARNING: This method is not supported for sparse tensors. If called on a sparse tensor,
@@ -1427,41 +269,4 @@ public boolean isInfinite() {
public boolean isNaN() {
return FieldOps.isNaN(data);
}
-
-
- /**
- * Coalesces this sparse COO matrix. An uncoalesced matrix is a sparse matrix with multiple data for a single index. This
- * method will ensure that each index only has one non-zero value by summing duplicated data. If another form of aggregation other
- * than summing is desired, use {@link #coalesce(BinaryOperator)}.
- * @return A new coalesced sparse COO matrix which is equivalent to this COO matrix.
- * @see #coalesce(BinaryOperator)
- */
- public T coalesce() {
- SparseMatrixData The non-zero indices of this sparse tensor.
- *
- * Has shape {@code (nnz, rank)} where {@code nnz} is the number of non-zero data in this sparse tensor.
- */
- public final int[][] indices;
- /**
- * The number of non-zero data in this sparse tensor.
- */
- public final int nnz;
- /**
- * Stores the sparsity of this matrix.
- */
- public final double sparsity;
-
-
/**
* Creates a tensor with the specified data and shape.
*
@@ -114,451 +79,7 @@ public abstract class AbstractCooFieldTensor Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- SparseTensorData Computes the inner product between two vectors.
- *
- * Note: this method is distinct from {@link #dot(AbstractCooFieldVector)}. The inner product is equivalent to the dot product
- * of this tensor with the conjugation of {@code b}.
- *
- * @param b Second vector in the inner product.
- *
- * @return The inner product between this vector and the vector {@code b}.
- *
- * @throws IllegalArgumentException If this vector and vector {@code b} do not have the same number of data.
- * @see #dot(AbstractCooFieldVector)
- */
- @Override
- public Y inner(T b) {
- return CooFieldVectorOps.inner(this, b);
- }
-
-
- /**
- * Computes the dot product between two vectors.
- *
- * Note: this method is distinct from {@link #inner(AbstractCooFieldVector)}.
- * The inner product is equivalent to the dot product of this tensor with the conjugation of {@code b}.
- *
- * @param b Second vector in the dot product.
- *
- * @return The dot product between this vector and the vector {@code b}.
- *
- * @throws IllegalArgumentException If this vector and vector {@code b} do not have the same number of data.
- * @see #inner(AbstractCooFieldVector)
- */
- @Override
- public Y dot(T b) {
- return (Y) CooSemiringVectorOps.dot(shape, data, indices, b.shape, b.data, b.indices);
- }
-
-
- /**
- * Gets the length of a vector. Same as {@link #size()}.
- * WARNING: This method will throw a {@link ArithmeticException} if the
- * total number of data in this vector is greater than the maximum integer. In this case, the true size of this vector can
- * still be found by calling {@code shape.totalEntries()} on this vector.
- *
- * @return The length, i.e. the number of data, in this vector.
- * @throws ArithmeticException If the total number of data in this vector is greater than the maximum integer.
- */
- @Override
- public int length() {
- return shape.totalEntriesIntValueExact();
- }
-
-
- /**
- * Repeats a vector {@code n} times along a certain axis to create a matrix.
- *
- * @param n Number of times to repeat vector.
- * @param axis Axis along which to repeat vector:
- *
- * Stacks two vectors along specified axis.
- *
- *
- *
- * Stacking two vectors of length {@code n} along axis 0 stacks the vectors
- * as if they were row vectors resulting in a {@code 2-by-n} matrix.
- *
- *
- *
- * Stacking two vectors of length {@code n} along axis 1 stacks the vectors
- * as if they were column vectors resulting in a {@code n-by-2} matrix.
- *
- *
- * @param b Vector to stack with this vector.
- * @param axis Axis along which to stack vectors. If {@code axis=0}, then vectors are stacked as if they are row
- * vectors. If {@code axis=1}, then vectors are stacked as if they are column vectors.
- *
- * @return The result of stacking this vector and the vector {@code b}.
- *
- * @throws IllegalArgumentException If the number of data in this vector is different from the number of
- * data in the vector {@code b}.
- * @throws IllegalArgumentException If axis is not either 0 or 1.
- */
- @Override
- public V stack(T b, int axis) {
- ValidateParameters.ensureEquals(size, b.size);
- Y[] destEntries = makeEmptyDataArray(data.length + b.data.length);
- int[][] destIndices = new int[2][indices.length + b.indices.length]; // Row and column indices.
-
- CooConcat.stack(data, indices, b.data, b.indices, destEntries, destIndices[0], destIndices[1]);
- V mat = makeLikeMatrix(new Shape(2, size), destEntries, destIndices[0], destIndices[1]);
-
- return (axis == 0) ? mat : mat.T();
- }
-
-
- /**
- * Computes the outer product of two vectors.
- *
- * @param b Second vector in the outer product.
- *
- * @return The result of the vector outer product between this vector and {@code b}.
- *
- * @throws IllegalArgumentException If the two vectors do not have the same number of data.
- */
- @Override
- public W outer(T b) {
- // TODO: This should almost certainly return a sparse tensor. It seems unlikely that if a vectors are worth storing as
- // as COO vectors that the outer product would be dense. Further, this would almost never be useful as the dense matrix
- // would take up so much more memory than the two sparse COO vectors (assuming they are 'very' sparse).
- Shape destShape = new Shape(size, b.size);
- Y[] dest = makeEmptyDataArray(size*b.size);
- CooSemiringVectorOps.outerProduct(data, indices, size, b.data, b.indices, dest);
- return makeLikeDenseMatrix(shape, dest);
- }
-
-
- /**
- * Converts a vector to an equivalent matrix representing either a row or column vector.
- *
- * @param columVector Flag indicating whether to convert this vector to a matrix representing a row or column vector:
- * If {@code true}, the vector will be converted to a matrix representing a column vector.
- * If {@code false}, The vector will be converted to a matrix representing a row vector.
- *
- * @return A matrix equivalent to this vector.
- */
- @Override
- public V toMatrix(boolean columVector) {
- if(columVector) {
- // Convert to column vector
- int[] rowIndices = indices.clone();
- int[] colIndices = new int[data.length];
- Shape matShape = new Shape(size, 1);
-
- return makeLikeMatrix(matShape, data.clone(), rowIndices, colIndices);
- } else {
- // Convert to row vector.
- int[] rowIndices = new int[data.length];
- int[] colIndices = indices.clone();
- Shape matShape = new Shape(1, size);
-
- return makeLikeMatrix(matShape, data.clone(), rowIndices, colIndices);
- }
- }
-
-
- /**
- * Computes the element-wise sum between two tensors of the same shape.
- *
- * @param b Second tensor in the element-wise sum.
- *
- * @return The sum of this tensor with {@code b}.
- *
- * @throws TensorShapeException If this tensor and {@code b} do not have the same shape.
- */
- @Override
- public T add(T b) {
- SparseVectorData Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- throw new LinearAlgebraException("Tensor trace cannot be computed for a rank 1 tensor " +
- "(must be rank 2 or " + "greater).");
- }
-
-
- /**
- * Gets the zero element for the field of this vector.
- * @return The zero element for the field of this vector. If it could not be determined during construction of this object
- * and has not been set explicitly by {@link #setZeroElement(Field)} then {@code null} will be returned.
- */
- public Y getZeroElement() {
- return (Y) zeroElement;
- }
-
-
- /**
- * Sets the zero element for the field of this tensor.
- * @param zeroElement The zero element of this tensor.
- * @throws IllegalArgumentException If {@code zeroElement} is not an additive identity for the ring.
- */
- public void setZeroElement(Y zeroElement) {
- if (zeroElement.isZero()) {
- this.zeroElement = zeroElement;
- } else {
- throw new IllegalArgumentException("The provided zeroElement is not an additive identity.");
- }
- }
-
-
- /**
- * Converts this sparse COO matrix to an equivalent dense matrix.
- * @return A dense matrix equivalent to this sparse COO matrix.
- */
- public U toDense() {
- Y[] entries = makeEmptyDataArray(shape.totalEntriesIntValueExact());
- Arrays.fill(entries, zeroElement);
-
- for(int i = 0; i< nnz; i++)
- entries[indices[i]] = data[i];
-
- return makeLikeDenseTensor(shape, entries);
- }
-
-
- /**
- * Converts this matrix to an equivalent rank 1 tensor.
- * @return A tensor which is equivalent to this matrix.
- */
- public abstract AbstractTensor, Y[], Y> toTensor();
-
-
- /**
- * Converts this vector to an equivalent tensor with the specified shape.
- * @param newShape New shape for the tensor. Can be any rank but must be broadcastable to {@link #shape this.shape}.
- * @return A tensor equivalent to this matrix which has been reshaped to {@code newShape}
- */
- public abstract AbstractTensor, Y[], Y> toTensor(Shape newShape);
-
-
- /**
- * Computes the element-wise difference between two tensors of the same shape.
- *
- * @param b Second tensor in the element-wise difference.
- *
- * @return The difference of this tensor with {@code b}.
- *
- * @throws TensorShapeException If this tensor and {@code b} do not have the same shape.
- */
- @Override
- public T sub(T b) {
- SparseVectorData Pointers indicating starting index of each row within the {@link #colIndices} and {@link #data} arrays.
- * Has length {@link #numRows numRows + 1}.
- *
- * The range [{@code data[rowPointers[i]], data[rowPointers[i+1]]}) contains all {@link #data non-zero data} within
- * row {@code i}.
- *
- * Similarly, [{@code colData[rowPointers[i]], colData[rowPointers[i+1]]}) contains all {@link #colIndices column indices}
- * for the data in row {@code i}.
- *
- */
- public final int[] rowPointers;
- /**
- * Column indices for non-zero values of this sparse CSR matrix.
- */
- public final int[] colIndices;
- /**
- * Number of non-zero data in this CSR matrix.
- */
- public final int nnz;
- /**
- * The number of rows in this matrix.
- */
- public final int numRows;
- /**
- * The number of columns in this matrix.
- */
- public final int numCols;
- /**
- * The sparsity of this matrix.
- */
- private final double sparsity;
/**
@@ -106,498 +57,16 @@ public abstract class AbstractCsrFieldMatrix Constructs a sparse COO matrix of a similar type to this sparse CSR matrix.
- * Note: this method constructs a new COO matrix with the specified data and indices. It does not convert this matrix
- * to a CSR matrix. To convert this matrix to a sparse COO matrix use {@link #toCoo()}.
- * @param shape Shape of the COO matrix.
- * @param entries Non-zero data of the COO matrix.
- * @param rowIndices Non-zero row indices of the sparse COO matrix.
- * @param colIndices Non-zero column indices of the Sparse COO matrix.
- * @return A sparse COO matrix of a similar type to this sparse CSR matrix.
- */
- public abstract AbstractCooFieldMatrix, U, V, W> makeLikeCooMatrix(
- Shape shape, W[] entries, int[] rowIndices, int[] colIndices);
-
-
- /**
- * Gets the sparsity of this matrix as a decimal percentage.
- * That is, the percentage of data in this matrix that are zero.
- * @return The sparsity of this matrix as a decimal percentage.
- * @see #density()
- */
- public double sparsity() {
- return sparsity;
- }
-
-
- /**
- * Gets the density of this matrix as a decimal percentage.
- * That is, the percentage of data in this matrix that are non-zero.
- * @return The density of this matrix as a decimal percentage.
- * @see #sparsity
- */
- public double density() {
- return 1.0 - sparsity;
- }
-
-
- /**
- * Gets the length of the data array which backs this matrix.
- *
- * @return The length of the data array which backs this matrix.
- */
- @Override
- public int dataLength() {
- return data.length;
- }
-
-
- /**
- * Gets the zero element for the field of this tensor.
- * @return The zero element for the field of this tensor. If it could not be determined during construction of this object
- * and has not been set explicitly by {@link #setZeroElement(Field)} then {@code null} will be returned.
- *
- * @see #setZeroElement(Field)
- */
- public W getZeroElement() {
- return zeroElement;
- }
-
-
- /**
- * Sets the zero element for the field of this tensor.
- * @param zeroElement The zero element of this tensor.
- * @throws IllegalArgumentException If {@code zeroElement} is not an additive identity for the field.
- *
- * @see #getZeroElement()
- */
- public void setZeroElement(W zeroElement) {
- if (zeroElement.isZero()) {
- this.zeroElement = zeroElement;
- } else {
- throw new IllegalArgumentException("The provided zeroElement is not an additive identity.");
- }
- }
-
-
-
- /**
- * Gets the element of this tensor at the specified indices.
- *
- * @param indices Indices of the element to get.
- *
- * @return The element of this tensor at the specified indices.
- *
- * @throws ArrayIndexOutOfBoundsException If any indices are not within this tensor.
- */
- @Override
- public W get(int... indices) {
- ValidateParameters.validateTensorIndex(shape, indices);
- int row = indices[0];
- int col = indices[1];
- return get(row, col);
- }
-
-
- /**
- * Sets the element of this tensor at the specified indices.
- *
- * @param value New value to set the specified index of this tensor to.
- * @param indices Indices of the element to set.
- *
- * @return If this tensor is dense, a reference to this tensor is returned. If this tensor is sparse, a copy of this tensor with
- * the updated value is returned.
- *
- * @throws IndexOutOfBoundsException If {@code indices} is not within the bounds of this tensor.
- */
- @Override
- public T set(W value, int... indices) {
- ValidateParameters.validateTensorIndex(shape, indices);
- return set(value, indices[0], indices[1]);
- }
-
-
- /**
- * Flattens tensor to single dimension while preserving order of data.
- *
- * @return The flattened tensor.
- *
- * @see #flatten(int)
- */
- @Override
- public T flatten() {
- int[] newRowPointers = new int[2];
- newRowPointers[1] = nnz;
- return makeLikeTensor(
- new Shape(1, shape.totalEntriesIntValueExact()),
- data.clone(),
- newRowPointers,
- colIndices.clone());
- }
-
-
- /**
- * Flattens a tensor along the specified axis. Unlike {@link #flatten()}
- *
- * @param axis Axis along which to flatten tensor.
- *
- * @throws ArrayIndexOutOfBoundsException If the axis is not positive or larger than {@code this.{@link #getRank()}-1}.
- * @see #flatten()
- */
- @Override
- public T flatten(int axis) {
- ValidateParameters.ensureValidAxes(shape, axis);
- int[] newRowPointers;
- int[] newColIndices;
-
- if (axis == 0) {
- // Flatten to a single row.
- newRowPointers = new int[2];
- newRowPointers[1] = nnz;
- newColIndices = new int[nnz];
- } else {
- // Flatten to a single column.
- int flatSize = shape.totalEntriesIntValueExact();
- newColIndices = new int[nnz]; // Set all column indices to 0.
- newRowPointers = new int[flatSize + 1];
- }
-
- Shape newShape = CsrConversions.flatten(shape, data, rowPointers, colIndices, axis, newRowPointers, newColIndices);
-
- return makeLikeTensor(
- new Shape(shape.totalEntriesIntValueExact(), 1),
- data.clone(),
- newRowPointers,
- newColIndices);
- }
-
-
- /**
- * Copies and reshapes this tensor.
- *
- * @param newShape New shape for the tensor.
- *
- * @return A copy of this tensor with the new shape.
- *
- * @throws TensorShapeException If {@code newShape} is not broadcastable to {@link #shape this.shape}.
- */
- @Override
- public T reshape(Shape newShape) {
- return (T) toCoo().reshape(newShape).toCsr();
- }
-
-
- /**
- * Computes the transpose of a tensor by exchanging the first and last axes of this tensor.
- *
- * @return The transpose of this tensor.
- *
- * @see #T(int, int)
- * @see #T(int...)
- */
- @Override
- public T T() {
- W[] dest = makeEmptyDataArray(data.length);
- int[] destRowPointers = new int[numCols+1];
- int[] destColIndices = new int[data.length];
- CsrOps.transpose(data, rowPointers, colIndices, dest, destRowPointers, destColIndices);
-
- return makeLikeTensor(shape.swapAxes(0, 1), dest, destRowPointers, destColIndices);
- }
-
-
- /**
- * Computes the element-wise sum between two tensors of the same shape.
- *
- * @param b Second tensor in the element-wise sum.
- *
- * @return The sum of this tensor with {@code b}.
- *
- * @throws TensorShapeException If this tensor and {@code b} do not have the same shape.
- */
- @Override
- public T add(T b) {
- SparseMatrixData Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- // TODO: Needs to return a tensor and probably be abstract and implemented in concrete children classes.
- ValidateParameters.ensureNotEquals(axis1, axis2);
- ValidateParameters.ensureValidAxes(shape, axis1, axis2);
-
- // TODO: Investigate the (W[]) cast for array of specific field implementation (e.g. complex128).
- return (T) makeLikeTensor(new Shape(1, 1), (W[]) new Field[]{tr()}, new int[]{0}, new int[]{0});
- }
-
-
- /**
- * Computes the transpose of a tensor by exchanging {@code axis1} and {@code axis2}.
- *
- * @param axis1 First axis to exchange.
- * @param axis2 Second axis to exchange.
- *
- * @return The transpose of this tensor according to the specified axes.
- *
- * @throws IndexOutOfBoundsException If either {@code axis1} or {@code axis2} are out of bounds for the rank of this tensor.
- * @see #T()
- * @see #T(int...)
- */
- @Override
- public T T(int axis1, int axis2) {
- ValidateParameters.ensureValidAxes(shape, axis1, axis2);
- if(axis1 == axis2) return copy();
- return T();
- }
-
-
- /**
- * Computes the transpose of this tensor. That is, permutes the axes of this tensor so that it matches
- * the permutation specified by {@code axes}.
- *
- * @param axes Permutation of tensor axis. If the tensor has rank {@code N}, then this must be an array of length
- * {@code N} which is a permutation of {@code {0, 1, 2, ..., N-1}}.
- *
- * @return The transpose of this tensor with its axes permuted by the {@code axes} array.
- *
- * @throws IndexOutOfBoundsException If any element of {@code axes} is out of bounds for the rank of this tensor.
- * @throws IllegalArgumentException If {@code axes} is not a permutation of {@code {1, 2, 3, ... N-1}}.
- * @see #T(int, int)
- * @see #T()
- */
- @Override
- public T T(int... axes) {
- if(axes.length != 2) {
- throw new IllegalArgumentException("Cannot transpose axes "
- + Arrays.toString(axes) + " for a tensor of rank " + rank);
- }
-
- return T(axes[0], axes[1]);
- }
-
-
- /**
- * Gets the number of rows in this matrix.
- *
- * @return The number of rows in this matrix.
- */
- @Override
- public int numRows() {
- return numRows;
- }
-
-
- /**
- * Gets the number of columns in this matrix.
- *
- * @return The number of columns in this matrix.
- */
- @Override
- public int numCols() {
- return numCols;
- }
-
-
- /**
- * Gets the element of this matrix at this specified {@code row} and {@code col}.
- *
- * @param row Row index of the item to get from this matrix.
- * @param col Column index of the item to get from this matrix.
- *
- * @return The element of this matrix at the specified index.
- */
- @Override
- public W get(int row, int col) {
- ValidateParameters.validateTensorIndex(shape, row, col);
- int loc = Arrays.binarySearch(colIndices, rowPointers[row], rowPointers[row+1], col);
-
- if(loc >= 0) return data[loc];
- else return zeroElement;
- }
-
-
- /**
- * Computes the trace of this matrix. That is, the sum of elements along the principle diagonal of this matrix.
- *
- * Same as {@link #trace()}.
- *
- * @return The trace of this matrix.
- *
- * @throws IllegalArgumentException If this matrix is not square.
- */
- @Override
- public W tr() {
- ValidateParameters.ensureSquare(shape);
- W tr = SemiringCsrOps.trace(data, rowPointers, colIndices);
- return (tr == null) ? zeroElement : tr;
- }
-
-
- /**
- * Checks if this matrix is upper triangular.
- *
- * @return {@code true} is this matrix is upper triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriL()
- * @see #isDiag()
- */
- @Override
- public boolean isTriU() {
- return SemiringCsrProperties.isTriU(shape, data, rowPointers, colIndices);
- }
-
-
- /**
- * Checks if this matrix is lower triangular.
- *
- * @return {@code true} is this matrix is lower triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriU()
- * @see #isDiag()
- */
- @Override
- public boolean isTriL() {
- return SemiringCsrProperties.isTriL(shape, data, rowPointers, colIndices);
+ super(shape, entries, rowPointers, colIndices);
}
-
- /**
- * Checks if this matrix is the identity matrix. That is, checks if this matrix is square and contains
- * only ones along the principle diagonal and zeros everywhere else.
- *
- * @return {@code true} if this matrix is the identity matrix; {@code false} otherwise.
- */
- @Override
- public boolean isI() {
- return SemiringCsrProperties.isIdentity(shape, data, rowPointers, colIndices);
- }
-
-
- /**
- * Computes the matrix multiplication between two matrices.
- *
- * @param b Second matrix in the matrix multiplication.
- *
- * @return The result of matrix multiplying this matrix with matrix {@code b}.
- *
- * @throws LinearAlgebraException If the number of columns in this matrix do not equal the number
- * of rows in matrix {@code b}.
- * @see #mult2Csr(AbstractCsrFieldMatrix)
- */
- @Override
- public U mult(T b) {
- Shape destShape = new Shape(numRows, b.numCols);
- W[] destArray = makeEmptyDataArray(numRows*b.numCols);
-
- SemiringCsrMatMult.standard(
- shape, data, rowPointers, colIndices, b.shape,
- b.data, b.rowPointers, b.colIndices,
- destArray, zeroElement);
-
- return makeLikeDenseTensor(destShape, destArray);
- }
-
-
/**
* Computes the matrix multiplication between two sparse CSR matrices and stores the result in a sparse matrix.
* Warning: this method should be used with caution as sparse-sparse matrix multiplication may result in a dense matrix.
- * In such a case, this method will likely be significantly slower than {@link #mult(AbstractCsrFieldMatrix)}.
+ * In such a case, this method will likely be significantly slower than {@link #mult(AbstractCsrSemiringMatrix)}.
* @param b Second matrix in the matrix multiplication.
* @return The result of matrix multiplying this matrix with matrix {@code b} as a sparse CSR matrix.
- * @see #mult(AbstractCsrFieldMatrix)
+ * @see #mult(AbstractCsrSemiringMatrix)
*/
public T mult2Csr(T b) {
SparseMatrixData Converts this sparse CSR matrix to an equivalent dense matrix.
- *
- * The zero data of this CSR matrix will be attempted to be filled with a zero value if it could be determined during
- * construction of this sparse CSR matrix. If the zero value could not be determined the zero data will be filled with
- * {@code null} (this only happens when {@code nnz==0}). To avoid this, the zero element of the field for this
- * matrix can be set explicitly using {@link #setZeroElement(Field)}.
- *
- * @return A dense matrix which is equivalent to this sparse CSR matrix.
- */
- public U toDense() {
- W[] dest = makeEmptyDataArray(shape.totalEntriesIntValueExact());
- CsrConversions.toDense(shape, data, rowPointers, colIndices, dest, zeroElement);
- return makeLikeDenseTensor(shape, dest);
- }
-
-
- /**
- * Converts this sparse CSR matrix to an equivalent sparse COO matrix.
- * @return A sparse COO matrix equivalent to this sparse CSR matrix.
- */
- public abstract AbstractCooFieldMatrix toCoo();
-
-
- /**
- * Converts this CSR matrix to an equivalent sparse COO tensor.
- * @return An sparse COO tensor equivalent to this CSR matrix.
- */
- public abstract AbstractCooFieldTensor, ?, W> toTensor();
-
-
- /**
- * Converts this CSR matrix to an equivalent COO tensor with the specified shape.
- * @param newShape New shape for the COO tensor. Can be any rank but must be broadcastable to {@link #shape this.shape}.
- * @return A COO tensor equivalent to this CSR matrix which has been reshaped to {@code newShape}
- */
- public abstract AbstractCooFieldTensor, ?, W> toTensor(Shape shape);
-
-
- /**
- * Converts this sparse CSR matrix to an equivalent vector. If this matrix is not a row or column vector it will be flattened
- * before conversion.
- * @return A vector equivalent to this CSR matrix.
- */
- public V toVector() {
- return (V) toCoo().toVector();
- }
-
-
/**
* Computes the element-wise quotient between two tensors.
* WARNING: This method is not supported for sparse tensors. If called on a sparse tensor,
diff --git a/src/main/java/org/flag4j/arrays/backend/field_arrays/AbstractDenseFieldMatrix.java b/src/main/java/org/flag4j/arrays/backend/field_arrays/AbstractDenseFieldMatrix.java
index 1bafb8efd..9c697c842 100644
--- a/src/main/java/org/flag4j/arrays/backend/field_arrays/AbstractDenseFieldMatrix.java
+++ b/src/main/java/org/flag4j/arrays/backend/field_arrays/AbstractDenseFieldMatrix.java
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2024. Jacob Watters
+ * Copyright (c) 2024-2025. Jacob Watters
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,32 +26,20 @@
import org.flag4j.algebraic_structures.Field;
import org.flag4j.arrays.Shape;
-import org.flag4j.arrays.SparseMatrixData;
import org.flag4j.arrays.backend.MatrixMixin;
+import org.flag4j.arrays.backend.ring_arrays.AbstractDenseRingMatrix;
import org.flag4j.arrays.dense.Matrix;
import org.flag4j.linalg.ops.TransposeDispatcher;
+import org.flag4j.linalg.ops.common.field_ops.FieldOps;
import org.flag4j.linalg.ops.common.ring_ops.RingOps;
-import org.flag4j.linalg.ops.dense.field_ops.DenseFieldProperties;
-import org.flag4j.linalg.ops.dense.semiring_ops.DenseSemiringConversions;
-import org.flag4j.linalg.ops.dense.semiring_ops.DenseSemiringMatMultDispatcher;
-import org.flag4j.util.ArrayUtils;
-import org.flag4j.util.ValidateParameters;
-import org.flag4j.util.exceptions.LinearAlgebraException;
-
-import java.util.Arrays;
+import org.flag4j.linalg.ops.common.ring_ops.RingProperties;
+import org.flag4j.linalg.ops.dense.field_ops.DenseFieldElemDiv;
+// TODO: Javadoc.
public abstract class AbstractDenseFieldMatrix Computes the trace of this matrix. That is, the sum of elements along the principle diagonal of this matrix.
- *
- * Same as {@link #trace()}.
- *
- * @return The trace of this matrix.
- *
- * @throws IllegalArgumentException If this matrix is not square.
- */
- @Override
- public V tr() {
- ValidateParameters.ensureSquareMatrix(shape);
- V sum = data[0];
- int colsOffset = this.numCols + 1;
-
- for(int i=1; i The base class for all dense {@link Field} tensors.
@@ -54,14 +43,9 @@
* @param Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- Shape destShape = DenseSemiringOps.getTrShape(shape, axis1, axis2);
- V[] dest = makeEmptyDataArray(destShape.totalEntriesIntValueExact());
- return makeLikeTensor(destShape, dest);
- }
-
-
/**
* Computes the element-wise quotient between two tensors.
*
@@ -486,51 +152,17 @@ public boolean isNaN() {
}
- /**
- * Converts this tensor to an equivalent sparse COO tensor.
- * @return A sparse COO tensor that is equivalent to this dense tensor.
- * @see #toCoo(double)
- */
- public AbstractTensor, ?, V> toCoo() {
- return toCoo(0.9);
- }
-
-
- /**
- * Converts this tensor to an equivalent sparse COO tensor.
- * @param estimatedSparsity Estimated sparsity of the tensor. Must be between 0 and 1 inclusive. If this is an accurate estimation
- * it may provide a slight speedup and can reduce unneeded memory consumption. If memory is a concern, it is better to
- * over-estimate the sparsity. If speed is the concern it is better to under-estimate the sparsity.
- * @return A sparse COO tensor that is equivalent to this dense tensor.
- * @see #toCoo(double)
- */
- public AbstractTensor, ?, V> toCoo(double estimatedSparsity) {
- SparseTensorData Computes the dot product between two vectors.
- *
- * Note: this method is distinct from {@link #inner(AbstractDenseFieldVector)}. The inner product is equivalent to the dot product
- * of this tensor with the conjugation of {@code b}.
+ * Computes the outer product of two vectors.
*
- * @param b Second vector in the dot product.
+ * @param b Second vector in the outer product.
*
- * @return The dot product between this vector and the vector {@code b}.
+ * @return The result of the vector outer product between this vector and {@code b}.
*
- * @throws IllegalArgumentException If this vector and vector {@code b} do not have the same number of data.
- * @see #inner(AbstractDenseFieldVector)
+ * @throws IllegalArgumentException If the two vectors do not have the same number of data.
*/
@Override
- public V dot(T b) {
- return DenseSemiringVectorOps.dotProduct(data, b.data);
+ public U outer(T b) {
+ V[] dest = makeEmptyDataArray(size*b.size);
+ DenseFieldVectorOps.outerProduct(data, b.data, dest);
+ return makeLikeMatrix(new Shape(size, b.size), dest);
}
/**
- * Gets the length of a vector. Same as {@link #size()}.
+ * Computes the element-wise absolute value of this tensor.
*
- * @return The length, i.e. the number of data, in this vector.
+ * @return The element-wise absolute value of this tensor.
*/
@Override
- public int length() {
- return size;
+ public Vector abs() {
+ double[] abs = new double[data.length];
+ RingOps.abs(data, abs);
+ return new Vector(shape, abs);
}
/**
- * Repeats a vector {@code n} times along a certain axis to create a matrix.
- *
- * @param n Number of times to repeat vector. Must be positive.
- * @param axis Axis along which to repeat vector. Must be either 1 or 0.
- * Stacks two vectors along specified axis.
- *
- * Stacking two vectors of length {@code n} along axis 0 stacks the vectors
- * as if they were row vectors resulting in a {@code 2-by-n} matrix.
- *
- * Stacking two vectors of length {@code n} along axis 1 stacks the vectors
- * as if they were column vectors resulting in a {@code n-by-2} matrix.
- *
- * @param b Vector to stack with this vector.
- * @param axis Axis along which to stack vectors. If {@code axis=0}, then vectors are stacked as if they are row
- * vectors. If {@code axis=1}, then vectors are stacked as if they are column vectors.
- *
- * @return The result of stacking this vector and the vector {@code b}.
+ * Computes the magnitude of this vector.
*
- * @throws IllegalArgumentException If the number of data in this vector is different from the number of
- * data in the vector {@code b}.
- * @throws IllegalArgumentException If axis is not either 0 or 1.
+ * @return The magnitude of this vector.
*/
@Override
- public U stack(T b, int axis) {
- V[] dest = makeEmptyDataArray(2*size);
- DenseConcat.stack(data, b.data, axis, dest);
- Shape shape = (axis==0) ? new Shape(2, size) : new Shape(size, 2);
- return makeLikeMatrix(shape, dest);
+ public V mag() {
+ V mag = getZeroElement();
+
+ for(int i=0; i A sparse matrix stored in coordinate list (COO) format. The {@link #data} of this COO matrix are
* elements of a {@link Ring}.
@@ -89,40 +70,10 @@ public abstract class AbstractCooRingMatrix Computes the trace of this matrix. That is, the sum of elements along the principle diagonal of this matrix.
- *
- * Same as {@link #trace()}.
- *
- * @return The trace of this matrix.
- *
- * @throws IllegalArgumentException If this matrix is not square.
- */
- @Override
- public W tr() {
- W trace = getZeroElement();
-
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i]==colIndices[i]) trace = trace.add((W) data[i]); // Then entry is on the diagonal.
-
- return trace;
- }
-
-
- /**
- * Checks if this matrix is upper triangular.
- *
- * @return {@code true} is this matrix is upper triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriL()
- * @see #isDiag()
- */
- @Override
- public boolean isTriU() {
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i] > colIndices[i] && !data[i].isZero()) return false; // Then non-zero entry is not in upper triangle.
-
- return true;
- }
-
-
- /**
- * Checks if this matrix is lower triangular.
- *
- * @return {@code true} is this matrix is lower triangular; {@code false} otherwise.
- *
- * @see #isTri()
- * @see #isTriU()
- * @see #isDiag()
- */
- @Override
- public boolean isTriL() {
- for(int i = 0; i< data.length; i++)
- if(rowIndices[i] < colIndices[i] && !data[i].isZero()) return false; // Then non-zero entry is not in lower triangle.
-
- return true;
- }
-
-
- /**
- * Checks if this matrix is the identity matrix. That is, checks if this matrix is square and contains
- * only ones along the principle diagonal and zeros everywhere else.
- *
- * @return {@code true} if this matrix is the identity matrix; {@code false} otherwise.
- */
- @Override
- public boolean isI() {
- return CooSemiringMatrixProperties.isIdentity(shape, data, rowIndices, colIndices);
- }
-
-
- /**
- * Computes the matrix multiplication between two matrices.
- *
- * @param b Second matrix in the matrix multiplication.
- *
- * @return The result of matrix multiplying this matrix with matrix {@code b}.
- *
- * @throws LinearAlgebraException If the number of columns in this matrix do not equal the number
- * of rows in matrix {@code b}.
- */
- @Override
- public U mult(T b) {
- ValidateParameters.ensureMatMultShapes(shape, b.shape);
- W[] dest = (W[]) new Ring[numRows*b.numCols];
- CooSemiringMatMult.standard(
- data, rowIndices, colIndices, shape,
- b.data, b.rowIndices, b.colIndices, b.shape, dest);
-
- return makeLikeDenseTensor(new Shape(numRows, b.numCols), dest);
- }
-
-
- /**
- * Multiplies this matrix with the transpose of the {@code b} tensor as if by
- * {@code this.mult(b.T())}.
- * For large matrices, this method may
- * be significantly faster than directly computing the transpose followed by the multiplication as
- * {@code this.mult(b.T())}.
- *
- * @param b The second matrix in the multiplication and the matrix to transpose.
- *
- * @return The result of multiplying this matrix with the transpose of {@code b}.
- */
- @Override
- public U multTranspose(T b) {
- ValidateParameters.ensureEquals(numCols, b.numCols);
- return mult(b.T());
- }
-
-
- /**
- * Stacks matrices along columns. Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- ValidateParameters.ensureNotEquals(axis1, axis2);
- ValidateParameters.ensureValidAxes(shape, axis1, axis2);
-
- return makeLikeTensor(new Shape(1, 1), (W[]) new Ring[]{tr()}, new int[]{0}, new int[]{0});
- }
-
-
- /**
- * Sorts the indices of this tensor in lexicographical order while maintaining the associated value for each index.
- */
- public void sortIndices() {
- CooDataSorter.wrap(data, rowIndices, colIndices).sparseSort().unwrap(data, rowIndices, colIndices);
- }
-
-
- /**
- * Converts this sparse COO matrix to an equivalent dense matrix.
- * @return A dense matrix equivalent to this sparse COO matrix.
- */
- public U toDense() {
- W[] data = (W[]) new Ring[totalEntries().intValueExact()];
-
- for(int i = 0; i< nnz; i++)
- data[rowIndices[i]*numCols + colIndices[i]] = this.data[i];
-
- return makeLikeDenseTensor(shape, data);
- }
-
-
- /**
- * Converts this sparse COO matrix to an equivalent sparse CSR matrix.
- * @return A sparse CSR matrix equivalent to this sparse COO matrix.
- */
- public AbstractCsrRingMatrix, U, V, W> toCsr() {
- W[] csrEntries = (W[]) new Ring[data.length];
- int[] csrRowPointers = new int[numRows + 1];
- int[] csrColPointers = new int[colIndices.length];
- CooConversions.toCsr(shape, data, rowIndices, colIndices, csrEntries, csrRowPointers, csrColPointers);
- return makeLikeCsrMatrix(shape, csrEntries, csrRowPointers, csrColPointers);
- }
-
-
- /**
- * Converts this matrix to an equivalent tensor.
- * @return A tensor which is equivalent to this matrix.
- */
- public abstract AbstractTensor, W[], W> toTensor();
-
-
- /**
- * Converts this matrix to an equivalent tensor with the specified shape.
- * @param newShape New shape for the tensor. Can be any rank but must be broadcastable to {@link #shape this.shape}.
- * @return A tensor equivalent to this matrix which has been reshaped to {@code newShape}
- */
- public abstract AbstractTensor, W[], W> toTensor(Shape newShape);
-
-
- /**
- * Converts this sparse CSR matrix to an equivalent vector. If this matrix is not a row or column vector it will be flattened
- * before conversion.
- * @return A vector equivalent to this CSR matrix.
- */
- public V toVector() {
- int[] destIndices = new int[data.length];
- for(int i = 0; i< data.length; i++)
- destIndices[i] = rowIndices[i]*colIndices[i];
-
- return makeLikeVector(new Shape(numRows*numCols), data.clone(), destIndices);
- }
-
-
- /**
- * Coalesces this sparse COO matrix. An uncoalesced matrix is a sparse matrix with multiple data for a single index. This
- * method will ensure that each index only has one non-zero value by summing duplicated data. If another form of aggregation other
- * than summing is desired, use {@link #coalesce(BinaryOperator)}.
- * @return A new coalesced sparse COO matrix which is equivalent to this COO matrix.
- * @see #coalesce(BinaryOperator)
- */
- public T coalesce() {
- SparseMatrixData Base class for all sparse {@link Ring} tensors stored in coordinate list (COO) format. The data of this COO tensor are
* elements of a {@link Ring}.
@@ -77,28 +64,9 @@
*/
public abstract class AbstractCooRingTensor The non-zero indices of this sparse tensor.
- *
- * Has shape {@code (nnz, rank)} where {@code nnz} is the number of non-zero data in this sparse tensor.
- */
- public final int[][] indices;
- /**
- * The number of non-zero data in this sparse tensor.
- */
- public final int nnz;
- /**
- * Stores the sparsity of this matrix.
- */
- public final double sparsity;
-
/**
* Creates a tensor with the specified data and shape.
@@ -108,430 +76,7 @@ public abstract class AbstractCooRingTensor Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- SparseTensorData A sparse vector stored in coordinate list (COO) format. The {@link #data} of this COO vector are
* elements of a {@link Ring}.
@@ -85,32 +69,10 @@ public abstract class AbstractCooRingVector<
V extends AbstractCooRingMatrix Computes the inner product between two vectors.
*
- * Note: this method is distinct from {@link #dot(AbstractCooRingVector)}. The inner product is equivalent to the dot product
+ * Note: this method is distinct from {@link #dot(AbstractCooSemiringVector)}. The inner product is equivalent to the dot product
* of this tensor with the conjugation of {@code b}.
*
* @param b Second vector in the inner product.
@@ -399,337 +97,14 @@ public T join(T b) {
* @return The inner product between this vector and the vector {@code b}.
*
* @throws IllegalArgumentException If this vector and vector {@code b} do not have the same number of data.
- * @see #dot(AbstractCooRingVector)
+ * @see #dot(AbstractCooSemiringVector)
*/
@Override
public Y inner(T b) {
- return dot(b); // For rings, this will be the same.
- }
-
-
- /**
- * Computes the dot product between two vectors.
- *
- * Note: this method is distinct from {@link #inner(AbstractCooRingVector)}.
- * The inner product is equivalent to the dot product of this tensor with the conjugation of {@code b}.
- *
- * @param b Second vector in the dot product.
- *
- * @return The dot product between this vector and the vector {@code b}.
- *
- * @throws IllegalArgumentException If this vector and vector {@code b} do not have the same number of data.
- * @see #inner(AbstractCooRingVector)
- */
- @Override
- public Y dot(T b) {
- return CooSemiringVectorOps.dot(shape, data, indices, b.shape, b.data, b.indices);
- }
-
-
- /**
- * Gets the length of a vector. Same as {@link #size()}.
- * WARNING: This method will throw a {@link ArithmeticException} if the
- * total number of data in this vector is greater than the maximum integer. In this case, the true size of this vector can
- * still be found by calling {@code shape.totalEntries()} on this vector.
- *
- * @return The length, i.e. the number of data, in this vector.
- * @throws ArithmeticException If the total number of data in this vector is greater than the maximum integer.
- */
- @Override
- public int length() {
- return shape.totalEntriesIntValueExact();
- }
-
-
- /**
- * Repeats a vector {@code n} times along a certain axis to create a matrix.
- *
- * @param n Number of times to repeat vector.
- * @param axis Axis along which to repeat vector:
- *
- * Stacks two vectors along specified axis.
- *
- *
- *
- * Stacking two vectors of length {@code n} along axis 0 stacks the vectors
- * as if they were row vectors resulting in a {@code 2-by-n} matrix.
- *
- *
- *
- * Stacking two vectors of length {@code n} along axis 1 stacks the vectors
- * as if they were column vectors resulting in a {@code n-by-2} matrix.
- *
- *
- * @param b Vector to stack with this vector.
- * @param axis Axis along which to stack vectors. If {@code axis=0}, then vectors are stacked as if they are row
- * vectors. If {@code axis=1}, then vectors are stacked as if they are column vectors.
- *
- * @return The result of stacking this vector and the vector {@code b}.
- *
- * @throws IllegalArgumentException If the number of data in this vector is different from the number of
- * data in the vector {@code b}.
- * @throws IllegalArgumentException If axis is not either 0 or 1.
- */
- @Override
- public V stack(T b, int axis) {
- ValidateParameters.ensureEquals(size, b.size);
- Y[] destEntries = (Y[]) new Ring[data.length + b.data.length];
- int[][] destIndices = new int[2][indices.length + indices.length]; // Row and column indices.
-
- CooConcat.stack(data, indices, b.data, b.indices, destEntries, destIndices[0], destIndices[1]);
- V mat = makeLikeMatrix(new Shape(2, size), destEntries, destIndices[0], destIndices[1]);
-
- return (axis == 0) ? mat : mat.T();
- }
-
-
- /**
- * Computes the outer product of two vectors.
- *
- * @param b Second vector in the outer product.
- *
- * @return The result of the vector outer product between this vector and {@code b}.
- *
- * @throws IllegalArgumentException If the two vectors do not have the same number of data.
- */
- @Override
- public W outer(T b) {
- Shape destShape = new Shape(size, b.size);
- Y[] dest = (Y[]) new Ring[size*b.size];
- CooSemiringVectorOps.outerProduct(data, indices, size, b.data, b.indices, dest);
- return makeLikeDenseMatrix(shape, dest);
- }
-
-
- /**
- * Converts a vector to an equivalent matrix representing either a row or column vector.
- *
- * @param columVector Flag indicating whether to convert this vector to a matrix representing a row or column vector:
- * If {@code true}, the vector will be converted to a matrix representing a column vector.
- * If {@code false}, The vector will be converted to a matrix representing a row vector.
- *
- * @return A matrix equivalent to this vector.
- */
- @Override
- public V toMatrix(boolean columVector) {
- if(columVector) {
- // Convert to column vector
- int[] rowIndices = indices.clone();
- int[] colIndices = new int[data.length];
- Shape matShape = new Shape(size, 1);
-
- return makeLikeMatrix(matShape, data.clone(), rowIndices, colIndices);
- } else {
- // Convert to row vector.
- int[] rowIndices = new int[data.length];
- int[] colIndices = indices.clone();
- Shape matShape = new Shape(1, size);
-
- return makeLikeMatrix(matShape, data.clone(), rowIndices, colIndices);
- }
- }
-
-
- /**
- * Normalizes this vector to a unit length vector.
- *
- * @return This vector normalized to a unit length.
- */
- @Override
- public T normalize() {
- throw new UnsupportedOperationException("Normalization not supported for arrays vectors.");
- }
-
-
- /**
- * Computes the magnitude of this vector.
- *
- * @return The magnitude of this vector.
- */
- @Override
- public Y mag() {
- return AggregateSemiring.sum(data);
- }
-
-
- /**
- * Gets the element of this vector at the specified index.
- *
- * @param idx Index of the element to get within this vector.
- *
- * @return The element of this vector at index {@code idx}.
- */
- @Override
- public Y get(int idx) {
- ValidateParameters.validateTensorIndex(shape, idx);
- Y value = CooGetSet.getCoo(data, indices, idx);
- return (value == null) ? getZeroElement() : value;
- }
-
-
- /**
- * Computes the element-wise sum between two tensors of the same shape.
- *
- * @param b Second tensor in the element-wise sum.
- *
- * @return The sum of this tensor with {@code b}.
- *
- * @throws TensorShapeException If this tensor and {@code b} do not have the same shape.
- */
- @Override
- public T add(T b) {
- SparseVectorData Computes the generalized trace of this tensor along the specified axes.
- *
- * The generalized tensor trace is the sum along the diagonal values of the 2D sub-arrays of this tensor specified by
- * {@code axis1} and {@code axis2}. The shape of the resulting tensor is equal to this tensor with the
- * {@code axis1} and {@code axis2} removed.
- *
- * @param axis1 First axis for 2D sub-array.
- * @param axis2 Second axis for 2D sub-array.
- *
- * @return The generalized trace of this tensor along {@code axis1} and {@code axis2}.
- *
- * @throws IndexOutOfBoundsException If the two axes are not both larger than zero and less than this tensors rank.
- * @throws IllegalArgumentException If {@code axis1 == axis2} or {@code this.shape.get(axis1) != this.shape.get(axis1)}
- * (i.e. the axes are equal or the tensor does not have the same length along the two axes.)
- */
- @Override
- public T tensorTr(int axis1, int axis2) {
- throw new LinearAlgebraException("Tensor trace cannot be computed for a rank 1 tensor " +
- "(must be rank 2 or " + "greater).");
- }
-
-
- /**
- * Gets the zero element for the field of this vector.
- * @return The zero element for the field of this vector. If it could not be determined during construction of this object
- * and has not been set explicitly by {@link #setZeroElement(Ring)} then {@code null} will be returned.
- */
- public Y getZeroElement() {
- return zeroElement;
- }
-
-
- /**
- * Sets the zero element for the field of this tensor.
- * @param zeroElement The zero element of this tensor.
- * @throws IllegalArgumentException If {@code zeroElement} is not an additive identity for the ring.
- */
- public void setZeroElement(Y zeroElement) {
- if (zeroElement.isZero()) {
- this.zeroElement = zeroElement;
- } else {
- throw new IllegalArgumentException("The provided zeroElement is not an additive identity.");
- }
+ return CooRingVectorOps.inner(this, b);
}
- /**
- * Converts this sparse COO matrix to an equivalent dense matrix.
- * @return A dense matrix equivalent to this sparse COO matrix.
- */
- public U toDense() {
- Y[] entries = (Y[]) new Ring[shape.totalEntriesIntValueExact()];
-
- for(int i = 0; i< nnz; i++)
- entries[indices[i]] = this.data[i];
-
- return makeLikeDenseTensor(shape, entries);
- }
-
-
- /**
- * Converts this matrix to an equivalent rank 1 tensor.
- * @return A tensor which is equivalent to this matrix.
- */
- public abstract AbstractTensor, Y[], Y> toTensor();
-
-
- /**
- * Converts this vector to an equivalent tensor with the specified shape.
- * @param newShape New shape for the tensor. Can be any rank but must be broadcastable to {@link #shape this.shape}.
- * @return A tensor equivalent to this matrix which has been reshaped to {@code newShape}
- */
- public abstract AbstractTensor, Y[], Y> toTensor(Shape newShape);
-
-
/**
* Computes the element-wise difference between two tensors of the same shape.
*
@@ -783,40 +158,4 @@ public T H(int axis1, int axis2) {
public T H(int... axes) {
return T(axes);
}
-
-
- /**
- * Coalesces this sparse COO vector. An uncoalesced vector is a sparse vector with multiple data for a single index. This
- * method will ensure that each index only has one non-zero value by summing duplicated data. If another form of aggregation other
- * than summing is desired, use {@link #coalesce(BinaryOperator)}.
- * @return A new coalesced sparse COO vector which is equivalent to this COO vector.
- * @see #coalesce(BinaryOperator)
- */
- public T coalesce() {
- SparseVectorData
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking this matrix on top of the matrix {@code b}.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of columns.
- * @see #stack(MatrixMixin, int)
- * @see #augment(T)
- */
- @Override
- public T stack(T b) {
- ValidateParameters.ensureEquals(numCols, b.numCols);
-
- Shape destShape = new Shape(numRows+b.numRows, numCols);
- W[] destEntries = makeEmptyDataArray(data.length + b.data.length);
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.stack(data, rowIndices, colIndices, numRows,
- b.data, b.rowIndices, b.colIndices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
- }
-
-
- /**
- * Stacks matrices along rows.
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking {@code b} to the right of this matrix.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of rows.
- * @see #stack(T)
- * @see #stack(MatrixMixin, int)
- */
- @Override
- public T augment(T b) {
- ValidateParameters.ensureEquals(numRows, b.numRows);
-
- Shape destShape = new Shape(numRows, numCols + b.numCols);
- W[] destEntries = makeEmptyDataArray(data.length + b.data.length);
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.augment(data, rowIndices, colIndices, numCols,
- b.data, b.rowIndices, b.colIndices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
- }
-
-
- /**
- * Augments a vector to this matrix.
- *
- * @param b The vector to augment to this matrix.
- *
- * @return The result of augmenting {@code b} to this matrix.
- */
- @Override
- public T augment(V b) {
- ValidateParameters.ensureEquals(numRows, b.size);
-
- Shape destShape = new Shape(numRows, numCols + 1);
- W[] destEntries = makeEmptyDataArray(nnz + b.data.length);
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.augmentVector(
- data, rowIndices, colIndices, numCols,
- b.data, b.indices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
- }
-
-
- /**
- * Swaps specified rows in the matrix. This is done in place.
- *
- * @param rowIndex1 Index of the first row to swap.
- * @param rowIndex2 Index of the second row to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapRows(int rowIndex1, int rowIndex2) {
- CooManipulations.swapRows(shape, data, rowIndices, colIndices, rowIndex1, rowIndex2);
- return (T) this;
- }
-
-
- /**
- * Swaps specified columns in the matrix. This is done in place.
- *
- * @param colIndex1 Index of the first column to swap.
- * @param colIndex2 Index of the second column to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapCols(int colIndex1, int colIndex2) {
- CooManipulations.swapCols(shape, data, rowIndices, colIndices, colIndex1, colIndex2);
- return (T) this;
- }
-
-
- /**
- * Checks if a matrix is symmetric. That is, if the matrix is square and equal to its transpose.
- *
- * @return {@code true} if this matrix is symmetric; {@code false} otherwise.
- */
- @Override
- public boolean isSymmetric() {
- return CooSemiringMatrixProperties.isSymmetric(shape, data, rowIndices, colIndices);
- }
-
-
- /**
- * Checks if a matrix is Hermitian. That is, if the matrix is square and equal to its conjugate transpose.
- *
- * @return {@code true} if this matrix is Hermitian; {@code false} otherwise.
- */
- @Override
- public boolean isHermitian() {
- return CooFieldMatrixProperties.isHermitian(shape, data, rowIndices, colIndices);
- }
-
-
- /**
- * Checks if this matrix is orthogonal. That is, if the inverse of this matrix is equal to its transpose.
- *
- * @return {@code true} if this matrix it is orthogonal; {@code false} otherwise.
- */
- @Override
- public boolean isOrthogonal() {
- if(isSquare()) return mult(T()).isI();
- else return false;
- }
-
-
- /**
- * Gets a range of a row of this matrix.
- *
- * @param rowIdx The index of the row to get.
- * @param start The staring column of the row range to get (inclusive).
- * @param stop The ending column of the row range to get (exclusive).
- *
- * @return A vector containing the elements of the specified row over the range [start, stop).
- *
- * @throws IllegalArgumentException If {@code rowIdx < 0 || rowIdx >= this.numRows()} or {@code start < 0 || start >= numCols} or
- * {@code stop < start || stop > numCols}.
- */
- @Override
- public V getRow(int rowIdx, int start, int stop) {
- SparseVectorData
- *
- *
- * @return The elements of the specified diagonal as a vector.
- */
- @Override
- public V getDiag(int diagOffset) {
- SparseVectorData
- *
- *
- * @return The upper-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriU(int diagOffset) {
- SparseMatrixDataCOO Representation:
+ * A sparse COO matrix is stored as:
+ *
+ *
+ *
+ *
- *
- *
- * @return The lower-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
+ * Creates a sparse coo matrix with the specified non-zero data, non-zero indices, and shape.
*
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
+ * @param shape Shape of this tensor.
+ * @param entries Non-zero data of this sparse matrix.
+ * @param rowIndices Non-zero row indices of this sparse matrix.
+ * @param colIndices Non-zero column indies of this sparse matrix.
*/
- @Override
- public T getTriL(int diagOffset) {
- SparseMatrixData
- *
- *
- * @return A matrix whose rows/columns are this vector repeated.
- */
- @Override
- public V repeat(int n, int axis) {
- Y[] tiledEntries = makeEmptyDataArray(n*data.length);
- int[] tiledRows = new int[tiledEntries.length];
- int[] tiledCols = new int[tiledEntries.length];
- Shape tiledShape = CooConcat.repeat(data, indices, size, n, axis, tiledEntries, tiledRows, tiledCols);
- return makeLikeMatrix(tiledShape, tiledEntries, tiledRows, tiledCols);
- }
-
-
- /**
- *
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking this matrix on top of the matrix {@code b}.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of columns.
- * @see #stack(MatrixMixin, int)
- * @see #augment(T)
- */
- @Override
- public T stack(T b) {
- return (T) toCoo().stack(b.toCoo()).toCsr();
- }
-
-
- /**
- * Stacks matrices along rows.
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking {@code b} to the right of this matrix.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of rows.
- * @see #stack(T)
- * @see #stack(MatrixMixin, int)
- */
- @Override
- public T augment(T b) {
- return (T) toCoo().augment(b.toCoo()).toCsr();
- }
-
-
- /**
- * Augments a vector to this matrix.
- *
- * @param b The vector to augment to this matrix.
- *
- * @return The result of augmenting {@code b} to this matrix.
- */
- @Override
- public T augment(V b) {
- return (T) toCoo().augment(b).toCsr();
- }
-
-
- /**
- * Swaps specified rows in the matrix. This is done in place.
- *
- * @param rowIndex1 Index of the first row to swap.
- * @param rowIndex2 Index of the second row to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapRows(int rowIndex1, int rowIndex2) {
- CsrOps.swapRows(data, rowPointers, colIndices, rowIndex1, rowIndex2);
- return (T) this;
- }
-
-
- /**
- * Swaps specified columns in the matrix. This is done in place.
- *
- * @param colIndex1 Index of the first column to swap.
- * @param colIndex2 Index of the second column to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapCols(int colIndex1, int colIndex2) {
- CsrOps.swapCols(data, rowPointers, colIndices, colIndex1, colIndex2);
- return (T) this;
- }
-
-
- /**
- * Checks if a matrix is symmetric. That is, if the matrix is square and equal to its transpose.
- *
- * @return {@code true} if this matrix is symmetric; {@code false} otherwise.
- */
- @Override
- public boolean isSymmetric() {
- return CsrProperties.isSymmetric(shape, data, rowPointers, colIndices);
- }
-
-
/**
* Checks if a matrix is Hermitian. That is, if the matrix is square and equal to its conjugate transpose.
*
@@ -726,7 +85,7 @@ public boolean isSymmetric() {
@Override
public boolean isHermitian() {
// For a field matrix, same as isSymmetric.
- return CsrFieldMatrixProperties.isHermitian(this);
+ return CsrRingProperties.isHermitian(shape, data, rowPointers, colIndices);
}
@@ -735,260 +94,12 @@ public boolean isHermitian() {
*
* @return {@code true} if this matrix it is orthogonal; {@code false} otherwise.
*/
- @Override
- public boolean isOrthogonal() {
- if(isSquare()) return mult(T()).isI();
+ public boolean isUnitary() {
+ if(isSquare()) return mult(H()).isI();
else return false;
}
- /**
- * Sets a specified row of this matrix to a vector.
- *
- * @param row Vector to replace specified row in this matrix.
- * @param rowIdx Index of the row to set.
- *
- * @return If this matrix is dense, the row set operation is done in place and a reference to this matrix is returned.
- * If this matrix is sparse a copy will be created with the new row and returned.
- */
- @Override
- public T setRow(V row, int rowIdx) {
- return (T) toCoo().setRow(row, rowIdx).toCsr();
- }
-
-
- /**
- * Sets a specified column of this matrix to a vector.
- *
- * @param col Vector to replace specified column in this matrix.
- * @param colIdx Index of the column to set.
- *
- * @return If this matrix is dense, the column set operation is done in place and a reference to this matrix is returned.
- * If this matrix is sparse a copy will be created with the new column and returned.
- */
- @Override
- public T setCol(V col, int colIdx) {
- return (T) toCoo().setCol(col, colIdx).toCsr();
- }
-
-
- /**
- * Removes a specified row from this matrix.
- *
- * @param rowIndex Index of the row to remove from this matrix.
- *
- * @return A copy of this matrix with the specified row removed.
- */
- @Override
- public T removeRow(int rowIndex) {
- return (T) toCoo().removeRow(rowIndex).toCsr();
- }
-
-
- /**
- * Removes a specified set of rows from this matrix.
- *
- * @param rowIndices The indices of the rows to remove from this matrix. Assumed to contain unique values.
- *
- * @return A copy of this matrix with the specified column removed.
- */
- @Override
- public T removeRows(int... rowIndices) {
- return (T) toCoo().removeRows(rowIndices).toCsr();
- }
-
-
- /**
- * Removes a specified column from this matrix.
- *
- * @param colIndex Index of the column to remove from this matrix.
- *
- * @return A copy of this matrix with the specified column removed.
- */
- @Override
- public T removeCol(int colIndex) {
- return (T) toCoo().removeCol(colIndex).toCsr();
- }
-
-
- /**
- * Removes a specified set of columns from this matrix.
- *
- * @param colIndices Indices of the columns to remove from this matrix. Assumed to contain unique values.
- *
- * @return A copy of this matrix with the specified column removed.
- */
- @Override
- public T removeCols(int... colIndices) {
- return (T) toCoo().removeCols(colIndices).toCsr();
- }
-
-
- /**
- * Creates a copy of this matrix and sets a slice of the copy to the specified values. The rowStart and colStart parameters specify the upper
- * left index location of the slice to set.
- *
- * @param values New values for the specified slice.
- * @param rowStart Starting row index for the slice (inclusive).
- * @param colStart Starting column index for the slice (inclusive).
- *
- * @return A copy of this matrix with the given slice set to the specified values.
- *
- * @throws IndexOutOfBoundsException If rowStart or colStart are not within the matrix.
- * @throws IllegalArgumentException If the values slice, with upper left corner at the specified location, does not
- * fit completely within this matrix.
- */
- @Override
- public T setSliceCopy(T values, int rowStart, int colStart) {
- return (T) toCoo().setSliceCopy(values.toCoo(), rowStart, colStart).toCsr();
- }
-
-
- /**
- * Gets a specified slice of this matrix.
- *
- * @param rowStart Starting row index of slice (inclusive).
- * @param rowEnd Ending row index of slice (exclusive).
- * @param colStart Starting column index of slice (inclusive).
- * @param colEnd Ending row index of slice (exclusive).
- *
- * @return The specified slice of this matrix. This is a completely new matrix and NOT a view into the matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If any of the indices are out of bounds of this matrix.
- * @throws IllegalArgumentException If {@code rowEnd} is not greater than {@code rowStart} or if {@code colEnd} is not greater than {@code colStart}.
- */
- @Override
- public T getSlice(int rowStart, int rowEnd, int colStart, int colEnd) {
- SparseMatrixData
- *
- *
- * @return The upper-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriU(int diagOffset) {
- return (T) toCoo().getTriU(diagOffset).toCsr();
- }
-
-
- /**
- * Extracts the lower-triangular portion of this matrix with a specified diagonal offset. All other data of the resulting
- * matrix will be zero.
- *
- * @param diagOffset Diagonal offset for lower-triangular portion to extract:
- *
- *
- *
- * @return The lower-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriL(int diagOffset) {
- return (T) toCoo().getTriL(diagOffset).toCsr();
- }
-
-
- /**
- * Creates a deep copy of this tensor.
- *
- * @return A deep copy of this tensor.
- */
- @Override
- public T copy() {
- return makeLikeTensor(shape, data.clone());
- }
-
-
- /**
- * Computes the element-wise difference between two tensors of the same shape.
- *
- * @param b Second tensor in the element-wise difference.
- *
- * @return The difference of this tensor with {@code b}.
- *
- * @throws TensorShapeException If this tensor and {@code b} do not have the same shape.
- */
- @Override
- public T sub(T b) {
- SparseMatrixData
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking this matrix on top of the matrix {@code b}.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of columns.
- * @see #stack(MatrixMixin, int)
- * @see #augment(T)
- */
- @Override
- public T stack(T b) {
- ValidateParameters.ensureArrayLengthsEq(this.numCols, b.numCols);
- Shape stackedShape = new Shape(this.numRows + b.numRows, this.numCols);
- V[] stackedEntries = makeEmptyDataArray(stackedShape.totalEntries().intValueExact());
-
- System.arraycopy(this.data, 0, stackedEntries, 0, this.data.length);
- System.arraycopy(b.data, 0, stackedEntries, this.data.length, b.data.length);
-
- return makeLikeTensor(stackedShape, stackedEntries);
- }
-
-
- /**
- * Stacks matrices along rows.
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking {@code b} to the right of this matrix.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of rows.
- * @see #stack(T)
- * @see #stack(MatrixMixin, int)
- */
- @Override
- public T augment(T b) {
- ValidateParameters.ensureArrayLengthsEq(numRows, b.numRows);
-
- int augNumCols = numCols + b.numCols;
- Shape augShape = new Shape(numRows, augNumCols);
- V[] augEntries = makeEmptyDataArray(numRows*augNumCols);
-
- // Copy data from this matrix.
- for(int i=0; i
- *
- *
- * @return The lower-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriL(int diagOffset) {
- ValidateParameters.ensureInRange(diagOffset, -numRows+1, numCols-1, "diagOffset");
- V[] copyEntries = makeEmptyDataArray(data.length);
- Arrays.fill(copyEntries, (data.length > 0) ? data[0].getZero() : null);
- T result = makeLikeTensor(shape, copyEntries);
-
- // Extract the lower triangular portion
- for(int i=0; i
- *
+ * Normalizes this vector to a unit length vector.
*
- * @return A matrix whose rows/columns are this vector repeated.
+ * @return This vector normalized to a unit length.
*/
@Override
- public U repeat(int n, int axis) {
- V[] dest = makeEmptyDataArray(size*n);
- DenseConcat.repeat(data, n, axis, dest); // axis is verified to be 1 or 0 here.
- Shape shape = (axis==0) ? new Shape(n, size) : new Shape(size, n);
-
- return makeLikeMatrix(shape, dest);
+ public T normalize() {
+ V[] dest = makeEmptyDataArray(size);
+ FieldOps.div(data, mag(), dest);
+ return makeLikeTensor(shape, dest);
}
/**
- *
- *
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking this matrix on top of the matrix {@code b}.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of columns.
- * @see #stack(MatrixMixin, int)
- * @see #augment(T)
+ * @see #H(int, int)
+ * @see #H()
*/
@Override
- public T stack(T b) {
- ValidateParameters.ensureEquals(numCols, b.numCols);
-
- Shape destShape = new Shape(numRows+b.numRows, numCols);
- W[] destEntries = (W[]) new Ring[data.length + b.data.length];
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.stack(data, rowIndices, colIndices, numRows,
- b.data, b.rowIndices, b.colIndices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
+ public T H(int... axes) {
+ return T(axes);
}
/**
- * Stacks matrices along rows.
+ * Checks if the matrix is "close" to an identity matrix. Two entries {@code x} and {@code y} are considered
+ * "close" if they satisfy the following:
+ * {@code
+ * |x-y| <= (1E-08 + 1E-05*|y|)
+ * }
*
- * @param b Matrix to stack to this matrix.
- *
- * @return The result of stacking {@code b} to the right of this matrix.
- *
- * @throws IllegalArgumentException If this matrix and matrix {@code b} have a different number of rows.
- * @see #stack(T)
- * @see #stack(MatrixMixin, int)
- */
- @Override
- public T augment(T b) {
- ValidateParameters.ensureEquals(numRows, b.numRows);
-
- Shape destShape = new Shape(numRows, numCols + b.numCols);
- W[] destEntries = (W[]) new Ring[data.length + b.data.length];
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.augment(data, rowIndices, colIndices, numCols,
- b.data, b.rowIndices, b.colIndices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
- }
-
-
- /**
- * Augments a vector to this matrix.
- *
- * @param b The vector to augment to this matrix.
- *
- * @return The result of augmenting {@code b} to this matrix.
- */
- @Override
- public T augment(V b) {
- ValidateParameters.ensureEquals(numRows, b.size);
-
- Shape destShape = new Shape(numRows, numCols + 1);
- W[] destEntries = (W[]) new Ring[nnz + b.data.length];
- int[] destRowIndices = new int[destEntries.length];
- int[] destColIndices = new int[destEntries.length];
- CooConcat.augmentVector(
- data, rowIndices, colIndices, numCols,
- b.data, b.indices,
- destEntries, destRowIndices, destColIndices);
-
- return makeLikeTensor(destShape, destEntries, destRowIndices, destColIndices);
- }
-
-
- /**
- * Swaps specified rows in the matrix. This is done in place.
- *
- * @param rowIndex1 Index of the first row to swap.
- * @param rowIndex2 Index of the second row to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapRows(int rowIndex1, int rowIndex2) {
- CooManipulations.swapRows(shape, data, rowIndices, colIndices, rowIndex1, rowIndex2);
- return (T) this;
- }
-
-
- /**
- * Swaps specified columns in the matrix. This is done in place.
- *
- * @param colIndex1 Index of the first column to swap.
- * @param colIndex2 Index of the second column to swap.
- *
- * @return A reference to this matrix.
- *
- * @throws ArrayIndexOutOfBoundsException If either index is outside the matrix bounds.
- */
- @Override
- public T swapCols(int colIndex1, int colIndex2) {
- CooManipulations.swapCols(shape, data, rowIndices, colIndices, colIndex1, colIndex2);
- return (T) this;
- }
-
-
- /**
- * Checks if a matrix is symmetric. That is, if the matrix is square and equal to its transpose.
- *
- * @return {@code true} if this matrix is symmetric; {@code false} otherwise.
- */
- @Override
- public boolean isSymmetric() {
- return CooSemiringMatrixProperties.isSymmetric(shape, data, rowIndices, colIndices);
- }
-
-
- /**
- * Checks if a matrix is Hermitian. That is, if the matrix is square and equal to its conjugate transpose.
- *
- * @return {@code true} if this matrix is Hermitian; {@code false} otherwise.
- */
- @Override
- public boolean isHermitian() {
- return isSymmetric();
- }
-
-
- /**
- * Checks if this matrix is orthogonal. That is, if the inverse of this matrix is equal to its transpose.
- *
- * @return {@code true} if this matrix it is orthogonal; {@code false} otherwise.
- */
- @Override
- public boolean isOrthogonal() {
- if(isSquare()) return mult(T()).isI();
- else return false;
- }
-
-
- /**
- * Gets a range of a row of this matrix.
- *
- * @param rowIdx The index of the row to get.
- * @param start The staring column of the row range to get (inclusive).
- * @param stop The ending column of the row range to get (exclusive).
- *
- * @return A vector containing the elements of the specified row over the range [start, stop).
- *
- * @throws IllegalArgumentException If {@code rowIdx < 0 || rowIdx >= this.numRows()} or {@code start < 0 || start >= numCols} or
- * {@code stop < start || stop > numCols}.
- */
- @Override
- public V getRow(int rowIdx, int start, int stop) {
- SparseVectorData
- *
- *
- * @return The elements of the specified diagonal as a vector.
- */
- @Override
- public V getDiag(int diagOffset) {
- SparseVectorData
- *
- *
- * @return The upper-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriU(int diagOffset) {
- SparseMatrixData
- *
- *
- * @return The lower-triangular portion of this matrix with a specified diagonal offset. All other data of the returned
- * matrix will be zero.
- *
- * @throws IllegalArgumentException If {@code diagOffset} is not in the range (-numRows, numCols).
- */
- @Override
- public T getTriL(int diagOffset) {
- SparseMatrixData
- *
- *
- * @return A matrix whose rows/columns are this vector repeated.
- */
- @Override
- public V repeat(int n, int axis) {
- Y[] tiledEntries = (Y[]) new Field[n*data.length];
- int[] tiledRows = new int[tiledEntries.length];
- int[] tiledCols = new int[tiledEntries.length];
- Shape tiledShape = CooConcat.repeat(data, indices, size, n, axis, tiledEntries, tiledRows, tiledCols);
- return makeLikeMatrix(tiledShape, data, tiledRows, tiledCols);
- }
-
-
- /**
- *