1 /* 2 * This file is part of ELKI: 3 * Environment for Developing KDD-Applications Supported by Index-Structures 4 * 5 * Copyright (C) 2018 6 * ELKI Development Team 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Affero General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Affero General Public License for more details. 17 * 18 * You should have received a copy of the GNU Affero General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 package de.lmu.ifi.dbs.elki.math.linearalgebra; 22 23 import static de.lmu.ifi.dbs.elki.math.linearalgebra.VMath.*; 24 import static de.lmu.ifi.dbs.elki.math.linearalgebra.VMathOperationsTest.assertDimensionMismatch; 25 import static org.junit.Assert.*; 26 27 import org.junit.Test; 28 29 /** 30 * Class testing the methods of the {@link VMath} class, 31 * which provide mathematical operations and have two dimensional double arrays 32 * as input. 33 * <p> 34 * Two dimensional double arrays are interpreted as rows x columns matrixes. 35 * 36 * @author Merlin Dietrich 37 */ 38 @SuppressWarnings("deprecation") 39 public class VMathMatrixTest { 40 /** 41 * A non symmetric 4 x 5 (rows x columns) matrix as test-data. 42 */ 43 protected static final double[][] TESTMATRIX = { // 44 { 1, 2, 3, 4, 5 }, // 45 { 2, 3, 4, 5, 1 }, // 46 { 3, 4, 5, 1, 2 }, // 47 { 4, 5, 1, 2, 3 } }; 48 49 /** 50 * Testing the transposed method of VMath class. 51 */ 52 @Test testTransposed()53 public void testTransposed() { 54 final double[][] m1 = TESTMATRIX; 55 final double[][] res_case1 = { // 56 { m1[0][0], m1[1][0], m1[2][0], m1[3][0] }, // 57 { m1[0][1], m1[1][1], m1[2][1], m1[3][1] }, // 58 { m1[0][2], m1[1][2], m1[2][2], m1[3][2] }, // 59 { m1[0][3], m1[1][3], m1[2][3], m1[3][3] }, // 60 { m1[0][4], m1[1][4], m1[2][4], m1[3][4] } }; 61 assertTrue(almostEquals(transpose(m1), res_case1)); 62 } 63 64 /** 65 * Testing the plus, plusEquals methods of VMath class. 66 */ 67 @Test testPlus()68 public void testPlus() { 69 final double[][] m1 = { // 70 { -14, -1, 0.01, 0.100000000000006100004 }, // 71 { 1.21, 0, 2, 0.500000000000006100004 }, // 72 { -14, 1, -3.42, 1.100000000000006100007 } }; 73 final double[][] m2 = { // 74 { 7, 6, 0, -0.1000000000000069 }, // 75 { -1.21, -9, 2, 0.4000000000000069 }, // 76 { -3, 26, 1, 0 } }; 77 final double s = 13; 78 final double[][] res_plus = { // 79 { m1[0][0] + m2[0][0], m1[0][1] + m2[0][1], m1[0][2] + m2[0][2], m1[0][3] + m2[0][3] }, // 80 { m1[1][0] + m2[1][0], m1[1][1] + m2[1][1], m1[1][2] + m2[1][2], m1[1][3] + m2[1][3] }, // 81 { m1[2][0] + m2[2][0], m1[2][1] + m2[2][1], m1[2][2] + m2[2][2], m1[2][3] + m2[2][3] } }; 82 final double[][] res_plusTimes = { { m1[0][0] + s * m2[0][0], m1[0][1] + s * m2[0][1], m1[0][2] + s * m2[0][2], m1[0][3] + s * m2[0][3] }, // 83 { m1[1][0] + s * m2[1][0], m1[1][1] + s * m2[1][1], m1[1][2] + s * m2[1][2], m1[1][3] + s * m2[1][3] }, // 84 { m1[2][0] + s * m2[2][0], m1[2][1] + s * m2[2][1], m1[2][2] + s * m2[2][2], m1[2][3] + s * m2[2][3] } }; 85 86 // testing plus and plusEquals 87 assertTrue(almostEquals(res_plus, plus(m1, m2), 0.)); 88 assertTrue(almostEquals(res_plus, plusEquals(copy(m1), m2), 0.)); 89 // via minusTimes 90 assertTrue(almostEquals(res_plus, plusTimes(m1, m2, 1), 0.)); 91 92 // testing plusTimes and plusTimesEquals 93 assertTrue(almostEquals(res_plusTimes, plusTimes(m1, m2, s), 0.)); 94 assertTrue(almostEquals(res_plusTimes, plusTimesEquals(copy(m1), m2, s), 0.)); 95 } 96 97 /** 98 * Testing the matrix minus, minusEquals methods of VMath class. 99 */ 100 @Test testMinus()101 public void testMinus() { 102 final double[][] m1 = { // 103 { 13, 0, 5 }, // 104 { -3, 1, 3 }, // 105 { 1, 2, -4.7 }, // 106 { -7, -2.21, 72 }, // 107 { -27, 12, 0 } }; 108 final double[][] m2 = { // 109 { -13, 0.1, 0.0000000000000006 }, // 110 { 5, 42, 2 }, // 111 { 7, 3, 4.7 }, // 112 { -7, 4, 2 }, // 113 { 7, 6, -6 } }; 114 final double s = 13; 115 final double[][] res_minus = { // 116 { m1[0][0] - m2[0][0], m1[0][1] - m2[0][1], m1[0][2] - m2[0][2] }, // 117 { m1[1][0] - m2[1][0], m1[1][1] - m2[1][1], m1[1][2] - m2[1][2] }, // 118 { m1[2][0] - m2[2][0], m1[2][1] - m2[2][1], m1[2][2] - m2[2][2] }, // 119 { m1[3][0] - m2[3][0], m1[3][1] - m2[3][1], m1[3][2] - m2[3][2] }, // 120 { m1[4][0] - m2[4][0], m1[4][1] - m2[4][1], m1[4][2] - m2[4][2] } }; 121 final double[][] res_minusTimes = { // 122 { m1[0][0] - s * m2[0][0], m1[0][1] - s * m2[0][1], m1[0][2] - s * m2[0][2] }, // 123 { m1[1][0] - s * m2[1][0], m1[1][1] - s * m2[1][1], m1[1][2] - s * m2[1][2] }, // 124 { m1[2][0] - s * m2[2][0], m1[2][1] - s * m2[2][1], m1[2][2] - s * m2[2][2] }, // 125 { m1[3][0] - s * m2[3][0], m1[3][1] - s * m2[3][1], m1[3][2] - s * m2[3][2] }, // 126 { m1[4][0] - s * m2[4][0], m1[4][1] - s * m2[4][1], m1[4][2] - s * m2[4][2] } }; 127 128 // testing minus and minusEquals (Matrix - Matrix) 129 assertTrue(almostEquals(res_minus, minus(m1, m2), 0.)); 130 assertTrue(almostEquals(res_minus, minusEquals(copy(m1), m2), 0.)); 131 // via minusTimes 132 assertTrue(almostEquals(res_minus, minusTimes(m1, m2, 1), 0.)); 133 134 // testing minusTimes and minusTimesEquals 135 assertTrue(almostEquals(res_minusTimes, minusTimes(m1, m2, s), 0.)); 136 assertTrue(almostEquals(res_minusTimes, minusTimesEquals(copy(m1), m2, s), 0.)); 137 // via plusTimes (this is a test for plusTimes as well) 138 assertTrue(almostEquals(plusTimes(m1, m2, -s), minusTimes(m1, m2, s), 0.)); 139 } 140 141 /** 142 * Testing the matrix times scalar multiplication methods times, timesEquals 143 * of VMath class. 144 */ 145 @Test testMatrixScalarMultiplication()146 public void testMatrixScalarMultiplication() { 147 final double[][] m1 = TESTMATRIX; 148 final double s1 = 1. / 3; 149 final double[][] m1_times_one_third = { // 150 { s1 * m1[0][0], s1 * m1[0][1], s1 * m1[0][2], s1 * m1[0][3], s1 * m1[0][4] }, // 151 { s1 * m1[1][0], s1 * m1[1][1], s1 * m1[1][2], s1 * m1[1][3], s1 * m1[1][4] }, // 152 { s1 * m1[2][0], s1 * m1[2][1], s1 * m1[2][2], s1 * m1[2][3], s1 * m1[2][4] }, // 153 { s1 * m1[3][0], s1 * m1[3][1], s1 * m1[3][2], s1 * m1[3][3], s1 * m1[3][4] } }; 154 155 assertTrue(almostEquals(m1_times_one_third, times(m1, s1), 0.)); 156 assertTrue(almostEquals(m1_times_one_third, timesEquals(m1, s1), 0.)); 157 158 // check if 0 works a clear 159 final double[][] m1_times_zero = new double[m1.length][m1[0].length]; 160 161 assertTrue(almostEquals(times(m1, 0), m1_times_zero)); 162 assertTrue(almostEquals(timesEquals(m1, 0), m1_times_zero)); 163 164 // check if 1 works a identity 165 assertTrue(almostEquals(times(m1, 1), m1)); 166 assertTrue(almostEquals(timesEquals(m1, 1), m1)); 167 } 168 169 /** 170 * Testing the matrix times matrix multiplications methods of VMath class. 171 * 172 * The following VMath methods are tested:<br> 173 * times, transposeTimesTranspose, timesTranspose, transposeTimes 174 */ 175 @Test testMatrixMatrixMultiplication()176 public void testMatrixMatrixMultiplication() { 177 // testing times and transposedTimestranspose 178 final double[][] m1 = { // 179 { 1.21, 2000 }, // 180 { 0, -1 }, // 181 { 7, 0 } }; 182 final double[][] m2 = { // 183 { -1.21, 2000, 2 }, // 184 { -700, -2368, 4.3 } }; 185 final double[][] res_times = { // 186 { m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0], m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1], m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] }, // 187 { m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0], m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1], m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] }, // 188 { m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0], m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1], m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] } }; 189 final double[][] res_transTimesTrans = { // 190 { m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] }, // 191 { m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] } }; 192 193 assertTrue(almostEquals(times(m1, m2), res_times)); 194 assertTrue(almostEquals(transposeTimesTranspose(m2, m1), transpose(res_times))); 195 196 assertTrue(almostEquals(transposeTimesTranspose(m1, m2), res_transTimesTrans)); 197 assertTrue(almostEquals(times(m2, m1), transpose(res_transTimesTrans))); 198 199 // general testing and testing transposeTimes and timesTranspose 200 final double[][] m3 = TESTMATRIX; 201 final double[][] m4 = { // 202 { 5, 0, 4, 3, 1 }, // 203 { 9, -3, 2, 8, 8 }, // 204 { -4, -1, 4, 9, -9 }, // 205 { 1, 1, 7, 5, 7 } }; 206 final double[][] m3_t = transpose(m3), m4_t = transpose(m4); 207 208 // check times(Matrix, id) = Matrix = times(id, Matrix) 209 assertTrue(almostEquals(times(m3, unitMatrix(5)), m3)); 210 assertTrue(almostEquals(times(unitMatrix(4), m3), m3)); 211 212 // check transposeTimesTranspose(Matrix, id) = transpose(Matrix) = 213 // transposeTimesTranspose(id, Matrix) 214 assertTrue(almostEquals(transposeTimesTranspose(m3, unitMatrix(4)), m3_t)); 215 assertTrue(almostEquals(transposeTimesTranspose(unitMatrix(5), m3), m3_t)); 216 217 final double[][] m3_times_m4transposed = { // 218 { transposeTimes(m3[0], m4[0]), transposeTimes(m3[0], m4[1]), transposeTimes(m3[0], m4[2]), transposeTimes(m3[0], m4[3]) }, // 219 { transposeTimes(m3[1], m4[0]), transposeTimes(m3[1], m4[1]), transposeTimes(m3[1], m4[2]), transposeTimes(m3[1], m4[3]) }, // 220 { transposeTimes(m3[2], m4[0]), transposeTimes(m3[2], m4[1]), transposeTimes(m3[2], m4[2]), transposeTimes(m3[2], m4[3]) }, // 221 { transposeTimes(m3[3], m4[0]), transposeTimes(m3[3], m4[1]), transposeTimes(m3[3], m4[2]), transposeTimes(m3[3], m4[3]) } }; 222 223 // testing timesTranspose without not using a matrix methods times 224 assertTrue(almostEquals(timesTranspose(m3, m4), m3_times_m4transposed)); 225 226 // testing timesTranspose without not using a vector method transposeTimes 227 // this is at the same time a test for the times method assuming the test 228 // before succeeded. 229 assertTrue(almostEquals(timesTranspose(m3, m4), times(m3, m4_t))); 230 // and the following analog a test for the transposeTimesTranspose method 231 assertTrue(almostEquals(timesTranspose(m3, m4), transposeTimesTranspose(m3_t, m4))); 232 233 final double[][] m3transposed_times_m4 = { // 234 { transposeTimes(m3_t[0], m4_t[0]), transposeTimes(m3_t[0], m4_t[1]), transposeTimes(m3_t[0], m4_t[2]), transposeTimes(m3_t[0], m4_t[3]), transposeTimes(m3_t[0], m4_t[4]) }, // 235 { transposeTimes(m3_t[1], m4_t[0]), transposeTimes(m3_t[1], m4_t[1]), transposeTimes(m3_t[1], m4_t[2]), transposeTimes(m3_t[1], m4_t[3]), transposeTimes(m3_t[1], m4_t[4]) }, // 236 { transposeTimes(m3_t[2], m4_t[0]), transposeTimes(m3_t[2], m4_t[1]), transposeTimes(m3_t[2], m4_t[2]), transposeTimes(m3_t[2], m4_t[3]), transposeTimes(m3_t[2], m4_t[4]) }, // 237 { transposeTimes(m3_t[3], m4_t[0]), transposeTimes(m3_t[3], m4_t[1]), transposeTimes(m3_t[3], m4_t[2]), transposeTimes(m3_t[3], m4_t[3]), transposeTimes(m3_t[3], m4_t[4]) }, // 238 { transposeTimes(m3_t[4], m4_t[0]), transposeTimes(m3_t[4], m4_t[1]), transposeTimes(m3_t[4], m4_t[2]), transposeTimes(m3_t[4], m4_t[3]), transposeTimes(m3_t[4], m4_t[4]) } }; 239 240 // testing transposeTimes without not using a matrix methods times 241 // without transpose and times 242 assertTrue(almostEquals(transposeTimes(m3, m4), m3transposed_times_m4)); 243 244 // testing transposeTimes without using a vector method timesTransposed 245 // this is as well a test for the times method assuming the test before 246 // succeeded. 247 assertTrue(almostEquals(transposeTimes(m3, m4), times(m3_t, m4))); 248 // and the following analog a test for the transposeTimesTranspose method 249 assertTrue(almostEquals(transposeTimes(m3, m4), transposeTimesTranspose(m3, m4_t))); 250 } 251 252 /** 253 * Testing the Matrix times Vector multiplications methods of VMath class. 254 * 255 * The following VMath methods are tested:<br> 256 * times(matrix, vector), times(vector, matrix), transposeTimes(matrix, 257 * vector), transposeTimes(vector, matrix), 258 * timesTranspose(vector, matrix), transposeTimesTimes(vector, matrix, vector) 259 */ 260 @Test testMatrixVectorMultiplication()261 public void testMatrixVectorMultiplication() { 262 final double[] v1 = { 1.21, 2 }, v2 = { 3, 0.5, -3 }; 263 final double[][] m1 = { // 264 { 1.21, 2000 }, // 265 { 0, -1 }, // 266 { 7, 0 } }; 267 final double[] res_times = { m1[0][0] * v1[0] + m1[0][1] * v1[1], m1[1][0] * v1[0] + m1[1][1] * v1[1], m1[2][0] * v1[0] + m1[2][1] * v1[1], }; 268 final double[] res_transposeTimes = { m1[0][0] * v2[0] + m1[1][0] * v2[1] + m1[2][0] * v2[2], m1[0][1] * v2[0] + m1[1][1] * v2[1] + m1[2][1] * v2[2] }; 269 final double res_transposeTimesTimes = (m1[0][0] * v2[0] + m1[1][0] * v2[1] + m1[2][0] * v2[2]) * v1[0] + (m1[0][1] * v2[0] + m1[1][1] * v2[1] + m1[2][1] * v2[2]) * v1[1]; 270 271 // testing times(m1, v2) 272 assertArrayEquals(res_times, times(m1, v1), 0.); 273 assertArrayEquals(transpose(m1)[0], times(m1, unitVector(2, 0)), 0.); 274 assertArrayEquals(transpose(m1)[1], times(m1, unitVector(2, 1)), 0.); 275 276 // testing transposeTimes(m1, v2); 277 assertArrayEquals(res_transposeTimes, transposeTimes(m1, v2), 0.); 278 assertArrayEquals(m1[0], transposeTimes(m1, unitVector(3, 0)), 0.); 279 assertArrayEquals(m1[1], transposeTimes(m1, unitVector(3, 1)), 0.); 280 assertArrayEquals(m1[2], transposeTimes(m1, unitVector(3, 2)), 0.); 281 282 // testing transposeTimesTimes(a, B, c); 283 assertEquals(res_transposeTimesTimes, transposeTimesTimes(v2, m1, v1), 0.); 284 assertEquals(transposeTimes(v2, times(m1, v1)), transposeTimesTimes(v2, m1, v1), 0.); 285 assertEquals(times(transposeTimes(v2, m1), v1)[0], transposeTimesTimes(v2, m1, v1), 0.); 286 287 // testing transposedTimes(vector, Matrix) via 288 // transpose(transposeTimes(matrix, vector)) 289 assertTrue(VMath.equals(transposeTimes(unitVector(3, 0), m1), transpose(transposeTimes(m1, unitVector(3, 0))))); 290 assertTrue(VMath.equals(transposeTimes(unitVector(3, 1), m1), transpose(transposeTimes(m1, unitVector(3, 1))))); 291 assertTrue(VMath.equals(transposeTimes(unitVector(3, 2), m1), transpose(transposeTimes(m1, unitVector(3, 2))))); 292 } 293 294 /** 295 * Testing the timesTranspose(vector, matrix), times(vector, matrix) 296 * multiplication methods of VMath class, 297 * where the matrix as two dimensional double array actually need to be a 298 * vector. 299 */ 300 @Test testVectorVectorMultiplication()301 public void testVectorVectorMultiplication() { 302 final double[] v3 = { 1, 2, -7 }; 303 final double[] v4 = { -5, 1, 3, -4 }; 304 final double[][] m2 = { v4 }; 305 final double[][] m2_t = { { v4[0] }, { v4[1] }, { v4[2] }, { v4[3] } }; 306 final double[][] res = { // 307 { v3[0] * v4[0], v3[0] * v4[1], v3[0] * v4[2], v3[0] * v4[3] }, // 308 { v3[1] * v4[0], v3[1] * v4[1], v3[1] * v4[2], v3[1] * v4[3] }, // 309 { v3[2] * v4[0], v3[2] * v4[1], v3[2] * v4[2], v3[2] * v4[3] } }; 310 311 // testing times(vector, matrix) 312 assertTrue(almostEquals(times(v3, m2), res)); 313 // via timesTranspose(vector,vector) 314 assertTrue(almostEquals(times(v3, m2), timesTranspose(v3, v4))); 315 316 // testing timesTranspose(vector, matrix) 317 assertTrue(almostEquals(timesTranspose(v3, m2_t), res)); 318 // via timesTranspose(vector,vector) 319 assertTrue(almostEquals(timesTranspose(v3, m2_t), timesTranspose(v3, v4))); 320 } 321 322 /** 323 * Testing the unitMatrix and the identity method of VMath class. 324 */ 325 @Test testUnitMatrix()326 public void testUnitMatrix() { 327 // test unitMatrix(dim) and unitMatrix(dim) equals identity(dim, dim) 328 final double[][] m_unit = { { 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 1 } }; 329 assertTrue(VMath.equals(unitMatrix(5), m_unit)); 330 assertTrue(VMath.equals(identity(5, 5), m_unit)); 331 332 // test identity with dimensions 3x5 and 5x3 333 final double[][] m_identity3x5 = { { 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 0 } }; 334 assertTrue(VMath.equals(identity(3, 5), m_identity3x5)); 335 assertTrue(VMath.equals(identity(5, 3), transpose(m_identity3x5))); 336 } 337 338 @Test testFrobenius()339 public void testFrobenius() { 340 final double[][] m = identity(4, 6); 341 assertEquals(2, normF(m), 0.); 342 m[0][5] = 5; 343 assertEquals(Math.sqrt(29), normF(m), 0.); 344 } 345 346 /** 347 * Testing that the *Equals methods tested in this class 348 * class work in place and that other methods tested 349 * create a new instance. 350 * 351 * Methods where the class of the instance 352 * returned differs form class of the input are reasonably omitted 353 * when testing reference. 354 */ 355 @Test testReference()356 public void testReference() { 357 final double[][] m1 = { { 42 } }; 358 final double[] inner = { 42 }; 359 final double[][] m2 = { inner }; 360 361 // Ensure the compiler did not optimize away this test. 362 assertNotSame(m1[0], m2[0]); 363 364 // testing the methods as in testInverse 365 assertNotSame(m1, inverse(m1)); 366 367 // testing the methods as in testMatrixMatrixMultiplication 368 assertNotSame(m1, times(m1, m1)); 369 370 assertNotSame(m1, transposeTimesTranspose(m1, m1)); 371 372 assertNotSame(m1, timesTranspose(m1, m1)); 373 374 assertNotSame(m1, transposeTimes(m1, m1)); 375 376 // testing the methods as in testMatrixScalarMultiplication 377 final double s1 = 3.14; 378 assertNotSame(m1, times(m1, s1)); 379 assertSame(m1, timesEquals(m1, s1)); 380 381 // testing the methods as in testTranspose 382 assertNotSame(m1, transpose(m1)); 383 384 // testing the methods as in testMatrixVectorMultiplication 385 final double[] v1 = { 3.14 }; 386 assertNotSame(m1, times(v1, m1)); 387 assertNotSame(m1, times(m1, v1)); 388 389 assertNotSame(m1, transposeTimes(m1, v1)); 390 assertNotSame(m1, transposeTimes(v1, m1)); 391 392 assertNotSame(m1, timesTranspose(v1, m1)); 393 394 // testing the methods as in testMinus 395 assertNotSame(m1, minus(m1, m2)); 396 assertSame(m1, minusEquals(m1, m2)); 397 398 assertNotSame(m1, minusTimes(m1, m1, s1)); 399 assertSame(m1, minusTimesEquals(m1, m1, s1)); 400 401 // testing the methods as in testPlus 402 assertNotSame(m1, plus(m1, m2)); 403 assertSame(m1, plusEquals(m1, m2)); 404 405 assertNotSame(m1, plusTimes(m1, m1, s1)); 406 assertSame(m1, plusTimesEquals(m1, m1, s1)); 407 408 // testing the methods as in testTraspose 409 assertNotSame(m1, transpose(m1)); 410 } 411 412 /** 413 * Testing that correct error is raised when dimension of the input data 414 * mismatch the needs of the method. 415 * Methods where no error is to be raised are omitted. 416 * <p> 417 * See {@link VMathOperationsTest#assertDimensionMismatch} for details. 418 */ 419 @Test testDimensionMismatch()420 public void testDimensionMismatch() { 421 // testing the appendColums method 422 assertDimensionMismatch("m.getRowDimension() != column.getRowDimension()", () -> appendColumns(identity(3, 2), identity(2, 2))); 423 424 // testing the methods as in testMatrixMatrixMultiplication 425 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> times(unitMatrix(3), identity(2, 3))); 426 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimesTranspose(unitMatrix(3), identity(3, 2))); 427 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> timesTranspose(unitMatrix(3), identity(3, 2))); 428 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimes(unitMatrix(3), identity(2, 3))); 429 430 // testing the methods as in testMatrixVectorMultiplication 431 // vector length and number of rows in matrix differ 432 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> times(identity(2, 3), unitVector(2, 0))); 433 434 // vector length and number of columns in matrix differ 435 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimes(identity(2, 3), unitVector(3, 0))); 436 437 // first vector has wrong length 438 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimesTimes(unitVector(3, 0), identity(2, 3), unitVector(3, 0))); 439 // second vector has wrong length 440 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimesTimes(unitVector(2, 0), identity(2, 3), unitVector(2, 0))); 441 442 // matrix has more than one row 443 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> times(unitVector(3, 0), identity(2, 3))); 444 445 // matrix has more than one column 446 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> timesTranspose(unitVector(3, 0), identity(3, 2))); 447 448 // vector length and number of rows in matrix differ 449 assertDimensionMismatch(ERR_MATRIX_INNERDIM, () -> transposeTimes(unitVector(3, 0), identity(2, 3))); 450 451 // testing the methods as in testMinus 452 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> minus(identity(3, 3), identity(2, 3))); 453 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> minusEquals(identity(2, 2), identity(2, 3))); 454 455 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> minusTimes(identity(3, 3), identity(2, 3), 1)); 456 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> minusTimesEquals(identity(2, 2), identity(2, 3), 1)); 457 458 // testing the methods as in testPlus 459 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> plus(identity(3, 3), identity(2, 3))); 460 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> plusEquals(identity(2, 2), identity(2, 3))); 461 462 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> plusTimes(identity(3, 3), identity(2, 3), 1)); 463 assertDimensionMismatch(ERR_MATRIX_DIMENSIONS, () -> plusTimesEquals(identity(2, 2), identity(2, 3), 1)); 464 465 // testSolve, testTraspose, testUnitMatrix are tested in separate classes 466 } 467 } 468