View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.linear;
23  
24  import org.hipparchus.UnitTestUtils;
25  import org.hipparchus.exception.LocalizedCoreFormats;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  import org.hipparchus.exception.NullArgumentException;
28  import org.hipparchus.random.RandomGenerator;
29  import org.hipparchus.random.Well1024a;
30  import org.hipparchus.util.Precision;
31  import org.junit.Assert;
32  import org.junit.Test;
33  
34  /**
35   * Test cases for the {@link DiagonalMatrix} class.
36   */
37  public class DiagonalMatrixTest {
38      @Test
39      public void testConstructor1() {
40          final int dim = 3;
41          final DiagonalMatrix m = new DiagonalMatrix(dim);
42          Assert.assertEquals(dim, m.getRowDimension());
43          Assert.assertEquals(dim, m.getColumnDimension());
44      }
45  
46      @Test
47      public void testConstructor2() {
48          final double[] d = { -1.2, 3.4, 5 };
49          final DiagonalMatrix m = new DiagonalMatrix(d);
50          for (int i = 0; i < m.getRowDimension(); i++) {
51              for (int j = 0; j < m.getRowDimension(); j++) {
52                  if (i == j) {
53                      Assert.assertEquals(d[i], m.getEntry(i, j), 0d);
54                  } else {
55                      Assert.assertEquals(0d, m.getEntry(i, j), 0d);
56                  }
57              }
58          }
59  
60          // Check that the underlying was copied.
61          d[0] = 0;
62          Assert.assertFalse(d[0] == m.getEntry(0, 0));
63      }
64  
65      @Test
66      public void testConstructor3() {
67          final double[] d = { -1.2, 3.4, 5 };
68          final DiagonalMatrix m = new DiagonalMatrix(d, false);
69          for (int i = 0; i < m.getRowDimension(); i++) {
70              for (int j = 0; j < m.getRowDimension(); j++) {
71                  if (i == j) {
72                      Assert.assertEquals(d[i], m.getEntry(i, j), 0d);
73                  } else {
74                      Assert.assertEquals(0d, m.getEntry(i, j), 0d);
75                  }
76              }
77          }
78  
79          // Check that the underlying is referenced.
80          d[0] = 0;
81          Assert.assertTrue(d[0] == m.getEntry(0, 0));
82  
83      }
84  
85      @Test(expected=MathIllegalArgumentException.class)
86      public void testCreateError() {
87          final double[] d = { -1.2, 3.4, 5 };
88          final DiagonalMatrix m = new DiagonalMatrix(d, false);
89          m.createMatrix(5, 3);
90      }
91  
92      @Test
93      public void testCreate() {
94          final double[] d = { -1.2, 3.4, 5 };
95          final DiagonalMatrix m = new DiagonalMatrix(d, false);
96          final RealMatrix p = m.createMatrix(5, 5);
97          Assert.assertTrue(p instanceof DiagonalMatrix);
98          Assert.assertEquals(5, p.getRowDimension());
99          Assert.assertEquals(5, p.getColumnDimension());
100     }
101 
102     @Test
103     public void testCopy() {
104         final double[] d = { -1.2, 3.4, 5 };
105         final DiagonalMatrix m = new DiagonalMatrix(d, false);
106         final DiagonalMatrix p = (DiagonalMatrix) m.copy();
107         for (int i = 0; i < m.getRowDimension(); ++i) {
108             Assert.assertEquals(m.getEntry(i, i), p.getEntry(i, i), 1.0e-20);
109         }
110     }
111 
112     @Test
113     public void testGetData() {
114         final double[] data = { -1.2, 3.4, 5 };
115         final int dim = 3;
116         final DiagonalMatrix m = new DiagonalMatrix(dim);
117         for (int i = 0; i < dim; i++) {
118             m.setEntry(i, i, data[i]);
119         }
120 
121         final double[][] out = m.getData();
122         Assert.assertEquals(dim, out.length);
123         for (int i = 0; i < m.getRowDimension(); i++) {
124             Assert.assertEquals(dim, out[i].length);
125             for (int j = 0; j < m.getRowDimension(); j++) {
126                 if (i == j) {
127                     Assert.assertEquals(data[i], out[i][j], 0d);
128                 } else {
129                     Assert.assertEquals(0d, out[i][j], 0d);
130                 }
131             }
132         }
133     }
134 
135     @Test
136     public void testAdd() {
137         final double[] data1 = { -1.2, 3.4, 5 };
138         final DiagonalMatrix m1 = new DiagonalMatrix(data1);
139 
140         final double[] data2 = { 10.1, 2.3, 45 };
141         final DiagonalMatrix m2 = new DiagonalMatrix(data2);
142 
143         final DiagonalMatrix result = m1.add(m2);
144         Assert.assertEquals(m1.getRowDimension(), result.getRowDimension());
145         for (int i = 0; i < result.getRowDimension(); i++) {
146             for (int j = 0; j < result.getRowDimension(); j++) {
147                 if (i == j) {
148                     Assert.assertEquals(data1[i] + data2[i], result.getEntry(i, j), 0d);
149                 } else {
150                     Assert.assertEquals(0d, result.getEntry(i, j), 0d);
151                 }
152             }
153         }
154     }
155 
156     @Test
157     public void testSubtract() {
158         final double[] data1 = { -1.2, 3.4, 5 };
159         final DiagonalMatrix m1 = new DiagonalMatrix(data1);
160 
161         final double[] data2 = { 10.1, 2.3, 45 };
162         final DiagonalMatrix m2 = new DiagonalMatrix(data2);
163 
164         final DiagonalMatrix result = m1.subtract(m2);
165         Assert.assertEquals(m1.getRowDimension(), result.getRowDimension());
166         for (int i = 0; i < result.getRowDimension(); i++) {
167             for (int j = 0; j < result.getRowDimension(); j++) {
168                 if (i == j) {
169                     Assert.assertEquals(data1[i] - data2[i], result.getEntry(i, j), 0d);
170                 } else {
171                     Assert.assertEquals(0d, result.getEntry(i, j), 0d);
172                 }
173             }
174         }
175     }
176 
177     @Test
178     public void testAddToEntry() {
179         final double[] data = { -1.2, 3.4, 5 };
180         final DiagonalMatrix m = new DiagonalMatrix(data);
181 
182         for (int i = 0; i < m.getRowDimension(); i++) {
183             m.addToEntry(i, i, i);
184             Assert.assertEquals(data[i] + i, m.getEntry(i, i), 0d);
185         }
186     }
187 
188     @Test
189     public void testMultiplyEntry() {
190         final double[] data = { -1.2, 3.4, 5 };
191         final DiagonalMatrix m = new DiagonalMatrix(data);
192 
193         for (int i = 0; i < m.getRowDimension(); i++) {
194             m.multiplyEntry(i, i, i);
195             Assert.assertEquals(data[i] * i, m.getEntry(i, i), 0d);
196         }
197     }
198 
199     @Test
200     public void testMultiply1() {
201         final double[] data1 = { -1.2, 3.4, 5 };
202         final DiagonalMatrix m1 = new DiagonalMatrix(data1);
203         final double[] data2 = { 10.1, 2.3, 45 };
204         final DiagonalMatrix m2 = new DiagonalMatrix(data2);
205 
206         final DiagonalMatrix result = (DiagonalMatrix) m1.multiply((RealMatrix) m2);
207         Assert.assertEquals(m1.getRowDimension(), result.getRowDimension());
208         for (int i = 0; i < result.getRowDimension(); i++) {
209             for (int j = 0; j < result.getRowDimension(); j++) {
210                 if (i == j) {
211                     Assert.assertEquals(data1[i] * data2[i], result.getEntry(i, j), 0d);
212                 } else {
213                     Assert.assertEquals(0d, result.getEntry(i, j), 0d);
214                 }
215             }
216         }
217     }
218 
219     @Test
220     public void testMultiply2() {
221         final double[] data1 = { -1.2, 3.4, 5 };
222         final DiagonalMatrix diag1 = new DiagonalMatrix(data1);
223 
224         final double[][] data2 = { { -1.2, 3.4 },
225                                    { -5.6, 7.8 },
226                                    {  9.1, 2.3 } };
227         final RealMatrix dense2 = new Array2DRowRealMatrix(data2);
228         final RealMatrix dense1 = new Array2DRowRealMatrix(diag1.getData());
229 
230         final RealMatrix diagResult = diag1.multiply(dense2);
231         final RealMatrix denseResult = dense1.multiply(dense2);
232 
233         for (int i = 0; i < dense1.getRowDimension(); i++) {
234             for (int j = 0; j < dense2.getColumnDimension(); j++) {
235                 Assert.assertEquals(denseResult.getEntry(i, j),
236                                     diagResult.getEntry(i, j), 0d);
237             }
238         }
239     }
240 
241     @Test
242     public void testMultiplyTransposedDiagonalMatrix() {
243         RandomGenerator randomGenerator = new Well1024a(0x4b20cb5a0440c929l);
244         for (int rows = 1; rows <= 64; rows += 7) {
245             final DiagonalMatrix a = new DiagonalMatrix(rows);
246             for (int i = 0; i < rows; ++i) {
247                 a.setEntry(i, i, randomGenerator.nextDouble());
248             }
249             final DiagonalMatrix b = new DiagonalMatrix(rows);
250             for (int i = 0; i < rows; ++i) {
251                 b.setEntry(i, i, randomGenerator.nextDouble());
252             }
253             Assert.assertEquals(0.0,
254                                 a.multiplyTransposed(b).subtract(a.multiply(b.transpose())).getNorm1(),
255                                 1.0e-15);
256         }
257     }
258 
259     @Test
260     public void testMultiplyTransposedArray2DRowRealMatrix() {
261         RandomGenerator randomGenerator = new Well1024a(0x0fa7b97d4826cd43l);
262         final RealMatrixChangingVisitor randomSetter = new DefaultRealMatrixChangingVisitor() {
263             public double visit(final int row, final int column, final double value) {
264                 return randomGenerator.nextDouble();
265             }
266         };
267         for (int rows = 1; rows <= 64; rows += 7) {
268             final DiagonalMatrix a = new DiagonalMatrix(rows);
269             for (int i = 0; i < rows; ++i) {
270                 a.setEntry(i, i, randomGenerator.nextDouble());
271             }
272             for (int interm = 1; interm <= 64; interm += 7) {
273                 final Array2DRowRealMatrix b = new Array2DRowRealMatrix(interm, rows);
274                 b.walkInOptimizedOrder(randomSetter);
275                 Assert.assertEquals(0.0,
276                                     a.multiplyTransposed(b).subtract(a.multiply(b.transpose())).getNorm1(),
277                                     1.0e-15);
278             }
279         }
280     }
281 
282     @Test
283     public void testMultiplyTransposedWrongDimensions() {
284         try {
285             new DiagonalMatrix(3).multiplyTransposed(new DiagonalMatrix(2));
286             Assert.fail("an exception should have been thrown");
287         } catch (MathIllegalArgumentException miae) {
288             Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
289             Assert.assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
290             Assert.assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
291         }
292     }
293 
294     @Test
295     public void testTransposeMultiplyDiagonalMatrix() {
296         RandomGenerator randomGenerator = new Well1024a(0x4b20cb5a0440c929l);
297         for (int rows = 1; rows <= 64; rows += 7) {
298             final DiagonalMatrix a = new DiagonalMatrix(rows);
299             for (int i = 0; i < rows; ++i) {
300                 a.setEntry(i, i, randomGenerator.nextDouble());
301             }
302             final DiagonalMatrix b = new DiagonalMatrix(rows);
303             for (int i = 0; i < rows; ++i) {
304                 b.setEntry(i, i, randomGenerator.nextDouble());
305             }
306             Assert.assertEquals(0.0,
307                                 a.transposeMultiply(b).subtract(a.transpose().multiply(b)).getNorm1(),
308                                 1.0e-15);
309         }
310     }
311 
312     @Test
313     public void testTransposeMultiplyArray2DRowRealMatrix() {
314         RandomGenerator randomGenerator = new Well1024a(0x0fa7b97d4826cd43l);
315         final RealMatrixChangingVisitor randomSetter = new DefaultRealMatrixChangingVisitor() {
316             public double visit(final int row, final int column, final double value) {
317                 return randomGenerator.nextDouble();
318             }
319         };
320         for (int rows = 1; rows <= 64; rows += 7) {
321             final DiagonalMatrix a = new DiagonalMatrix(rows);
322             for (int i = 0; i < rows; ++i) {
323                 a.setEntry(i, i, randomGenerator.nextDouble());
324             }
325             for (int interm = 1; interm <= 64; interm += 7) {
326                 final Array2DRowRealMatrix b = new Array2DRowRealMatrix(rows, interm);
327                 b.walkInOptimizedOrder(randomSetter);
328                 Assert.assertEquals(0.0,
329                                     a.transposeMultiply(b).subtract(a.transpose().multiply(b)).getNorm1(),
330                                     1.0e-15);
331             }
332         }
333     }
334 
335     @Test
336     public void testTransposeMultiplyWrongDimensions() {
337         try {
338             new DiagonalMatrix(3).transposeMultiply(new DiagonalMatrix(2));
339             Assert.fail("an exception should have been thrown");
340         } catch (MathIllegalArgumentException miae) {
341             Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
342             Assert.assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
343             Assert.assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
344         }
345     }
346 
347     @Test
348     public void testOperate() {
349         final double[] data = { -1.2, 3.4, 5 };
350         final DiagonalMatrix diag = new DiagonalMatrix(data);
351         final RealMatrix dense = new Array2DRowRealMatrix(diag.getData());
352 
353         final double[] v = { 6.7, 890.1, 23.4 };
354         final double[] diagResult = diag.operate(v);
355         final double[] denseResult = dense.operate(v);
356 
357         UnitTestUtils.assertEquals(diagResult, denseResult, 0d);
358     }
359 
360     @Test
361     public void testPreMultiply() {
362         final double[] data = { -1.2, 3.4, 5 };
363         final DiagonalMatrix diag = new DiagonalMatrix(data);
364         final RealMatrix dense = new Array2DRowRealMatrix(diag.getData());
365 
366         final double[] v = { 6.7, 890.1, 23.4 };
367         final double[] diagResult = diag.preMultiply(v);
368         final double[] denseResult = dense.preMultiply(v);
369 
370         UnitTestUtils.assertEquals(diagResult, denseResult, 0d);
371     }
372 
373     @Test
374     public void testPreMultiplyVector() {
375         final double[] data = { -1.2, 3.4, 5 };
376         final DiagonalMatrix diag = new DiagonalMatrix(data);
377         final RealMatrix dense = new Array2DRowRealMatrix(diag.getData());
378 
379         final double[] v = { 6.7, 890.1, 23.4 };
380         final RealVector vector = MatrixUtils.createRealVector(v);
381         final RealVector diagResult = diag.preMultiply(vector);
382         final RealVector denseResult = dense.preMultiply(vector);
383 
384         UnitTestUtils.assertEquals("preMultiply(Vector) returns wrong result", diagResult, denseResult, 0d);
385     }
386 
387     @Test(expected=MathIllegalArgumentException.class)
388     public void testSetNonDiagonalEntry() {
389         final DiagonalMatrix diag = new DiagonalMatrix(3);
390         diag.setEntry(1, 2, 3.4);
391     }
392 
393     @Test
394     public void testSetNonDiagonalZero() {
395         final DiagonalMatrix diag = new DiagonalMatrix(3);
396         diag.setEntry(1, 2, 0.0);
397         Assert.assertEquals(0.0, diag.getEntry(1, 2), Precision.SAFE_MIN);
398     }
399 
400     @Test(expected=MathIllegalArgumentException.class)
401     public void testAddNonDiagonalEntry() {
402         final DiagonalMatrix diag = new DiagonalMatrix(3);
403         diag.addToEntry(1, 2, 3.4);
404     }
405 
406     @Test
407     public void testAddNonDiagonalZero() {
408         final DiagonalMatrix diag = new DiagonalMatrix(3);
409         diag.addToEntry(1, 2, 0.0);
410         Assert.assertEquals(0.0, diag.getEntry(1, 2), Precision.SAFE_MIN);
411     }
412 
413     @Test
414     public void testMultiplyNonDiagonalEntry() {
415         final DiagonalMatrix diag = new DiagonalMatrix(3);
416         diag.multiplyEntry(1, 2, 3.4);
417         Assert.assertEquals(0.0, diag.getEntry(1, 2), Precision.SAFE_MIN);
418     }
419 
420     @Test
421     public void testMultiplyNonDiagonalZero() {
422         final DiagonalMatrix diag = new DiagonalMatrix(3);
423         diag.multiplyEntry(1, 2, 0.0);
424         Assert.assertEquals(0.0, diag.getEntry(1, 2), Precision.SAFE_MIN);
425     }
426 
427     @Test(expected=MathIllegalArgumentException.class)
428     public void testSetEntryOutOfRange() {
429         final DiagonalMatrix diag = new DiagonalMatrix(3);
430         diag.setEntry(3, 3, 3.4);
431     }
432 
433     @Test(expected=NullArgumentException.class)
434     public void testNull() {
435         new DiagonalMatrix(null, false);
436     }
437 
438     @Test(expected=MathIllegalArgumentException.class)
439     public void testSetSubMatrixError() {
440         final double[] data = { -1.2, 3.4, 5 };
441         final DiagonalMatrix diag = new DiagonalMatrix(data);
442         diag.setSubMatrix(new double[][] { {1.0, 1.0}, {1.0, 1.0}}, 1, 1);
443     }
444 
445     @Test
446     public void testSetSubMatrix() {
447         final double[] data = { -1.2, 3.4, 5 };
448         final DiagonalMatrix diag = new DiagonalMatrix(data);
449         diag.setSubMatrix(new double[][] { {0.0, 5.0, 0.0}, {0.0, 0.0, 6.0}}, 1, 0);
450         Assert.assertEquals(-1.2, diag.getEntry(0, 0), 1.0e-20);
451         Assert.assertEquals( 5.0, diag.getEntry(1, 1), 1.0e-20);
452         Assert.assertEquals( 6.0, diag.getEntry(2, 2), 1.0e-20);
453     }
454 
455     @Test(expected=MathIllegalArgumentException.class)
456     public void testInverseError() {
457         final double[] data = { 1, 2, 0 };
458         final DiagonalMatrix diag = new DiagonalMatrix(data);
459         diag.inverse();
460     }
461 
462     @Test(expected=MathIllegalArgumentException.class)
463     public void testInverseError2() {
464         final double[] data = { 1, 2, 1e-6 };
465         final DiagonalMatrix diag = new DiagonalMatrix(data);
466         diag.inverse(1e-5);
467     }
468 
469     @Test
470     public void testInverse() {
471         final double[] data = { 1, 2, 3 };
472         final DiagonalMatrix m = new DiagonalMatrix(data);
473         final DiagonalMatrix inverse = m.inverse();
474 
475         final DiagonalMatrix result = m.multiply(inverse);
476         UnitTestUtils.assertEquals("DiagonalMatrix.inverse() returns wrong result",
477                 MatrixUtils.createRealIdentityMatrix(data.length), result, Math.ulp(1d));
478     }
479 
480 }