~ubuntu-branches/ubuntu/trusty/cdk/trusty-proposed

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/math/IMatrix.java

  • Committer: Bazaar Package Importer
  • Author(s): Paul Cager
  • Date: 2008-04-09 21:17:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080409211753-46lmjw5z8mx5pd8d
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* IMatrix.java
 
2
 * 
 
3
 * Autor: Stephan Michels 
 
4
 * EMail: stephan@vern.chem.tu-berlin.de
 
5
 * Datum: 22.7.2001
 
6
 * 
 
7
 * Copyright (C) 1997-2007  The Chemistry Development Kit (CDK) project
 
8
 * 
 
9
 * Contact: cdk-devel@lists.sourceforge.net
 
10
 * 
 
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.
 
19
 * 
 
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.
 
24
 * 
 
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.
 
28
 *  */
 
29
 
 
30
package org.openscience.cdk.math;
 
31
 
 
32
import java.text.DecimalFormat;
 
33
 
 
34
/**
 
35
 * This class contains a complex matrix
 
36
 */
 
37
public class IMatrix
 
38
{
 
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;
 
44
 
 
45
  /** the count of rows of the matrix */
 
46
  public int rows;
 
47
  /** the count of columns of the matrix */
 
48
  public int columns;
 
49
 
 
50
  /**
 
51
   * Creates a complex matrix
 
52
   */
 
53
  public IMatrix(int rows, int columns)
 
54
  {
 
55
    this.rows = rows;
 
56
    this.columns = columns;
 
57
    realmatrix = new double[rows][columns];
 
58
    imagmatrix = new double[rows][columns];
 
59
  }
 
60
 
 
61
  /**
 
62
   * Creates a complex copy of a matrix
 
63
   */
 
64
  public IMatrix(Matrix m)
 
65
  {
 
66
    rows = m.rows;
 
67
    columns = m.columns;
 
68
    int i,j;
 
69
    for(i=0; i<rows; i++)
 
70
      for(j=0; j<columns; j++)
 
71
      {
 
72
        realmatrix[i][j] = m.matrix[i][j];
 
73
        imagmatrix[i][j] = 0d;
 
74
      }
 
75
  }
 
76
 
 
77
  /**
 
78
   * Returns the count of rows
 
79
   */
 
80
  public int getRows()
 
81
  {
 
82
    return rows;
 
83
  }
 
84
 
 
85
  /**
 
86
   * Returns the count of columns
 
87
   */
 
88
  public int getColumns()
 
89
  {
 
90
    return columns;
 
91
  }
 
92
 
 
93
  /**
 
94
   * Creates a vector with the content of a row from this matrix
 
95
   */
 
96
  public IVector getVectorFromRow(int index)
 
97
  {
 
98
    IVector result = new IVector(columns);
 
99
    for(int i=0; i<columns; i++)
 
100
    {
 
101
      result.realvector[i] = realmatrix[index][i];
 
102
      result.imagvector[i] = imagmatrix[index][i];
 
103
    }
 
104
    return result;
 
105
  }
 
106
 
 
107
  /**
 
108
   * Creates a vector with the content of a column from this matrix
 
109
   */
 
110
  public IVector getVectorFromColumn(int index)
 
111
  {
 
112
    IVector result = new IVector(rows);
 
113
    for(int i=0; i<rows; i++)
 
114
    {
 
115
      result.realvector[i] = realmatrix[i][index];
 
116
      result.imagvector[i] = imagmatrix[i][index];
 
117
    }
 
118
    return result;
 
119
  }
 
120
 
 
121
  /**
 
122
   * Creates a vector with the content of the diagonal elements from this matrix
 
123
   */
 
124
  public IVector getVectorFromDiagonal()
 
125
  {
 
126
    int size = Math.min(rows, columns);
 
127
    IVector result = new IVector(size);
 
128
    for(int i=0; i<rows; i++)
 
129
    {
 
130
      result.realvector[i] = realmatrix[i][i];
 
131
      result.imagvector[i] = imagmatrix[i][i];
 
132
    }
 
133
    return result;
 
134
  }
 
135
 
 
136
  /**
 
137
   *  Addition from two matrices
 
138
   */
 
139
  public IMatrix add(IMatrix b)
 
140
  {
 
141
    IMatrix result = new IMatrix(rows,columns);
 
142
    add(b, result);
 
143
    return result;
 
144
  }
 
145
 
 
146
  /**
 
147
   *  Addition from two matrices
 
148
   */
 
149
  public void add(IMatrix b, IMatrix result)
 
150
  {
 
151
    if ((b==null) ||
 
152
        (rows!=b.rows) || (columns!=b.columns))
 
153
      return;
 
154
      
 
155
    if ((result.rows!=rows) || (result.columns!=columns))
 
156
      result.reshape(rows,columns);
 
157
 
 
158
    int i, j;
 
159
    for(i=0; i<rows; i++)
 
160
      for(j=0; j<columns; j++)
 
161
      {
 
162
        result.realmatrix[i][j] = realmatrix[i][j]+b.realmatrix[i][j];
 
163
        result.imagmatrix[i][j] = imagmatrix[i][j]+b.imagmatrix[i][j];
 
164
      }
 
165
  }
 
166
  
 
167
  /**
 
168
   *  Subtraktion from two matrices
 
169
   */
 
170
  public IMatrix sub(IMatrix b)
 
171
  {
 
172
    IMatrix result = new IMatrix(rows,columns);
 
173
    sub(b, result);
 
174
    return result;
 
175
  }
 
176
 
 
177
  /**
 
178
   *  Subtraktion from two matrices
 
179
   */
 
180
  public void sub(IMatrix b, IMatrix result)
 
181
  {
 
182
    if ((b==null) ||
 
183
        (rows!=b.rows) || (columns!=b.columns))
 
184
      return;
 
185
      
 
186
    if ((result.rows!=rows) || (result.columns!=columns))
 
187
      result.reshape(rows,columns);
 
188
 
 
189
    int i, j;
 
190
    for(i=0; i<rows; i++) 
 
191
      for(j=0; j<columns; j++)
 
192
      {
 
193
        result.realmatrix[i][j] = realmatrix[i][j]-b.realmatrix[i][j];
 
194
        result.imagmatrix[i][j] = imagmatrix[i][j]-b.imagmatrix[i][j];
 
195
      }
 
196
  }
 
197
 
 
198
  /**
 
199
   *  Multiplikation from two matrices
 
200
   */
 
201
  public IMatrix mul(IMatrix b)
 
202
  { 
 
203
    IMatrix result = new IMatrix(rows,columns);
 
204
    mul(b, result);
 
205
    return result;
 
206
  }
 
207
  
 
208
  /**
 
209
   *  Multiplikation from two matrices
 
210
   */
 
211
  public void mul(IMatrix b, IMatrix result)
 
212
  {
 
213
    if ((b==null) ||
 
214
        (columns!=b.rows))
 
215
      return;
 
216
 
 
217
    if ((result.rows!=rows) || (result.columns!=b.columns))
 
218
      result.reshape(rows,b.columns);
 
219
    int i,j,k;
 
220
    double realsum,imagsum;
 
221
    for(i=0; i<rows; i++)
 
222
      for(k=0; k<b.columns; k++)
 
223
      {
 
224
        realsum = 0; imagsum = 0;
 
225
        for(j=0; j<columns; j++)
 
226
        {
 
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];
 
229
        }
 
230
        result.realmatrix[i][k] = realsum;
 
231
        result.imagmatrix[i][k] = imagsum;
 
232
      }
 
233
  }
 
