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 import de.lmu.ifi.dbs.elki.math.MathUtil; 30 31 /** 32 * Class testing the methods of the {@link VMath} class, which provide 33 * mathematical operations and have 34 * one dimensional double arrays as input. 35 * 36 * One dimensional double arrays are interpreted column vectors. 37 * 38 * @author Merlin Dietrich 39 */ 40 public final class VMathVectorTest { 41 /** 42 * A vector of length 5 as test-data. 43 */ 44 protected static final double[] TESTVEC = { 2, 3, 5, 7, 9 }; 45 46 /** 47 * Testing the vector times scalar method of VMath class. 48 */ 49 @Test testTimes()50 public void testTimes() { 51 final double[] v1 = { 1, 3, 9, 7 }; 52 final double s_case1 = 5; 53 final double s_case2 = 1. / 3; 54 final double s_case3 = 0.100000000000006100004; 55 56 final double[] res_case1 = { v1[0] * s_case1, v1[1] * s_case1, v1[2] * s_case1, v1[3] * s_case1 }; 57 final double[] res_case2 = { v1[0] * s_case2, v1[1] * s_case2, v1[2] * s_case2, v1[3] * s_case2 }; 58 final double[] res_case3 = { v1[0] * s_case3, v1[1] * s_case3, v1[2] * s_case3, v1[3] * s_case3 }; 59 60 // test the three cases 61 assertArrayEquals(res_case1, times(v1, s_case1), 0.); 62 assertArrayEquals(res_case2, times(v1, s_case2), 0.); 63 assertArrayEquals(res_case3, times(v1, s_case3), 0.); 64 } 65 66 /** 67 * Testing VMath methods, which operate as addition on vectors. 68 * <p> 69 * The following VMath methods are tested:<br> 70 * plus,plusEquals; timesPlus, timesPlusEquals; 71 * plusTimes, plusTimesEquals, timesPlus, timesPlusEquals; 72 * timesPlustimes, timesPlustimesEquals 73 */ 74 @Test testPlus()75 public void testPlus() { 76 /* 77 * test-data I: 78 * Four dimensional test vectors, Near 0 numerical loss of precision in ResultData res* and 79 * mixed positive and negative numbers. 80 */ 81 final double[] v1_I = { -14, 1, 2, 0.100000000000006100004 }; 82 final double[] v2_I = { 7, 6, 2, -0.1000000000000069 }; 83 final double s_I = 13, s1_I = 2, s2_I = -3; 84 85 final double[] res_plus_I = { v1_I[0] + v2_I[0], v1_I[1] + v2_I[1], v1_I[2] + v2_I[2], v1_I[3] + v2_I[3] }; 86 final double[] res_plus_scal_I = { v1_I[0] + s_I, v1_I[1] + s_I, v1_I[2] + s_I, v1_I[3] + s_I }; 87 final double[] res_timesPlus_I = { s1_I * v1_I[0] + v2_I[0], s1_I * v1_I[1] + v2_I[1], s1_I * v1_I[2] + v2_I[2], s1_I * v1_I[3] + v2_I[3] }; 88 final double[] res_plusTimes_I = { v1_I[0] + s2_I * v2_I[0], v1_I[1] + s2_I * v2_I[1], v1_I[2] + s2_I * v2_I[2], v1_I[3] + s2_I * v2_I[3] }; 89 final double[] res_timesPlustimes_I = { s1_I * v1_I[0] + s2_I * v2_I[0], s1_I * v1_I[1] + s2_I * v2_I[1], s1_I * v1_I[2] + s2_I * v2_I[2], s1_I * v1_I[3] + s2_I * v2_I[3] }; 90 91 // testing plus and plusEquals 92 assertArrayEquals(res_plus_I, plus(v1_I, v2_I), 0.); 93 assertArrayEquals(res_plus_I, plusEquals(copy(v1_I), v2_I), 0.); 94 95 // testing plus and plusEquals 96 assertArrayEquals(res_plus_scal_I, plus(v1_I, s_I), 0.); 97 assertArrayEquals(res_plus_scal_I, plusEquals(copy(v1_I), s_I), 0.); 98 99 // testing timesPlus and timesPlusEquals 100 assertArrayEquals(res_timesPlus_I, timesPlus(v1_I, s1_I, v2_I), 0.); 101 assertArrayEquals(res_timesPlus_I, timesPlusEquals(copy(v1_I), s1_I, v2_I), 0.); 102 103 // testing plusTimes and plusTimesEquals 104 assertArrayEquals(res_plusTimes_I, plusTimes(v1_I, v2_I, s2_I), 0.); 105 assertArrayEquals(res_plusTimes_I, plusTimesEquals(copy(v1_I), v2_I, s2_I), 0.); 106 107 // testing timesPlustimes and timesPlustimesEquals 108 assertArrayEquals(res_timesPlustimes_I, timesPlusTimes(v1_I, s1_I, v2_I, s2_I), 0.); 109 assertArrayEquals(res_timesPlustimes_I, timesPlusTimesEquals(copy(v1_I), s1_I, v2_I, s2_I), 0); 110 111 /* 112 * test-data II: 113 * Three dimensional test vectors of type double with 5 decimal places as 114 * mantissa. Numbers are strictly positive. 115 */ 116 final double delta = 1E-10; 117 final double[] v1_II = { 0.17825, 32.546, 2958.3 }; 118 final double[] v2_II = { 0.82175, 67.454, 7041.7 }; 119 120 final double s_II = 0.92175, s1_II = 1.5, s2_II = 0.5; 121 122 final double[] res_plus_II = { v1_II[0] + v2_II[0], v1_II[1] + v2_II[1], v1_II[2] + v2_II[2] }; 123 final double[] res_plus_scal_II = { v1_II[0] + s_II, v1_II[1] + s_II, v1_II[2] + s_II }; 124 final double[] res_timesPlus_II = { s1_II * v1_II[0] + v2_II[0], s1_II * v1_II[1] + v2_II[1], s1_II * v1_II[2] + v2_II[2] }; 125 final double[] res_plusTimes_II = { v1_II[0] + s2_II * v2_II[0], v1_II[1] + s2_II * v2_II[1], v1_II[2] + s2_II * v2_II[2] }; 126 final double[] res_timesPlustimes_II = { s1_II * v1_II[0] + s2_II * v2_II[0], s1_II * v1_II[1] + s2_II * v2_II[1], s1_II * v1_II[2] + s2_II * v2_II[2] }; 127 128 // testing plus and plusEquals (Vector + Vector) 129 assertArrayEquals(res_plus_II, plus(v1_II, v2_II), delta); 130 assertArrayEquals(res_plus_II, plusEquals(copy(v1_II), v2_II), delta); 131 132 // testingplus() and plusEquals (Vector + Skalar) 133 assertArrayEquals(res_plus_scal_II, plus(v1_II, s_II), delta); 134 assertArrayEquals(res_plus_scal_II, plusEquals(copy(v1_II), s_II), delta); 135 136 // testing timesPlus() and timesPlusEquals() 137 assertArrayEquals(res_timesPlus_II, timesPlus(v1_II, s1_II, v2_II), delta); 138 assertArrayEquals(res_timesPlus_II, timesPlusEquals(copy(v1_II), s1_II, v2_II), delta); 139 140 // testing plusTimes() and plusTimesEquals() 141 assertArrayEquals(res_plusTimes_II, plusTimes(v1_II, v2_II, s2_II), delta); 142 assertArrayEquals(res_plusTimes_II, plusTimesEquals(copy(v1_II), v2_II, s2_II), delta); 143 144 // testing timesPlustimes() and timesPlustimesEquals() 145 assertArrayEquals(res_timesPlustimes_II, timesPlusTimes(v1_II, s1_II, v2_II, s2_II), delta); 146 assertArrayEquals(res_timesPlustimes_II, timesPlusTimesEquals(copy(v1_II), s1_II, v2_II, s2_II), delta); 147 148 /* 149 * general testing 150 */ 151 final double[] v5 = { 1, 2, 3 }, v6 = { 4, 5, 6 }; 152 final double s5 = 2, s6 = 3; 153 154 // consistency check to minus method 155 assertArrayEquals(minus(v5, times(v6, -1)), plus(v5, v6), 0.); 156 // consistency check within the plus methods 157 assertArrayEquals(plus(v5, times(v6, s6)), plusTimes(v5, v6, s6), 0.); 158 assertArrayEquals(plus(times(v5, s5), v6), timesPlus(v5, s5, v6), 0.); 159 assertArrayEquals(plus(times(v5, s5), times(v6, s6)), timesPlusTimes(v5, s5, v6, s6), 0.); 160 } 161 162 /** 163 * Testing VMath methods, which operate as subtraction on vectors. 164 * <p> 165 * The following VMath methods are tested:<br> 166 * minus, minusEquals, timesMinus, timesMinusEquals; 167 * minusTimes, minusTimesEquals, timesMinus, timesMinusEquals; 168 * timesMinustimes, timesMinustimesEquals 169 */ 170 @Test testMinus()171 public void testMinus() { 172 // test case I 173 final double[] v1 = { -14, 1, 2, 0.100000000000006100004 }; 174 final double[] v2 = { 7, 6, 2, -0.1000000000000069 }; 175 176 final double s0 = 13, s1 = 2, s2 = -3; 177 final double[] res_minus_I = { v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2], v1[3] - v2[3] }; 178 final double[] res_minus_scal_I = { v1[0] - s0, v1[1] - s0, v1[2] - s0, v1[3] - s0 }; 179 final double[] res_timesMinus_I = { s1 * v1[0] - v2[0], s1 * v1[1] - v2[1], s1 * v1[2] - v2[2], s1 * v1[3] - v2[3] }; 180 final double[] res_minusTimes_I = { v1[0] - s2 * v2[0], v1[1] - s2 * v2[1], v1[2] - s2 * v2[2], v1[3] - s2 * v2[3] }; 181 final double[] res_timesMinustimes_I = { s1 * v1[0] - s2 * v2[0], s1 * v1[1] - s2 * v2[1], s1 * v1[2] - s2 * v2[2], s1 * v1[3] - s2 * v2[3] }; 182 183 // minus and minusEquals 184 assertArrayEquals(res_minus_I, minus(v1, v2), 0.); 185 assertArrayEquals(res_minus_I, minusEquals(copy(v1), v2), 0.); 186 187 // minus and minusEquals 188 assertArrayEquals(res_minus_scal_I, minus(v1, s0), 0.); 189 assertArrayEquals(res_minus_scal_I, minusEquals(copy(v1), s0), 0.); 190 191 // timesMinus and timesMinusEquals 192 assertArrayEquals(res_timesMinus_I, timesMinus(v1, s1, v2), 0.); 193 assertArrayEquals(res_timesMinus_I, timesMinusEquals(copy(v1), s1, v2), 0.); 194 195 // minusTimes and minusTimesEquals 196 assertArrayEquals(res_minusTimes_I, minusTimes(v1, v2, s2), 0.); 197 assertArrayEquals(res_minusTimes_I, minusTimesEquals(copy(v1), v2, s2), 0.); 198 199 // timesMinustimes and timesMinustimesEquals 200 assertArrayEquals(res_timesMinustimes_I, timesMinusTimes(v1, s1, v2, s2), 0.); 201 assertArrayEquals(res_timesMinustimes_I, timesMinusTimesEquals(copy(v1), s1, v2, s2), 0); 202 203 // test case II 204 final double delta = 1E-10; 205 final double[] v3 = { 0.17825, 32.546, 2958.3 }; 206 final double[] v4 = { 0.82175, 67.454, 7041.7 }; 207 208 final double s00 = 0.92175, s3 = 1.5, s4 = 0.5; 209 210 final double[] res_minus_II = { v3[0] - v4[0], v3[1] - v4[1], v3[2] - v4[2] }; 211 final double[] res_minus_scal_II = { v3[0] - s00, v3[1] - s00, v3[2] - s00 }; 212 final double[] res_timesMinus_II = { s3 * v3[0] - v4[0], s3 * v3[1] - v4[1], s3 * v3[2] - v4[2] }; 213 final double[] res_minusTimes_II = { v3[0] - s4 * v4[0], v3[1] - s4 * v4[1], v3[2] - s4 * v4[2] }; 214 final double[] res_timesMinustimes_II = { s3 * v3[0] - s4 * v4[0], s3 * v3[1] - s4 * v4[1], s3 * v3[2] - s4 * v4[2] }; 215 216 // minus and minusEquals 217 assertArrayEquals(res_minus_II, minus(v3, v4), delta); 218 assertArrayEquals(res_minus_II, minusEquals(copy(v3), v4), delta); 219 220 // minus and minusEquals 221 assertArrayEquals(res_minus_scal_II, minus(v3, s00), delta); 222 assertArrayEquals(res_minus_scal_II, minusEquals(copy(v3), s00), delta); 223 224 // timesMinus and timesMinusEquals 225 assertArrayEquals(res_timesMinus_II, timesMinus(v3, s3, v4), delta); 226 assertArrayEquals(res_timesMinus_II, timesMinusEquals(copy(v3), s3, v4), delta); 227 228 // minusTimes and minusTimesEquals 229 assertArrayEquals(res_minusTimes_II, minusTimes(v3, v4, s4), delta); 230 assertArrayEquals(res_minusTimes_II, minusTimesEquals(copy(v3), v4, s4), delta); 231 232 // timesMinustimes and timesMinustimesEquals 233 assertArrayEquals(res_timesMinustimes_II, timesMinusTimes(v3, s3, v4, s4), delta); 234 assertArrayEquals(res_timesMinustimes_II, timesMinusTimesEquals(copy(v3), s3, v4, s4), delta); 235 236 // general testing 237 final double[] v5 = { 1, 2, 3 }; 238 final double[] v6 = { 4, 5, 6 }; 239 final double s5 = 2, s6 = 3; 240 241 // checking that vector - same_vector is zero 242 assertArrayEquals(new double[] { 0, 0, 0, }, minus(v5, v5), 0.); 243 // consistency check to plus methods 244 assertArrayEquals(plus(v5, times(v6, -1)), minus(v5, v6), 0.); 245 // consistency check within the minus methods 246 assertArrayEquals(minus(v5, times(v6, s6)), minusTimes(v5, v6, s6), 0.); 247 assertArrayEquals(minus(times(v5, s5), v6), timesMinus(v5, s5, v6), 0.); 248 assertArrayEquals(minus(times(v5, s5), times(v6, s6)), timesMinusTimes(v5, s5, v6, s6), 0.); 249 } 250 251 /** 252 * Testing scalarProduct and transposeTimes methods of the VMath class. 253 */ 254 @Test testScalarProduct()255 public void testScalarProduct() { 256 // testing scalarProduct and transposeTimes return the same result 257 final double[] v1 = { 1.21, 3, 7, -2 }; 258 final double[] v2 = { 3.5, -1, 4, -7 }; 259 final double res = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3]; 260 261 assertEquals(transposeTimes(v1, v2), scalarProduct(v1, v2), 0.); 262 assertEquals(res, scalarProduct(v1, v2), 0.); 263 264 // testing scalarProduct and transposeTimes via squareSum 265 assertEquals(squareSum(v1), scalarProduct(v1, v1), 0.); 266 assertEquals(transposeTimes(v1, v1), scalarProduct(v1, v1), 0.); 267 268 assertEquals(squareSum(v2), transposeTimes(v2, v2), 0.); 269 assertEquals(transposeTimes(v2, v2), scalarProduct(v2, v2), 0.); 270 } 271 272 /** 273 * Testing the timesTranspose(vector, vector) method of {@link VMath} class. 274 */ 275 @Test testTimesTranspose()276 public void testTimesTranspose() { 277 final double[] v1 = { 1.21, 3, 7, -2 }, v2 = { 3.5, -1, 4, -7 }; 278 final double[][] res = { // 279 { v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2], v1[0] * v2[3] }, // 280 { v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2], v1[1] * v2[3] }, // 281 { v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2], v1[2] * v2[3] }, // 282 { v1[3] * v2[0], v1[3] * v2[1], v1[3] * v2[2], v1[3] * v2[3] } }; 283 assertTrue(VMath.equals(timesTranspose(v1, v2), res)); 284 285 // testing timesTranspose(vector, vector) via times(matrix, matrix) 286 // because times(vector) returns a matrix. This is at the same time a test 287 // for transpose if timesTranspose is correct. 288 final double[][] m1 = transpose(transpose(TESTVEC)); 289 final double[][] m2 = transpose(TESTVEC); 290 assertTrue(VMath.equals(timesTranspose(TESTVEC, TESTVEC), times(m1, m2))); 291 } 292 293 /** 294 * Testing the normalizeVector) and normalizeEquals(Vector) methods of the 295 * {@link VMath} class. 296 */ 297 @Test testNormalize()298 public void testNormalize() { 299 final double[] v1 = copy(TESTVEC), v1_copy = copy(v1); 300 final double[] v1_normal = normalize(v1); 301 302 // Test that both methods return a vector with length 1. 303 // That more methods ensure the result we use squareSum instead of 304 // euclideanLength here 305 assertEquals(1, squareSum(v1_normal), 0.); 306 assertEquals(1, squareSum(normalizeEquals(v1)), 0.); 307 308 // Check that both methods return the same Vector 309 assertArrayEquals(v1_normal, v1, 0.); 310 311 // Check that the normalize Vector times the euclidean length of the 312 // original Vector equals the original vector 313 assertArrayEquals(v1_copy, times(v1_normal, euclideanLength(v1_copy)), 1e-15); 314 } 315 316 /** 317 * Testing the cosine angle(Vector, Vector) methods of the VMath class. 318 */ 319 @Test testAngle()320 public void testAngle() { 321 // test case I 322 final double[] v1_I = { 1, 0 }, v2_I = { 1, 1 }, v3_I = { 2, 0, 0 }; 323 assertEquals(MathUtil.SQRTHALF, angle(v2_I, v1_I), 0.); 324 assertEquals(MathUtil.SQRTHALF, angle(v1_I, v2_I), 0.); 325 assertEquals(1., angle(v3_I, v1_I), 0.); 326 assertEquals(1., angle(v1_I, v3_I), 0.); 327 328 // set the origin, no change of data needed 329 final double[] origin_I = { 0, 1 }; 330 assertEquals(MathUtil.SQRTHALF, angle(v2_I, v1_I, origin_I), 0.); 331 assertEquals(MathUtil.SQRTHALF, angle(v1_I, v2_I, origin_I), 0.); 332 assertEquals(Math.sqrt(0.8), angle(v3_I, v2_I, origin_I), 0.); 333 assertEquals(Math.sqrt(0.8), angle(v2_I, v3_I, origin_I), 0.); 334 335 // test case II 336 final double[] v1_II = { 1, 0 }, v2_II = { 1, Math.tan(Math.PI / 3) }; 337 assertEquals(Math.sqrt(.25), angle(v2_II, v1_II), 1e-15); 338 assertEquals(Math.sqrt(.25), angle(v1_II, v2_II), 1e-15); 339 340 // change the origin 341 final double[] v3_II = { 2, 3 }, v4_II = { 2, 3 + Math.tan(Math.PI / 3) }; 342 final double[] origin_II = { 1, 3 }; 343 assertEquals(Math.sqrt(.25), angle(v3_II, v4_II, origin_II), 1e-15); 344 assertEquals(Math.sqrt(.25), angle(v4_II, v3_II, origin_II), 1e-15); 345 } 346 347 /** 348 * Testing the summation methods and the euclidienLength method of VMath 349 * class. 350 */ 351 @Test testSummation()352 public void testSummation() { 353 // testing sum 354 final double[] v = { 1.21, -3, 2, 3.2, -5, 1 }; 355 final double res_vsum = v[0] + v[1] + v[2] + v[3] + v[4] + v[5]; 356 assertEquals(res_vsum, sum(v), 0.); 357 358 assertEquals(1, sum(unitVector(3, 1)), 0.); 359 360 final double[] v1 = { 0.1234512345123456, -0.123451234512345 }; 361 assertEquals(0, sum(v1), 1e-15); 362 363 // testing squareSum 364 final double res_vsumsqare = v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3] + v[4] * v[4] + v[5] * v[5]; 365 assertEquals(res_vsumsqare, squareSum(v), 0.); 366 assertEquals(1, squareSum(unitVector(20, 10)), 0.); 367 // via transposeTimes and scalarProduct 368 assertEquals(transposeTimes(v, v), squareSum(v), 0.); 369 370 // testing euclideanLength 371 final double res_veuclid = Math.sqrt(res_vsumsqare); 372 assertEquals(res_veuclid, euclideanLength(v), 0.); 373 assertEquals(1, euclideanLength(unitVector(3, 1)), 0.); 374 } 375 376 /** 377 * Testing the transpose(vector) method of VMath class. 378 */ 379 @Test testTransposed()380 public void testTransposed() { 381 final double[] v1 = TESTVEC; 382 final double[][] v1_t = { v1 }; 383 assertTrue(VMath.equals(transpose(v1), v1_t)); 384 385 final double[] v2 = { 4, 5, 6, 0, 2, 1 }; 386 final double[][] v2_t = { v2 }; 387 assertTrue(VMath.equals(transpose(v2), v2_t)); 388 } 389 390 /** 391 * Testing the rotate90Equals(vector) method of VMath class. 392 */ 393 @Test testRotate90Equals()394 public void testRotate90Equals() { 395 // simple test case 396 final double[] v1 = { 1, 0 }; 397 final double[] res = { 0, -1 }; 398 assertArrayEquals(res, rotate90Equals(v1), 0); 399 400 // more complex test case 401 final double[] v2 = { 1.21, -2.4 }; 402 final double[] v2_copy = copy(v2); 403 // first rotation -> angle of 90° while cos(90°) = 0 404 assertEquals(0.0, angle(v2_copy, rotate90Equals(v2)), 0.); 405 final double[] v2_copy1rotate = copy(v2); 406 // second rotation -> additive inverse 407 assertArrayEquals(times(v2_copy, -1), rotate90Equals(v2), 0.); 408 // third rotation -> additive inverse to first rotation 409 assertArrayEquals(times(v2_copy1rotate, -1), rotate90Equals(v2), 0.); 410 // forth rotation -> identity 411 assertArrayEquals(v2_copy, rotate90Equals(v2), 0.); 412 } 413 414 /** 415 * Testing that the *Equals methods tested in this class work in place and 416 * that the other 417 * methods tested create a new instance. 418 * 419 * Tests of methods where the class of the instance returned differs form the 420 * class of input are reasonably omitted, 421 * when testing reference. 422 */ 423 @Test testReference()424 public void testReference() { 425 final double[] v1 = { 0 }, v2 = { 0 }; 426 final double s1 = 0, s2 = 0; 427 428 // testing methods as in testMinus 429 assertNotSame(v1, minus(v1, s1)); 430 assertSame(v1, minusEquals(v1, s1)); 431 432 assertNotSame(v1, minus(v1, v2)); 433 assertSame(v1, minusEquals(v1, v2)); 434 435 assertNotSame(v1, timesMinus(v1, s1, v2)); 436 assertSame(v1, timesMinusEquals(v1, s1, v2)); 437 438 assertNotSame(v1, minusTimes(v1, v2, s2)); 439 assertSame(v1, minusTimesEquals(v1, v2, s2)); 440 441 assertNotSame(v1, timesMinusTimes(v1, s1, v2, s2)); 442 assertSame(v1, timesMinusTimesEquals(v1, s1, v2, s2)); 443 444 // testing methods as in testNormalize 445 final double[] v3 = { 2 }; 446 assertNotSame(v3, normalize(v3)); 447 assertSame(v3, normalizeEquals(v3)); 448 449 // testing methods as in testPlus 450 assertNotSame(v1, plus(v1, s1)); 451 assertSame(v1, plusEquals(v1, s1)); 452 453 assertNotSame(v1, plus(v1, v2)); 454 assertSame(v1, plusEquals(v1, v2)); 455 456 assertNotSame(v1, timesPlus(v1, s1, v2)); 457 assertSame(v1, timesPlusEquals(v1, s1, v2)); 458 459 assertNotSame(v1, plusTimes(v1, v2, s2)); 460 assertSame(v1, plusTimesEquals(v1, v2, s2)); 461 462 assertNotSame(v1, timesPlusTimes(v1, s1, v2, s2)); 463 assertSame(v1, timesPlusTimesEquals(v1, s1, v2, s2)); 464 465 // testing methods as in testTimes 466 assertNotSame(v1, times(v1, s1)); 467 assertSame(v1, timesEquals(v1, s1)); 468 469 // testing methods as in testRotate90Equals 470 final double[] v4 = { 1, 0 }; 471 assertSame(v4, rotate90Equals(v4)); 472 } 473 474 /** 475 * Testing that correct Error is raised when dimension of the input data 476 * mismatch the needs of the method. 477 * Methods where no error is to be raised are omitted. 478 * 479 * See {@link VMathOperationsTest#assertDimensionMismatch} for details. 480 */ 481 @Test testDimensionMismatch()482 public void testDimensionMismatch() { 483 final double[] v_len1 = { 1 }, v_len2 = { 1, 1 }, v_len3 = { 1, 1, 1 }; 484 double s1 = 1, s2 = 1; 485 486 // methods as in testPlus 487 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> plus(v_len1, v_len2)); 488 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> plusEquals(v_len1, v_len2)); 489 490 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesPlus(v_len1, s1, v_len2)); 491 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesPlusEquals(v_len1, s1, v_len2)); 492 493 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> plusTimes(v_len1, v_len2, s2)); 494 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> plusTimesEquals(v_len1, v_len2, s2)); 495 496 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesPlusTimes(v_len1, s1, v_len2, s2)); 497 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesPlusTimesEquals(v_len1, s1, v_len2, s2)); 498 499 // methods as in testMinus 500 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> minus(v_len1, v_len2)); 501 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> minusEquals(v_len1, v_len2)); 502 503 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesMinus(v_len1, s1, v_len2)); 504 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesMinusEquals(v_len1, s1, v_len2)); 505 506 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> minusTimes(v_len1, v_len2, s2)); 507 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> minusTimesEquals(v_len1, v_len2, s2)); 508 509 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesMinusTimes(v_len1, s1, v_len2, s2)); 510 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> timesMinusTimesEquals(v_len1, s1, v_len2, s2)); 511 512 // methods as in testScalarProduct 513 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> scalarProduct(v_len1, v_len2)); 514 assertDimensionMismatch(ERR_VEC_DIMENSIONS, () -> transposeTimes(v_len1, v_len2)); 515 516 // test rotate90 517 assertDimensionMismatch("rotate90Equals is only valid for 2d vectors.", () -> rotate90Equals(v_len1)); 518 assertDimensionMismatch("rotate90Equals is only valid for 2d vectors.", () -> rotate90Equals(v_len3)); 519 } 520 } 521