1 9 package org.jscience.mathematics.vectors; 10 11 import java.util.Comparator ; 12 13 import javolution.lang.Immutable; 14 import javolution.lang.MathLib; 15 import javolution.text.Text; 16 import javolution.text.TextBuilder; 17 import javolution.context.PoolContext; 18 import javolution.context.RealtimeObject; 19 import javolution.xml.XMLFormat; 20 import javolution.xml.stream.XMLStreamException; 21 22 import org.jscience.mathematics.numbers.Complex; 23 import org.jscience.mathematics.numbers.Float64; 24 import org.jscience.mathematics.structures.Field; 25 import org.jscience.mathematics.structures.Ring; 26 import org.jscience.mathematics.structures.VectorSpace; 27 28 78 public abstract class Matrix<F extends Field<F>> extends RealtimeObject 79 implements VectorSpace<Matrix<F>, F>, Ring<Matrix<F>>, Immutable { 80 81 90 protected static final XMLFormat<Matrix> XML = new XMLFormat<Matrix>( 91 Matrix.class) { 92 93 @Override 94 public void read(InputElement xml, Matrix M) throws XMLStreamException { 95 } 97 98 @Override 99 public void write(Matrix M, OutputElement xml) 100 throws XMLStreamException { 101 final int m = M.getNumberOfRows(); 102 final int n = M.getNumberOfColumns(); 103 xml.setAttribute("rows", m); 104 xml.setAttribute("columns", n); 105 for (int i = 0; i < m; i++) { 106 for (int j = 0; j < n; j++) { 107 xml.add(M.get(i, j)); 108 } 109 } 110 } 111 }; 112 113 122 public static <F extends Field<F>> Matrix<F> valueOf(F[][] elements) { 123 return DenseMatrix.valueOf(elements); 124 } 125 126 135 public static Matrix<Float64> valueOf(double[][] values) { 136 return Float64Matrix.valueOf(values); 137 } 138 139 148 public static Matrix<Complex> valueOf(Complex[][] elements) { 149 return ComplexMatrix.valueOf(elements); 150 } 151 152 162 public static <F extends Field<F>> Matrix<F> valueOf(Vector<F> diagonal, 163 F zero) { 164 return SparseMatrix.valueOf(diagonal, zero); 165 } 166 167 170 protected Matrix() { 171 } 172 173 178 public abstract int getNumberOfRows(); 179 180 185 public abstract int getNumberOfColumns(); 186 187 196 public abstract F get(int i, int j); 197 198 205 public abstract Vector<F> getRow(int i); 206 207 214 public abstract Vector<F> getColumn(int j); 215 216 221 public abstract Vector<F> getDiagonal(); 222 223 228 public abstract Matrix<F> opposite(); 229 230 237 public abstract Matrix<F> plus(Matrix<F> that); 238 239 246 public Matrix<F> minus(Matrix<F> that) { 247 return this.plus(that.opposite()); 248 } 249 250 256 public abstract Matrix<F> times(F k); 257 258 266 public abstract Vector<F> times(Vector<F> v); 267 268 276 public abstract Matrix<F> times(Matrix<F> that); 277 278 284 public abstract Matrix<F> inverse(); 285 286 294 public Matrix<F> divide(Matrix<F> that) { 295 return this.times(that.inverse()); 296 } 297 298 307 public Matrix<F> pseudoInverse() { 308 if (isSquare()) 309 return this.inverse(); 310 Matrix<F> thisTranspose = this.transpose(); 311 return (thisTranspose.times(this)).inverse().times(thisTranspose); 312 } 313 314 320 public abstract F determinant(); 321 322 327 public abstract Matrix<F> transpose(); 328 329 340 public abstract F cofactor(int i, int j); 341 342 352 public abstract Matrix<F> adjoint(); 353 354 359 public boolean isSquare() { 360 return getNumberOfRows() == getNumberOfColumns(); 361 } 362 363 372 public Vector<F> solve(Vector<F> y) { 373 DenseMatrix<F> M = DenseMatrix.newInstance(y.getDimension(), true); 374 M._rows.add(DenseVector.valueOf(y)); 375 return solve(M).getColumn(0); 376 } 377 378 387 public Matrix<F> solve(Matrix<F> y) { 388 return LUDecomposition.valueOf(this).solve(y); } 390 391 398 public Matrix<F> pow(int exp) { 399 if (exp > 0) { 400 PoolContext.enter(); 401 try { 402 Matrix<F> pow2 = this; 403 Matrix<F> result = null; 404 while (exp >= 1) { if ((exp & 1) == 1) { 406 result = (result == null) ? pow2 : result.times(pow2); 407 } 408 pow2 = pow2.times(pow2); 409 exp >>>= 1; 410 } 411 result.export(); 412 return result; 413 } finally { 414 PoolContext.exit(); 415 } 416 } else if (exp == 0) { 417 return this.times(this.inverse()); } else { 419 return this.pow(-exp).inverse(); 420 } 421 } 422 423 428 public F trace() { 429 F sum = this.get(0, 0); 430 for (int i = MathLib.min(getNumberOfColumns(), getNumberOfRows()); --i > 0;) { 431 sum = sum.plus(get(i, i)); 432 } 433 return sum; 434 } 435 436 446 public abstract Matrix<F> tensor(Matrix<F> that); 447 448 458 public abstract Vector<F> vectorization(); 459 460 465 public Text toText() { 466 final int m = this.getNumberOfRows(); 467 final int n = this.getNumberOfColumns(); 468 TextBuilder tmp = TextBuilder.newInstance(); 469 tmp.append('{'); 470 for (int i = 0; i < m; i++) { 471 tmp.append('{'); 472 for (int j = 0; j < n; j++) { 473 tmp.append(get(i, j).toText()); 474 if (j != n - 1) { 475 tmp.append(", "); 476 } 477 } 478 if (i != m - 1) { 479 tmp.append("},\n"); 480 } 481 } 482 tmp.append("}}"); 483 Text txt = tmp.toText(); 484 TextBuilder.recycle(tmp); 485 return txt; 486 } 487 488 500 public boolean equals(Matrix<F> that, Comparator <F> cmp) { 501 if (this == that) 502 return true; 503 final int m = this.getNumberOfRows(); 504 final int n = this.getNumberOfColumns(); 505 if ((that.getNumberOfRows() != m) || (that.getNumberOfColumns() != n)) 506 return false; 507 for (int i = m; --i >= 0;) { 508 for (int j = n; --j >= 0;) { 509 if (cmp.compare(this.get(i, j), that.get(i, j)) != 0) 510 return false; 511 } 512 } 513 return true; 514 } 515 516 524 public boolean equals(Object that) { 525 if (this == that) 526 return true; 527 if (!(that instanceof Matrix)) 528 return false; 529 final int m = this.getNumberOfRows(); 530 final int n = this.getNumberOfColumns(); 531 Matrix M = (Matrix) that; 532 if ((M.getNumberOfRows() != m) || (M.getNumberOfColumns() != n)) 533 return false; 534 for (int i = m; --i >= 0;) { 535 for (int j = n; --j >= 0;) { 536 if (!this.get(i, j).equals(M.get(i, j))) 537 return false; 538 } 539 } 540 return true; 541 } 542 543 550 public int hashCode() { 551 final int m = this.getNumberOfRows(); 552 final int n = this.getNumberOfColumns(); 553 int code = 0; 554 for (int i = m; --i >= 0;) { 555 for (int j = n; --j >= 0;) { 556 code += get(i, j).hashCode(); 557 } 558 } 559 return code; 560 } 561 562 } | Popular Tags |