234
  
 
235
  /**
 
236
   *  Multiplikation from a vector and a matrix
 
237
   */
 
238
  public IVector mul(IVector a)
 
239
  { 
 
240
    IVector result = new IVector(rows);
 
241
    mul(a, result); 
 
242
    return result;
 
243
  } 
 
244
  
 
245
  /**
 
246
   *  Multiplikation from a vector and a matrix
 
247
   */
 
248
  public void mul(IVector a, IVector result)
 
249
  {
 
250
    if ((a==null) ||
 
251
        (columns!=a.size))
 
252
      return;
 
253
 
 
254
    if (result.size!=rows)
 
255
      result.reshape(rows);
 
256
 
 
257
    int i,j;
 
258
    double realsum, imagsum;
 
259
    for(i=0; i<rows; i++)
 
260
    {
 
261
      realsum = 0; imagsum = 0;
 
262
      for(j=0; j<columns; j++)
 
263
      {
 
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];
 
266
      }
 
267
      result.realvector[i] = realsum;
 
268
      result.imagvector[i] = imagsum;
 
269
    }
 
270
  }
 
271
 
 
272
  /**
 
273
   *  Multiplikation from a scalar and a matrix
 
274
   */
 
275
  public IMatrix mul(Complex a)
 
276
  {
 
277
    IMatrix result = new IMatrix(rows,columns);
 
278
    mul(a, result);
 
279
    return result;
 
280
  }
 
