View Javadoc
1   package org.djunits.vecmat.def;
2   
3   import java.util.Arrays;
4   
5   import org.djunits.quantity.SIQuantity;
6   import org.djunits.quantity.def.Quantity;
7   import org.djunits.unit.Unit;
8   import org.djunits.util.ArrayMath;
9   import org.djutils.exceptions.Throw;
10  
11  /**
12   * SquareDenseMatrix implements the core functions for a matrix with n x n real-valued entries. The data is stored in a dense
13   * double[] field. The matrix is immutable, except for the display unit, which can be changed.
14   * <p>
15   * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
16   * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
17   * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
18   * @author Alexander Verbraeck
19   * @param <Q> the quantity type
20   * @param <M> the 'SELF' square dense matrix type
21   * @param <SI> the square dense matrix type with generics &lt;SIQuantity, SIUnit&lt;
22   * @param <H> the generic square dense matrix type with generics &lt;?, ?&lt; for Hadamard operations
23   */
24  public abstract class SquareDenseMatrix<Q extends Quantity<Q>, M extends SquareDenseMatrix<Q, M, SI, H>,
25          SI extends SquareDenseMatrix<SIQuantity, SI, ?, ?>, H extends SquareDenseMatrix<?, ?, ?, ?>>
26          extends SquareMatrix<Q, M, SI, H>
27  {
28      /** */
29      private static final long serialVersionUID = 600L;
30  
31      /** The n x n values in SI-units as a row-major array. */
32      private final double[] dataSi;
33  
34      /** the order (n in n x n) of the matrix. */
35      private final int order;
36  
37      /**
38       * Create a new SquareDenseMatrix with a unit. NO SAFE COPY of the double[] data element is made.
39       * @param dataSi the matrix values {a11, a12, ..., a21, a22, ...} expressed in the SI unit
40       * @param displayUnit the display unit to use
41       * @param order the order of the square matrix (number of rows/columns)
42       * @throws IllegalArgumentException when dataSi.length != order * order.
43       */
44      protected SquareDenseMatrix(final double[] dataSi, final Unit<?, Q> displayUnit, final int order)
45      {
46          super(displayUnit);
47          Throw.when(dataSi.length != order * order, IllegalArgumentException.class,
48                  "SquareDenseMatrix initialized with %d values instead of %d", dataSi.length, order * order);
49          this.dataSi = dataSi;
50          this.order = order;
51      }
52  
53      @Override
54      public double[] unsafeSiArray()
55      {
56          return this.dataSi;
57      }
58  
59      @Override
60      public double[] getSiArray()
61      {
62          return this.dataSi.clone();
63      }
64  
65      @Override
66      public double si(final int row, final int col)
67      {
68          checkRow(row);
69          checkCol(col);
70          return this.dataSi[this.order * row + col];
71      }
72  
73      @Override
74      public int rows()
75      {
76          return this.order;
77      }
78  
79      @Override
80      public int cols()
81      {
82          return this.order;
83      }
84  
85      @Override
86      public int nonZeroCount()
87      {
88          return ArrayMath.nnz(this.dataSi);
89      }
90  
91      @Override
92      public double[] getRowSi(final int row)
93      {
94          checkRow(row);
95          double[] vSi = new double[this.order];
96          for (int col = 0; col < this.order; col++)
97          {
98              vSi[col] = this.dataSi[this.order * row + col];
99          }
100         return vSi;
101     }
102 
103     @Override
104     public double[] getColumnSi(final int col)
105     {
106         checkCol(col);
107         double[] vSi = new double[this.order];
108         for (int row = 0; row < this.order; row++)
109         {
110             vSi[row] = this.dataSi[this.order * row + col];
111         }
112         return vSi;
113     }
114 
115     @Override
116     public int hashCode()
117     {
118         final int prime = 31;
119         int result = 1;
120         result = prime * result + Arrays.hashCode(this.dataSi);
121         return result;
122     }
123 
124     @SuppressWarnings("checkstyle:needbraces")
125     @Override
126     public boolean equals(final Object obj)
127     {
128         if (this == obj)
129             return true;
130         if (obj == null)
131             return false;
132         if (getClass() != obj.getClass())
133             return false;
134         SquareDenseMatrix<?, ?, ?, ?> other = (SquareDenseMatrix<?, ?, ?, ?>) obj;
135         return Arrays.equals(this.dataSi, other.dataSi);
136     }
137 
138 }