001: /* AUTO-GENERATED */
002: package JSci.maths.matrices;
003:
004: import JSci.maths.ExtraMath;
005: import JSci.maths.Mapping;
006: import JSci.maths.DimensionException;
007: import JSci.maths.MaximumIterationsExceededException;
008: import JSci.maths.vectors.AbstractIntegerVector;
009: import JSci.maths.vectors.IntegerVector;
010: import JSci.maths.groups.AbelianGroup;
011: import JSci.maths.algebras.*;
012: import JSci.maths.fields.*;
013:
014: /**
015: * The IntegerDiagonalMatrix class provides an object for encapsulating integer diagonal matrices.
016: * @version 2.2
017: * @author Mark Hale
018: */
019: public class IntegerDiagonalMatrix extends AbstractIntegerSquareMatrix
020: implements DiagonalMatrix {
021: /**
022: * Diagonal data.
023: */
024: protected final int diag[];
025:
026: /**
027: * Constructs an empty matrix.
028: * @param size the number of rows/columns
029: */
030: public IntegerDiagonalMatrix(final int size) {
031: this (new int[size]);
032: }
033:
034: /**
035: * Constructs a matrix from an array.
036: * Any non-diagonal elements in the array are ignored.
037: * @param array an assigned value
038: * @exception MatrixDimensionException If the array is not square.
039: */
040: public IntegerDiagonalMatrix(final int array[][]) {
041: this (array.length);
042: for (int i = 0; i < array.length; i++) {
043: if (array[i].length != array.length)
044: throw new MatrixDimensionException(
045: "Array is not square.");
046: diag[i] = array[i][i];
047: }
048: }
049:
050: /**
051: * Constructs a matrix by wrapping an array containing the diagonal elements.
052: * @param array an assigned value
053: */
054: public IntegerDiagonalMatrix(final int array[]) {
055: super (array.length);
056: diag = array;
057: }
058:
059: /**
060: * Creates an identity matrix.
061: * @param size the number of rows/columns
062: */
063: public static IntegerDiagonalMatrix identity(final int size) {
064: int array[] = new int[size];
065: for (int i = 0; i < size; i++)
066: array[i] = 1;
067: return new IntegerDiagonalMatrix(array);
068: }
069:
070: /**
071: * Compares two ${nativeTyp} matrices for equality.
072: * @param m a int matrix
073: */
074: public boolean equals(AbstractIntegerMatrix m, double tol) {
075: if (m instanceof DiagonalMatrix) {
076: if (numRows != m.rows() || numCols != m.columns())
077: return false;
078: int sumSqr = 0;
079: int delta = diag[0] - m.getElement(0, 0);
080: sumSqr += delta * delta;
081: for (int i = 1; i < numRows; i++) {
082: delta = diag[i] - m.getElement(i, i);
083: sumSqr += delta * delta;
084: }
085: return (sumSqr <= tol * tol);
086: } else {
087: return false;
088: }
089: }
090:
091: /**
092: * Returns a string representing this matrix.
093: */
094: public String toString() {
095: final StringBuffer buf = new StringBuffer(5 * numRows * numCols);
096: for (int i = 0; i < numRows; i++) {
097: for (int j = 0; j < numCols; j++) {
098: buf.append(getElement(i, j));
099: buf.append(' ');
100: }
101: buf.append('\n');
102: }
103: return buf.toString();
104: }
105:
106: /**
107: * Converts this matrix to a double matrix.
108: * @return a double matrix
109: */
110: public AbstractDoubleMatrix toDoubleMatrix() {
111: final double array[] = new double[numRows];
112: for (int i = 0; i < numRows; i++)
113: array[i] = diag[i];
114: return new DoubleDiagonalMatrix(array);
115: }
116:
117: /**
118: * Converts this matrix to a complex matrix.
119: * @return a complex matrix
120: */
121: public AbstractComplexMatrix toComplexMatrix() {
122: final double array[] = new double[numRows];
123: for (int i = 0; i < numRows; i++)
124: array[i] = diag[i];
125: return new ComplexDiagonalMatrix(array, new double[numRows]);
126: }
127:
128: /**
129: * Returns an element of the matrix.
130: * @param i row index of the element
131: * @param j column index of the element
132: * @exception MatrixDimensionException If attempting to access an invalid element.
133: */
134: public int getElement(int i, int j) {
135: if (i >= 0 && i < numRows && j >= 0 && j < numCols) {
136: if (i == j)
137: return diag[i];
138: else
139: return 0;
140: } else
141: throw new MatrixDimensionException(getInvalidElementMsg(i,
142: j));
143: }
144:
145: /**
146: * Sets the value of an element of the matrix.
147: * Should only be used to initialise this matrix.
148: * @param i row index of the element
149: * @param j column index of the element
150: * @param x a number
151: * @exception MatrixDimensionException If attempting to access an invalid element.
152: */
153: public void setElement(int i, int j, final int x) {
154: if (i >= 0 && i < numRows && j >= 0 && j < numCols) {
155: if (i == j)
156: diag[i] = x;
157: else
158: throw new MatrixDimensionException(
159: getInvalidElementMsg(i, j));
160: } else
161: throw new MatrixDimensionException(getInvalidElementMsg(i,
162: j));
163: }
164:
165: /**
166: * Returns true if this matrix is symmetric.
167: */
168: public boolean isSymmetric() {
169: return true;
170: }
171:
172: /**
173: * Returns the determinant.
174: */
175: public int det() {
176: int det = diag[0];
177: for (int i = 1; i < numRows; i++)
178: det *= diag[i];
179: return det;
180: }
181:
182: /**
183: * Returns the trace.
184: */
185: public int trace() {
186: int tr = diag[0];
187: for (int i = 1; i < numRows; i++)
188: tr += diag[i];
189: return tr;
190: }
191:
192: /**
193: * Returns the l<sup><img border=0 alt="infinity" src="doc-files/infinity.gif"></sup>-norm.
194: * @author Taber Smith
195: */
196: public int infNorm() {
197: int result = Math.abs(diag[0]);
198: int tmpResult;
199: for (int i = 1; i < numRows; i++) {
200: tmpResult = Math.abs(diag[i]);
201: if (tmpResult > result)
202: result = tmpResult;
203: }
204: return result;
205: }
206:
207: /**
208: * Returns the Frobenius (l<sup>2</sup>) norm.
209: * @author Taber Smith
210: */
211: public double frobeniusNorm() {
212: double result = diag[0];
213: for (int i = 1; i < numRows; i++)
214: result = ExtraMath.hypot(result, diag[i]);
215: return result;
216: }
217:
218: /**
219: * Returns the operator norm.
220: * @exception MaximumIterationsExceededException If it takes more than 50 iterations to determine an eigenvalue.
221: */
222: public double operatorNorm()
223: throws MaximumIterationsExceededException {
224: return infNorm();
225: }
226:
227: //============
228: // OPERATIONS
229: //============
230:
231: // ADDITION
232:
233: /**
234: * Returns the addition of this matrix and another.
235: * @param m a int matrix
236: * @exception MatrixDimensionException If the matrices are different sizes.
237: */
238: public AbstractIntegerSquareMatrix add(
239: final AbstractIntegerSquareMatrix m) {
240: if (m instanceof IntegerDiagonalMatrix)
241: return add((IntegerDiagonalMatrix) m);
242: if (m instanceof DiagonalMatrix)
243: return addDiagonal(m);
244: if (m instanceof IntegerTridiagonalMatrix)
245: return add((IntegerTridiagonalMatrix) m);
246: if (m instanceof TridiagonalMatrix)
247: return addTridiagonal(m);
248: if (m instanceof IntegerSquareMatrix)
249: return add((IntegerSquareMatrix) m);
250:
251: if (numRows == m.rows() && numCols == m.columns()) {
252: final int array[][] = new int[numRows][numCols];
253: for (int i = 0; i < numRows; i++) {
254: array[i][0] = m.getElement(i, 0);
255: for (int j = 1; j < numCols; j++)
256: array[i][j] = m.getElement(i, j);
257: }
258: for (int i = 0; i < numRows; i++)
259: array[i][i] += diag[i];
260: return new IntegerSquareMatrix(array);
261: } else {
262: throw new MatrixDimensionException(
263: "Matrices are different sizes.");
264: }
265: }
266:
267: public IntegerSquareMatrix add(final IntegerSquareMatrix m) {
268: if (numRows == m.numRows && numCols == m.numCols) {
269: final int array[][] = new int[numRows][numCols];
270: for (int i = 0; i < numRows; i++)
271: System.arraycopy(m.matrix[i], 0, array[i], 0, numRows);
272: for (int i = 0; i < numRows; i++)
273: array[i][i] += diag[i];
274: return new IntegerSquareMatrix(array);
275: } else
276: throw new MatrixDimensionException(
277: "Matrices are different sizes.");
278: }
279:
280: /**
281: * Returns the addition of this matrix and another.
282: * @param m a int tridiagonal matrix
283: * @exception MatrixDimensionException If the matrices are different sizes.
284: */
285: public IntegerTridiagonalMatrix add(final IntegerTridiagonalMatrix m) {
286: if (numRows == m.numRows) {
287: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
288: numRows);
289: System.arraycopy(m.ldiag, 0, ans.ldiag, 0, m.ldiag.length);
290: System.arraycopy(m.udiag, 0, ans.udiag, 0, m.udiag.length);
291: ans.diag[0] = diag[0] + m.diag[0];
292: for (int i = 1; i < numRows; i++)
293: ans.diag[i] = diag[i] + m.diag[i];
294: return ans;
295: } else
296: throw new MatrixDimensionException(
297: "Matrices are different sizes.");
298: }
299:
300: private IntegerTridiagonalMatrix addTridiagonal(
301: final AbstractIntegerSquareMatrix m) {
302: int mRow = numRows;
303: if (mRow == m.rows()) {
304: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
305: mRow);
306: ans.diag[0] = diag[0] + m.getElement(0, 0);
307: ans.udiag[0] = m.getElement(0, 1);
308: mRow--;
309: for (int i = 1; i < mRow; i++) {
310: ans.ldiag[i] = m.getElement(i, i - 1);
311: ans.diag[i] = diag[i] + m.getElement(i, i);
312: ans.udiag[i] = m.getElement(i, i + 1);
313: }
314: ans.ldiag[mRow] = m.getElement(mRow, mRow - 1);
315: ans.diag[mRow] = diag[mRow] + m.getElement(mRow, mRow);
316: return ans;
317: } else {
318: throw new MatrixDimensionException(
319: "Matrices are different sizes.");
320: }
321: }
322:
323: /**
324: * Returns the addition of this matrix and another.
325: * @param m a int diagonal matrix
326: * @exception MatrixDimensionException If the matrices are different sizes.
327: */
328: public IntegerDiagonalMatrix add(final IntegerDiagonalMatrix m) {
329: if (numRows == m.numRows) {
330: final int array[] = new int[numRows];
331: array[0] = diag[0] + m.diag[0];
332: for (int i = 1; i < numRows; i++)
333: array[i] = diag[i] + m.diag[i];
334: return new IntegerDiagonalMatrix(array);
335: } else
336: throw new MatrixDimensionException(
337: "Matrices are different sizes.");
338: }
339:
340: private IntegerDiagonalMatrix addDiagonal(
341: final AbstractIntegerSquareMatrix m) {
342: if (numRows == m.numRows) {
343: final int array[] = new int[numRows];
344: array[0] = diag[0] + m.getElement(0, 0);
345: for (int i = 1; i < numRows; i++)
346: array[i] = diag[i] + m.getElement(i, i);
347: return new IntegerDiagonalMatrix(array);
348: } else
349: throw new MatrixDimensionException(
350: "Matrices are different sizes.");
351: }
352:
353: // SUBTRACTION
354:
355: /**
356: * Returns the subtraction of this matrix by another.
357: * @param m a int matrix
358: * @exception MatrixDimensionException If the matrices are different sizes.
359: */
360: public AbstractIntegerSquareMatrix subtract(
361: final AbstractIntegerSquareMatrix m) {
362: if (m instanceof IntegerDiagonalMatrix)
363: return subtract((IntegerDiagonalMatrix) m);
364: if (m instanceof DiagonalMatrix)
365: return subtractDiagonal(m);
366: if (m instanceof IntegerTridiagonalMatrix)
367: return subtract((IntegerTridiagonalMatrix) m);
368: if (m instanceof TridiagonalMatrix)
369: return subtractTridiagonal(m);
370: if (m instanceof IntegerSquareMatrix)
371: return subtract((IntegerSquareMatrix) m);
372:
373: if (numRows == m.rows() && numCols == m.columns()) {
374: final int array[][] = new int[numRows][numCols];
375: for (int i = 0; i < numRows; i++) {
376: array[i][0] = -m.getElement(i, 0);
377: for (int j = 1; j < numCols; j++)
378: array[i][j] = -m.getElement(i, j);
379: }
380: for (int i = 0; i < numRows; i++)
381: array[i][i] += diag[i];
382: return new IntegerSquareMatrix(array);
383: } else {
384: throw new MatrixDimensionException(
385: "Matrices are different sizes.");
386: }
387: }
388:
389: public IntegerSquareMatrix subtract(final IntegerSquareMatrix m) {
390: if (numRows == m.numRows && numCols == m.numCols) {
391: final int array[][] = new int[numRows][numCols];
392: for (int i = 0; i < numRows; i++) {
393: array[i][0] = -m.matrix[i][0];
394: for (int j = 1; j < numCols; j++)
395: array[i][j] = -m.matrix[i][j];
396: }
397: for (int i = 0; i < numRows; i++)
398: array[i][i] += diag[i];
399: return new IntegerSquareMatrix(array);
400: } else
401: throw new MatrixDimensionException(
402: "Matrices are different sizes.");
403: }
404:
405: /**
406: * Returns the subtraction of this matrix and another.
407: * @param m a int tridiagonal matrix
408: * @exception MatrixDimensionException If the matrices are different sizes.
409: */
410: public IntegerTridiagonalMatrix subtract(
411: final IntegerTridiagonalMatrix m) {
412: int mRow = numRows;
413: if (mRow == m.numRows) {
414: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
415: mRow);
416: ans.diag[0] = diag[0] - m.diag[0];
417: ans.udiag[0] = -m.udiag[0];
418: mRow--;
419: for (int i = 1; i < mRow; i++) {
420: ans.ldiag[i] = -m.ldiag[i];
421: ans.diag[i] = diag[i] - m.diag[i];
422: ans.udiag[i] = -m.udiag[i];
423: }
424: ans.ldiag[mRow] = -m.ldiag[mRow];
425: ans.diag[mRow] = diag[mRow] - m.diag[mRow];
426: return ans;
427: } else
428: throw new MatrixDimensionException(
429: "Matrices are different sizes.");
430: }
431:
432: private IntegerTridiagonalMatrix subtractTridiagonal(
433: final AbstractIntegerSquareMatrix m) {
434: int mRow = numRows;
435: if (mRow == m.rows()) {
436: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
437: mRow);
438: ans.diag[0] = diag[0] - m.getElement(0, 0);
439: ans.udiag[0] = -m.getElement(0, 1);
440: mRow--;
441: for (int i = 1; i < mRow; i++) {
442: ans.ldiag[i] = -m.getElement(i, i - 1);
443: ans.diag[i] = diag[i] - m.getElement(i, i);
444: ans.udiag[i] = -m.getElement(i, i + 1);
445: }
446: ans.ldiag[mRow] = -m.getElement(mRow, mRow - 1);
447: ans.diag[mRow] = diag[mRow] - m.getElement(mRow, mRow);
448: return ans;
449: } else {
450: throw new MatrixDimensionException(
451: "Matrices are different sizes.");
452: }
453: }
454:
455: /**
456: * Returns the subtraction of this matrix and another.
457: * @param m a int diagonal matrix
458: * @exception MatrixDimensionException If the matrices are different sizes.
459: */
460: public IntegerDiagonalMatrix subtract(final IntegerDiagonalMatrix m) {
461: if (numRows == m.numRows) {
462: final int array[] = new int[numRows];
463: array[0] = diag[0] - m.diag[0];
464: for (int i = 1; i < numRows; i++)
465: array[i] = diag[i] - m.diag[i];
466: return new IntegerDiagonalMatrix(array);
467: } else
468: throw new MatrixDimensionException(
469: "Matrices are different sizes.");
470: }
471:
472: private IntegerDiagonalMatrix subtractDiagonal(
473: final AbstractIntegerSquareMatrix m) {
474: if (numRows == m.numRows) {
475: final int array[] = new int[numRows];
476: array[0] = diag[0] - m.getElement(0, 0);
477: for (int i = 1; i < numRows; i++)
478: array[i] = diag[i] - m.getElement(i, i);
479: return new IntegerDiagonalMatrix(array);
480: } else
481: throw new MatrixDimensionException(
482: "Matrices are different sizes.");
483: }
484:
485: // SCALAR MULTIPLICATION
486:
487: /**
488: * Returns the multiplication of this matrix by a scalar.
489: * @param x a int.
490: * @return a int diagonal matrix.
491: */
492: public AbstractIntegerMatrix scalarMultiply(final int x) {
493: final int array[] = new int[numRows];
494: array[0] = x * diag[0];
495: for (int i = 1; i < numRows; i++)
496: array[i] = x * diag[i];
497: return new IntegerDiagonalMatrix(array);
498: }
499:
500: // SCALAR DIVISON
501:
502: // SCALAR PRODUCT
503:
504: /**
505: * Returns the scalar product of this matrix and another.
506: * @param m a int matrix.
507: * @exception MatrixDimensionException If the matrices are different sizes.
508: */
509: public int scalarProduct(final AbstractIntegerSquareMatrix m) {
510: if (m instanceof IntegerDiagonalMatrix)
511: return scalarProduct((IntegerDiagonalMatrix) m);
512: if (m instanceof IntegerTridiagonalMatrix)
513: return scalarProduct((IntegerTridiagonalMatrix) m);
514: if (m instanceof IntegerSquareMatrix)
515: return scalarProduct((IntegerSquareMatrix) m);
516:
517: if (numRows == m.rows() && numCols == m.columns()) {
518: int ans = diag[0] * m.getElement(0, 0);
519: for (int i = 1; i < numRows; i++)
520: ans += diag[i] * m.getElement(i, i);
521: return ans;
522: } else {
523: throw new MatrixDimensionException(
524: "Matrices are different sizes.");
525: }
526: }
527:
528: public int scalarProduct(final IntegerSquareMatrix m) {
529: if (numRows == m.numRows && numCols == m.numCols) {
530: int ans = diag[0] * m.matrix[0][0];
531: for (int i = 1; i < numRows; i++)
532: ans += diag[i] * m.matrix[i][i];
533: return ans;
534: } else
535: throw new MatrixDimensionException(
536: "Matrices are different sizes.");
537: }
538:
539: public int scalarProduct(final IntegerTridiagonalMatrix m) {
540: if (numRows == m.numRows) {
541: int ans = diag[0] * m.diag[0];
542: for (int i = 1; i < numRows; i++)
543: ans += diag[i] * m.diag[i];
544: return ans;
545: } else
546: throw new MatrixDimensionException(
547: "Matrices are different sizes.");
548: }
549:
550: public int scalarProduct(final IntegerDiagonalMatrix m) {
551: if (numRows == m.numRows) {
552: int ans = diag[0] * m.diag[0];
553: for (int i = 1; i < numRows; i++)
554: ans += diag[i] * m.diag[i];
555: return ans;
556: } else
557: throw new MatrixDimensionException(
558: "Matrices are different sizes.");
559: }
560:
561: // MATRIX MULTIPLICATION
562:
563: /**
564: * Returns the multiplication of a vector by this matrix.
565: * @param v a int vector.
566: * @exception DimensionException If the matrix and vector are incompatible.
567: */
568: public AbstractIntegerVector multiply(final AbstractIntegerVector v) {
569: if (numCols == v.dimension()) {
570: final int array[] = new int[numRows];
571: array[0] = diag[0] * v.getComponent(0);
572: for (int i = 1; i < numRows; i++)
573: array[i] = diag[i] * v.getComponent(i);
574: return new IntegerVector(array);
575: } else {
576: throw new DimensionException(
577: "Matrix and vector are incompatible.");
578: }
579: }
580:
581: /**
582: * Returns the multiplication of this matrix and another.
583: * @param m a int matrix
584: * @return a AbstractIntegerMatrix or a AbstractIntegerSquareMatrix as appropriate
585: * @exception MatrixDimensionException If the matrices are incompatible.
586: */
587: public AbstractIntegerSquareMatrix multiply(
588: final AbstractIntegerSquareMatrix m) {
589: if (m instanceof IntegerDiagonalMatrix)
590: return multiply((IntegerDiagonalMatrix) m);
591: if (m instanceof DiagonalMatrix)
592: return multiplyDiagonal(m);
593: if (m instanceof IntegerTridiagonalMatrix)
594: return multiply((IntegerTridiagonalMatrix) m);
595: if (m instanceof TridiagonalMatrix)
596: return multiplyTridiagonal(m);
597: if (m instanceof IntegerSquareMatrix)
598: return multiply((IntegerSquareMatrix) m);
599:
600: if (numCols == m.rows()) {
601: final int mColumns = m.columns();
602: final int array[][] = new int[numRows][mColumns];
603: for (int i = 0; i < numRows; i++) {
604: array[i][0] = diag[0] * m.getElement(i, 0);
605: for (int j = 1; j < mColumns; j++)
606: array[i][j] = diag[i] * m.getElement(i, j);
607: }
608: return new IntegerSquareMatrix(array);
609: } else {
610: throw new MatrixDimensionException("Incompatible matrices.");
611: }
612: }
613:
614: public IntegerSquareMatrix multiply(final IntegerSquareMatrix m) {
615: if (numCols == m.numRows) {
616: final int array[][] = new int[numRows][m.numCols];
617: for (int i = 0; i < numRows; i++) {
618: array[i][0] = diag[0] * m.matrix[i][0];
619: for (int j = 1; j < m.numCols; j++)
620: array[i][j] = diag[i] * m.matrix[i][j];
621: }
622: return new IntegerSquareMatrix(array);
623: } else
624: throw new MatrixDimensionException("Incompatible matrices.");
625: }
626:
627: public IntegerTridiagonalMatrix multiply(
628: final IntegerTridiagonalMatrix m) {
629: int mRow = numRows;
630: if (numCols == m.numRows) {
631: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
632: mRow);
633: ans.diag[0] = diag[0] * m.diag[0];
634: ans.udiag[0] = diag[0] * m.udiag[0];
635: mRow--;
636: for (int i = 1; i < mRow; i++) {
637: ans.ldiag[i] = diag[i] * m.ldiag[i];
638: ans.diag[i] = diag[i] * m.diag[i];
639: ans.udiag[i] = diag[i] * m.udiag[i];
640: }
641: ans.ldiag[mRow] = diag[mRow] * m.ldiag[mRow];
642: ans.diag[mRow] = diag[mRow] * m.diag[mRow];
643: return ans;
644: } else
645: throw new MatrixDimensionException("Incompatible matrices.");
646: }
647:
648: private IntegerTridiagonalMatrix multiplyTridiagonal(
649: final AbstractIntegerSquareMatrix m) {
650: int mRow = numRows;
651: if (numCols == m.rows()) {
652: final IntegerTridiagonalMatrix ans = new IntegerTridiagonalMatrix(
653: mRow);
654: ans.diag[0] = diag[0] * m.getElement(0, 0);
655: ans.udiag[0] = diag[0] * m.getElement(0, 1);
656: mRow--;
657: for (int i = 1; i < mRow; i++) {
658: ans.ldiag[i] = diag[i] * m.getElement(i, i - 1);
659: ans.diag[i] = diag[i] * m.getElement(i, i);
660: ans.udiag[i] = diag[i] * m.getElement(i, i + 1);
661: }
662: ans.ldiag[mRow] = diag[mRow] * m.getElement(mRow, mRow - 1);
663: ans.diag[mRow] = diag[mRow] * m.getElement(mRow, mRow);
664: return ans;
665: } else {
666: throw new MatrixDimensionException("Incompatible matrices.");
667: }
668: }
669:
670: public IntegerDiagonalMatrix multiply(final IntegerDiagonalMatrix m) {
671: if (numCols == m.numRows) {
672: final int array[] = new int[numRows];
673: array[0] = diag[0] * m.diag[0];
674: for (int i = 1; i < numRows; i++) {
675: array[i] = diag[i] * m.diag[i];
676: }
677: return new IntegerDiagonalMatrix(array);
678: } else
679: throw new MatrixDimensionException("Incompatible matrices.");
680: }
681:
682: private IntegerDiagonalMatrix multiplyDiagonal(
683: final AbstractIntegerSquareMatrix m) {
684: if (numCols == m.rows()) {
685: final int array[] = new int[numRows];
686: array[0] = diag[0] * m.getElement(0, 0);
687: for (int i = 1; i < numRows; i++) {
688: array[i] = diag[i] * m.getElement(i, i);
689: }
690: return new IntegerDiagonalMatrix(array);
691: } else {
692: throw new MatrixDimensionException("Incompatible matrices.");
693: }
694: }
695:
696: // TRANSPOSE
697:
698: /**
699: * Returns the transpose of this matrix.
700: * @return a int matrix
701: */
702: public Matrix transpose() {
703: return this ;
704: }
705:
706: // INVERSE
707:
708: /**
709: * Returns the inverse of this matrix.
710: * @return a double diagonal matrix
711: */
712: public AbstractDoubleSquareMatrix inverse() {
713: final double array[] = new double[numRows];
714: array[0] = 1.0 / diag[0];
715: for (int i = 1; i < numRows; i++)
716: array[i] = 1.0 / diag[i];
717: return new DoubleDiagonalMatrix(array);
718: }
719:
720: // LU DECOMPOSITION
721:
722: /**
723: * Returns the LU decomposition of this matrix.
724: * @param pivot an empty array of length <code>rows()+1</code>
725: * to hold the pivot information (null if not interested).
726: * The last array element will contain the parity.
727: * @return an array with [0] containing the L-matrix
728: * and [1] containing the U-matrix.
729: */
730: public AbstractDoubleSquareMatrix[] luDecompose(int pivot[]) {
731: if (LU != null) {
732: if (pivot != null)
733: System.arraycopy(LUpivot, 0, pivot, 0, pivot.length);
734: return LU;
735: }
736: if (pivot == null)
737: pivot = new int[numRows + 1];
738: for (int i = 0; i < numRows; i++)
739: pivot[i] = i;
740: pivot[numRows] = 1;
741: LU = new AbstractDoubleSquareMatrix[2];
742: LU[0] = DoubleDiagonalMatrix.identity(numRows);
743: LU[1] = (AbstractDoubleSquareMatrix) this .toDoubleMatrix();
744: LUpivot = new int[pivot.length];
745: System.arraycopy(pivot, 0, LUpivot, 0, pivot.length);
746: return LU;
747: }
748:
749: /**
750: * Returns the LU decomposition of this matrix.
751: * @return an array with [0] containing the L-matrix
752: * and [1] containing the U-matrix.
753: * @jsci.planetmath LUDecomposition
754: */
755: public AbstractDoubleSquareMatrix[] luDecompose() {
756: return luDecompose(null);
757: }
758:
759: // CHOLESKY DECOMPOSITION
760:
761: /**
762: * Returns the Cholesky decomposition of this matrix.
763: * Matrix must be symmetric and positive definite.
764: * @return an array with [0] containing the L-matrix and [1] containing the U-matrix.
765: */
766: public AbstractDoubleSquareMatrix[] choleskyDecompose() {
767: final AbstractDoubleSquareMatrix lu[] = new AbstractDoubleSquareMatrix[2];
768: final double array[] = new double[numRows];
769: array[0] = Math.sqrt(diag[0]);
770: for (int i = 1; i < numRows; i++)
771: array[i] = Math.sqrt(diag[i]);
772: lu[0] = new DoubleDiagonalMatrix(array);
773: lu[1] = lu[0];
774: return lu;
775: }
776:
777: // QR DECOMPOSITION
778:
779: /**
780: * Returns the QR decomposition of this matrix.
781: * @return an array with [0] containing the Q-matrix and [1] containing the R-matrix.
782: * @jsci.planetmath QRDecomposition
783: */
784: public AbstractDoubleSquareMatrix[] qrDecompose() {
785: final AbstractDoubleSquareMatrix qr[] = new AbstractDoubleSquareMatrix[2];
786: qr[0] = DoubleDiagonalMatrix.identity(numRows);
787: qr[1] = (AbstractDoubleSquareMatrix) this .toDoubleMatrix();
788: return qr;
789: }
790:
791: // SINGULAR VALUE DECOMPOSITION
792:
793: /**
794: * Returns the singular value decomposition of this matrix.
795: * @return an array with [0] containing the U-matrix, [1] containing the S-matrix and [2] containing the V-matrix.
796: */
797: public AbstractDoubleSquareMatrix[] singularValueDecompose() {
798: final int N = numRows;
799: final int Nm1 = N - 1;
800: final double arrayU[] = new double[N];
801: final double arrayS[] = new double[N];
802: final double arrayV[] = new double[N];
803: for (int i = 0; i < Nm1; i++) {
804: arrayU[i] = -1.0;
805: arrayS[i] = Math.abs(diag[i]);
806: arrayV[i] = diag[i] < 0.0 ? 1.0 : -1.0;
807: }
808: arrayU[Nm1] = 1.0;
809: arrayS[Nm1] = Math.abs(diag[Nm1]);
810: arrayV[Nm1] = diag[Nm1] < 0.0 ? -1.0 : 1.0;
811: final AbstractDoubleSquareMatrix svd[] = new AbstractDoubleSquareMatrix[3];
812: svd[0] = new DoubleDiagonalMatrix(arrayU);
813: svd[1] = new DoubleDiagonalMatrix(arrayS);
814: svd[2] = new DoubleDiagonalMatrix(arrayV);
815: return svd;
816: }
817:
818: }
|