3
* Autor: Stephan Michels
4
* EMail: stephan@vern.chem.tu-berlin.de
7
* Copyright (C) 1997-2007 The Chemistry Development Kit (CDK) project
9
* Contact: cdk-devel@lists.sourceforge.net
11
* This program is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Lesser General Public License
13
* as published by the Free Software Foundation; either version 2.1
14
* of the License, or (at your option) any later version.
15
* All we ask is that proper credit is given for our work, which includes
16
* - but is not limited to - adding the above copyright notice to the beginning
17
* of your source code files, and to any copyright notice that you may distribute
18
* with programs based on this work.
20
* This program is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU Lesser General Public License for more details.
25
* You should have received a copy of the GNU Lesser General Public License
26
* along with this program; if not, write to the Free Software
27
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30
package org.openscience.cdk.math;
32
import java.text.DecimalFormat;
35
* This class contains a complex matrix
39
// Attention! Variables are unprotected
40
/** the real part of the content */
41
public double[][] realmatrix;
42
/** the imaginary part of the content */
43
public double[][] imagmatrix;
45
/** the count of rows of the matrix */
47
/** the count of columns of the matrix */
51
* Creates a complex matrix
53
public IMatrix(int rows, int columns)
56
this.columns = columns;
57
realmatrix = new double[rows][columns];
58
imagmatrix = new double[rows][columns];
62
* Creates a complex copy of a matrix
64
public IMatrix(Matrix m)
70
for(j=0; j<columns; j++)
72
realmatrix[i][j] = m.matrix[i][j];
73
imagmatrix[i][j] = 0d;
78
* Returns the count of rows
86
* Returns the count of columns
88
public int getColumns()
94
* Creates a vector with the content of a row from this matrix
96
public IVector getVectorFromRow(int index)
98
IVector result = new IVector(columns);
99
for(int i=0; i<columns; i++)
101
result.realvector[i] = realmatrix[index][i];
102
result.imagvector[i] = imagmatrix[index][i];
108
* Creates a vector with the content of a column from this matrix
110
public IVector getVectorFromColumn(int index)
112
IVector result = new IVector(rows);
113
for(int i=0; i<rows; i++)
115
result.realvector[i] = realmatrix[i][index];
116
result.imagvector[i] = imagmatrix[i][index];
122
* Creates a vector with the content of the diagonal elements from this matrix
124
public IVector getVectorFromDiagonal()
126
int size = Math.min(rows, columns);
127
IVector result = new IVector(size);
128
for(int i=0; i<rows; i++)
130
result.realvector[i] = realmatrix[i][i];
131
result.imagvector[i] = imagmatrix[i][i];
137
* Addition from two matrices
139
public IMatrix add(IMatrix b)
141
IMatrix result = new IMatrix(rows,columns);
147
* Addition from two matrices
149
public void add(IMatrix b, IMatrix result)
152
(rows!=b.rows) || (columns!=b.columns))
155
if ((result.rows!=rows) || (result.columns!=columns))
156
result.reshape(rows,columns);
159
for(i=0; i<rows; i++)
160
for(j=0; j<columns; j++)
162
result.realmatrix[i][j] = realmatrix[i][j]+b.realmatrix[i][j];
163
result.imagmatrix[i][j] = imagmatrix[i][j]+b.imagmatrix[i][j];
168
* Subtraktion from two matrices
170
public IMatrix sub(IMatrix b)
172
IMatrix result = new IMatrix(rows,columns);
178
* Subtraktion from two matrices
180
public void sub(IMatrix b, IMatrix result)
183
(rows!=b.rows) || (columns!=b.columns))
186
if ((result.rows!=rows) || (result.columns!=columns))
187
result.reshape(rows,columns);
190
for(i=0; i<rows; i++)
191
for(j=0; j<columns; j++)
193
result.realmatrix[i][j] = realmatrix[i][j]-b.realmatrix[i][j];
194
result.imagmatrix[i][j] = imagmatrix[i][j]-b.imagmatrix[i][j];
199
* Multiplikation from two matrices
201
public IMatrix mul(IMatrix b)
203
IMatrix result = new IMatrix(rows,columns);
209
* Multiplikation from two matrices
211
public void mul(IMatrix b, IMatrix result)
217
if ((result.rows!=rows) || (result.columns!=b.columns))
218
result.reshape(rows,b.columns);
220
double realsum,imagsum;
221
for(i=0; i<rows; i++)
222
for(k=0; k<b.columns; k++)
224
realsum = 0; imagsum = 0;
225
for(j=0; j<columns; j++)
227
realsum += realmatrix[i][j]*b.realmatrix[j][k]-imagmatrix[i][j]*b.imagmatrix[j][k];
228
imagsum += realmatrix[i][j]*b.imagmatrix[j][k]+imagmatrix[i][j]*b.realmatrix[j][k];
230
result.realmatrix[i][k] = realsum;
231
result.imagmatrix[i][k] = imagsum;
236
* Multiplikation from a vector and a matrix
238
public IVector mul(IVector a)
240
IVector result = new IVector(rows);
246
* Multiplikation from a vector and a matrix
248
public void mul(IVector a, IVector result)
254
if (result.size!=rows)
255
result.reshape(rows);
258
double realsum, imagsum;
259
for(i=0; i<rows; i++)
261
realsum = 0; imagsum = 0;
262
for(j=0; j<columns; j++)
264
realsum += realmatrix[i][j]*a.realvector[j]-imagmatrix[i][j]*a.imagvector[j];
265
imagsum += realmatrix[i][j]*a.imagvector[j]+imagmatrix[i][j]*a.realvector[j];
267
result.realvector[i] = realsum;
268
result.imagvector[i] = imagsum;
273
* Multiplikation from a scalar and a matrix
275
public IMatrix mul(Complex a)
277
IMatrix result = new IMatrix(rows,columns);
283
* Multiplikation from a scalar and a matrix
285
public void mul(Complex a, IMatrix result)
287
if ((result.rows!=rows) || (result.columns!=columns))
288
result.reshape(rows,columns);
291
for(i=0; i<rows; i++)
292
for(j=0; j<columns; j++)
294
result.realmatrix[i][j] = realmatrix[i][j]*a.real-imagmatrix[i][j]*a.imag;
295
result.imagmatrix[i][j] = realmatrix[i][j]*a.imag+imagmatrix[i][j]*a.real;
302
public IMatrix duplicate()
304
IMatrix result = new IMatrix(rows,columns);
312
public void duplicate(IMatrix result)
314
if ((result.rows!=rows) || (result.columns!=columns))
315
result.reshape(rows,columns);
318
for(i=0; i<rows; i++)
319
for(j=0; j<columns; j++)
321
result.realmatrix[i][j] = realmatrix[i][j];
322
result.imagmatrix[i][j] = imagmatrix[i][j];
329
public IMatrix transpose()
331
IMatrix result = new IMatrix(rows,columns);
339
public void transpose(IMatrix result)
341
if ((result.rows!=rows) || (result.columns!=columns))
342
result.reshape(rows,columns);
345
for(i=0; i<rows; i++)
346
for(j=0; j<columns; j++)
348
result.realmatrix[j][i] = realmatrix[i][j];
349
result.imagmatrix[j][i] = imagmatrix[i][j];
354
* Similar transformation
357
public IMatrix similar(IMatrix U)
359
IMatrix result = new IMatrix(rows,columns);
365
* Similar transformation
368
public void similar(IMatrix U, IMatrix result)
370
if ((result.rows!=U.columns) || (result.columns!=U.columns))
371
result.reshape(U.columns,U.columns);
373
double realsum, imagsum, realinnersum, imaginnersum;
374
for(int i=0; i<U.columns; i++)
375
for(int j=0; j<U.columns; j++)
377
realsum = 0d; imagsum = 0d;
378
for(int k=0; k<U.columns; k++)
380
realinnersum = 0d; imaginnersum = 0d;
381
for(int l=0; l<U.columns; l++)
383
realinnersum += realmatrix[k][l]*U.realmatrix[l][j]-imagmatrix[k][l]*U.imagmatrix[l][j];
384
imaginnersum += realmatrix[k][l]*U.imagmatrix[l][j]+imagmatrix[k][l]*U.realmatrix[l][j];
386
realsum += U.realmatrix[k][i]*realinnersum-U.imagmatrix[k][i]*imaginnersum;
387
imagsum += U.realmatrix[k][i]*imaginnersum+U.imagmatrix[k][i]*realinnersum;
389
result.realmatrix[i][j] = realsum;
390
result.imagmatrix[i][j] = imagsum;
395
* Calculates the contraction from a matrix
397
public Complex contraction()
400
Complex result = new Complex(0d,0d);
401
for(i=0; i<rows; i++)
402
for(j=0; j<columns; j++)
404
result.real += realmatrix[i][j];
405
result.imag += imagmatrix[i][j];
411
* Return a matrix as a string
413
public String toString()
415
if ((rows<=0) || (columns<=0))
418
DecimalFormat format = new DecimalFormat("00.0000");
419
format.setPositivePrefix("+");
421
StringBuffer str = new StringBuffer();
422
for(i=0; i<(rows-1); i++)
424
for(j=0; j<(columns-1); j++)
425
if ((Math.round(realmatrix[i][j]*10000)!=0) && (Math.round(imagmatrix[i][j]*10000)!=0))
426
str.append(format.format(realmatrix[i][j])+"+i*"+format.format(imagmatrix[i][j])+" ");
428
str.append("--------+i*-------- ");
429
if ((Math.round(realmatrix[i][columns-1]*10000)!=0) && (Math.round(imagmatrix[i][columns-1]*10000)!=0))
430
str.append(format.format(realmatrix[i][columns-1])+"+i*"+format.format(imagmatrix[i][columns-1])+"\n");
432
str.append("--------+i*--------\n");
434
for(j=0; j<(columns-1); j++)
435
if ((Math.round(realmatrix[rows-1][j]*10000)!=0) && (Math.round(imagmatrix[rows-1][j]*10000)!=0))
436
str.append(format.format(realmatrix[rows-1][j])+"+i*"+format.format(imagmatrix[rows-1][j])+" ");
438
str.append("--------+i*-------- ");
439
if ((Math.round(realmatrix[rows-1][columns-1]*10000)!=0) &&
440
(Math.round(imagmatrix[rows-1][columns-1]*10000)!=0))
441
str.append(format.format(realmatrix[rows-1][columns-1])+
442
"+i*"+format.format(imagmatrix[rows-1][columns-1]));
444
str.append("--------+i*-------- ");
445
return str.toString();
451
public void reshape(int newrows, int newcolumns)
453
if (((newrows==rows) && (newcolumns==columns)) ||
454
(newrows<=0) || (newcolumns<=0))
457
double[][] newrealmatrix = new double[newrows][newcolumns];
458
double[][] newimagmatrix = new double[newrows][newcolumns];
459
int minrows = Math.min(rows,newrows);
460
int mincolumns = Math.min(columns,newcolumns);
462
for(i=0; i<minrows; i++)
463
for(j=0; j<mincolumns; j++)
465
newrealmatrix[i][j] = realmatrix[i][j];
466
newimagmatrix[i][j] = imagmatrix[i][j];
469
for(i=minrows; i<newrows; i++)
470
for(j=0; j<mincolumns; j++)
472
newrealmatrix[i][j] = 0d;
473
newimagmatrix[i][j] = 0d;
476
for(i=0; i<minrows; i++)
477
for(j=mincolumns; j<newcolumns; j++)
479
newrealmatrix[i][j] = 0d;
480
newimagmatrix[i][j] = 0d;
483
for(i=minrows; i<newrows; i++)
484
for(j=mincolumns; j<newcolumns; j++)
486
newrealmatrix[i][j] = 0d;
487
newimagmatrix[i][j] = 0d;
490
realmatrix = newrealmatrix;
491
imagmatrix = newimagmatrix;
493
columns = newcolumns;