281
 
 
282
  /**
 
283
   *  Multiplikation from a scalar and a matrix
 
284
   */
 
285
  public void mul(Complex a, IMatrix result)
 
286
  {
 
287
    if ((result.rows!=rows) || (result.columns!=columns))
 
288
      result.reshape(rows,columns);
 
289
 
 
290
    int i,j;
 
291
    for(i=0; i<rows; i++)
 
292
      for(j=0; j<columns; j++)
 
293
      {
 
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;
 
296
      }
 
297
  }
 
298
 
 
299
  /**
 
300
   *  Copy a matrix
 
301
   */
 
302
  public IMatrix duplicate()
 
303
  {
 
304
    IMatrix result = new IMatrix(rows,columns);
 
305
    duplicate(result); 
 
306
    return result;
 
307
  } 
 
308
  
 
309
  /**
 
310
   *  Copy a matrix
 
311
   */
 
312
  public void duplicate(IMatrix result)
 
313
  {
 
314
    if ((result.rows!=rows) || (result.columns!=columns))
 
315
      result.reshape(rows,columns);
 
316
 
 
317
    int i,j;
 
318
    for(i=0; i<rows; i++)
 
319
      for(j=0; j<columns; j++)
 
320
      {
 
321
        result.realmatrix[i][j] = realmatrix[i][j];
 
322
        result.imagmatrix[i][j] = imagmatrix[i][j];
 
323
      }
 
324
  }
 
325
 
 
326
  /**
 
327
   *  Transpose a matrix
 
328
   */
 
329
  public IMatrix transpose()
 
330
  {
 
331
    IMatrix result = new IMatrix(rows,columns);
 
332
    transpose(result);  
 
333
    return result;
 
334
  } 
 
335
  
 
336
  /**
 
337
   *  Transpose a matrix
 
338
   */
 
339
  public void transpose(IMatrix result)
 
340
  { 
 
341
    if ((result.rows!=rows) || (result.columns!=columns))
 
342
      result.reshape(rows,columns);
 
343
 
 
344
    int i,j; 
 
345
    for(i=0; i<rows; i++) 
 
346
      for(j=0; j<columns; j++)
 
347
      {
 
348
        result.realmatrix[j][i] = realmatrix[i][j];
 
349
        result.imagmatrix[j][i] = imagmatrix[i][j];
 
350
      }
 
351
  }
 
352
 
 
353
  /**
 
354
   * Similar transformation
 
355
   * Ut * M * U
 
356
   */
 
357
  public IMatrix similar(IMatrix U)
 
358
  {
 
359
    IMatrix result = new IMatrix(rows,columns);
 
360
    similar(U, result);  
 
361
    return result;
 
362
  } 
 
363
  
 
364
  /**
 
365
   * Similar transformation
 
366
   * Ut * M * U
 
367
   */
 
368
  public void similar(IMatrix U, IMatrix result)
 
