View Javadoc
1   package org.djunits.vecmat.def;
2   
3   import org.djunits.quantity.SIQuantity;
4   import org.djunits.quantity.def.Quantity;
5   import org.djunits.unit.UnitInterface;
6   import org.djunits.unit.si.SIUnit;
7   import org.djunits.util.MatrixMath;
8   import org.djunits.vecmat.dnxm.MatrixNxM;
9   import org.djunits.vecmat.storage.DenseDoubleDataSi;
10  import org.djunits.vecmat.storage.DenseFloatDataSi;
11  import org.djutils.exceptions.Throw;
12  
13  /**
14   * Matrix contains a number of standard operations on matrices of relative quantities.
15   * <p>
16   * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
17   * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
18   * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
19   * @author Alexander Verbraeck
20   * @param <Q> the quantity type
21   * @param <U> the unit type
22   * @param <M> the 'SELF' matrix type
23   * @param <SI> the matrix type with generics &lt;SIQuantity, SIUnit&lt;
24   * @param <H> the generic matrix type with generics &lt;?, ?&lt; for Hadamard operations
25   */
26  public abstract class Matrix<Q extends Quantity<Q, U>, U extends UnitInterface<U, Q>, M extends Matrix<Q, U, M, SI, H>,
27          SI extends Matrix<SIQuantity, SIUnit, SI, ?, ?>, H extends Matrix<?, ?, ?, ?, ?>> extends VectorMatrix<Q, U, M, SI, H>
28  {
29      /** */
30      private static final long serialVersionUID = 600L;
31  
32      /**
33       * Create a new matrix with a unit.
34       * @param displayUnit the display unit to use
35       */
36      public Matrix(final U displayUnit)
37      {
38          super(displayUnit);
39      }
40  
41      /**
42       * Check if the multiplication with the other matrix is valid. A valid matrix multiplication is (M x N) x (N x P).
43       * @param matrix the other matrix
44       * @throws IllegalArgumentException when this.cols() != other.rows()
45       */
46      protected void checkMultiply(final Matrix<?, ?, ?, ?, ?> matrix)
47      {
48          Throw.whenNull(matrix, "matrix");
49          Throw.when(cols() != matrix.rows(), IllegalArgumentException.class,
50                  "Matrix multiplication (M x N) x (N x P): this.cols (%d) != matrix.rows (%d)", cols(), matrix.rows());
51      }
52  
53      /**
54       * Check if the multiplication with the other matrix is valid. A valid matrix multiplication is (M x N) x (N x P).
55       * @param vector the other matrix
56       * @throws IllegalArgumentException when this.cols() != other.rows()
57       */
58      protected void checkMultiply(final Vector<?, ?, ?, ?, ?> vector)
59      {
60          Throw.whenNull(vector, "matrix");
61          Throw.when(cols() != vector.rows(), IllegalArgumentException.class,
62                  "Matrix multiplication (M x N) x (N x P): this.cols (%d) != vector.rows (%d)", cols(), vector.rows());
63      }
64  
65      /**
66       * Multiply this vector or matrix with a MatrixNxM, resulting in a MatrixNxM. The multiplication is a (NxM) x (MxP) matrix
67       * multiplication resulting in an (NxP) matrix.
68       * @param matrix the matrix to multiply with
69       * @return a MatrixNxM of an SIQuantity as the result of the matrix multiplication
70       * @throws IllegalArgumentException when the number of columns of this matrix does not equal the number of rows of the
71       *             matrix or vector to multiply with
72       */
73      public MatrixNxM<SIQuantity, SIUnit> multiply(final MatrixNxM<?, ?> matrix)
74      {
75          checkMultiply(matrix);
76          double[] result = MatrixMath.multiply(si(), matrix.si(), rows(), cols(), matrix.cols());
77          SIUnit siUnit = getDisplayUnit().siUnit().plus(matrix.getDisplayUnit().siUnit());
78          if (matrix.getDataGrid().isDouble())
79          {
80              return new MatrixNxM<SIQuantity, SIUnit>(new DenseDoubleDataSi(result, rows(), matrix.cols()), siUnit);
81          }
82          return new MatrixNxM<SIQuantity, SIUnit>(new DenseFloatDataSi(result, rows(), matrix.cols()), siUnit);
83      }
84  
85  }