1 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 import JSci.maths.groups.AbelianGroup; 10 import JSci.maths.algebras.*; 11 import JSci.maths.fields.*; 12 13 18 public class ComplexMatrix extends AbstractComplexMatrix { 19 22 protected double matrixRe[][],matrixIm[][]; 23 28 public ComplexMatrix(final int rows,final int cols) { 29 super(rows,cols); 30 matrixRe=new double[rows][cols]; 31 matrixIm=new double[rows][cols]; 32 } 33 38 public ComplexMatrix(final double arrayRe[][],final double arrayIm[][]) { 39 this(arrayRe.length,arrayRe[0].length); 40 matrixRe=arrayRe; 41 matrixIm=arrayIm; 42 } 43 47 public ComplexMatrix(final Complex array[][]) { 48 this(array.length,array[0].length); 49 for(int j,i=0;i<numRows;i++) { 50 for(j=0;j<numCols;j++) { 51 matrixRe[i][j]=array[i][j].real(); 52 matrixIm[i][j]=array[i][j].imag(); 53 } 54 } 55 } 56 60 public ComplexMatrix(ComplexVector array[]) { 61 this(array[0].dimension(),array.length); 62 for(int j,i=0;i<numRows;i++) { 63 for(j=0;j<numCols;j++) { 64 matrixRe[i][j]=array[j].getComponent(i).real(); 65 matrixIm[i][j]=array[j].getComponent(i).imag(); 66 } 67 } 68 } 69 73 public boolean equals(AbstractComplexMatrix m, double tol) { 74 if(m != null && numRows == m.rows() && numCols == m.columns()) { 75 double sumSqr = 0.0; 76 for(int i=0;i<numRows;i++) { 77 for(int j=0;j<numCols;j++) { 78 double deltaRe = matrixRe[i][j]-m.getRealElement(i,j); 79 double deltaIm = matrixIm[i][j]-m.getImagElement(i,j); 80 sumSqr += deltaRe*deltaRe + deltaIm*deltaIm; 81 } 82 } 83 return (sumSqr <= tol*tol); 84 } else { 85 return false; 86 } 87 } 88 91 public String toString() { 92 final StringBuffer buf=new StringBuffer (5*numRows*numCols); 93 for(int j,i=0;i<numRows;i++) { 94 for(j=0;j<numCols;j++) { 95 buf.append(Complex.toString(matrixRe[i][j],matrixIm[i][j])); 96 buf.append(' '); 97 } 98 buf.append('\n'); 99 } 100 return buf.toString(); 101 } 102 105 public int hashCode() { 106 return (int)Math.exp(infNorm()); 107 } 108 112 public AbstractDoubleMatrix real() { 113 return new DoubleMatrix(matrixRe); 114 } 115 119 public AbstractDoubleMatrix imag() { 120 return new DoubleMatrix(matrixIm); 121 } 122 128 public Complex getElement(final int i, final int j) { 129 if(i>=0 && i<numRows && j>=0 && j<numCols) 130 return new Complex(matrixRe[i][j],matrixIm[i][j]); 131 else 132 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 133 } 134 public double getRealElement(final int i, final int j) { 135 if(i>=0 && i<numRows && j>=0 && j<numCols) 136 return matrixRe[i][j]; 137 else 138 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 139 } 140 public double getImagElement(final int i, final int j) { 141 if(i>=0 && i<numRows && j>=0 && j<numCols) 142 return matrixIm[i][j]; 143 else 144 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 145 } 146 154 public void setElement(final int i, final int j, final Complex z) { 155 if(i>=0 && i<numRows && j>=0 && j<numCols) { 156 matrixRe[i][j]=z.real(); 157 matrixIm[i][j]=z.imag(); 158 } else 159 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 160 } 161 170 public void setElement(final int i, final int j, final double x, final double y) { 171 if(i>=0 && i<numRows && j>=0 && j<numCols) { 172 matrixRe[i][j]=x; 173 matrixIm[i][j]=y; 174 } else 175 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 176 } 177 181 public double infNorm() { 182 double result=0.0,tmpResult; 183 for(int i=0;i<numRows;i++) { 184 tmpResult=0.0; 185 for(int j=0;j<numCols;j++) 186 tmpResult += Math.sqrt((matrixRe[i][j]*matrixRe[i][j] + matrixIm[i][j]*matrixIm[i][j])); 187 if(tmpResult>result) 188 result=tmpResult; 189 } 190 return result; 191 } 192 197 public double frobeniusNorm() { 198 double result=0.0; 199 for(int j,i=0;i<numRows;i++) 200 for(j=0;j<numCols;j++) 201 result+=matrixRe[i][j]*matrixRe[i][j]+matrixIm[i][j]*matrixIm[i][j]; 202 return Math.sqrt(result); 203 } 204 205 209 212 public AbelianGroup.Member negate() { 213 final double arrayRe[][]=new double[numRows][numCols]; 214 final double arrayIm[][]=new double[numRows][numCols]; 215 for(int j,i=0;i<numRows;i++) { 216 arrayRe[i][0]=-matrixRe[i][0]; 217 arrayIm[i][0]=-matrixIm[i][0]; 218 for(j=1;j<numCols;j++) { 219 arrayRe[i][j]=-matrixRe[i][j]; 220 arrayIm[i][j]=-matrixIm[i][j]; 221 } 222 } 223 return new ComplexMatrix(arrayRe,arrayIm); 224 } 225 226 228 233 public AbstractComplexMatrix add(final AbstractComplexMatrix m) { 234 if(m instanceof ComplexMatrix) { 235 return add((ComplexMatrix)m); 236 } else { 237 if(numRows==m.rows() && numCols==m.columns()) { 238 final double arrayRe[][]=new double[numRows][numCols]; 239 final double arrayIm[][]=new double[numRows][numCols]; 240 for(int j,i=0;i<numRows;i++) { 241 arrayRe[i][0]=matrixRe[i][0]+m.getElement(i,0).real(); 242 arrayIm[i][0]=matrixIm[i][0]+m.getElement(i,0).imag(); 243 for(j=1;j<numCols;j++) { 244 arrayRe[i][j]=matrixRe[i][j]+m.getElement(i,j).real(); 245 arrayIm[i][j]=matrixIm[i][j]+m.getElement(i,j).imag(); 246 } 247 } 248 return new ComplexMatrix(arrayRe,arrayIm); 249 } else 250 throw new MatrixDimensionException("Matrices are different sizes."); 251 } 252 } 253 public ComplexMatrix add(final ComplexMatrix m) { 254 if(numRows==m.numRows && numCols==m.numCols) { 255 final double arrayRe[][]=new double[numRows][numCols]; 256 final double arrayIm[][]=new double[numRows][numCols]; 257 for(int j,i=0;i<numRows;i++) { 258 arrayRe[i][0]=matrixRe[i][0]+m.matrixRe[i][0]; 259 arrayIm[i][0]=matrixIm[i][0]+m.matrixIm[i][0]; 260 for(j=1;j<numCols;j++) { 261 arrayRe[i][j]=matrixRe[i][j]+m.matrixRe[i][j]; 262 arrayIm[i][j]=matrixIm[i][j]+m.matrixIm[i][j]; 263 } 264 } 265 return new ComplexMatrix(arrayRe,arrayIm); 266 } else 267 throw new MatrixDimensionException("Matrices are different sizes."); 268 } 269 270 272 277 public AbstractComplexMatrix subtract(final AbstractComplexMatrix m) { 278 if(m instanceof ComplexMatrix) { 279 return subtract((ComplexMatrix)m); 280 } else { 281 if(numRows==m.rows() && numCols==m.columns()) { 282 final double arrayRe[][]=new double[numRows][numCols]; 283 final double arrayIm[][]=new double[numRows][numCols]; 284 for(int j,i=0;i<numRows;i++) { 285 arrayRe[i][0]=matrixRe[i][0]-m.getElement(i,0).real(); 286 arrayIm[i][0]=matrixIm[i][0]-m.getElement(i,0).imag(); 287 for(j=1;j<numCols;j++) { 288 arrayRe[i][j]=matrixRe[i][j]-m.getElement(i,j).real(); 289 arrayIm[i][j]=matrixIm[i][j]-m.getElement(i,j).imag(); 290 } 291 } 292 return new ComplexMatrix(arrayRe,arrayIm); 293 } else 294 throw new MatrixDimensionException("Matrices are different sizes."); 295 } 296 } 297 public ComplexMatrix subtract(final ComplexMatrix m) { 298 if(numRows==m.numRows && numCols==m.numCols) { 299 final double arrayRe[][]=new double[numRows][numCols]; 300 final double arrayIm[][]=new double[numRows][numCols]; 301 for(int j,i=0;i<numRows;i++) { 302 arrayRe[i][0]=matrixRe[i][0]-m.matrixRe[i][0]; 303 arrayIm[i][0]=matrixIm[i][0]-m.matrixIm[i][0]; 304 for(j=1;j<numCols;j++) { 305 arrayRe[i][j]=matrixRe[i][j]-m.matrixRe[i][j]; 306 arrayIm[i][j]=matrixIm[i][j]-m.matrixIm[i][j]; 307 } 308 } 309 return new ComplexMatrix(arrayRe,arrayIm); 310 } else 311 throw new MatrixDimensionException("Matrices are different sizes."); 312 } 313 314 316 321 public AbstractComplexMatrix scalarMultiply(final Complex z) { 322 final double real=z.real(); 323 final double imag=z.imag(); 324 final double arrayRe[][]=new double[numRows][numCols]; 325 final double arrayIm[][]=new double[numRows][numCols]; 326 for(int j,i=0;i<numRows;i++) { 327 arrayRe[i][0]=real*matrixRe[i][0]-imag*matrixIm[i][0]; 328 arrayIm[i][0]=imag*matrixRe[i][0]+real*matrixIm[i][0]; 329 for(j=1;j<numCols;j++) { 330 arrayRe[i][j]=real*matrixRe[i][j]-imag*matrixIm[i][j]; 331 arrayIm[i][j]=imag*matrixRe[i][j]+real*matrixIm[i][j]; 332 } 333 } 334 return new ComplexMatrix(arrayRe,arrayIm); 335 } 336 341 public AbstractComplexMatrix scalarMultiply(final double x) { 342 final double arrayRe[][]=new double[numRows][numCols]; 343 final double arrayIm[][]=new double[numRows][numCols]; 344 for(int j,i=0;i<numRows;i++) { 345 arrayRe[i][0]=x*matrixRe[i][0]; 346 arrayIm[i][0]=x*matrixIm[i][0]; 347 for(j=1;j<numCols;j++) { 348 arrayRe[i][j]=x*matrixRe[i][j]; 349 arrayIm[i][j]=x*matrixIm[i][j]; 350 } 351 } 352 return new ComplexMatrix(arrayRe,arrayIm); 353 } 354 355 357 362 public AbstractComplexMatrix scalarDivide(final Complex z) { 363 final Complex array[][]=new Complex[numRows][numCols]; 364 for(int j,i=0;i<numRows;i++) { 365 array[i][0]=new Complex(matrixRe[i][0],matrixIm[i][0]).divide(z); 366 for(j=1;j<numCols;j++) 367 array[i][j]=new Complex(matrixRe[i][j],matrixIm[i][j]).divide(z); 368 } 369 return new ComplexMatrix(array); 370 } 371 376 public AbstractComplexMatrix scalarDivide(final double x) { 377 final double arrayRe[][]=new double[numRows][numCols]; 378 final double arrayIm[][]=new double[numRows][numCols]; 379 for(int j,i=0;i<numRows;i++) { 380 arrayRe[i][0]=matrixRe[i][0]/x; 381 arrayIm[i][0]=matrixIm[i][0]/x; 382 for(j=1;j<numCols;j++) { 383 arrayRe[i][j]=matrixRe[i][j]/x; 384 arrayIm[i][j]=matrixIm[i][j]/x; 385 } 386 } 387 return new ComplexMatrix(arrayRe,arrayIm); 388 } 389 390 392 397 public AbstractComplexVector multiply(final AbstractComplexVector v) { 398 if(numCols==v.dimension()) { 399 final double arrayRe[]=new double[numRows]; 400 final double arrayIm[]=new double[numRows]; 401 Complex comp; 402 for(int j,i=0;i<numRows;i++) { 403 comp=v.getComponent(0); 404 arrayRe[i]=(matrixRe[i][0]*comp.real() - matrixIm[i][0]*comp.imag()); 405 arrayIm[i]=(matrixIm[i][0]*comp.real() + matrixRe[i][0]*comp.imag()); 406 for(j=1;j<numCols;j++) { 407 comp=v.getComponent(j); 408 arrayRe[i]+=(matrixRe[i][j]*comp.real() - matrixIm[i][j]*comp.imag()); 409 arrayIm[i]+=(matrixIm[i][j]*comp.real() + matrixRe[i][j]*comp.imag()); 410 } 411 } 412 return new ComplexVector(arrayRe,arrayIm); 413 } else 414 throw new DimensionException("Matrix and vector are incompatible."); 415 } 416 422 public AbstractComplexMatrix multiply(final AbstractComplexMatrix m) { 423 if(m instanceof ComplexMatrix) { 424 return multiply((ComplexMatrix)m); 425 } else { 426 if(numCols==m.rows()) { 427 final double arrayRe[][]=new double[numRows][m.columns()]; 428 final double arrayIm[][]=new double[numRows][m.columns()]; 429 int n,k; 430 Complex elem; 431 for(int j=0;j<numRows;j++) { 432 for(k=0;k<m.columns();k++) { 433 elem=m.getElement(0,k); 434 arrayRe[j][k]=(matrixRe[j][0]*elem.real() - matrixIm[j][0]*elem.imag()); 435 arrayIm[j][k]=(matrixIm[j][0]*elem.real() + matrixRe[j][0]*elem.imag()); 436 for(n=1;n<numCols;n++) { 437 elem=m.getElement(n,k); 438 arrayRe[j][k]+=(matrixRe[j][n]*elem.real() - matrixIm[j][n]*elem.imag()); 439 arrayIm[j][k]+=(matrixIm[j][n]*elem.real() + matrixRe[j][n]*elem.imag()); 440 } 441 } 442 } 443 if(numRows==m.columns()) 444 return new ComplexSquareMatrix(arrayRe,arrayIm); 445 else 446 return new ComplexMatrix(arrayRe,arrayIm); 447 } else 448 throw new MatrixDimensionException("Incompatible matrices."); 449 } 450 } 451 public AbstractComplexMatrix multiply(final ComplexMatrix m) { 452 if(numCols==m.numRows) { 453 final double arrayRe[][]=new double[numRows][m.numCols]; 454 final double arrayIm[][]=new double[numRows][m.numCols]; 455 int n,k; 456 for(int j=0;j<numRows;j++) { 457 for(k=0;k<m.numCols;k++) { 458 arrayRe[j][k]=(matrixRe[j][0]*m.matrixRe[0][k] - matrixIm[j][0]*m.matrixIm[0][k]); 459 arrayIm[j][k]=(matrixIm[j][0]*m.matrixRe[0][k] + matrixRe[j][0]*m.matrixIm[0][k]); 460 for(n=1;n<numCols;n++) { 461 arrayRe[j][k]+=(matrixRe[j][n]*m.matrixRe[n][k] - matrixIm[j][n]*m.matrixIm[n][k]); 462 arrayIm[j][k]+=(matrixIm[j][n]*m.matrixRe[n][k] + matrixRe[j][n]*m.matrixIm[n][k]); 463 } 464 } 465 } 466 if(numRows==m.numCols) 467 return new ComplexSquareMatrix(arrayRe,arrayIm); 468 else 469 return new ComplexMatrix(arrayRe,arrayIm); 470 } else 471 throw new MatrixDimensionException("Incompatible matrices."); 472 } 473 474 476 479 public AbstractComplexMatrix directSum(final AbstractComplexMatrix m) { 480 final double arrayRe[][]=new double[numRows+m.numRows][numCols+m.numCols]; 481 final double arrayIm[][]=new double[numRows+m.numRows][numCols+m.numCols]; 482 for(int j,i=0;i<numRows;i++) { 483 for(j=0;j<numCols;j++) { 484 arrayRe[i][j]=matrixRe[i][j]; 485 arrayIm[i][j]=matrixIm[i][j]; 486 } 487 } 488 for(int j,i=0;i<m.numRows;i++) { 489 for(j=0;j<m.numCols;j++) { 490 Complex elem=m.getElement(i,j); 491 arrayRe[i+numRows][j+numCols]=elem.real(); 492 arrayIm[i+numRows][j+numCols]=elem.imag(); 493 } 494 } 495 return new ComplexMatrix(arrayRe,arrayIm); 496 } 497 498 500 503 public AbstractComplexMatrix tensor(final AbstractComplexMatrix m) { 504 final double arrayRe[][]=new double[numRows*m.numRows][numCols*m.numCols]; 505 final double arrayIm[][]=new double[numRows*m.numRows][numCols*m.numCols]; 506 for(int i=0;i<numRows;i++) { 507 for(int j=0;j<numCols;j++) { 508 for(int k=0;k<m.numRows;j++) { 509 for(int l=0;l<m.numCols;l++) { 510 Complex elem=m.getElement(k,l); 511 arrayRe[i*m.numRows+k][j*m.numCols+l]=(matrixRe[i][j]*elem.real() - matrixIm[i][j]*elem.imag()); 512 arrayIm[i*m.numRows+k][j*m.numCols+l]=(matrixIm[i][j]*elem.real() + matrixRe[i][j]*elem.imag()); 513 } 514 } 515 } 516 } 517 return new ComplexMatrix(arrayRe,arrayIm); 518 } 519 520 522 526 public AbstractComplexMatrix hermitianAdjoint() { 527 final double arrayRe[][]=new double[numCols][numRows]; 528 final double arrayIm[][]=new double[numCols][numRows]; 529 for(int j,i=0;i<numRows;i++) { 530 arrayRe[0][i]=matrixRe[i][0]; 531 arrayIm[0][i]=-matrixIm[i][0]; 532 for(j=1;j<numCols;j++) { 533 arrayRe[j][i]=matrixRe[i][j]; 534 arrayIm[j][i]=-matrixIm[i][j]; 535 } 536 } 537 return new ComplexMatrix(arrayRe,arrayIm); 538 } 539 540 542 546 public AbstractComplexMatrix conjugate() { 547 final double arrayIm[][]=new double[numRows][numCols]; 548 for(int j,i=0;i<numRows;i++) { 549 arrayIm[i][0]=-matrixIm[i][0]; 550 for(j=1;j<numCols;j++) 551 arrayIm[i][j]=-matrixIm[i][j]; 552 } 553 return new ComplexMatrix(matrixRe,arrayIm); 554 } 555 556 558 562 public Matrix transpose() { 563 final double arrayRe[][]=new double[numCols][numRows]; 564 final double arrayIm[][]=new double[numCols][numRows]; 565 for(int j,i=0;i<numRows;i++) { 566 arrayRe[0][i]=matrixRe[i][0]; 567 arrayIm[0][i]=matrixIm[i][0]; 568 for(j=1;j<numCols;j++) { 569 arrayRe[j][i]=matrixRe[i][j]; 570 arrayIm[j][i]=matrixIm[i][j]; 571 } 572 } 573 return new ComplexMatrix(arrayRe,arrayIm); 574 } 575 576 578 583 public AbstractComplexMatrix mapElements(final ComplexMapping f) { 584 final Complex array[][]=new Complex[numRows][numCols]; 585 for(int j,i=0;i<numRows;i++) { 586 array[i][0]=f.map(matrixRe[i][0],matrixIm[i][0]); 587 for(j=1;j<numCols;j++) 588 array[i][j]=f.map(matrixRe[i][j],matrixIm[i][j]); 589 } 590 return new ComplexMatrix(array); 591 } 592 } 593 | Popular Tags |