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

io.proximax.core.math.DenseMatrix Maven / Gradle / Ivy

Go to download

The ProximaX Sirius Chain Java SDK is a Java library for interacting with the Sirius Blockchain.

The newest version!
/*
 * Copyright 2018 NEM
 *
 * 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 io.proximax.core.math;

import java.text.DecimalFormat;
import java.util.function.DoubleConsumer;

import io.proximax.core.utils.FormatUtils;

/**
 * Represents a dense matrix.
 */
public final class DenseMatrix extends Matrix {
    private final int numCols;
    private final double[] values;

    /**
     * Creates a new matrix of the specified size.
     *
     * @param rows The desired number of rows.
     * @param cols The desired number of columns.
     */
    public DenseMatrix(final int rows, final int cols) {
        super(rows, cols);
        this.numCols = cols;
        this.values = new double[this.getElementCount()];
    }

    /**
     * Creates a new matrix of the specified size and values.
     *
     * @param rows   The desired number of rows.
     * @param cols   The desired number of columns.
     * @param values The specified values.
     */
    public DenseMatrix(final int rows, final int cols, final double[] values) {
        super(rows, cols);

        if (values.length != this.getElementCount()) {
            throw new IllegalArgumentException("incompatible number of values");
        }

        this.numCols = cols;
        this.values = values;
    }

    /**
     * Gets the underlying, raw array.
     *
     * @return The underlying, raw array.
     */
    public double[] getRaw() {
        return this.values;
    }

    // region Matrix abstract functions

    @Override
    protected final Matrix create(final int numRows, final int numCols) {
        return new DenseMatrix(numRows, numCols);
    }

    @Override
    protected final double getAtUnchecked(final int row, final int col) {
        return this.values[row * this.numCols + col];
    }

    @Override
    protected final void setAtUnchecked(final int row, final int col, final double val) {
        this.values[row * this.numCols + col] = val;
    }

    @Override
    protected final void forEach(final ElementVisitorFunction func) {
        for (int i = 0; i < this.getRowCount(); ++i) {
            for (int j = 0; j < this.getColumnCount(); ++j) {
                final SetWrapper setWrapper = new SetWrapper(i, j);
                func.visit(i, j, this.getAtUnchecked(i, j), setWrapper);
            }
        }
    }

    @Override
    public MatrixNonZeroElementRowIterator getNonZeroElementRowIterator(final int row) {
        return new MatrixNonZeroElementRowIterator() {
            private int index;

            @Override
            public boolean hasNext() {
                for (int i = this.index; i < DenseMatrix.this.getColumnCount(); i++) {
                    if (DenseMatrix.this.getAt(row, i) != 0.0) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public MatrixElement next() {
                while (this.index < DenseMatrix.this.getColumnCount()) {
                    if (DenseMatrix.this.getAt(row, this.index++) != 0.0) {
                        return new MatrixElement(row, this.index - 1, DenseMatrix.this.getAt(row, this.index - 1));
                    }
                }

                throw new IndexOutOfBoundsException("index out of range");
            }
        };
    }

    @Override
    public String toString() {
        final DecimalFormat format = FormatUtils.getDefaultDecimalFormat();
        final StringBuilder builder = new StringBuilder();

        this.forEach((r, c, v) -> {
            if (0 != r && 0 == c) {
                builder.append(System.lineSeparator());
            }

            if (0 != c) {
                builder.append(" ");
            }

            builder.append(format.format(v));
        });

        return builder.toString();
    }

    // endregion

    class SetWrapper implements DoubleConsumer {
        final int i;
        final int j;

        SetWrapper(final int i, final int j) {
            this.i = i;
            this.j = j;
        }

        @Override
        public void accept(final double value) {
            DenseMatrix.this.setAtUnchecked(this.i, this.j, value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy