KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > maths > matrices > DoubleDiagonalMatrix


1 /* AUTO-GENERATED */
2 package JSci.maths.matrices;
3
4 import JSci.maths.ExtraMath;
5 import JSci.maths.Mapping;
6 import JSci.maths.DimensionException;
7 import JSci.maths.MaximumIterationsExceededException;
8 import JSci.maths.vectors.AbstractDoubleVector;
9 import JSci.maths.vectors.DoubleVector;
10 import JSci.maths.groups.AbelianGroup;
11 import JSci.maths.algebras.*;
12 import JSci.maths.fields.*;
13
14 /**
15 * The DoubleDiagonalMatrix class provides an object for encapsulating double diagonal matrices.
16 * @version 2.2
17 * @author Mark Hale
18 */

19 public class DoubleDiagonalMatrix extends AbstractDoubleSquareMatrix implements DiagonalMatrix {
20         /**
21         * Diagonal data.
22         */

23         protected final double diag[];
24         /**
25         * Constructs an empty matrix.
26         * @param size the number of rows/columns
27         */

28         public DoubleDiagonalMatrix(final int size) {
29                 this(new double[size]);
30         }
31         /**
32         * Constructs a matrix from an array.
33         * Any non-diagonal elements in the array are ignored.
34         * @param array an assigned value
35         * @exception MatrixDimensionException If the array is not square.
36         */

37         public DoubleDiagonalMatrix(final double array[][]) {
38                 this(array.length);
39                 for(int i=0;i<array.length;i++) {
40                         if(array[i].length != array.length)
41                                 throw new MatrixDimensionException("Array is not square.");
42                         diag[i]=array[i][i];
43                 }
44         }
45         /**
46         * Constructs a matrix by wrapping an array containing the diagonal elements.
47         * @param array an assigned value
48         */

49         public DoubleDiagonalMatrix(final double array[]) {
50                 super(array.length);
51                 diag=array;
52         }
53         /**
54         * Creates an identity matrix.
55         * @param size the number of rows/columns
56         */

57         public static DoubleDiagonalMatrix identity(final int size) {
58                 double array[]=new double[size];
59                 for(int i=0;i<size;i++)
60                         array[i]=1;
61                 return new DoubleDiagonalMatrix(array);
62         }
63         /**
64         * Compares two ${nativeTyp} matrices for equality.
65         * @param m a double matrix
66         */

67         public boolean equals(AbstractDoubleMatrix m, double tol) {
68                 if(m instanceof DiagonalMatrix) {
69                         if(numRows != m.rows() || numCols != m.columns())
70                                 return false;
71             double sumSqr = 0;
72             double delta = diag[0] - m.getElement(0,0);
73             sumSqr += delta*delta;
74                         for(int i=1;i<numRows;i++) {
75                 delta = diag[i] - m.getElement(i,i);
76                 sumSqr += delta*delta;
77                         }
78                         return (sumSqr <= tol*tol);
79                 } else {
80                         return false;
81                 }
82         }
83         /**
84         * Returns a string representing this matrix.
85         */

86         public String JavaDoc toString() {
87                 final StringBuffer JavaDoc buf=new StringBuffer JavaDoc(5*numRows*numCols);
88                 for(int i=0;i<numRows;i++) {
89                         for(int j=0;j<numCols;j++) {
90                                 buf.append(getElement(i,j));
91                                 buf.append(' ');
92                         }
93                         buf.append('\n');
94                 }
95                 return buf.toString();
96         }
97         /**
98         * Converts this matrix to an integer matrix.
99         * @return an integer matrix
100         */

101         public AbstractIntegerMatrix toIntegerMatrix() {
102                 final int array[]=new int[numRows];
103                 for(int i=0;i<numRows;i++)
104                         array[i]=Math.round((float)diag[i]);
105                 return new IntegerDiagonalMatrix(array);
106         }
107         /**
108         * Converts this matrix to a complex matrix.
109         * @return a complex matrix
110         */

111         public AbstractComplexMatrix toComplexMatrix() {
112                 final double array[]=new double[numRows];
113                 for(int i=0;i<numRows;i++)
114                         array[i]=diag[i];
115                 return new ComplexDiagonalMatrix(array,new double[numRows]);
116         }
117         /**
118         * Returns an element of the matrix.
119         * @param i row index of the element
120         * @param j column index of the element
121         * @exception MatrixDimensionException If attempting to access an invalid element.
122         */

123         public double getElement(int i, int j) {
124                 if(i>=0 && i<numRows && j>=0 && j<numCols) {
125                         if(i == j)
126                                 return diag[i];
127                         else
128                                 return 0;
129                 } else
130                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
131         }
132         /**
133         * Sets the value of an element of the matrix.
134         * Should only be used to initialise this matrix.
135         * @param i row index of the element
136         * @param j column index of the element
137         * @param x a number
138         * @exception MatrixDimensionException If attempting to access an invalid element.
139         */

140         public void setElement(int i, int j, final double x) {
141                 if(i>=0 && i<numRows && j>=0 && j<numCols) {
142                         if(i == j)
143                                 diag[i] = x;
144                         else
145                                 throw new MatrixDimensionException(getInvalidElementMsg(i,j));
146                 } else
147                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
148         }
149         /**
150         * Returns true if this matrix is symmetric.
151         */

152         public boolean isSymmetric() {
153                 return true;
154         }
155         /**
156         * Returns the determinant.
157         */

158         public double det() {
159                 double det=diag[0];
160                 for(int i=1;i<numRows;i++)
161                         det*=diag[i];
162                 return det;
163         }
164         /**
165         * Returns the trace.
166         */

167         public double trace() {
168                 double tr=diag[0];
169                 for(int i=1;i<numRows;i++)
170                         tr+=diag[i];
171                 return tr;
172         }
173         /**
174         * Returns the l<sup><img border=0 alt="infinity" SRC="doc-files/infinity.gif"></sup>-norm.
175         * @author Taber Smith
176         */

177         public double infNorm() {
178                 double result=Math.abs(diag[0]);
179                 double tmpResult;
180                 for(int i=1;i<numRows;i++) {
181                         tmpResult=Math.abs(diag[i]);
182                         if(tmpResult>result)
183                                 result=tmpResult;
184                 }
185                 return result;
186         }
187         /**
188         * Returns the Frobenius (l<sup>2</sup>) norm.
189         * @author Taber Smith
190         */

191         public double frobeniusNorm() {
192                 double result=diag[0];
193                 for(int i=1;i<numRows;i++)
194                         result=ExtraMath.hypot(result,diag[i]);
195                 return result;
196         }
197         /**
198         * Returns the operator norm.
199         * @exception MaximumIterationsExceededException If it takes more than 50 iterations to determine an eigenvalue.
200         */

201         public double operatorNorm() throws MaximumIterationsExceededException {
202                 return infNorm();
203         }
204
205 //============
206
// OPERATIONS
207
//============
208

209 // ADDITION
210

211         /**
212         * Returns the addition of this matrix and another.
213         * @param m a double matrix
214         * @exception MatrixDimensionException If the matrices are different sizes.
215         */

216         public AbstractDoubleSquareMatrix add(final AbstractDoubleSquareMatrix m) {
217                 if(m instanceof DoubleDiagonalMatrix)
218                         return add((DoubleDiagonalMatrix)m);
219                 if(m instanceof DiagonalMatrix)
220                         return addDiagonal(m);
221                 if(m instanceof DoubleTridiagonalMatrix)
222                         return add((DoubleTridiagonalMatrix)m);
223                 if(m instanceof TridiagonalMatrix)
224                         return addTridiagonal(m);
225                 if(m instanceof DoubleSquareMatrix)
226                         return add((DoubleSquareMatrix)m);
227
228                 if(numRows==m.rows() && numCols==m.columns()) {
229                         final double array[][]=new double[numRows][numCols];
230                         for(int i=0;i<numRows;i++) {
231                                 array[i][0]=m.getElement(i,0);
232                                 for(int j=1;j<numCols;j++)
233                                         array[i][j]=m.getElement(i,j);
234                         }
235                         for(int i=0; i<numRows; i++)
236                                 array[i][i] += diag[i];
237                         return new DoubleSquareMatrix(array);
238                 } else {
239                         throw new MatrixDimensionException("Matrices are different sizes.");
240                 }
241         }
242         public DoubleSquareMatrix add(final DoubleSquareMatrix m) {
243                 if(numRows==m.numRows && numCols==m.numCols) {
244                         final double array[][]=new double[numRows][numCols];
245                         for(int i=0;i<numRows;i++)
246                                 System.arraycopy(m.matrix[i],0,array[i],0,numRows);
247                         for(int i=0; i<numRows; i++)
248                                 array[i][i] += diag[i];
249                         return new DoubleSquareMatrix(array);
250                 } else
251                         throw new MatrixDimensionException("Matrices are different sizes.");
252         }
253         /**
254         * Returns the addition of this matrix and another.
255         * @param m a double tridiagonal matrix
256         * @exception MatrixDimensionException If the matrices are different sizes.
257         */

258         public DoubleTridiagonalMatrix add(final DoubleTridiagonalMatrix m) {
259                 if(numRows==m.numRows) {
260                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(numRows);
261                         System.arraycopy(m.ldiag,0,ans.ldiag,0,m.ldiag.length);
262                         System.arraycopy(m.udiag,0,ans.udiag,0,m.udiag.length);
263                         ans.diag[0]=diag[0]+m.diag[0];
264                         for(int i=1;i<numRows;i++)
265                                 ans.diag[i]=diag[i]+m.diag[i];
266                         return ans;
267                 } else
268                         throw new MatrixDimensionException("Matrices are different sizes.");
269         }
270         private DoubleTridiagonalMatrix addTridiagonal(final AbstractDoubleSquareMatrix m) {
271                 int mRow=numRows;
272                 if(mRow==m.rows()) {
273                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(mRow);
274                         ans.diag[0]=diag[0]+m.getElement(0,0);
275                         ans.udiag[0]=m.getElement(0,1);
276                         mRow--;
277                         for(int i=1;i<mRow;i++) {
278                                 ans.ldiag[i]=m.getElement(i,i-1);
279                                 ans.diag[i]=diag[i]+m.getElement(i,i);
280                                 ans.udiag[i]=m.getElement(i,i+1);
281                         }
282                         ans.ldiag[mRow]=m.getElement(mRow,mRow-1);
283                         ans.diag[mRow]=diag[mRow]+m.getElement(mRow,mRow);
284                         return ans;
285                 } else {
286                         throw new MatrixDimensionException("Matrices are different sizes.");
287                 }
288         }
289         /**
290         * Returns the addition of this matrix and another.
291         * @param m a double diagonal matrix
292         * @exception MatrixDimensionException If the matrices are different sizes.
293         */

294         public DoubleDiagonalMatrix add(final DoubleDiagonalMatrix m) {
295                 if(numRows==m.numRows) {
296                         final double array[]=new double[numRows];
297                         array[0]=diag[0]+m.diag[0];
298                         for(int i=1;i<numRows;i++)
299                                 array[i]=diag[i]+m.diag[i];
300                         return new DoubleDiagonalMatrix(array);
301                 } else
302                         throw new MatrixDimensionException("Matrices are different sizes.");
303         }
304         private DoubleDiagonalMatrix addDiagonal(final AbstractDoubleSquareMatrix m) {
305                 if(numRows==m.numRows) {
306                         final double array[]=new double[numRows];
307                         array[0]=diag[0]+m.getElement(0,0);
308                         for(int i=1;i<numRows;i++)
309                                 array[i]=diag[i]+m.getElement(i,i);
310                         return new DoubleDiagonalMatrix(array);
311                 } else
312                         throw new MatrixDimensionException("Matrices are different sizes.");
313         }
314
315 // SUBTRACTION
316

317         /**
318         * Returns the subtraction of this matrix by another.
319         * @param m a double matrix
320         * @exception MatrixDimensionException If the matrices are different sizes.
321         */

322         public AbstractDoubleSquareMatrix subtract(final AbstractDoubleSquareMatrix m) {
323                 if(m instanceof DoubleDiagonalMatrix)
324                         return subtract((DoubleDiagonalMatrix)m);
325                 if(m instanceof DiagonalMatrix)
326                         return subtractDiagonal(m);
327                 if(m instanceof DoubleTridiagonalMatrix)
328                         return subtract((DoubleTridiagonalMatrix)m);
329                 if(m instanceof TridiagonalMatrix)
330                         return subtractTridiagonal(m);
331                 if(m instanceof DoubleSquareMatrix)
332                         return subtract((DoubleSquareMatrix)m);
333
334                 if(numRows==m.rows() && numCols==m.columns()) {
335                         final double array[][]=new double[numRows][numCols];
336                         for(int i=0;i<numRows;i++) {
337                                 array[i][0] = -m.getElement(i,0);
338                                 for(int j=1;j<numCols;j++)
339                                         array[i][j] = -m.getElement(i,j);
340                         }
341                         for(int i=0; i<numRows; i++)
342                                 array[i][i] += diag[i];
343                         return new DoubleSquareMatrix(array);
344                 } else {
345                         throw new MatrixDimensionException("Matrices are different sizes.");
346                 }
347         }
348         public DoubleSquareMatrix subtract(final DoubleSquareMatrix m) {
349                 if(numRows==m.numRows && numCols==m.numCols) {
350                         final double array[][]=new double[numRows][numCols];
351                         for(int i=0;i<numRows;i++) {
352                                 array[i][0] = -m.matrix[i][0];
353                                 for(int j=1;j<numCols;j++)
354                                         array[i][j] = -m.matrix[i][j];
355                         }
356                         for(int i=0; i<numRows; i++)
357                                 array[i][i] += diag[i];
358                         return new DoubleSquareMatrix(array);
359                 } else
360                         throw new MatrixDimensionException("Matrices are different sizes.");
361         }
362         /**
363         * Returns the subtraction of this matrix and another.
364         * @param m a double tridiagonal matrix
365         * @exception MatrixDimensionException If the matrices are different sizes.
366         */

367         public DoubleTridiagonalMatrix subtract(final DoubleTridiagonalMatrix m) {
368                 int mRow=numRows;
369                 if(mRow==m.numRows) {
370                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(mRow);
371                         ans.diag[0]=diag[0]-m.diag[0];
372                         ans.udiag[0]=-m.udiag[0];
373                         mRow--;
374                         for(int i=1;i<mRow;i++) {
375                                 ans.ldiag[i]=-m.ldiag[i];
376                                 ans.diag[i]=diag[i]-m.diag[i];
377                                 ans.udiag[i]=-m.udiag[i];
378                         }
379                         ans.ldiag[mRow]=-m.ldiag[mRow];
380                         ans.diag[mRow]=diag[mRow]-m.diag[mRow];
381                         return ans;
382                 } else
383                         throw new MatrixDimensionException("Matrices are different sizes.");
384         }
385         private DoubleTridiagonalMatrix subtractTridiagonal(final AbstractDoubleSquareMatrix m) {
386                 int mRow=numRows;
387                 if(mRow==m.rows()) {
388                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(mRow);
389                         ans.diag[0]=diag[0]-m.getElement(0,0);
390                         ans.udiag[0]=-m.getElement(0,1);
391                         mRow--;
392                         for(int i=1;i<mRow;i++) {
393                                 ans.ldiag[i]=-m.getElement(i,i-1);
394                                 ans.diag[i]=diag[i]-m.getElement(i,i);
395                                 ans.udiag[i]=-m.getElement(i,i+1);
396                         }
397                         ans.ldiag[mRow]=-m.getElement(mRow,mRow-1);
398                         ans.diag[mRow]=diag[mRow]-m.getElement(mRow,mRow);
399                         return ans;
400                 } else {
401                         throw new MatrixDimensionException("Matrices are different sizes.");
402                 }
403         }
404         /**
405         * Returns the subtraction of this matrix and another.
406         * @param m a double diagonal matrix
407         * @exception MatrixDimensionException If the matrices are different sizes.
408         */

409         public DoubleDiagonalMatrix subtract(final DoubleDiagonalMatrix m) {
410                 if(numRows==m.numRows) {
411                         final double array[]=new double[numRows];
412                         array[0]=diag[0]-m.diag[0];
413                         for(int i=1;i<numRows;i++)
414                                 array[i]=diag[i]-m.diag[i];
415                         return new DoubleDiagonalMatrix(array);
416                 } else
417                         throw new MatrixDimensionException("Matrices are different sizes.");
418         }
419         private DoubleDiagonalMatrix subtractDiagonal(final AbstractDoubleSquareMatrix m) {
420                 if(numRows==m.numRows) {
421                         final double array[]=new double[numRows];
422                         array[0]=diag[0]-m.getElement(0,0);
423                         for(int i=1;i<numRows;i++)
424                                 array[i]=diag[i]-m.getElement(i,i);
425                         return new DoubleDiagonalMatrix(array);
426                 } else
427                         throw new MatrixDimensionException("Matrices are different sizes.");
428         }
429
430 // SCALAR MULTIPLICATION
431

432         /**
433         * Returns the multiplication of this matrix by a scalar.
434         * @param x a double.
435         * @return a double diagonal matrix.
436         */

437         public AbstractDoubleMatrix scalarMultiply(final double x) {
438                 final double array[]=new double[numRows];
439                 array[0] = x*diag[0];
440                 for(int i=1;i<numRows;i++)
441                         array[i] = x*diag[i];
442                 return new DoubleDiagonalMatrix(array);
443         }
444
445 // SCALAR DIVISON
446

447         /**
448         * Returns the division of this matrix by a scalar.
449         * @param x a double.
450         * @return a double diagonal matrix.
451         */

452         public AbstractDoubleMatrix scalarDivide(final double x) {
453                 final double array[]=new double[numRows];
454                 array[0] = diag[0]/x;
455                 for(int i=1;i<numRows;i++)
456                         array[i] = diag[i]/x;
457                 return new DoubleDiagonalMatrix(array);
458         }
459
460 // SCALAR PRODUCT
461

462         /**
463         * Returns the scalar product of this matrix and another.
464         * @param m a double matrix.
465         * @exception MatrixDimensionException If the matrices are different sizes.
466         */

467         public double scalarProduct(final AbstractDoubleSquareMatrix m) {
468                 if(m instanceof DoubleDiagonalMatrix)
469                         return scalarProduct((DoubleDiagonalMatrix)m);
470                 if(m instanceof DoubleTridiagonalMatrix)
471                         return scalarProduct((DoubleTridiagonalMatrix)m);
472                 if(m instanceof DoubleSquareMatrix)
473                         return scalarProduct((DoubleSquareMatrix)m);
474
475                 if(numRows==m.rows() && numCols==m.columns()) {
476                         double ans = diag[0]*m.getElement(0,0);
477                         for(int i=1;i<numRows;i++)
478                                 ans += diag[i]*m.getElement(i,i);
479                         return ans;
480                 } else {
481                        throw new MatrixDimensionException("Matrices are different sizes.");
482                 }
483         }
484         public double scalarProduct(final DoubleSquareMatrix m) {
485                 if(numRows==m.numRows && numCols==m.numCols) {
486                         double ans = diag[0]*m.matrix[0][0];
487                         for(int i=1;i<numRows;i++)
488                                 ans += diag[i]*m.matrix[i][i];
489                         return ans;
490                 } else
491                         throw new MatrixDimensionException("Matrices are different sizes.");
492         }
493         public double scalarProduct(final DoubleTridiagonalMatrix m) {
494                 if(numRows==m.numRows) {
495                         double ans = diag[0]*m.diag[0];
496                         for(int i=1;i<numRows;i++)
497                                 ans += diag[i]*m.diag[i];
498                         return ans;
499                 } else
500                         throw new MatrixDimensionException("Matrices are different sizes.");
501         }
502         public double scalarProduct(final DoubleDiagonalMatrix m) {
503                 if(numRows==m.numRows) {
504                         double ans = diag[0]*m.diag[0];
505                         for(int i=1;i<numRows;i++)
506                                 ans += diag[i]*m.diag[i];
507                         return ans;
508                 } else
509                         throw new MatrixDimensionException("Matrices are different sizes.");
510         }
511
512 // MATRIX MULTIPLICATION
513

514         /**
515         * Returns the multiplication of a vector by this matrix.
516         * @param v a double vector.
517         * @exception DimensionException If the matrix and vector are incompatible.
518         */

519         public AbstractDoubleVector multiply(final AbstractDoubleVector v) {
520                 if(numCols==v.dimension()) {
521                         final double array[]=new double[numRows];
522                         array[0]=diag[0]*v.getComponent(0);
523                         for(int i=1;i<numRows;i++)
524                                 array[i]=diag[i]*v.getComponent(i);
525                         return new DoubleVector(array);
526                 } else {
527                         throw new DimensionException("Matrix and vector are incompatible.");
528                 }
529         }
530         /**
531         * Returns the multiplication of this matrix and another.
532         * @param m a double matrix
533         * @return a AbstractDoubleMatrix or a AbstractDoubleSquareMatrix as appropriate
534         * @exception MatrixDimensionException If the matrices are incompatible.
535         */

536         public AbstractDoubleSquareMatrix multiply(final AbstractDoubleSquareMatrix m) {
537                 if(m instanceof DoubleDiagonalMatrix)
538                         return multiply((DoubleDiagonalMatrix)m);
539                 if(m instanceof DiagonalMatrix)
540                         return multiplyDiagonal(m);
541                 if(m instanceof DoubleTridiagonalMatrix)
542                         return multiply((DoubleTridiagonalMatrix)m);
543                 if(m instanceof TridiagonalMatrix)
544                         return multiplyTridiagonal(m);
545                 if(m instanceof DoubleSquareMatrix)
546                         return multiply((DoubleSquareMatrix)m);
547
548                 if(numCols==m.rows()) {
549                         final int mColumns = m.columns();
550                         final double array[][]=new double[numRows][mColumns];
551                         for(int i=0; i<numRows; i++) {
552                                 array[i][0]=diag[0]*m.getElement(i,0);
553                                 for(int j=1; j<mColumns; j++)
554                                         array[i][j]=diag[i]*m.getElement(i,j);
555                         }
556                         return new DoubleSquareMatrix(array);
557                 } else {
558                         throw new MatrixDimensionException("Incompatible matrices.");
559                 }
560         }
561         public DoubleSquareMatrix multiply(final DoubleSquareMatrix m) {
562                 if(numCols==m.numRows) {
563                         final double array[][]=new double[numRows][m.numCols];
564                         for(int i=0; i<numRows; i++) {
565                                 array[i][0]=diag[0]*m.matrix[i][0];
566                                 for(int j=1; j<m.numCols; j++)
567                                         array[i][j]=diag[i]*m.matrix[i][j];
568                         }
569                         return new DoubleSquareMatrix(array);
570                 } else
571                         throw new MatrixDimensionException("Incompatible matrices.");
572         }
573         public DoubleTridiagonalMatrix multiply(final DoubleTridiagonalMatrix m) {
574                 int mRow=numRows;
575                 if(numCols==m.numRows) {
576                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(mRow);
577                         ans.diag[0]=diag[0]*m.diag[0];
578                         ans.udiag[0]=diag[0]*m.udiag[0];
579                         mRow--;
580                         for(int i=1;i<mRow;i++) {
581                                 ans.ldiag[i]=diag[i]*m.ldiag[i];
582                                 ans.diag[i]=diag[i]*m.diag[i];
583                                 ans.udiag[i]=diag[i]*m.udiag[i];
584                         }
585                         ans.ldiag[mRow]=diag[mRow]*m.ldiag[mRow];
586                         ans.diag[mRow]=diag[mRow]*m.diag[mRow];
587                         return ans;
588                 } else
589                         throw new MatrixDimensionException("Incompatible matrices.");
590         }
591         private DoubleTridiagonalMatrix multiplyTridiagonal(final AbstractDoubleSquareMatrix m) {
592                 int mRow=numRows;
593                 if(numCols==m.rows()) {
594                         final DoubleTridiagonalMatrix ans=new DoubleTridiagonalMatrix(mRow);
595                         ans.diag[0]=diag[0]*m.getElement(0,0);
596                         ans.udiag[0]=diag[0]*m.getElement(0,1);
597                         mRow--;
598                         for(int i=1;i<mRow;i++) {
599                                 ans.ldiag[i]=diag[i]*m.getElement(i,i-1);
600                                 ans.diag[i]=diag[i]*m.getElement(i,i);
601                                 ans.udiag[i]=diag[i]*m.getElement(i,i+1);
602                         }
603                         ans.ldiag[mRow]=diag[mRow]*m.getElement(mRow,mRow-1);
604                         ans.diag[mRow]=diag[mRow]*m.getElement(mRow,mRow);
605                         return ans;
606                 } else {
607                         throw new MatrixDimensionException("Incompatible matrices.");
608                 }
609         }
610         public DoubleDiagonalMatrix multiply(final DoubleDiagonalMatrix m) {
611                 if(numCols==m.numRows) {
612                         final double array[]=new double[numRows];
613                         array[0]=diag[0]*m.diag[0];
614                         for(int i=1;i<numRows;i++) {
615                                 array[i]=diag[i]*m.diag[i];
616                         }
617                         return new DoubleDiagonalMatrix(array);
618                 } else
619                         throw new MatrixDimensionException("Incompatible matrices.");
620         }
621         private DoubleDiagonalMatrix multiplyDiagonal(final AbstractDoubleSquareMatrix m) {
622                 if(numCols==m.rows()) {
623                         final double array[]=new double[numRows];
624                         array[0]=diag[0]*m.getElement(0,0);
625                         for(int i=1;i<numRows;i++) {
626                                 array[i]=diag[i]*m.getElement(i,i);
627                         }
628                         return new DoubleDiagonalMatrix(array);
629                 } else {
630                         throw new MatrixDimensionException("Incompatible matrices.");
631                 }
632         }
633
634 // TRANSPOSE
635

636         /**
637         * Returns the transpose of this matrix.
638         * @return a double matrix
639         */

640         public Matrix transpose() {
641                 return this;
642         }
643
644 // INVERSE
645

646         /**
647         * Returns the inverse of this matrix.
648         * @return a double diagonal matrix
649         */

650         public AbstractDoubleSquareMatrix inverse() {
651                 final double array[]=new double[numRows];
652                 array[0]=1.0/diag[0];
653                 for(int i=1;i<numRows;i++)
654                         array[i]=1.0/diag[i];
655                 return new DoubleDiagonalMatrix(array);
656         }
657
658 // LU DECOMPOSITION
659

660         /**
661         * Returns the LU decomposition of this matrix.
662         * @param pivot an empty array of length <code>rows()+1</code>
663         * to hold the pivot information (null if not interested).
664         * The last array element will contain the parity.
665         * @return an array with [0] containing the L-matrix
666         * and [1] containing the U-matrix.
667         */

668         public AbstractDoubleSquareMatrix[] luDecompose(int pivot[]) {
669                 if(LU!=null) {
670                         if(pivot!=null)
671                                 System.arraycopy(LUpivot,0,pivot,0,pivot.length);
672                         return LU;
673                 }
674                 if(pivot==null)
675                         pivot=new int[numRows+1];
676                 for(int i=0;i<numRows;i++)
677                         pivot[i]=i;
678                 pivot[numRows]=1;
679                 LU=new AbstractDoubleSquareMatrix[2];
680                 LU[0]=DoubleDiagonalMatrix.identity(numRows);
681                 LU[1]=this;
682                 LUpivot=new int[pivot.length];
683                 System.arraycopy(pivot,0,LUpivot,0,pivot.length);
684                 return LU;
685         }
686         /**
687         * Returns the LU decomposition of this matrix.
688         * @return an array with [0] containing the L-matrix
689         * and [1] containing the U-matrix.
690         * @jsci.planetmath LUDecomposition
691         */

692         public AbstractDoubleSquareMatrix[] luDecompose() {
693                 return luDecompose(null);
694         }
695
696 // CHOLESKY DECOMPOSITION
697

698         /**
699         * Returns the Cholesky decomposition of this matrix.
700         * Matrix must be symmetric and positive definite.
701         * @return an array with [0] containing the L-matrix and [1] containing the U-matrix.
702         */

703         public AbstractDoubleSquareMatrix[] choleskyDecompose() {
704                 final AbstractDoubleSquareMatrix lu[]=new AbstractDoubleSquareMatrix[2];
705                 final double array[]=new double[numRows];
706                 array[0]=Math.sqrt(diag[0]);
707                 for(int i=1;i<numRows;i++)
708                         array[i]=Math.sqrt(diag[i]);
709                 lu[0]=new DoubleDiagonalMatrix(array);
710                 lu[1]=lu[0];
711                 return lu;
712         }
713
714 // QR DECOMPOSITION
715

716         /**
717         * Returns the QR decomposition of this matrix.
718         * @return an array with [0] containing the Q-matrix and [1] containing the R-matrix.
719         * @jsci.planetmath QRDecomposition
720         */

721         public AbstractDoubleSquareMatrix[] qrDecompose() {
722                 final AbstractDoubleSquareMatrix qr[]=new AbstractDoubleSquareMatrix[2];
723                 qr[0]=DoubleDiagonalMatrix.identity(numRows);
724                 qr[1]=this;
725                 return qr;
726         }
727
728 // SINGULAR VALUE DECOMPOSITION
729

730         /**
731         * Returns the singular value decomposition of this matrix.
732         * @return an array with [0] containing the U-matrix, [1] containing the S-matrix and [2] containing the V-matrix.
733         */

734         public AbstractDoubleSquareMatrix[] singularValueDecompose() {
735                 final int N=numRows;
736                 final int Nm1=N-1;
737                 final double arrayU[]=new double[N];
738                 final double arrayS[]=new double[N];
739                 final double arrayV[]=new double[N];
740                 for(int i=0;i<Nm1;i++) {
741                         arrayU[i]=-1.0;
742                         arrayS[i]=Math.abs(diag[i]);
743                         arrayV[i]=diag[i]<0.0 ? 1.0 : -1.0;
744                 }
745                 arrayU[Nm1]=1.0;
746                 arrayS[Nm1]=Math.abs(diag[Nm1]);
747                 arrayV[Nm1]=diag[Nm1]<0.0 ? -1.0 : 1.0;
748                 final AbstractDoubleSquareMatrix svd[]=new AbstractDoubleSquareMatrix[3];
749                 svd[0]=new DoubleDiagonalMatrix(arrayU);
750                 svd[1]=new DoubleDiagonalMatrix(arrayS);
751                 svd[2]=new DoubleDiagonalMatrix(arrayV);
752                 return svd;
753         }
754
755 // MAP ELEMENTS
756

757         /**
758         * Applies a function on all the matrix elements.
759         * @param f a user-defined function
760         * @return a double matrix
761         */

762         public AbstractDoubleMatrix mapElements(final Mapping f) {
763         double zeroValue = f.map(0.0);
764         if(Math.abs(zeroValue) <= JSci.GlobalSettings.ZERO_TOL)
765             return diagonalMap(f);
766         else
767             return generalMap(f, zeroValue);
768     }
769     private AbstractDoubleMatrix diagonalMap(Mapping f) {
770                 final double array[]=new double[numRows];
771                 array[0]=f.map(diag[0]);
772                 for(int i=1;i<numRows;i++)
773                         array[i]=f.map(diag[i]);
774                 return new DoubleDiagonalMatrix(array);
775         }
776     private AbstractDoubleMatrix generalMap(Mapping f, double zeroValue) {
777                 final double array[][]=new double[numRows][numRows];
778         for(int i=0; i<numRows; i++) {
779             for(int j=0; j<numRows; j++) {
780                 array[i][j] = zeroValue;
781             }
782         }
783                 array[0][0]=f.map(diag[0]);
784                 for(int i=1;i<numRows;i++)
785                         array[i][i]=f.map(diag[i]);
786                 return new DoubleSquareMatrix(array);
787         }
788 }
789
Popular Tags