View Javadoc
1   package org.djunits.vecmat.dn;
2   
3   import org.djunits.quantity.def.AbsQuantity;
4   import org.djunits.quantity.def.Quantity;
5   import org.djunits.quantity.def.Reference;
6   import org.djunits.unit.Unit;
7   import org.djunits.vecmat.def.AbsSquareMatrix;
8   import org.djunits.vecmat.storage.DenseDoubleDataSi;
9   import org.djutils.exceptions.Throw;
10  
11  /**
12   * AbsMatrixNxN implements a matrix with NxN absolute quantities with a reference point. The matrix is immutable, except for the
13   * display unit, which can be changed.
14   * <p>
15   * Copyright (c) 2026-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 <A> the absolute quantity type
20   * @param <Q> the corresponding relative quantity type
21   */
22  public class AbsMatrixNxN<A extends AbsQuantity<A, Q, ?>, Q extends Quantity<Q>>
23          extends AbsSquareMatrix<A, Q, AbsMatrixNxN<A, Q>, MatrixNxN<Q>>
24  {
25      /** */
26      private static final long serialVersionUID = 600L;
27  
28      /**
29       * Create a new AbsMatrixNxN with a display unit and a reference point.
30       * @param relativeMatrix the matrix values {a_ij} expressed in the displayUnit
31       * @param reference the reference point for the absolute values
32       */
33      public AbsMatrixNxN(final MatrixNxN<Q> relativeMatrix, final Reference<?, A, Q> reference)
34      {
35          super(relativeMatrix, reference);
36      }
37  
38      @Override
39      public AbsMatrixNxN<A, Q> instantiate(final MatrixNxN<Q> relativeMatrix, final Reference<?, A, Q> reference)
40      {
41          return new AbsMatrixNxN<>(relativeMatrix, reference);
42      }
43  
44      @Override
45      public AbsVectorN.Row<A, Q> getRowVector(final int row)
46      {
47          return new AbsVectorN.Row<>(getRelativeVecMat().getRowVector(row), getReference());
48      }
49  
50      @Override
51      public AbsVectorN.Row<A, Q> mgetRowVector(final int mRow)
52      {
53          return new AbsVectorN.Row<>(getRelativeVecMat().mgetRowVector(mRow), getReference());
54      }
55  
56      @Override
57      public AbsVectorN.Col<A, Q> getColumnVector(final int col)
58      {
59          return new AbsVectorN.Col<>(getRelativeVecMat().getColumnVector(col), getReference());
60      }
61  
62      @Override
63      public AbsVectorN.Col<A, Q> mgetColumnVector(final int mCol)
64      {
65          return new AbsVectorN.Col<>(getRelativeVecMat().mgetColumnVector(mCol), getReference());
66      }
67  
68      @Override
69      public AbsVectorN.Col<A, Q> getDiagonalVector()
70      {
71          return new AbsVectorN.Col<>(getRelativeVecMat().getDiagonalVector(), getReference());
72      }
73  
74      // ------------------------------------------ OF METHODS ------------------------------------------
75  
76      /**
77       * Create an AbsMatrixNxN without needing generics.
78       * @param dataInUnit the matrix values {a11, a12, 13, ..., aN1, aN2, ..., aNN} expressed as an array in the display unit
79       * @param unit the unit of the data, which will also be used as the display unit
80       * @param reference the reference point for the absolute quantities
81       * @return a new AbsMatrixNxN with a unit
82       * @param <A> the absolute quantity type
83       * @param <Q> the quantity type
84       * @param <R> the reference type
85       * @throws IllegalArgumentException when the size of the data object is not a square
86       */
87      public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>, R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(
88              final double[] dataInUnit, final Unit<?, Q> unit, final R reference)
89      {
90          return new AbsMatrixNxN<>(MatrixNxN.of(dataInUnit, unit), reference);
91      }
92  
93      /**
94       * Create an AbsMatrixNxN without needing generics.
95       * @param dataSi the matrix values {a11, a12, 13, ..., aN1, aN2, ..., aNN} expressed as an array in the SI units
96       * @param displayUnit the display unit to use
97       * @param reference the reference point for the absolute quantities
98       * @return a new AbsMatrixNxN with a unit
99       * @param <A> the absolute quantity type
100      * @param <Q> the quantity type
101      * @param <R> the reference type
102      * @throws IllegalArgumentException when the size of the data object is not a square
103      */
104     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>, R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> ofSi(
105             final double[] dataSi, final Unit<?, Q> displayUnit, final R reference)
106     {
107         return new AbsMatrixNxN<>(MatrixNxN.ofSi(dataSi, displayUnit), reference);
108     }
109 
110     /**
111      * Create an AbsMatrixNxN without needing generics.
112      * @param data the matrix values {a11, a12, 13, ..., aN1, aN2, ..., aNN} expressed as an array of quantities
113      * @param reference the reference point for the absolute quantities
114      * @return a new AbsMatrixNxN with a unit
115      * @param <A> the absolute quantity type
116      * @param <Q> the quantity type
117      * @param <R> the reference type
118      * @throws IllegalArgumentException when the size of the data object is not a square
119      */
120     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
121             R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(final Q[] data, final R reference)
122     {
123         return new AbsMatrixNxN<>(MatrixNxN.of(data), reference);
124     }
125 
126     /**
127      * Create a AbsMatrixNxN without needing generics, based on a row-major array of absolute quantities. The unit is taken from
128      * the first quantity in the grid. The reference points have to be all the same.
129      * @param absData the values {a11, a12, ..., A1N, ..., aN1, aN2, ..., aNN} expressed as an array of absolute quantities
130      * @return a new AbsMatrixNxN with a display unit and reference point
131      * @param <A> the absolute quantity type
132      * @param <Q> the quantity type
133      * @param <R> the reference type
134      * @throws IllegalArgumentException when the size of the data object is not a perfect square
135      */
136     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
137             R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(final A[] absData)
138     {
139         Throw.whenNull(absData, "absData");
140         int size = (int) Math.sqrt(absData.length);
141         Throw.when(size * size != absData.length, IllegalArgumentException.class, "absData.length is not square");
142         var ddd = DenseDoubleDataSi.of(absData, size, size); // guarantees that absGrid[0][0] exists
143         return new AbsMatrixNxN<>(new MatrixNxN<Q>(ddd, absData[0].getDisplayUnit()), absData[0].getReference());
144     }
145 
146     /**
147      * Create an AbsMatrixNxN with a unit, based on a 2-dimensional grid with SI-values.
148      * @param gridSi the matrix values {a11, a12, ..., a1N}, ..., {aN1, aN2, ..., aNN}} expressed in the SI or base unit
149      * @param displayUnit the unit of the data, which will also be used as the display unit
150      * @param reference the reference point for the absolute quantities
151      * @return a new AbsMatrixNxN with a unit
152      * @param <A> the absolute quantity type
153      * @param <Q> the quantity type
154      * @param <R> the reference type
155      * @throws IllegalArgumentException when the data object is not a square grid
156      */
157     @SuppressWarnings("checkstyle:needbraces")
158     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>, R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> ofSi(
159             final double[][] gridSi, final Unit<?, Q> displayUnit, final R reference)
160     {
161         return new AbsMatrixNxN<>(MatrixNxN.ofSi(gridSi, displayUnit), reference);
162     }
163 
164     /**
165      * Create an AbsMatrixNxN with a unit, based on a 2-dimensional grid.
166      * @param gridInUnit the matrix values {a11, a12, ..., a1N}, ..., {aN1, aN2, ..., aNN}} expressed in the unit
167      * @param unit the unit of the data, which will also be used as the display unit
168      * @param reference the reference point for the absolute quantities
169      * @return a new AbsMatrixNxN with a unit
170      * @param <A> the absolute quantity type
171      * @param <Q> the quantity type
172      * @param <R> the reference type
173      * @throws IllegalArgumentException when the data object is not a square grid
174      */
175     @SuppressWarnings("checkstyle:needbraces")
176     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>, R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(
177             final double[][] gridInUnit, final Unit<?, Q> unit, final R reference)
178     {
179         return new AbsMatrixNxN<>(MatrixNxN.of(gridInUnit, unit), reference);
180     }
181 
182     /**
183      * Create an AbsMatrixNxN without needing generics.
184      * @param grid the matrix values {a11, a12, ..., a1N}, ..., {aN1, aN2, ..., aNN}} expressed as an array of quantities
185      * @param reference the reference point for the absolute quantities
186      * @return a new AbsMatrixNxN with a unit
187      * @param <A> the absolute quantity type
188      * @param <Q> the quantity type
189      * @param <R> the reference type
190      * @throws IllegalArgumentException when the data object is not a square grid
191      */
192     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
193             R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(final Q[][] grid, final R reference)
194     {
195         return new AbsMatrixNxN<>(MatrixNxN.of(grid), reference);
196     }
197 
198     /**
199      * Create a AbsMatrixNxN without needing generics, based on a row-major array of absolute quantities. The unit is taken from
200      * the first quantity in the grid. The reference points have to be all the same.
201      * @param absGrid the values {{a11, a12, ..., A1N}, ..., {aN1, aN2, ..., aNN}} expressed as an array of absolute quantities
202      * @return a new AbsMatrixNxN with a display unit and reference point
203      * @param <A> the absolute quantity type
204      * @param <Q> the quantity type
205      * @param <R> the reference type
206      * @throws IllegalArgumentException when the size of the data object is not a perfect square
207      */
208     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
209             R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(final A[][] absGrid)
210     {
211         Throw.whenNull(absGrid, "absGrid");
212         var ddd = DenseDoubleDataSi.of(absGrid); // guarantees that absGrid[0][0] exists
213         return new AbsMatrixNxN<>(new MatrixNxN<Q>(ddd, absGrid[0][0].getDisplayUnit()), absGrid[0][0].getReference());
214     }
215 
216     /**
217      * Create an AbsMatrixNxN without needing generics.
218      * @param relativeMatrix the relative matrix with values relative to the reference point
219      * @param reference the reference point for the absolute quantities
220      * @return a new AbsMatrixNxN with a unit
221      * @param <A> the absolute quantity type
222      * @param <Q> the quantity type
223      * @param <R> the reference type
224      */
225     public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
226             R extends Reference<R, A, Q>> AbsMatrixNxN<A, Q> of(final MatrixNxN<Q> relativeMatrix, final R reference)
227     {
228         return new AbsMatrixNxN<>(relativeMatrix, reference);
229     }
230 
231 }