1require 'test/unit' 2require 'matrix' 3 4class TestMatrix < Test::Unit::TestCase 5 def setup 6 @m1 = Matrix[[1,2,3], [4,5,6]] 7 @m2 = Matrix[[1,2,3], [4,5,6]] 8 @m3 = @m1.clone 9 @m4 = Matrix[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] 10 @n1 = Matrix[[2,3,4], [5,6,7]] 11 end 12 13 def test_matrix 14 assert_equal(1, @m1[0, 0]) 15 assert_equal(2, @m1[0, 1]) 16 assert_equal(3, @m1[0, 2]) 17 assert_equal(4, @m1[1, 0]) 18 assert_equal(5, @m1[1, 1]) 19 assert_equal(6, @m1[1, 2]) 20 end 21 22 def test_identity 23 assert_same @m1, @m1 24 assert_not_same @m1, @m2 25 assert_not_same @m1, @m3 26 assert_not_same @m1, @m4 27 assert_not_same @m1, @n1 28 end 29 30 def test_equality 31 assert_equal @m1, @m1 32 assert_equal @m1, @m2 33 assert_equal @m1, @m3 34 assert_equal @m1, @m4 35 assert_not_equal @m1, @n1 36 end 37 38 def test_hash_equality 39 assert @m1.eql?(@m1) 40 assert @m1.eql?(@m2) 41 assert @m1.eql?(@m3) 42 assert !@m1.eql?(@m4) 43 assert !@m1.eql?(@n1) 44 45 hash = { @m1 => :value } 46 assert hash.key?(@m1) 47 assert hash.key?(@m2) 48 assert hash.key?(@m3) 49 assert !hash.key?(@m4) 50 assert !hash.key?(@n1) 51 end 52 53 def test_hash 54 assert_equal @m1.hash, @m1.hash 55 assert_equal @m1.hash, @m2.hash 56 assert_equal @m1.hash, @m3.hash 57 end 58 59 def test_rank 60 [ 61 [[0]], 62 [[0], [0]], 63 [[0, 0], [0, 0]], 64 [[0, 0], [0, 0], [0, 0]], 65 [[0, 0, 0]], 66 [[0, 0, 0], [0, 0, 0]], 67 [[0, 0, 0], [0, 0, 0], [0, 0, 0]], 68 [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], 69 ].each do |rows| 70 assert_equal 0, Matrix[*rows].rank 71 end 72 73 [ 74 [[1], [0]], 75 [[1, 0], [0, 0]], 76 [[1, 0], [1, 0]], 77 [[0, 0], [1, 0]], 78 [[1, 0], [0, 0], [0, 0]], 79 [[0, 0], [1, 0], [0, 0]], 80 [[0, 0], [0, 0], [1, 0]], 81 [[1, 0], [1, 0], [0, 0]], 82 [[0, 0], [1, 0], [1, 0]], 83 [[1, 0], [1, 0], [1, 0]], 84 [[1, 0, 0]], 85 [[1, 0, 0], [0, 0, 0]], 86 [[0, 0, 0], [1, 0, 0]], 87 [[1, 0, 0], [1, 0, 0]], 88 [[1, 0, 0], [1, 0, 0]], 89 [[1, 0, 0], [0, 0, 0], [0, 0, 0]], 90 [[0, 0, 0], [1, 0, 0], [0, 0, 0]], 91 [[0, 0, 0], [0, 0, 0], [1, 0, 0]], 92 [[1, 0, 0], [1, 0, 0], [0, 0, 0]], 93 [[0, 0, 0], [1, 0, 0], [1, 0, 0]], 94 [[1, 0, 0], [0, 0, 0], [1, 0, 0]], 95 [[1, 0, 0], [1, 0, 0], [1, 0, 0]], 96 [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], 97 [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], 98 [[1, 0, 0], [1, 0, 0], [0, 0, 0], [0, 0, 0]], 99 [[1, 0, 0], [0, 0, 0], [1, 0, 0], [0, 0, 0]], 100 [[1, 0, 0], [0, 0, 0], [0, 0, 0], [1, 0, 0]], 101 [[1, 0, 0], [1, 0, 0], [1, 0, 0], [0, 0, 0]], 102 [[1, 0, 0], [0, 0, 0], [1, 0, 0], [1, 0, 0]], 103 [[1, 0, 0], [1, 0, 0], [0, 0, 0], [1, 0, 0]], 104 [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]], 105 106 [[1]], 107 [[1], [1]], 108 [[1, 1]], 109 [[1, 1], [1, 1]], 110 [[1, 1], [1, 1], [1, 1]], 111 [[1, 1, 1]], 112 [[1, 1, 1], [1, 1, 1]], 113 [[1, 1, 1], [1, 1, 1], [1, 1, 1]], 114 [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]], 115 ].each do |rows| 116 matrix = Matrix[*rows] 117 assert_equal 1, matrix.rank 118 assert_equal 1, matrix.transpose.rank 119 end 120 121 [ 122 [[1, 0], [0, 1]], 123 [[1, 0], [0, 1], [0, 0]], 124 [[1, 0], [0, 1], [0, 1]], 125 [[1, 0], [0, 1], [1, 1]], 126 [[1, 0, 0], [0, 1, 0]], 127 [[1, 0, 0], [0, 0, 1]], 128 [[1, 0, 0], [0, 1, 0], [0, 0, 0]], 129 [[1, 0, 0], [0, 0, 1], [0, 0, 0]], 130 131 [[1, 0, 0], [0, 0, 0], [0, 1, 0]], 132 [[1, 0, 0], [0, 0, 0], [0, 0, 1]], 133 134 [[1, 0], [1, 1]], 135 [[1, 2], [1, 1]], 136 [[1, 2], [0, 1], [1, 1]], 137 ].each do |rows| 138 m = Matrix[*rows] 139 assert_equal 2, m.rank 140 assert_equal 2, m.transpose.rank 141 end 142 143 [ 144 [[1, 0, 0], [0, 1, 0], [0, 0, 1]], 145 [[1, 1, 0], [0, 1, 1], [1, 0, 1]], 146 [[1, 1, 0], [0, 1, 1], [1, 0, 1]], 147 [[1, 1, 0], [0, 1, 1], [1, 0, 1], [0, 0, 0]], 148 [[1, 1, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]], 149 [[1, 1, 1], [1, 1, 2], [1, 3, 1], [4, 1, 1]], 150 ].each do |rows| 151 m = Matrix[*rows] 152 assert_equal 3, m.rank 153 assert_equal 3, m.transpose.rank 154 end 155 end 156 157 def test_inverse 158 assert_equal(Matrix[[-1, 1], [0, -1]], Matrix[[-1, -1], [0, -1]].inverse) 159 end 160 161 def test_determinant 162 assert_equal(45, Matrix[[7,6], [3,9]].determinant) 163 assert_equal(-18, Matrix[[2,0,1],[0,-2,2],[1,2,3]].determinant) 164 end 165 166 def test_new_matrix 167 assert_raise(TypeError) { Matrix[Object.new] } 168 o = Object.new 169 def o.to_ary; [1,2,3]; end 170 assert_equal(@m1, Matrix[o, [4,5,6]]) 171 end 172 173 def test_rows 174 assert_equal(@m1, Matrix.rows([[1, 2, 3], [4, 5, 6]])) 175 end 176 177 def test_columns 178 assert_equal(@m1, Matrix.columns([[1, 4], [2, 5], [3, 6]])) 179 end 180 181 def test_diagonal 182 assert_equal(Matrix[[3,0,0],[0,2,0],[0,0,1]], Matrix.diagonal(3, 2, 1)) 183 assert_equal(Matrix[[4,0,0,0],[0,3,0,0],[0,0,2,0],[0,0,0,1]], Matrix.diagonal(4, 3, 2, 1)) 184 end 185 186 def test_scalar 187 assert_equal(Matrix[[2,0,0],[0,2,0],[0,0,2]], Matrix.scalar(3, 2)) 188 assert_equal(Matrix[[2,0,0,0],[0,2,0,0],[0,0,2,0],[0,0,0,2]], Matrix.scalar(4, 2)) 189 end 190 191 def test_identity2 192 assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.identity(3)) 193 assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.unit(3)) 194 assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.I(3)) 195 assert_equal(Matrix[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], Matrix.identity(4)) 196 end 197 198 def test_zero 199 assert_equal(Matrix[[0,0,0],[0,0,0],[0,0,0]], Matrix.zero(3)) 200 assert_equal(Matrix[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]], Matrix.zero(4)) 201 assert_equal(Matrix[[0]], Matrix.zero(1)) 202 end 203 204 def test_row_vector 205 assert_equal(Matrix[[1,2,3,4]], Matrix.row_vector([1,2,3,4])) 206 end 207 208 def test_column_vector 209 assert_equal(Matrix[[1],[2],[3],[4]], Matrix.column_vector([1,2,3,4])) 210 end 211 212 def test_empty 213 m = Matrix.empty(2, 0) 214 assert_equal(Matrix[ [], [] ], m) 215 n = Matrix.empty(0, 3) 216 assert_equal(Matrix.columns([ [], [], [] ]), n) 217 assert_equal(Matrix[[0, 0, 0], [0, 0, 0]], m * n) 218 end 219 220 def test_row 221 assert_equal(Vector[1, 2, 3], @m1.row(0)) 222 assert_equal(Vector[4, 5, 6], @m1.row(1)) 223 a = []; @m1.row(0) {|x| a << x } 224 assert_equal([1, 2, 3], a) 225 end 226 227 def test_column 228 assert_equal(Vector[1, 4], @m1.column(0)) 229 assert_equal(Vector[2, 5], @m1.column(1)) 230 assert_equal(Vector[3, 6], @m1.column(2)) 231 a = []; @m1.column(0) {|x| a << x } 232 assert_equal([1, 4], a) 233 end 234 235 def test_collect 236 assert_equal(Matrix[[1, 4, 9], [16, 25, 36]], @m1.collect {|x| x ** 2 }) 237 end 238 239 def test_minor 240 assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0..1, 0..1)) 241 assert_equal(Matrix[[2], [5]], @m1.minor(0..1, 1..1)) 242 assert_equal(Matrix[[4, 5]], @m1.minor(1..1, 0..1)) 243 assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0, 2, 0, 2)) 244 assert_equal(Matrix[[4, 5]], @m1.minor(1, 1, 0, 2)) 245 assert_equal(Matrix[[2], [5]], @m1.minor(0, 2, 1, 1)) 246 assert_raise(ArgumentError) { @m1.minor(0) } 247 end 248 249 def test_regular? 250 assert(Matrix[[1, 0], [0, 1]].regular?) 251 assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?) 252 assert(!Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].regular?) 253 end 254 255 def test_singular? 256 assert(!Matrix[[1, 0], [0, 1]].singular?) 257 assert(!Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].singular?) 258 assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].singular?) 259 end 260 261 def test_square? 262 assert(Matrix[[1, 0], [0, 1]].square?) 263 assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].square?) 264 assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].square?) 265 assert(!Matrix[[1, 0, 0], [0, 1, 0]].square?) 266 end 267 268 def test_mul 269 assert_equal(Matrix[[2,4],[6,8]], Matrix[[2,4],[6,8]] * Matrix.I(2)) 270 assert_equal(Matrix[[4,8],[12,16]], Matrix[[2,4],[6,8]] * 2) 271 assert_equal(Matrix[[4,8],[12,16]], 2 * Matrix[[2,4],[6,8]]) 272 assert_equal(Matrix[[14,32],[32,77]], @m1 * @m1.transpose) 273 assert_equal(Matrix[[17,22,27],[22,29,36],[27,36,45]], @m1.transpose * @m1) 274 assert_equal(Vector[14,32], @m1 * Vector[1,2,3]) 275 o = Object.new 276 def o.coerce(m) 277 [m, m.transpose] 278 end 279 assert_equal(Matrix[[14,32],[32,77]], @m1 * o) 280 end 281 282 def test_add 283 assert_equal(Matrix[[6,0],[-4,12]], Matrix.scalar(2,5) + Matrix[[1,0],[-4,7]]) 284 assert_equal(Matrix[[3,5,7],[9,11,13]], @m1 + @n1) 285 assert_equal(Matrix[[3,5,7],[9,11,13]], @n1 + @m1) 286 assert_equal(Matrix[[2],[4],[6]], Matrix[[1],[2],[3]] + Vector[1,2,3]) 287 assert_raise(Matrix::ErrOperationNotDefined) { @m1 + 1 } 288 o = Object.new 289 def o.coerce(m) 290 [m, m] 291 end 292 assert_equal(Matrix[[2,4,6],[8,10,12]], @m1 + o) 293 end 294 295 def test_sub 296 assert_equal(Matrix[[4,0],[4,-2]], Matrix.scalar(2,5) - Matrix[[1,0],[-4,7]]) 297 assert_equal(Matrix[[-1,-1,-1],[-1,-1,-1]], @m1 - @n1) 298 assert_equal(Matrix[[1,1,1],[1,1,1]], @n1 - @m1) 299 assert_equal(Matrix[[0],[0],[0]], Matrix[[1],[2],[3]] - Vector[1,2,3]) 300 assert_raise(Matrix::ErrOperationNotDefined) { @m1 - 1 } 301 o = Object.new 302 def o.coerce(m) 303 [m, m] 304 end 305 assert_equal(Matrix[[0,0,0],[0,0,0]], @m1 - o) 306 end 307 308 def test_div 309 assert_equal(Matrix[[0,1,1],[2,2,3]], @m1 / 2) 310 assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / Matrix.scalar(2,2)) 311 o = Object.new 312 def o.coerce(m) 313 [m, Matrix.scalar(2,2)] 314 end 315 assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / o) 316 end 317 318 def test_exp 319 assert_equal(Matrix[[67,96],[48,99]], Matrix[[7,6],[3,9]] ** 2) 320 assert_equal(Matrix.I(5), Matrix.I(5) ** -1) 321 assert_raise(Matrix::ErrOperationNotDefined) { Matrix.I(5) ** Object.new } 322 end 323 324 def test_det 325 assert_equal(45, Matrix[[7,6],[3,9]].det) 326 assert_equal(0, Matrix[[0,0],[0,0]].det) 327 assert_equal(-7, Matrix[[0,0,1],[0,7,6],[1,3,9]].det) 328 assert_equal(42, Matrix[[7,0,1,0,12],[8,1,1,9,1],[4,0,0,-7,17],[-1,0,0,-4,8],[10,1,1,8,6]].det) 329 end 330 331 def test_rank2 332 assert_equal(2, Matrix[[7,6],[3,9]].rank) 333 assert_equal(0, Matrix[[0,0],[0,0]].rank) 334 assert_equal(3, Matrix[[0,0,1],[0,7,6],[1,3,9]].rank) 335 assert_equal(1, Matrix[[0,1],[0,1],[0,1]].rank) 336 assert_equal(2, @m1.rank) 337 end 338 339 def test_trace 340 assert_equal(1+5+9, Matrix[[1,2,3],[4,5,6],[7,8,9]].trace) 341 end 342 343 def test_transpose 344 assert_equal(Matrix[[1,4],[2,5],[3,6]], @m1.transpose) 345 end 346 347 def test_row_vectors 348 assert_equal([Vector[1,2,3], Vector[4,5,6]], @m1.row_vectors) 349 end 350 351 def test_column_vectors 352 assert_equal([Vector[1,4], Vector[2,5], Vector[3,6]], @m1.column_vectors) 353 end 354 355 def test_to_s 356 assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.to_s) 357 assert_equal("Matrix.empty(0, 0)", Matrix[].to_s) 358 assert_equal("Matrix.empty(1, 0)", Matrix[[]].to_s) 359 end 360 361 def test_inspect 362 assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.inspect) 363 assert_equal("Matrix.empty(0, 0)", Matrix[].inspect) 364 assert_equal("Matrix.empty(1, 0)", Matrix[[]].inspect) 365 end 366 367 def test_scalar_add 368 s1 = @m1.coerce(1).first 369 assert_equal(Matrix[[1]], (s1 + 0) * Matrix[[1]]) 370 assert_raise(Matrix::ErrOperationNotDefined) { s1 + Vector[0] } 371 assert_raise(Matrix::ErrOperationNotDefined) { s1 + Matrix[[0]] } 372 o = Object.new 373 def o.coerce(x) 374 [1, 1] 375 end 376 assert_equal(2, s1 + o) 377 end 378 379 def test_scalar_sub 380 s1 = @m1.coerce(1).first 381 assert_equal(Matrix[[1]], (s1 - 0) * Matrix[[1]]) 382 assert_raise(Matrix::ErrOperationNotDefined) { s1 - Vector[0] } 383 assert_raise(Matrix::ErrOperationNotDefined) { s1 - Matrix[[0]] } 384 o = Object.new 385 def o.coerce(x) 386 [1, 1] 387 end 388 assert_equal(0, s1 - o) 389 end 390 391 def test_scalar_mul 392 s1 = @m1.coerce(1).first 393 assert_equal(Matrix[[1]], (s1 * 1) * Matrix[[1]]) 394 assert_equal(Vector[2], s1 * Vector[2]) 395 assert_equal(Matrix[[2]], s1 * Matrix[[2]]) 396 o = Object.new 397 def o.coerce(x) 398 [1, 1] 399 end 400 assert_equal(1, s1 * o) 401 end 402 403 def test_scalar_div 404 s1 = @m1.coerce(1).first 405 assert_equal(Matrix[[1]], (s1 / 1) * Matrix[[1]]) 406 assert_raise(Matrix::ErrOperationNotDefined) { s1 / Vector[0] } 407 assert_equal(Matrix[[Rational(1,2)]], s1 / Matrix[[2]]) 408 o = Object.new 409 def o.coerce(x) 410 [1, 1] 411 end 412 assert_equal(1, s1 / o) 413 end 414 415 def test_scalar_pow 416 s1 = @m1.coerce(1).first 417 assert_equal(Matrix[[1]], (s1 ** 1) * Matrix[[1]]) 418 assert_raise(Matrix::ErrOperationNotDefined) { s1 ** Vector[0] } 419 assert_raise(Matrix::ErrOperationNotImplemented) { s1 ** Matrix[[1]] } 420 o = Object.new 421 def o.coerce(x) 422 [1, 1] 423 end 424 assert_equal(1, s1 ** o) 425 end 426end 427