KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* AUTO-GENERATED */
2 package JSci.maths.matrices;
3
4 import JSci.maths.Complex;
5 import JSci.maths.ComplexMapping;
6 import JSci.maths.DimensionException;
7 import JSci.maths.vectors.AbstractComplexVector;
8 import JSci.maths.vectors.ComplexVector;
9
10 /**
11 * The ComplexDiagonalMatrix class provides an object for encapsulating diagonal matrices containing complex numbers.
12 * Uses compressed diagonal storage.
13 * @version 2.2
14 * @author Mark Hale
15 */

16 public class ComplexDiagonalMatrix extends AbstractComplexSquareMatrix implements DiagonalMatrix {
17         /**
18         * Arrays containing the elements of the matrix.
19         */

20         protected final double diagRe[],diagIm[];
21         /**
22         * Constructs a matrix by wrapping two arrays containing the diagonal elements.
23         * @param arrayRe an array of real values
24         * @param arrayIm an array of imaginary values
25         */

26         public ComplexDiagonalMatrix(final double arrayRe[],final double arrayIm[]) {
27                 super(arrayRe.length);
28                 diagRe=arrayRe;
29                 diagIm=arrayIm;
30         }
31         /**
32         * Constructs an empty matrix.
33         * @param size the number of rows/columns
34         */

35         public ComplexDiagonalMatrix(final int size) {
36                 this(new double[size], new double[size]);
37         }
38         /**
39         * Constructs a matrix from an array.
40         * @param array an assigned value
41         * @exception MatrixDimensionException If the array is not square.
42         */

43         public ComplexDiagonalMatrix(final Complex array[][]) {
44                 this(array.length);
45                 for(int i=0;i<numRows;i++) {
46                         if(array[i].length != array.length)
47                                 throw new MatrixDimensionException("Array is not square.");
48                         diagRe[i]=array[i][i].real();
49                         diagIm[i]=array[i][i].imag();
50                 }
51         }
52         /**
53         * Constructs a matrix from an array containing the diagonal elements.
54         * @param array an assigned value
55         */

56         public ComplexDiagonalMatrix(final Complex array[]) {
57                 this(array.length);
58                 diagRe[0]=array[0].real();
59                 diagIm[0]=array[0].imag();
60                 for(int i=1;i<array.length;i++) {
61                         diagRe[i]=array[i].real();
62                         diagIm[i]=array[i].imag();
63                 }
64         }
65         /**
66         * Creates an identity matrix.
67         * @param size the number of rows/columns
68         */

69         public static ComplexDiagonalMatrix identity(final int size) {
70                 final double arrayRe[]=new double[size];
71                 final double arrayIm[]=new double[size];
72                 for(int i=0;i<size;i++)
73                         arrayRe[i]=1.0;
74                 return new ComplexDiagonalMatrix(arrayRe,arrayIm);
75         }
76         /**
77         * Compares two complex diagonal matrices for equality.
78         * @param m a complex diagonal matrix
79         */

80         public boolean equals(AbstractComplexMatrix m, double tol) {
81                 if(m instanceof DiagonalMatrix) {
82                         if(numRows != m.rows() || numCols != m.columns())
83                                 return false;
84             double sumSqr = 0;
85             double deltaRe = diagRe[0] - m.getRealElement(0,0);
86             double deltaIm = diagIm[0] - m.getImagElement(0,0);
87             sumSqr += deltaRe*deltaRe+deltaIm*deltaIm;
88                         for(int i=1;i<numRows;i++) {
89                 deltaRe = diagRe[i] - m.getRealElement(i,i);
90                 deltaIm = diagIm[i] - m.getImagElement(i,i);
91                 sumSqr += deltaRe*deltaRe+deltaIm*deltaIm;
92                         }
93                         return (sumSqr <= tol*tol);
94                 } else {
95                         return super.equals(m);
96                 }
97         }
98         /**
99         * Returns the real part of this complex matrix.
100         * @return a double diagonal matrix
101         */

102         public AbstractDoubleMatrix real() {
103                 return new DoubleDiagonalMatrix(diagRe);
104         }
105         /**
106         * Returns the imaginary part of this complex matrix.
107         * @return a double diagonal matrix
108         */

109         public AbstractDoubleMatrix imag() {
110                 return new DoubleDiagonalMatrix(diagIm);
111         }
112         /**
113         * Returns an element of the matrix.
114         * @param i row index of the element
115         * @param j column index of the element
116         * @exception MatrixDimensionException If attempting to access an invalid element.
117         */

118         public Complex getElement(final int i, final int j) {
119                 if(i>=0 && i<numRows && j>=0 && j<numCols) {
120                         if(i==j)
121                                 return new Complex(diagRe[i],diagIm[i]);
122                         else
123                                 return Complex.ZERO;
124                 } else
125                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
126         }
127         public double getRealElement(final int i, final int j) {
128                 if(i>=0 && i<numRows && j>=0 && j<numCols) {
129                         if(i==j)
130                                 return diagRe[i];
131                         else
132                                 return 0.0;
133                 } else
134                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
135         }
136         public double getImagElement(final int i, final int j) {
137                 if(i>=0 && i<numRows && j>=0 && j<numCols) {
138                         if(i==j)
139                                 return diagIm[i];
140                         else
141                                 return 0.0;
142                 } else
143                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
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 z a complex number
151         * @exception MatrixDimensionException If attempting to access an invalid element.
152         */

153         public void setElement(final int i, final int j, final Complex z) {
154                 if(i>=0 && i<numRows && j>=0 && j<numCols && i==j) {
155                         diagRe[i]=z.real();
156                         diagIm[i]=z.imag();
157                 } else
158                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
159         }
160         /**
161         * Sets the value of an element of the matrix.
162         * Should only be used to initialise this matrix.
163         * @param i row index of the element
164         * @param j column index of the element
165         * @param x the real part of a complex number
166         * @param y the imaginary part of a complex number
167         * @exception MatrixDimensionException If attempting to access an invalid element.
168         */

169         public void setElement(final int i, final int j, final double x, final double y) {
170                 if(i>=0 && i<numRows && j>=0 && j<numCols && i==j) {
171                         diagRe[i]=x;
172                         diagIm[i]=y;
173                 } else
174                         throw new MatrixDimensionException(getInvalidElementMsg(i,j));
175         }
176         /**
177         * Returns the determinant.
178         */

179         public Complex det() {
180                 double detRe=diagRe[0];
181                 double detIm=diagIm[0];
182                 for(int i=1;i<numRows;i++) {
183                         double tmp=detRe*diagRe[i]-detIm*diagIm[i];
184                         detIm=detIm*diagRe[i]+detRe*diagIm[i];
185                         detRe=tmp;
186                 }
187                 return new Complex(detRe,detIm);
188         }
189         /**
190         * Returns the trace.
191         */

192         public Complex trace() {
193                 double trRe=diagRe[0];
194                 double trIm=diagIm[0];
195                 for(int i=1;i<numRows;i++) {
196                         trRe+=diagRe[i];
197                         trIm+=diagIm[i];
198                 }
199                 return new Complex(trRe,trIm);
200         }
201         /**
202         * Returns the l<sup><img border=0 alt="infinity" SRC="doc-files/infinity.gif"></sup>-norm.
203         * @author Taber Smith
204         */

205         public double infNorm() {
206                 double result=diagRe[0]*diagRe[0]+diagIm[0]*diagIm[0];
207                 double tmpResult;
208                 for(int i=1;i<numRows;i++) {
209                         tmpResult=diagRe[i]*diagRe[i]+diagIm[i]*diagIm[i];
210                         if(tmpResult>result)
211                                 result=tmpResult;
212                 }
213                 return Math.sqrt(result);
214         }
215         /**
216         * Returns the Frobenius (l<sup>2</sup>) norm.
217         * @author Taber Smith
218         */

219         public double frobeniusNorm() {
220                 double result=diagRe[0]*diagRe[0]+diagIm[0]*diagIm[0];
221                 for(int i=1;i<numRows;i++)
222                         result+=diagRe[i]*diagRe[i]+diagIm[i]*diagIm[i];
223                 return Math.sqrt(result);
224         }
225         /**
226         * Returns the operator norm.
227         */

228         public double operatorNorm() {
229                 return infNorm();
230         }
231
232 //============
233
// OPERATIONS
234
//============
235

236 // ADDITION
237

238         /**
239         * Returns the addition of this matrix and another.
240         * @param m a complex matrix
241         * @exception MatrixDimensionException If the matrices are different sizes.
242         */

243         public AbstractComplexSquareMatrix add(final AbstractComplexSquareMatrix m) {
244                 if(m instanceof ComplexDiagonalMatrix)
245                         return add((ComplexDiagonalMatrix)m);
246                 if(m instanceof ComplexTridiagonalMatrix)
247                         return add((ComplexTridiagonalMatrix)m);
248                 if(m instanceof TridiagonalMatrix)
249                         return addTridiagonal(m);
250                 if(m instanceof ComplexSquareMatrix)
251                         return add((ComplexSquareMatrix)m);
252
253                 if(numRows==m.rows() && numCols==m.columns()) {
254                         final double arrayRe[][]=new double[numRows][numCols];
255                         final double arrayIm[][]=new double[numRows][numCols];
256                         for(int i=0;i<numRows;i++) {
257                                 Complex elem=m.getElement(i,0);
258                                 arrayRe[i][0]=elem.real();
259                                 arrayIm[i][0]=elem.imag();
260                                 for(int j=1;j<numCols;j++) {
261                                         elem=m.getElement(i,j);
262                                         arrayRe[i][j]=elem.real();
263                                         arrayIm[i][j]=elem.imag();
264                                 }
265                         }
266                         for(int i=0;i<numRows;i++) {
267                                 arrayRe[i][i]+=diagRe[i];
268                                 arrayIm[i][i]+=diagIm[i];
269                         }
270                         return new ComplexSquareMatrix(arrayRe,arrayIm);
271                 } else {
272                         throw new MatrixDimensionException("Matrices are different sizes.");
273                 }
274         }
275         public ComplexSquareMatrix add(final ComplexSquareMatrix m) {
276                 if(numRows==m.numRows && numCols==m.numCols) {
277                         final double arrayRe[][]=new double[numRows][numCols];
278                         final double arrayIm[][]=new double[numRows][numCols];
279                         for(int i=0;i<numRows;i++) {
280                                 System.arraycopy(m.matrixRe[i],0,arrayRe[i],0,numCols);
281                                 System.arraycopy(m.matrixIm[i],0,arrayIm[i],0,numCols);
282                         }
283                         for(int i=0;i<numRows;i++) {
284                                 arrayRe[i][i]+=diagRe[i];
285                                 arrayIm[i][i]+=diagIm[i];
286                         }
287                         return new ComplexSquareMatrix(arrayRe,arrayIm);
288                 } else
289                         throw new MatrixDimensionException("Matrices are different sizes.");
290         }
291         /**
292         * Returns the addition of this matrix and another.
293         * @param m a complex tridiagonal matrix
294         * @exception MatrixDimensionException If the matrices are different sizes.
295         */

296         public ComplexTridiagonalMatrix add(final ComplexTridiagonalMatrix m) {
297                 if(numRows==m.numRows) {
298                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(numRows);
299                         System.arraycopy(m.ldiagRe,0,ans.ldiagRe,0,m.ldiagRe.length);
300                         System.arraycopy(m.ldiagIm,0,ans.ldiagIm,0,m.ldiagIm.length);
301                         System.arraycopy(m.udiagRe,0,ans.udiagRe,0,m.udiagRe.length);
302                         System.arraycopy(m.udiagIm,0,ans.udiagIm,0,m.udiagIm.length);
303                         ans.diagRe[0]=diagRe[0]+m.diagRe[0];
304                         ans.diagIm[0]=diagIm[0]+m.diagIm[0];
305                         for(int i=1;i<numRows;i++) {
306                                 ans.diagRe[i]=diagRe[i]+m.diagRe[i];
307                                 ans.diagIm[i]=diagIm[i]+m.diagIm[i];
308                         }
309                         return ans;
310                 } else
311                         throw new MatrixDimensionException("Matrices are different sizes.");
312         }
313         private ComplexTridiagonalMatrix addTridiagonal(final AbstractComplexSquareMatrix m) {
314                 int mRow=numRows;
315                 if(mRow==m.rows()) {
316                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(mRow);
317                         Complex elem=m.getElement(0,0);
318                         ans.diagRe[0]=diagRe[0]+elem.real();
319                         ans.diagIm[0]=diagIm[0]+elem.imag();
320                         elem=m.getElement(0,1);
321                         ans.udiagRe[0]=elem.real();
322                         ans.udiagIm[0]=elem.imag();
323                         mRow--;
324                         for(int i=1;i<mRow;i++) {
325                                 elem=m.getElement(i,i-1);
326                                 ans.ldiagRe[i]=elem.real();
327                                 ans.ldiagIm[i]=elem.imag();
328                                 elem=m.getElement(i,i);
329                                 ans.diagRe[i]=diagRe[i]+elem.real();
330                                 ans.diagIm[i]=diagIm[i]+elem.imag();
331                                 elem=m.getElement(i,i+1);
332                                 ans.udiagRe[i]=elem.real();
333                                 ans.udiagIm[i]=elem.imag();
334                         }
335                         elem=m.getElement(mRow,mRow-1);
336                         ans.ldiagRe[mRow]=elem.real();
337                         ans.ldiagIm[mRow]=elem.imag();
338                         elem=m.getElement(mRow,mRow);
339                         ans.diagRe[mRow]=diagRe[mRow]+elem.real();
340                         ans.diagIm[mRow]=diagIm[mRow]+elem.imag();
341                         return ans;
342                 } else {
343                         throw new MatrixDimensionException("Matrices are different sizes.");
344                 }
345         }
346         /**
347         * Returns the addition of this matrix and another.
348         * @param m a complex diagonal matrix
349         * @exception MatrixDimensionException If the matrices are different sizes.
350         */

351         public ComplexDiagonalMatrix add(final ComplexDiagonalMatrix m) {
352                 if(numRows==m.numRows) {
353                         final double arrayRe[]=new double[numRows];
354                         final double arrayIm[]=new double[numRows];
355                         arrayRe[0]=diagRe[0]+m.diagRe[0];
356                         arrayIm[0]=diagIm[0]+m.diagIm[0];
357                         for(int i=1;i<numRows;i++) {
358                                 arrayRe[i]=diagRe[i]+m.diagRe[i];
359                                 arrayIm[i]=diagIm[i]+m.diagIm[i];
360                         }
361                         return new ComplexDiagonalMatrix(arrayRe,arrayIm);
362                 } else
363                         throw new MatrixDimensionException("Matrices are different sizes.");
364         }
365
366 // SUBTRACTION
367

368         /**
369         * Returns the subtraction of this matrix by another.
370         * @param m a complex matrix
371         * @exception MatrixDimensionException If the matrices are different sizes.
372         */

373         public AbstractComplexSquareMatrix subtract(final AbstractComplexSquareMatrix m) {
374                 if(m instanceof ComplexDiagonalMatrix)
375                         return subtract((ComplexDiagonalMatrix)m);
376                 if(m instanceof ComplexTridiagonalMatrix)
377                         return subtract((ComplexTridiagonalMatrix)m);
378                 if(m instanceof TridiagonalMatrix)
379                         return subtractTridiagonal(m);
380                 if(m instanceof ComplexSquareMatrix)
381                         return subtract((ComplexSquareMatrix)m);
382
383                 if(numRows==m.rows() && numCols==m.columns()) {
384                         final double arrayRe[][]=new double[numRows][numCols];
385                         final double arrayIm[][]=new double[numRows][numCols];
386                         for(int i=0;i<numRows;i++) {
387                                 Complex elem=m.getElement(i,0);
388                                 arrayRe[i][0]=-elem.real();
389                                 arrayIm[i][0]=-elem.imag();
390                                 for(int j=1;j<numCols;j++) {
391                                         elem=m.getElement(i,j);
392                                         arrayRe[i][j]=-elem.real();
393                                         arrayIm[i][j]=-elem.imag();
394                                 }
395                         }
396                         for(int i=0;i<numRows;i++) {
397                                 arrayRe[i][i]+=diagRe[i];
398                                 arrayIm[i][i]+=diagIm[i];
399                         }
400                         return new ComplexSquareMatrix(arrayRe,arrayIm);
401                 } else {
402                         throw new MatrixDimensionException("Matrices are different sizes.");
403                 }
404         }
405         public ComplexSquareMatrix subtract(final ComplexSquareMatrix m) {
406                 if(numRows==m.numRows && numCols==m.numCols) {
407                         final double arrayRe[][]=new double[numRows][numCols];
408                         final double arrayIm[][]=new double[numRows][numCols];
409                         for(int j,i=0;i<numRows;i++) {
410                                 arrayRe[i][0]=-m.matrixRe[i][0];
411                                 arrayIm[i][0]=-m.matrixIm[i][0];
412                                 for(j=1;j<numCols;j++) {
413                                         arrayRe[i][j]=-m.matrixRe[i][j];
414                                         arrayIm[i][j]=-m.matrixIm[i][j];
415                                 }
416                         }
417                         for(int i=0;i<numRows;i++) {
418                                 arrayRe[i][i]+=diagRe[i];
419                                 arrayIm[i][i]+=diagIm[i];
420                         }
421                         return new ComplexSquareMatrix(arrayRe,arrayIm);
422                 } else
423                         throw new MatrixDimensionException("Matrices are different sizes.");
424         }
425         public ComplexTridiagonalMatrix subtract(final ComplexTridiagonalMatrix m) {
426                 int mRow=numRows;
427                 if(mRow==m.numRows) {
428                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(mRow);
429                         ans.diagRe[0]=diagRe[0]-m.diagRe[0];
430                         ans.diagIm[0]=diagIm[0]-m.diagIm[0];
431                         ans.udiagRe[0]=-m.udiagRe[0];
432                         ans.udiagIm[0]=-m.udiagIm[0];
433                         mRow--;
434                         for(int i=1;i<mRow;i++) {
435                                 ans.ldiagRe[i]=-m.ldiagRe[i];
436                                 ans.ldiagIm[i]=-m.ldiagIm[i];
437                                 ans.diagRe[i]=diagRe[i]-m.diagRe[i];
438                                 ans.diagIm[i]=diagIm[i]-m.diagIm[i];
439                                 ans.udiagRe[i]=-m.udiagRe[i];
440                                 ans.udiagIm[i]=-m.udiagIm[i];
441                         }
442                         ans.ldiagRe[mRow]=-m.ldiagRe[mRow];
443                         ans.ldiagIm[mRow]=-m.ldiagIm[mRow];
444                         ans.diagRe[mRow]=diagRe[mRow]-m.diagRe[mRow];
445                         ans.diagIm[mRow]=diagIm[mRow]-m.diagIm[mRow];
446                         return ans;
447                 } else
448                         throw new MatrixDimensionException("Matrices are different sizes.");
449         }
450         /**
451         * Returns the subtraction of this matrix by another.
452         * @param m a complex tridiagonal matrix
453         * @exception MatrixDimensionException If the matrices are different sizes.
454         */

455         private ComplexTridiagonalMatrix subtractTridiagonal(final AbstractComplexSquareMatrix m) {
456                 int mRow=numRows;
457                 if(mRow==m.rows()) {
458                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(mRow);
459                         Complex elem=m.getElement(0,0);
460                         ans.diagRe[0]=diagRe[0]-elem.real();
461                         ans.diagIm[0]=diagIm[0]-elem.imag();
462                         elem=m.getElement(0,1);
463                         ans.udiagRe[0]=-elem.real();
464                         ans.udiagIm[0]=-elem.imag();
465                         mRow--;
466                         for(int i=1;i<mRow;i++) {
467                                 elem=m.getElement(i,i-1);
468                                 ans.ldiagRe[i]=-elem.real();
469                                 ans.ldiagIm[i]=-elem.imag();
470                                 elem=m.getElement(i,i);
471                                 ans.diagRe[i]=diagRe[i]-elem.real();
472                                 ans.diagIm[i]=diagIm[i]-elem.imag();
473                                 elem=m.getElement(i,i+1);
474                                 ans.udiagRe[i]=-elem.real();
475                                 ans.udiagIm[i]=-elem.imag();
476                         }
477                         elem=m.getElement(mRow,mRow-1);
478                         ans.ldiagRe[mRow]=-elem.real();
479                         ans.ldiagIm[mRow]=-elem.imag();
480                         elem=m.getElement(mRow,mRow);
481                         ans.diagRe[mRow]=diagRe[mRow]-elem.real();
482                         ans.diagIm[mRow]=diagIm[mRow]-elem.imag();
483                         return ans;
484                 } else {
485                         throw new MatrixDimensionException("Matrices are different sizes.");
486                 }
487         }
488         /**
489         * Returns the subtraction of this matrix by another.
490         * @param m a complex diagonal matrix
491         * @exception MatrixDimensionException If the matrices are different sizes.
492         */

493         public ComplexDiagonalMatrix subtract(final ComplexDiagonalMatrix m) {
494                 if(numRows==m.numRows) {
495                         final double arrayRe[]=new double[numRows];
496                         final double arrayIm[]=new double[numRows];
497                         arrayRe[0]=diagRe[0]-m.diagRe[0];
498                         arrayIm[0]=diagIm[0]-m.diagIm[0];
499                         for(int i=1;i<numRows;i++) {
500                                 arrayRe[i]=diagRe[i]-m.diagRe[i];
501                                 arrayIm[i]=diagIm[i]-m.diagIm[i];
502                         }
503                         return new ComplexDiagonalMatrix(arrayRe,arrayIm);
504                 } else
505                         throw new MatrixDimensionException("Matrices are different sizes.");
506         }
507
508 // SCALAR MULTIPLY
509

510         /**
511         * Returns the multiplication of this matrix by a scalar.
512         * @param z a complex number
513         * @return a complex diagonal matrix
514         */

515         public AbstractComplexMatrix scalarMultiply(final Complex z) {
516                 final double real=z.real();
517                 final double imag=z.imag();
518                 final double arrayRe[]=new double[numRows];
519                 final double arrayIm[]=new double[numRows];
520                 arrayRe[0]=real*diagRe[0]-imag*diagIm[0];
521                 arrayIm[0]=imag*diagRe[0]+real*diagIm[0];
522                 for(int i=1;i<numRows;i++) {
523                         arrayRe[i]=real*diagRe[i]-imag*diagIm[i];
524                         arrayIm[i]=imag*diagRe[i]+real*diagIm[i];
525                 }
526                 return new ComplexDiagonalMatrix(arrayRe,arrayIm);
527         }
528         /**
529         * Returns the multiplication of this matrix by a scalar.
530         * @param x a double
531         * @return a complex diagonal matrix
532         */

533         public AbstractComplexMatrix scalarMultiply(final double x) {
534                 final double arrayRe[]=new double[numRows];
535                 final double arrayIm[]=new double[numRows];
536                 arrayRe[0]=x*diagRe[0];
537                 arrayIm[0]=x*diagIm[0];
538                 for(int i=1;i<numRows;i++) {
539                         arrayRe[i]=x*diagRe[i];
540                         arrayIm[i]=x*diagIm[i];
541                 }
542                 return new ComplexDiagonalMatrix(arrayRe,arrayIm);
543         }
544
545 // MATRIX MULTIPLICATION
546

547         /**
548         * Returns the multiplication of a vector by this matrix.
549         * @param v a complex vector
550         * @exception DimensionException If the matrix and vector are incompatible.
551         */

552         public AbstractComplexVector multiply(final AbstractComplexVector v) {
553                 if(numCols==v.dimension()) {
554                         final double arrayRe[]=new double[numRows];
555                         final double arrayIm[]=new double[numRows];
556                         Complex comp=v.getComponent(0);
557                         arrayRe[0]=(diagRe[0]*comp.real() - diagIm[0]*comp.imag());
558                         arrayIm[0]=(diagIm[0]*comp.real() + diagRe[0]*comp.imag());
559                         for(int i=1;i<numRows;i++) {
560                                 comp=v.getComponent(i);
561                                 arrayRe[i]=(diagRe[i]*comp.real() - diagIm[i]*comp.imag());
562                                 arrayIm[i]=(diagIm[i]*comp.real() + diagRe[i]*comp.imag());
563                         }
564                         return new ComplexVector(arrayRe,arrayIm);
565                 } else
566                         throw new DimensionException("Matrix and vector are incompatible.");
567         }
568         /**
569         * Returns the multiplication of this matrix and another.
570         * @param m a complex matrix
571         * @exception MatrixDimensionException If the matrices are different sizes.
572         */

573         public AbstractComplexSquareMatrix multiply(final AbstractComplexSquareMatrix m) {
574                 if(m instanceof ComplexDiagonalMatrix)
575                         return multiply((ComplexDiagonalMatrix)m);
576                 if(m instanceof ComplexTridiagonalMatrix)
577                         return multiply((ComplexTridiagonalMatrix)m);
578                 if(m instanceof TridiagonalMatrix)
579                         return multiplyTridiagonal(m);
580                 if(m instanceof ComplexSquareMatrix)
581                         return multiply((ComplexSquareMatrix)m);
582
583                 if(numCols==m.rows()) {
584                         final double arrayRe[][]=new double[numRows][m.columns()];
585                         final double arrayIm[][]=new double[numRows][m.columns()];
586                         Complex elem;
587                         for(int i=0;i<numRows;i++) {
588                                 elem=m.getElement(i,0);
589                                 arrayRe[i][0]=(diagRe[i]*elem.real() - diagIm[i]*elem.imag());
590                                 arrayIm[i][0]=(diagIm[i]*elem.real() + diagRe[i]*elem.imag());
591                                 for(int j=1;j<m.columns();j++) {
592                                         elem=m.getElement(i,j);
593                                         arrayRe[i][j]=(diagRe[i]*elem.real() - diagIm[i]*elem.imag());
594                                         arrayIm[i][j]=(diagIm[i]*elem.real() + diagRe[i]*elem.imag());
595                                 }
596                         }
597                         return new ComplexSquareMatrix(arrayRe,arrayIm);
598                 } else {
599                         throw new MatrixDimensionException("Matrices are different sizes.");
600                 }
601         }
602         /**
603         * Returns the multiplication of this matrix and another.
604         * @param m a complex square matrix
605         * @exception MatrixDimensionException If the matrices are different sizes.
606         */

607         public ComplexSquareMatrix multiply(final ComplexSquareMatrix m) {
608                 if(numCols==m.numRows) {
609                         final double arrayRe[][]=new double[numRows][numCols];
610                         final double arrayIm[][]=new double[numRows][numCols];
611                         for(int j,i=0;i<numRows;i++) {
612                                 arrayRe[i][0]=(diagRe[i]*m.matrixRe[i][0] - diagIm[i]*m.matrixIm[i][0]);
613                                 arrayIm[i][0]=(diagIm[i]*m.matrixRe[i][0] + diagRe[i]*m.matrixIm[i][0]);
614                                 for(j=1;j<numCols;j++) {
615                                         arrayRe[i][j]=(diagRe[i]*m.matrixRe[i][j] - diagIm[i]*m.matrixIm[i][j]);
616                                         arrayIm[i][j]=(diagIm[i]*m.matrixRe[i][j] + diagRe[i]*m.matrixIm[i][j]);
617                                 }
618                         }
619                         return new ComplexSquareMatrix(arrayRe,arrayIm);
620                 } else
621                         throw new MatrixDimensionException("Matrices are different sizes.");
622         }
623         /**
624         * Returns the multiplication of this matrix and another.
625         * @param m a complex tridiagonal matrix
626         * @exception MatrixDimensionException If the matrices are different sizes.
627         */

628         public ComplexTridiagonalMatrix multiply(final ComplexTridiagonalMatrix m) {
629                 int mRow=numRows;
630                 if(numCols==m.numRows) {
631                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(mRow);
632                         ans.diagRe[0]=(diagRe[0]*m.diagRe[0] - diagIm[0]*m.diagIm[0]);
633                         ans.diagIm[0]=(diagIm[0]*m.diagRe[0] + diagRe[0]*m.diagIm[0]);
634                         ans.udiagRe[0]=(diagRe[0]*m.udiagRe[0] - diagIm[0]*m.udiagIm[0]);
635                         ans.udiagIm[0]=(diagIm[0]*m.udiagRe[0] + diagRe[0]*m.udiagIm[0]);
636                         mRow--;
637                         for(int i=1;i<mRow;i++) {
638                                 ans.ldiagRe[i]=(diagRe[i]*m.ldiagRe[i] - diagIm[i]*m.ldiagIm[i]);
639                                 ans.ldiagIm[i]=(diagIm[i]*m.ldiagRe[i] + diagRe[i]*m.ldiagIm[i]);
640                                 ans.diagRe[i]=(diagRe[i]*m.diagRe[i] - diagIm[i]*m.diagIm[i]);
641                                 ans.diagIm[i]=(diagIm[i]*m.diagRe[i] + diagRe[i]*m.diagIm[i]);
642                                 ans.udiagRe[i]=(diagRe[i]*m.udiagRe[i] - diagIm[i]*m.udiagIm[i]);
643                                 ans.udiagIm[i]=(diagIm[i]*m.udiagRe[i] + diagRe[i]*m.udiagIm[i]);
644                         }
645                         ans.ldiagRe[mRow]=(diagRe[mRow]*m.ldiagRe[mRow] - diagIm[mRow]*m.ldiagIm[mRow]);
646                         ans.ldiagIm[mRow]=(diagIm[mRow]*m.ldiagRe[mRow] + diagRe[mRow]*m.ldiagIm[mRow]);
647                         ans.diagRe[mRow]=(diagRe[mRow]*m.diagRe[mRow] - diagIm[mRow]*m.diagIm[mRow]);
648                         ans.diagIm[mRow]=(diagIm[mRow]*m.diagRe[mRow] + diagRe[mRow]*m.diagIm[mRow]);
649                         return ans;
650                 } else
651                         throw new MatrixDimensionException("Matrices are different sizes.");
652         }
653         private ComplexTridiagonalMatrix multiplyTridiagonal(final AbstractComplexSquareMatrix m) {
654                 int mRow=numRows;
655                 if(numCols==m.rows()) {
656                         final ComplexTridiagonalMatrix ans=new ComplexTridiagonalMatrix(mRow);
657                         Complex elem=m.getElement(0,0);
658                         ans.diagRe[0]=(diagRe[0]*elem.real() - diagIm[0]*elem.imag());
659                         ans.diagIm[0]=(diagIm[0]*elem.real() + diagRe[0]*elem.imag());
660                         elem=m.getElement(0,1);
661                         ans.udiagRe[0]=(diagRe[0]*elem.real() - diagIm[0]*elem.imag());
662                         ans.udiagIm[0]=(diagIm[0]*elem.real() + diagRe[0]*elem.imag());
663                         mRow--;
664                         for(int i=1;i<mRow;i++) {
665                                 elem=m.getElement(i,i-1);
666                                 ans.ldiagRe[i]=(diagRe[i]*elem.real() - diagIm[i]*elem.imag());
667                                 ans.ldiagIm[i]=(diagIm[i]*elem.real() + diagRe[i]*elem.imag());
668                                 elem=m.getElement(i,i);
669                                 ans.diagRe[i]=(diagRe[i]*elem.real() - diagIm[i]*elem.imag());
670                                 ans.diagIm[i]=(diagIm[i]*elem.real() + diagRe[i]*elem.imag());
671                                 elem=m.getElement(i,i+1);
672                                 ans.udiagRe[i]=(diagRe[i]*elem.real() - diagIm[i]*elem.imag());
673                                 ans.udiagIm[i]=(diagIm[i]*elem.real() + diagRe[i]*elem.imag());
674                         }
675                         elem=m.getElement(mRow,mRow-1);
676                         ans.ldiagRe[mRow]=(diagRe[mRow]*elem.real() - diagIm[mRow]*elem.imag());
677                         ans.ldiagIm[mRow]=(diagIm[mRow]*elem.real() + diagRe[mRow]*elem.imag());
678                         elem=m.getElement(mRow,mRow);
679                         ans.diagRe[mRow]=(diagRe[mRow]*elem.real() - diagIm[mRow]*elem.imag());
680                         ans.diagIm[mRow]=(diagIm[mRow]*elem.real() + diagRe[mRow]*elem.imag());
681                         return ans;
682                 } else {
683                         throw new MatrixDimensionException("Matrices are different sizes.");
684                 }
685         }
686         /**
687         * Returns the multiplication of this matrix and another.
688         * @param m a complex diagonal matrix
689         * @exception MatrixDimensionException If the matrices are different sizes.
690         */

691         public ComplexDiagonalMatrix multiply(final ComplexDiagonalMatrix m) {
692                 if(numCols==m.numRows) {
693                         final double arrayRe[]=new double[numRows];
694                         final double arrayIm[]=new double[numRows];
695                         arrayRe[0]=(diagRe[0]*m.diagRe[0] - diagIm[0]*m.diagIm[0]);
696                         arrayIm[0]=(diagIm[0]*m.diagRe[0] + diagRe[0]*m.diagIm[0]);
697                         for(int i=1;i<numRows;i++) {
698                                 arrayRe[i]=(diagRe[i]*m.diagRe[i] - diagIm[i]*m.diagIm[i]);
699                                 arrayIm[i]=(diagIm[i]*m.diagRe[i] + diagRe[i]*m.diagIm[i]);
700                         }
701                         return new ComplexDiagonalMatrix(arrayRe,arrayIm);
702                 } else
703                         throw new MatrixDimensionException("Matrices are different sizes.");
704         }
705
706 // INVERSE
707

708         /**
709         * Returns the inverse of this matrix.
710         * @return a complex diagonal matrix
711         */

712         public AbstractComplexSquareMatrix inverse() {
713                 final double arrayRe[]=new double[numRows];
714                 final double arrayIm[]=new double[numRows];
715                 double denom=diagRe[0]*diagRe[0]+diagIm[0]*diagIm[0];
716                 arrayRe[0]=diagRe[0]/denom;
717                 arrayIm[0]=-diagIm[0]/denom;
718                 for(int i=1;i<numRows;i++) {
719                         denom=diagRe[i]*diagRe[i]+diagIm[i]*diagIm[i];
720                         arrayRe[i]=diagRe[i]/denom;
721                         arrayIm[i]=-diagIm[i]/denom;
722                 }
723                 return new ComplexDiagonalMatrix(arrayRe,arrayIm);
724         }
725
726 // HERMITIAN ADJOINT
727

728         /**
729         * Returns the hermitian adjoint of this matrix.
730         * @return a complex diagonal matrix
731         */

732         public AbstractComplexMatrix hermitianAdjoint() {
733                 return conjugate();
734         }
735
736 // CONJUGATE
737

738         /**
739         * Returns the complex conjugate of this matrix.
740         * @return a complex diagonal matrix
741         */

742         public AbstractComplexMatrix conjugate() {
743                 final double arrayIm[]=new double[numRows];
744                 arrayIm[0]=-diagIm[0];
745                 for(int i=1;i<numRows;i++)
746                         arrayIm[i]=-diagIm[i];
747                 return new ComplexDiagonalMatrix(diagRe,arrayIm);
748         }
749
750 // TRANSPOSE
751

752         /**
753         * Returns the transpose of this matrix.
754         * @return a complex diagonal matrix
755         */

756         public Matrix transpose() {
757                 return this;
758         }
759
760 // LU DECOMPOSITION
761

762         /**
763         * Returns the LU decomposition of this matrix.
764         * @return an array with [0] containing the L-matrix and [1] containing the U-matrix.
765         */

766         public AbstractComplexSquareMatrix[] luDecompose(int pivot[]) {
767                 if(LU!=null) {
768                         if(pivot!=null)
769                                 System.arraycopy(LUpivot,0,pivot,0,pivot.length);
770                         return LU;
771                 }
772                 if(pivot==null)
773                         pivot=new int[numRows+1];
774                 for(int i=0;i<numRows;i++)
775                         pivot[i]=i;
776                 pivot[numRows]=1;
777                 LU=new AbstractComplexSquareMatrix[2];
778                 LU[0]=identity(numRows);
779                 LU[1]=this;
780                 LUpivot=new int[pivot.length];
781                 System.arraycopy(pivot,0,LUpivot,0,pivot.length);
782                 return LU;
783         }
784         /**
785         * Returns the LU decomposition of this matrix.
786         * @return an array with [0] containing the L-matrix and [1] containing the U-matrix.
787         */

788         public AbstractComplexSquareMatrix[] luDecompose() {
789                 return luDecompose(null);
790         }
791
792 // MAP ELEMENTS
793

794         /**
795         * Applies a function on all the matrix elements.
796         * @param f a user-defined function
797         * @return a complex diagonal matrix
798         */

799         public AbstractComplexMatrix mapElements(final ComplexMapping f) {
800         Complex zeroValue = f.map(Complex.ZERO);
801         if(zeroValue.mod() <= JSci.GlobalSettings.ZERO_TOL)
802             return diagonalMap(f);
803         else
804             return generalMap(f, zeroValue);
805     }
806     private AbstractComplexMatrix diagonalMap(ComplexMapping f) {
807                 final Complex array[]=new Complex[numRows];
808                 array[0]=f.map(diagRe[0],diagIm[0]);
809                 for(int i=1;i<numRows;i++)
810                         array[i]=f.map(diagRe[i],diagIm[i]);
811                 return new ComplexDiagonalMatrix(array);
812         }
813     private AbstractComplexMatrix generalMap(ComplexMapping f, Complex zeroValue) {
814                 final double arrayRe[][]=new double[numRows][numRows];
815                 final double arrayIm[][]=new double[numRows][numRows];
816         for(int i=0; i<numRows; i++) {
817             for(int j=0; j<numRows; j++) {
818                 arrayRe[i][j] = zeroValue.real();
819                 arrayIm[i][j] = zeroValue.imag();
820             }
821         }
822         Complex z = f.map(diagRe[0], diagIm[0]);
823                 arrayRe[0][0]=z.real();
824                 arrayIm[0][0]=z.imag();
825                 for(int i=1;i<numRows;i++) {
826             z=f.map(diagRe[i], diagIm[i]);
827                         arrayRe[i][i]=z.real();
828                         arrayIm[i][i]=z.imag();
829         }
830                 return new ComplexSquareMatrix(arrayRe, arrayIm);
831     }
832 }
833
Popular Tags