369
  {
 
370
    if ((result.rows!=U.columns) || (result.columns!=U.columns))
 
371
      result.reshape(U.columns,U.columns);
 
372
 
 
373
    double realsum, imagsum, realinnersum, imaginnersum;
 
374
    for(int i=0; i<U.columns; i++)
 
375
      for(int j=0; j<U.columns; j++)
 
376
      {
 
377
        realsum = 0d; imagsum = 0d;
 
378
        for(int k=0; k<U.columns; k++)
 
379
        {
 
380
          realinnersum = 0d; imaginnersum = 0d;
 
381
          for(int l=0; l<U.columns; l++)
 
382
          {
 
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];
 
385
          }
 
386
          realsum += U.realmatrix[k][i]*realinnersum-U.imagmatrix[k][i]*imaginnersum;
 
387
          imagsum += U.realmatrix[k][i]*imaginnersum+U.imagmatrix[k][i]*realinnersum;
 
388
        }
 
389
        result.realmatrix[i][j] = realsum;
 
390
        result.imagmatrix[i][j] = imagsum;
 
391
      }
 
392
  }      
 
393
 
 
394
  /**
 
395
   * Calculates the contraction from a matrix
 
396
   */
 
397
  public Complex contraction()
 
398
  {
 
399
    int i,j;
 
400
    Complex result = new Complex(0d,0d);
 
401
    for(i=0; i<rows; i++)
 
402
      for(j=0; j<columns; j++)
 
403
      {
 
404
        result.real += realmatrix[i][j];
 
405
        result.imag += imagmatrix[i][j];
 
406
      }
 
407
    return result;
 
408
  }  
 
409
  
 
410
  /**
 
411
   *  Return a matrix as a string
 
412
   */
 
413
  public String toString()
 
414
  {
 
415
    if ((rows<=0) || (columns<=0))
 
416
      return "[]";
 
417
    int i,j;
 
418
    DecimalFormat format = new DecimalFormat("00.0000");
 
419
    format.setPositivePrefix("+");
 
420
 
 
421
    StringBuffer str = new StringBuffer();
 
422
    for(i=0; i<(rows-1); i++)
 
423
    {
 
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])+" ");
 
427
        else
 
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");
 
431
      else
 
432
          str.append("--------+i*--------\n");
 
433
    }
 
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])+" ");
 
437
      else
 
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]));
 
443
    else
 
444
      str.append("--------+i*-------- ");
 
445
    return str.toString();
 
446
  }
 
447
 
 
448
  /**
 
449
   * Resize the matrix
 
450
   */
 
451
  public void reshape(int newrows, int newcolumns)
 
452
  {
 
453
    if (((newrows==rows) && (newcolumns==columns)) || 
 
454
        (newrows<=0) || (newcolumns<=0))
 
455
      return;
 
456
 
 
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);
 
461
    int i,j;
 
462
    for(i=0; i<minrows; i++)
 
463
      for(j=0; j<mincolumns; j++)
 
464
      {
 
465
        newrealmatrix[i][j] = realmatrix[i][j];
 
466
        newimagmatrix[i][j] = imagmatrix[i][j];
 
467
      }
 
468
 
 
469
    for(i=minrows; i<newrows; i++)
 
470
      for(j=0; j<mincolumns; j++)
 
471
      {
 
472
        newrealmatrix[i][j] = 0d;
 
473
        newimagmatrix[i][j] = 0d;
 
474
      }
 
475
 
 
476
    for(i=0; i<minrows; i++)
 
477
      for(j=mincolumns; j<newcolumns; j++)
 
478
      {
 
479
        newrealmatrix[i][j] = 0d;
 
480
        newimagmatrix[i][j] = 0d;
 
481
      }
 
482
 
 
483
    for(i=minrows; i<newrows; i++)
 
484
      for(j=mincolumns; j<newcolumns; j++)
 
485
      {
 
486
        newrealmatrix[i][j] = 0d;
 
487
        newimagmatrix[i][j] = 0d;
 
488
      }
 
489
 
 
490
    realmatrix = newrealmatrix;
 
491
    imagmatrix = newimagmatrix;
 
492
    rows = newrows;
 
493
    columns = newcolumns;
 
494
  }
 
495
}