1 9 package org.jscience.mathematics.vectors; 10 11 import java.util.Iterator ; 12 import java.util.List ; 13 14 import javolution.context.ConcurrentContext; 15 import javolution.lang.MathLib; 16 import javolution.util.FastTable; 17 import javolution.util.Index; 18 19 import org.jscience.mathematics.numbers.Complex; 20 21 35 public final class ComplexMatrix extends Matrix<Complex> { 36 37 40 int _n;; 41 42 45 boolean _transposed; 46 47 50 final FastTable<ComplexVector> _rows = new FastTable<ComplexVector>(); 51 52 61 public static ComplexMatrix valueOf(Complex[][] elements) { 62 int m = elements.length; 63 int n = elements[0].length; 64 ComplexMatrix M = ComplexMatrix.newInstance(n, false); 65 for (int i = 0; i < m; i++) { 66 ComplexVector row = ComplexVector.valueOf(elements[i]); 67 if (row.getDimension() != n) 68 throw new DimensionException(); 69 M._rows.add(row); 70 } 71 return M; 72 } 73 74 82 public static ComplexMatrix valueOf(ComplexVector... rows) { 83 final int n = rows[0].getDimension(); 84 ComplexMatrix M = ComplexMatrix.newInstance(n, false); 85 for (int i = 0, m = rows.length; i < m; i++) { 86 ComplexVector rowi = rows[i]; 87 if (rowi.getDimension() != n) 88 throw new DimensionException( 89 "All vectors must have the same dimension."); 90 M._rows.add(rowi); 91 } 92 return M; 93 } 94 95 103 public static ComplexMatrix valueOf(List <ComplexVector> rows) { 104 final int n = rows.get(0).getDimension(); 105 ComplexMatrix M = ComplexMatrix.newInstance(n, false); 106 Iterator <ComplexVector> iterator = rows.iterator(); 107 for (int i = 0, m = rows.size(); i < m; i++) { 108 ComplexVector rowi = iterator.next(); 109 if (rowi.getDimension() != n) 110 throw new DimensionException( 111 "All vectors must have the same dimension."); 112 M._rows.add(rowi); 113 } 114 return M; 115 } 116 117 124 public static ComplexMatrix valueOf(Matrix<Complex> that) { 125 if (that instanceof ComplexMatrix) return (ComplexMatrix)that; 126 int n = that.getNumberOfColumns(); 127 int m = that.getNumberOfRows(); 128 ComplexMatrix M = ComplexMatrix.newInstance(n, false); 129 for (int i = 0; i < m; i++) { 130 ComplexVector rowi = ComplexVector.valueOf(that.getRow(i)); 131 M._rows.add(rowi); 132 } 133 return M; 134 } 135 136 @Override 137 public int getNumberOfRows() { 138 return _transposed ? _n : _rows.size(); 139 } 140 141 @Override 142 public int getNumberOfColumns() { 143 return _transposed ? _rows.size() : _n; 144 } 145 146 @Override 147 public Complex get(int i, int j) { 148 return _transposed ? _rows.get(j).get(i) : _rows.get(i).get(j); 149 } 150 151 @Override 152 public ComplexVector getRow(int i) { 153 if (!_transposed) return _rows.get(i); 154 int n = _rows.size(); 156 int m = _n; 157 if ((i < 0) || (i >= m)) throw new DimensionException(); 158 ComplexVector V = ComplexVector.newInstance(n); 159 for (int j=0; j < n; j++) { 160 V.set(j, _rows.get(j).get(i)); 161 } 162 return V; 163 } 164 165 @Override 166 public ComplexVector getColumn(int j) { 167 if (_transposed) return _rows.get(j); 168 int m = _rows.size(); 169 if ((j < 0) || (j >= _n)) throw new DimensionException(); 170 ComplexVector V = ComplexVector.newInstance(m); 171 for (int i=0; i < m; i++) { 172 V.set(i, _rows.get(i).get(j)); 173 } 174 return V; 175 } 176 177 @Override 178 public ComplexVector getDiagonal() { 179 int m = this.getNumberOfRows(); 180 int n = this.getNumberOfColumns(); 181 int dimension = MathLib.min(m, n); 182 ComplexVector V = ComplexVector.newInstance(dimension); 183 for (int i=0; i < dimension; i++) { 184 V.set(i, this.get(i, i)); 185 } 186 return V; 187 } 188 189 @Override 190 public ComplexMatrix opposite() { 191 ComplexMatrix M = ComplexMatrix.newInstance(_n, _transposed); 192 for (int i = 0, p = _rows.size(); i < p; i++) { 193 M._rows.add(_rows.get(i).opposite()); 194 } 195 return M; 196 } 197 198 @Override 199 public ComplexMatrix plus(Matrix<Complex> that) { 200 if (this.getNumberOfRows() != that.getNumberOfRows()) 201 throw new DimensionException(); 202 ComplexMatrix M = ComplexMatrix.newInstance(_n, _transposed); 203 for (int i = 0, p = _rows.size(); i < p; i++) { 204 M._rows.add(_rows.get(i).plus(_transposed ? that.getColumn(i) : that.getRow(i))); 205 } 206 return M; 207 } 208 209 @Override 210 public ComplexMatrix minus(Matrix<Complex> that) { return this.plus(that.opposite()); 212 } 213 214 @Override 215 public ComplexMatrix times(Complex k) { 216 ComplexMatrix M = ComplexMatrix.newInstance(_n, _transposed); 217 for (int i = 0, p = _rows.size(); i < p; i++) { 218 M._rows.add(_rows.get(i).times(k)); 219 } 220 return M; 221 } 222 223 @Override 224 public ComplexVector times(Vector<Complex> v) { 225 if (v.getDimension() != this.getNumberOfColumns()) 226 throw new DimensionException(); 227 final int m = this.getNumberOfRows(); 228 ComplexVector V = ComplexVector.newInstance(m); 229 for (int i = 0; i < m; i++) { 230 V.set(i, this.getRow(i).times(v)); 231 } 232 return V; 233 } 234 235 @Override 236 public ComplexMatrix times(Matrix<Complex> that) { 237 if (_transposed) return this.transpose().inverse().transpose(); 239 final int m = this.getNumberOfRows(); 241 final int p = that.getNumberOfColumns(); 242 if (that.getNumberOfRows() != _n) 243 throw new DimensionException(); 244 ComplexMatrix M = ComplexMatrix.newInstance(m, true); multiply(that, Index.valueOf(0), Index.valueOf(p), M._rows); 247 return M; 248 } 249 250 private void multiply( 252 Matrix<Complex> that, Index startColumn, Index endColumn, FastTable<ComplexVector> columnsResult) { 253 final int start = startColumn.intValue(); 254 final int end = endColumn.intValue(); 255 if (end - start < 32) { final int m = this._rows.size(); 257 for (int j = start; j < end; j++) { 258 Vector<Complex> thatColj = that.getColumn(j); 259 ComplexVector column = ComplexVector.newInstance(m); 260 columnsResult.add(column); 261 for (int i = 0; i < m; i++) { 262 ComplexVector thisRowi = this._rows.get(i); 263 column.set(i, thisRowi.times(thatColj)); 264 } 265 } 266 } else { FastTable<ComplexVector> r1 = FastTable.newInstance(); 268 FastTable<ComplexVector> r2 = FastTable.newInstance(); 269 Index half = Index.valueOf((start + end) >> 1); 270 ConcurrentContext.enter(); 271 try { 272 ConcurrentContext.execute(MULTIPLY, this, that, startColumn, half, r1); 273 ConcurrentContext.execute(MULTIPLY, this, that, half, endColumn, r2); 274 } finally { 275 ConcurrentContext.exit(); 276 } 277 columnsResult.addAll(r1); 278 columnsResult.addAll(r2); 279 FastTable.recycle(r1); 280 FastTable.recycle(r2); 281 } 282 } 283 private static ConcurrentContext.Logic MULTIPLY = new ConcurrentContext.Logic() { 284 @SuppressWarnings ("unchecked") 285 public void run() { 286 ComplexMatrix _this = getArgument(0); 287 Matrix _that = getArgument(1); 288 Index _startColumn = getArgument(2); 289 Index _endColumn = getArgument(3); 290 FastTable _columnsResult = getArgument(4); 291 _this.multiply(_that, _startColumn, _endColumn, _columnsResult); 292 } 293 }; 294 295 296 @Override 297 public ComplexMatrix inverse() { 298 if (!isSquare()) 299 throw new DimensionException("Matrix not square"); 300 return ComplexMatrix.valueOf(LUDecomposition.valueOf(this).inverse()); 301 } 302 303 @Override 304 public Complex determinant() { 305 return LUDecomposition.valueOf(this).determinant(); 306 } 307 308 @Override 309 public ComplexMatrix transpose() { 310 ComplexMatrix M = ComplexMatrix.newInstance(_n, !_transposed); 311 M._rows.addAll(this._rows); 312 return M; 313 } 314 315 @Override 316 public Complex cofactor(int i, int j) { 317 if (_transposed) { 318 int k = i; i = j; j = k; } 320 int m = _rows.size(); 321 ComplexMatrix M = ComplexMatrix.newInstance(m - 1, _transposed); 322 for (int k1=0; k1 < m; k1++) { 323 if (k1 == i) continue; 324 ComplexVector row = _rows.get(k1); 325 ComplexVector V = ComplexVector.newInstance(_n - 1); 326 M._rows.add(V); 327 for (int k2=0, k=0; k2 < _n; k2++) { 328 if (k2 == j) continue; 329 V.set(k++, row.get(k2)); 330 } 331 } 332 return M.determinant(); 333 } 334 335 @Override 336 public ComplexMatrix adjoint() { 337 ComplexMatrix M = ComplexMatrix.newInstance(_n, _transposed); 338 int m = _rows.size(); 339 for (int i = 0; i < m; i++) { 340 ComplexVector row = ComplexVector.newInstance(_n); 341 M._rows.add(row); 342 for (int j = 0; j < _n; j++) { 343 Complex cofactor = _transposed ? cofactor(j, i) : cofactor(i, j); 344 row.set(j, ((i + j) % 2 == 0) ? cofactor : cofactor.opposite()); 345 } 346 } 347 return M.transpose(); 348 } 349 350 @Override 351 public ComplexMatrix tensor(Matrix<Complex> that) { 352 return ComplexMatrix.valueOf(DenseMatrix.valueOf(this).tensor(that)); 353 } 354 355 @Override 356 public ComplexVector vectorization() { 357 return ComplexVector.valueOf(DenseMatrix.valueOf(this).vectorization()); 358 } 359 360 @Override 361 public boolean move(ObjectSpace os) { 362 if (super.move(os)) { 363 for (int i=0, n=_rows.size(); i < n; i++) { 368 _rows.get(i).move(os); 369 } 370 return true; 371 } 372 return false; 373 } 374 375 379 static ComplexMatrix newInstance(int n, boolean transposed) { 380 ComplexMatrix M = FACTORY.object(); 381 M._n = n; 382 M._transposed = transposed; 383 return M; 384 } 385 386 private static Factory<ComplexMatrix> FACTORY = new Factory<ComplexMatrix>() { 387 @Override 388 protected ComplexMatrix create() { 389 return new ComplexMatrix(); 390 } 391 @Override 392 protected void cleanup(ComplexMatrix matrix) { 393 matrix._rows.reset(); 394 } 395 }; 396 397 private ComplexMatrix() { 398 } 399 400 private static final long serialVersionUID = 1L; 401 402 403 } | Popular Tags |