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

com.landawn.abacus.util.AbstractMatrix Maven / Gradle / Ivy

/*
 * Copyright (C) 2016 HaiYang Li
 *
 * 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 com.landawn.abacus.util;

import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.util.Sheet.Point;
import com.landawn.abacus.util.stream.IntStream;
import com.landawn.abacus.util.stream.Stream;

/**
 * 
  • * {@code R} = Row, {@code C} = Column, {@code H} = Horizontal, {@code V} = Vertical. *
  • * * @param * @param * @param element stream * @param row/column stream. * @param */ public abstract sealed class AbstractMatrix> permits BooleanMatrix, CharMatrix, ByteMatrix, ShortMatrix, DoubleMatrix, FloatMatrix, IntMatrix, LongMatrix, Matrix { static final char CHAR_0 = (char) 0; static final byte BYTE_0 = (byte) 0; static final byte BYTE_1 = (byte) 1; static final short SHORT_0 = (short) 0; /** * Row length. */ public final int rows; /** * Column length. */ public final int cols; public final long count; final A[] a; @SuppressFBWarnings("CT_CONSTRUCTOR_THROW") protected AbstractMatrix(final A[] a) { this.a = a; rows = a.length; cols = a.length == 0 ? 0 : length(a[0]); if (a.length > 1) { for (int i = 1, len = a.length; i < len; i++) { if (length(a[i]) != cols) { throw new IllegalArgumentException("The length of sub arrays must be same"); } } } count = (long) cols * rows; } @SuppressWarnings("rawtypes") public abstract Class componentType(); /** * @return */ @SuppressFBWarnings("EI_EXPOSE_REP") public A[] array() { return a; } /** * Println. */ public abstract void println(); /** * Checks if is empty. * * @return {@code true}, if is empty */ public boolean isEmpty() { return count == 0; } // Replaced by stream and stream2. // public abstract PL row(int i); // // public abstract PL column(int j); /** * @return a new Matrix */ public abstract X copy(); /** * @param fromRowIndex * @param toRowIndex * @return a new Matrix */ public abstract X copy(int fromRowIndex, int toRowIndex); /** * @param fromRowIndex * @param toRowIndex * @param fromColumnIndex * @param toColumnIndex * @return a new Matrix */ public abstract X copy(int fromRowIndex, int toRowIndex, int fromColumnIndex, int toColumnIndex); /** * Rotate this matrix clockwise 90. * * @return a new Matrix */ public abstract X rotate90(); /** * Rotate this matrix clockwise 180. * * @return a new Matrix */ public abstract X rotate180(); /** * Rotate this matrix clockwise 270. * * @return a new Matrix */ public abstract X rotate270(); /** * @return */ public abstract X transpose(); /** * @param newCols * @return */ public X reshape(final int newCols) { return reshape((int) (count % newCols == 0 ? count / newCols : count / newCols + 1), newCols); } /** * @param newRows * @param newCols * @return */ public abstract X reshape(int newRows, int newCols); /** * Checks if is same shape. * * @param x * @return {@code true}, if is same shape */ public boolean isSameShape(final X x) { return rows == x.rows && cols == x.cols; } /** * Repeat elements {@code rowRepeats} times in row direction and {@code colRepeats} times in column direction. * * @param rowRepeats * @param colRepeats * @return a new matrix * @see https://www.mathworks.com/help/matlab/ref/repelem.html */ public abstract X repelem(int rowRepeats, int colRepeats); /** * Repeat this matrix {@code rowRepeats} times in row direction and {@code colRepeats} times in column direction. * * @param rowRepeats * @param colRepeats * @return a new matrix * @see https://www.mathworks.com/help/matlab/ref/repmat.html */ public abstract X repmat(int rowRepeats, int colRepeats); /** * @return */ public abstract PL flatten(); /** * flatten -> execute {@code op} -> set values back. *
         * 
         * matrix.flatOp(a -> N.sort(a));
         * 
         * 
    * * @param * @param op * @throws E the e */ public abstract void flatOp(Throwables.Consumer op) throws E; /** *
         * 
         * for (int i = 0; i < rows; i++) {
         *      for (int j = 0; j < cols; j++) {
         *          action.accept(i, j);
         *      }
         *  }
         * 
         * 
    * * @param * @param action * @throws E the e */ public void forEach(final Throwables.IntBiConsumer action) throws E { if (Matrixes.isParallelable(this)) { //noinspection FunctionalExpressionCanBeFolded final Throwables.IntBiConsumer cmd = action::accept; Matrixes.run(rows, cols, cmd, true); } else { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { action.accept(i, j); } } } } /** * @param * @param fromRowIndex * @param toRowIndex * @param fromColumnIndex * @param toColumnIndex * @param action * @throws IndexOutOfBoundsException * @throws E */ public void forEach(final int fromRowIndex, final int toRowIndex, final int fromColumnIndex, final int toColumnIndex, final Throwables.IntBiConsumer action) throws IndexOutOfBoundsException, E { N.checkFromToIndex(fromRowIndex, toRowIndex, rows); N.checkFromToIndex(fromColumnIndex, toColumnIndex, cols); if (Matrixes.isParallelable(this, ((long) (toRowIndex - fromRowIndex)) * (toColumnIndex - fromColumnIndex))) { //noinspection FunctionalExpressionCanBeFolded final Throwables.IntBiConsumer cmd = action::accept; Matrixes.run(fromRowIndex, toRowIndex, fromColumnIndex, toColumnIndex, cmd, true); } else { for (int i = fromRowIndex; i < toRowIndex; i++) { for (int j = fromColumnIndex; j < toColumnIndex; j++) { action.accept(i, j); } } } } /** * @param * @param action * @throws E */ public void forEach(final Throwables.BiIntObjConsumer action) throws E { final X x = (X) this; if (Matrixes.isParallelable(this)) { final Throwables.IntBiConsumer cmd = (i, j) -> action.accept(i, j, x); Matrixes.run(rows, cols, cmd, true); } else { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { action.accept(i, j, x); } } } } /** * @param * @param fromRowIndex * @param toRowIndex * @param fromColumnIndex * @param toColumnIndex * @param action * @throws IndexOutOfBoundsException * @throws E */ public void forEach(final int fromRowIndex, final int toRowIndex, final int fromColumnIndex, final int toColumnIndex, final Throwables.BiIntObjConsumer action) throws IndexOutOfBoundsException, E { N.checkFromToIndex(fromRowIndex, toRowIndex, rows); N.checkFromToIndex(fromColumnIndex, toColumnIndex, cols); final X x = (X) this; if (Matrixes.isParallelable(this, ((long) (toRowIndex - fromRowIndex)) * (toColumnIndex - fromColumnIndex))) { final Throwables.IntBiConsumer cmd = (i, j) -> action.accept(i, j, x); Matrixes.run(fromRowIndex, toRowIndex, fromColumnIndex, toColumnIndex, cmd, true); } else { for (int i = fromRowIndex; i < toRowIndex; i++) { for (int j = fromColumnIndex; j < toColumnIndex; j++) { action.accept(i, j, x); } } } } /** * Points LU 2 RD. * * @return */ public Stream pointsLU2RD() { checkIfRowAndColumnSizeAreSame(); //noinspection resource return IntStream.range(0, rows).mapToObj(i -> Point.of(i, i)); } /** * Points RU 2 LD. * * @return */ public Stream pointsRU2LD() { checkIfRowAndColumnSizeAreSame(); //noinspection resource return IntStream.range(0, rows).mapToObj(i -> Point.of(i, cols - i - 1)); } /** * @return */ public Stream pointsH() { return pointsH(0, rows); } /** * @param rowIndex * @return */ public Stream pointsH(final int rowIndex) { return pointsH(rowIndex, rowIndex + 1); } /** * @param fromRowIndex * @param toRowIndex * @return * @throws IndexOutOfBoundsException */ @SuppressWarnings("resource") public Stream pointsH(final int fromRowIndex, final int toRowIndex) throws IndexOutOfBoundsException { N.checkFromToIndex(fromRowIndex, toRowIndex, rows); return IntStream.range(fromRowIndex, toRowIndex) .flatMapToObj(rowIndex -> IntStream.range(0, cols).mapToObj(columnIndex -> Point.of(rowIndex, columnIndex))); } /** * @return */ public Stream pointsV() { return pointsV(0, cols); } /** * @param columnIndex * @return */ public Stream pointsV(final int columnIndex) { return pointsV(columnIndex, columnIndex + 1); } /** * @param fromColumnIndex * @param toColumnIndex * @return * @throws IndexOutOfBoundsException */ @SuppressWarnings("resource") public Stream pointsV(final int fromColumnIndex, final int toColumnIndex) throws IndexOutOfBoundsException { N.checkFromToIndex(fromColumnIndex, toColumnIndex, cols); return IntStream.range(fromColumnIndex, toColumnIndex) .flatMapToObj(columnIndex -> IntStream.range(0, rows).mapToObj(rowIndex -> Point.of(rowIndex, columnIndex))); } /** * @return */ public Stream> pointsR() { return pointsR(0, rows); } /** * @param fromRowIndex * @param toRowIndex * @return * @throws IndexOutOfBoundsException */ @SuppressWarnings("resource") public Stream> pointsR(final int fromRowIndex, final int toRowIndex) throws IndexOutOfBoundsException { N.checkFromToIndex(fromRowIndex, toRowIndex, rows); return IntStream.range(fromRowIndex, toRowIndex) .mapToObj(rowIndex -> IntStream.range(0, cols).mapToObj(columnIndex -> Point.of(rowIndex, columnIndex))); } /** * @return */ public Stream> pointsC() { return pointsR(0, cols); } /** * @param fromColumnIndex * @param toColumnIndex * @return * @throws IndexOutOfBoundsException */ @SuppressWarnings("resource") public Stream> pointsC(final int fromColumnIndex, final int toColumnIndex) throws IndexOutOfBoundsException { N.checkFromToIndex(fromColumnIndex, toColumnIndex, cols); return IntStream.range(fromColumnIndex, toColumnIndex) .mapToObj(columnIndex -> IntStream.range(0, rows).mapToObj(rowIndex -> Point.of(rowIndex, columnIndex))); } /** * Stream LU 2 RD. * * @return */ public abstract ES streamLU2RD(); /** * Stream RU 2 LD. * * @return */ public abstract ES streamRU2LD(); /** * @return */ public abstract ES streamH(); /** * @param rowIndex * @return */ public abstract ES streamH(final int rowIndex); /** * @param fromRowIndex * @param toRowIndex * @return */ public abstract ES streamH(final int fromRowIndex, final int toRowIndex); /** * @return */ public abstract ES streamV(); /** * @param columnIndex * @return */ public abstract ES streamV(final int columnIndex); /** * @param fromColumnIndex * @param toColumnIndex * @return */ public abstract ES streamV(final int fromColumnIndex, final int toColumnIndex); /** * @return */ public abstract RS streamR(); /** * @param fromRowIndex * @param toRowIndex * @return */ public abstract RS streamR(final int fromRowIndex, final int toRowIndex); /** * @return */ public abstract RS streamC(); /** * @param fromColumnIndex * @param toColumnIndex * @return */ public abstract RS streamC(final int fromColumnIndex, final int toColumnIndex); /** * @param * @param action * @throws E */ public void accept(final Throwables.Consumer action) throws E { action.accept((X) this); } /** * @param * @param * @param action * @return * @throws E */ public R apply(final Throwables.Function action) throws E { return action.apply((X) this); } protected abstract int length(@SuppressWarnings("hiding") A a); protected void checkSameShape(final X x) { N.checkArgument(this.isSameShape(x), "Must be same shape"); } protected void checkIfRowAndColumnSizeAreSame() { N.checkState(rows == cols, "'rows' and 'cols' must be same to get diagonals: rows=%s, cols=%s", rows, cols); } }




    © 2015 - 2025 Weber Informatics LLC | Privacy Policy