matrix4j.matrix.dense.RowMajorDenseMatrix2d Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2019 and onwards Makoto Yui
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package matrix4j.matrix.dense;
import matrix4j.matrix.RowMajorMatrix;
import matrix4j.matrix.builders.RowMajorDenseMatrixBuilder;
import matrix4j.utils.lang.Preconditions;
import matrix4j.vector.DenseVector;
import matrix4j.vector.VectorProcedure;
import java.util.Arrays;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
/**
* Fixed-size Dense 2-d double Matrix.
*/
public final class RowMajorDenseMatrix2d extends RowMajorMatrix {
@Nonnull
private final double[][] data;
@Nonnegative
private final int numRows;
@Nonnegative
private final int numColumns;
@Nonnegative
private int nnz;
public RowMajorDenseMatrix2d(@Nonnull double[][] data, @Nonnegative int numColumns) {
this(data, numColumns, nnz(data));
}
public RowMajorDenseMatrix2d(@Nonnull double[][] data, @Nonnegative int numColumns,
@Nonnegative int nnz) {
super();
this.data = data;
this.numRows = data.length;
this.numColumns = numColumns;
this.nnz = nnz;
}
@Override
public boolean isSparse() {
return false;
}
@Override
public boolean readOnly() {
return true;
}
@Override
public boolean swappable() {
return true;
}
@Override
public int nnz() {
return nnz;
}
@Override
public int numRows() {
return numRows;
}
@Override
public int numColumns() {
return numColumns;
}
@Override
public int numColumns(@Nonnegative final int row) {
checkRowIndex(row, numRows);
final double[] r = data[row];
if (r == null) {
return 0;
}
return r.length;
}
@Override
public DenseVector rowVector() {
return new DenseVector(numColumns);
}
@Override
public double[] getRow(@Nonnegative final int index) {
checkRowIndex(index, numRows);
final double[] row = data[index];
if (row == null) {
return new double[0];
} else if (row.length == numRows) {
return row;
}
final double[] result = new double[numRows];
System.arraycopy(row, 0, result, 0, row.length);
return result;
}
@Override
public double[] getRow(@Nonnull final int index, @Nonnull final double[] dst) {
checkRowIndex(index, numRows);
final double[] row = data[index];
if (row == null) {
return new double[0];
}
System.arraycopy(row, 0, dst, 0, row.length);
if (dst.length > row.length) {// zerofill
Arrays.fill(dst, row.length, dst.length, 0.d);
}
return dst;
}
@Override
public double get(@Nonnegative final int row, @Nonnegative final int col,
final double defaultValue) {
checkIndex(row, col, numRows, numColumns);
final double[] rowData = data[row];
if (rowData == null || col >= rowData.length) {
return defaultValue;
}
return rowData[col];
}
@Override
public double getAndSet(@Nonnegative final int row, @Nonnegative final int col,
final double value) {
checkIndex(row, col, numRows, numColumns);
final double[] rowData = data[row];
Preconditions.checkNotNull(rowData, "row does not exists: " + row);
checkColIndex(col, rowData.length);
double old = rowData[col];
rowData[col] = value;
if (old == 0.d && value != 0.d) {
++nnz;
}
return old;
}
@Override
public void set(@Nonnegative final int row, @Nonnegative final int col, final double value) {
checkIndex(row, col, numRows, numColumns);
if (value == 0.d) {
return;
}
final double[] rowData = data[row];
Preconditions.checkNotNull(rowData, "row does not exists: " + row);
checkColIndex(col, rowData.length);
if (rowData[col] == 0.d) {
++nnz;
}
rowData[col] = value;
}
@Override
public void swap(@Nonnegative final int row1, @Nonnegative final int row2) {
checkRowIndex(row1, numRows);
checkRowIndex(row2, numRows);
double[] oldRow1 = data[row1];
data[row1] = data[row2];
data[row2] = oldRow1;
}
@Override
public void eachInRow(@Nonnegative final int row, @Nonnull final VectorProcedure procedure,
final boolean nullOutput) {
checkRowIndex(row, numRows);
final double[] rowData = data[row];
if (rowData == null) {
if (nullOutput) {
for (int j = 0; j < numColumns; j++) {
procedure.apply(j, 0.d);
}
}
return;
}
int col = 0;
for (int len = rowData.length; col < len; col++) {
procedure.apply(col, rowData[col]);
}
if (nullOutput) {
for (; col < numColumns; col++) {
procedure.apply(col, 0.d);
}
}
}
@Override
public void eachNonZeroInRow(@Nonnegative final int row,
@Nonnull final VectorProcedure procedure) {
checkRowIndex(row, numRows);
final double[] rowData = data[row];
if (rowData == null) {
return;
}
for (int col = 0, len = rowData.length; col < len; col++) {
final double v = rowData[col];
if (v != 0.d) {
procedure.apply(col, v);
}
}
}
@Override
public void eachColumnIndexInRow(@Nonnegative final int row,
@Nonnull final VectorProcedure procedure) {
checkRowIndex(row, numRows);
final double[] rowData = data[row];
if (rowData == null) {
return;
}
for (int col = 0, len = rowData.length; col < len; col++) {
procedure.apply(col);
}
}
@Override
public void eachInColumn(@Nonnegative final int col, @Nonnull final VectorProcedure procedure,
final boolean nullOutput) {
checkColIndex(col, numColumns);
for (int row = 0; row < numRows; row++) {
final double[] rowData = data[row];
if (rowData != null && col < rowData.length) {
procedure.apply(row, rowData[col]);
} else {
if (nullOutput) {
procedure.apply(row, 0.d);
}
}
}
}
@Override
public void eachNonZeroInColumn(@Nonnegative final int col,
@Nonnull final VectorProcedure procedure) {
checkColIndex(col, numColumns);
for (int row = 0; row < numRows; row++) {
final double[] rowData = data[row];
if (rowData == null) {
continue;
}
if (col < rowData.length) {
final double v = rowData[col];
if (v != 0.d) {
procedure.apply(row, v);
}
}
}
}
@Override
public ColumnMajorDenseMatrix2d toColumnMajorMatrix() {
final double[][] colrow = new double[numColumns][numRows];
int nnz = 0;
for (int i = 0; i < data.length; i++) {
final double[] rowData = data[i];
if (rowData == null) {
continue;
}
for (int j = 0; j < rowData.length; j++) {
final double v = rowData[j];
if (v == 0.d) {
continue;
}
colrow[j][i] = v;
nnz++;
}
}
for (int j = 0; j < colrow.length; j++) {
final double[] col = colrow[j];
final int last = numRows - 1;
int maxi = last;
for (; maxi >= 0; maxi--) {
if (col[maxi] != 0.d) {
break;
}
}
if (maxi == last) {
continue;
} else if (maxi < 0) {
colrow[j] = null;
continue;
}
final double[] dstCol = new double[maxi + 1];
System.arraycopy(col, 0, dstCol, 0, dstCol.length);
colrow[j] = dstCol;
}
return new ColumnMajorDenseMatrix2d(colrow, numRows, nnz);
}
@Override
public RowMajorDenseMatrixBuilder builder() {
return new RowMajorDenseMatrixBuilder(numRows);
}
private static int nnz(@Nonnull final double[][] data) {
int count = 0;
for (int i = 0; i < data.length; i++) {
final double[] row = data[i];
if (row == null) {
continue;
}
for (int j = 0; j < row.length; j++) {
if (row[j] != 0.d) {
++count;
}
}
}
return count;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy