KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jscience > mathematics > matrices > Matrix


1 /*
2  * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
3  * Copyright (C) 2005 - JScience (http://jscience.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package org.jscience.mathematics.matrices;
10
11 import java.io.Serializable JavaDoc;
12 import java.util.Collection JavaDoc;
13 import java.util.Iterator JavaDoc;
14
15 import javolution.realtime.ConcurrentContext;
16 import javolution.realtime.PoolContext;
17 import javolution.realtime.RealtimeObject;
18 import javolution.realtime.ConcurrentContext.Logic;
19 import javolution.realtime.Realtime.ObjectSpace;
20 import javolution.lang.MathLib;
21 import javolution.lang.Text;
22 import javolution.lang.TextBuilder;
23 import javolution.xml.XmlElement;
24 import javolution.xml.XmlFormat;
25
26 import org.jscience.mathematics.numbers.Integer32;
27
28 /**
29  * <p> This class represents an immutable matrix of {@link Operable} elements.
30  * It may be used to resolve system of linear equations involving
31  * <i>any kind</i> of {@link Operable} elements
32  * (e.g. {@link org.jscience.mathematics.numbers.Real Real},
33  * {@link org.jscience.mathematics.numbers.Complex Complex},
34  * {@link org.jscience.physics.quantities.Quantity Quantity},
35  * {@link org.jscience.mathematics.functions.Function Function}, etc).</p>
36  *
37  * <p> Non-commutative multiplication is supported and this class itself
38  * implements the {@link Operable} interface. Consequently, this class may
39  * be used to resolve system of linear equations involving matrices
40  * (for which the multiplication is not commutative).</p>
41  *
42  * <p> <b>Implementation Note:</b> This class uses {@link ConcurrentContext
43  * concurrent contexts} to accelerate calculations on multi-processor
44  * systems.</p>
45  *
46  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
47  * @version 2.0, June 6, 2004
48  * @see <a HREF="http://mathworld.wolfram.com/Matrix.html">
49  * Matrix -- from MathWorld</a>
50  */

51 public class Matrix<O extends Operable<O>> extends RealtimeObject implements
52         Operable<Matrix<O>>, Serializable JavaDoc {
53
54     /**
55      * Holds the default XML representation for {@link Matrix} and its
56      * sub-classes. This representation consists of the matrix
57      * elements as nested XML elements and the matrix <code>row</code> and
58      * <code>column</code> as attributes. For example: <pre>
59      * &lt;math:Matrix row="2" column="1"&gt;
60      * &lt;math:Complex real="1.0" imaginary="0.0"/&gt;
61      * &lt;math:Complex real="0.0" imaginary="1.0"/&gt;
62      * &lt;/math:Matrix&gt;</pre>
63      */

64     protected static final XmlFormat<Matrix> XML = new XmlFormat<Matrix>(
65             Matrix.class) {
66         public void format(Matrix matrix, XmlElement xml) {
67             xml.setAttribute("rows", matrix.m);
68             xml.setAttribute("columns", matrix.n);
69             final int nm = matrix.m * matrix.n;
70             for (int i = 0; i < nm; i++) {
71                 xml.getContent().add(matrix.o[i]);
72             }
73         }
74
75         public Matrix parse(XmlElement xml) {
76             return Matrix.valueOf(xml.getAttribute("rows", 1), xml
77                     .getAttribute("columns", 1), (Collection JavaDoc<Operable>) xml
78                     .getContent());
79         }
80     };
81
82     /**
83      * The array of operable objects (M[i,j] = o[i*n+j], i < m, j < n).
84      */

85     final O[] o;
86
87     /**
88      * Holds the number of rows.
89      */

90     int m;
91
92     /**
93      * Holds the number of columns.
94      */

95     int n;
96
97     /**
98      * Base constructor.
99      *
100      * @param size the maximum number of elements.
101      */

102     Matrix(int size) {
103         this.o = (O[]) new Operable[size];
104     }
105
106     /**
107      * Creates a matrix from the specified 2-dimensional array of
108      * {@link Operable} objects.
109      * The first dimension being the row and the second being the column.
110      *
111      * <p>Note: It is safe to reuse the specified array as it is not internally
112      * referenced by the matrix being returned.</p>
113      * @param elements the array of {@link Operable} elements.
114      * @throws IllegalArgumentException if rows have different length.
115      */

116     public Matrix(O[][] elements) {
117         this.m = elements.length;
118         this.n = elements[0].length;
119         this.o = (O[]) new Operable[m * n];
120         for (int i = 0; i < m; i++) {
121             if (elements[i].length != n)
122                 throw new IllegalArgumentException JavaDoc(
123                         "All rows must have the same length.");
124             System.arraycopy(elements[i], 0, o, i * n, n);
125         }
126     }
127
128     /**
129      * Returns a m-by-n matrix filled with the specified diagonal element
130      * and the specified non-diagonal element.
131      * This constructor may be used to create an identity matrix
132      * (e.g. <code>valueOf(m, m, ONE, ZERO)</code>).
133      *
134      * @param m the number of rows.
135      * @param n the number of columns.
136      * @param diagonal the diagonal element.
137      * @param other the non-diagonal element.
138      * @return a m-by-n matrix with <code>d</code> on the diagonal and
139      * <code>o</code> elsewhere.
140      */

141     public static <O extends Operable<O>> Matrix<O> valueOf(int m, int n,
142             O diagonal, O other) {
143         Matrix<O> M = newInstance(m, n);
144         for (int i = 0; i < m; i++) {
145             for (int j = 0; j < n; j++) {
146                 M.o[i * n + j] = (i != j) ? other : diagonal;
147             }
148         }
149         return M;
150     }
151
152     /**
153      * Returns a matrix from a 2-dimensional array of {@link Operable} objects.
154      * The first dimension being the number of rows and the second being the
155      * number of columns ([m,n]).
156      *
157      * <p>Note: It is safe to reuse the specifed array as it is not internally
158      * referenced by the matrix being returned.</p>
159      *
160      * @param elements the array of {@link Operable} objects.
161      * @return the matrix having the specified components.
162      * @throws IllegalArgumentException if rows have different length.
163      */

164     public static <O extends Operable<O>> Matrix<O> valueOf(O[][] elements) {
165         int m = elements.length;
166         int n = elements[0].length;
167         Matrix<O> M = newInstance(m, n);
168         for (int i = 0; i < m; i++) {
169             if (elements[i].length != n)
170                 throw new IllegalArgumentException JavaDoc(
171                         "All rows must have the same length.");
172             System.arraycopy(elements[i], 0, M.o, i * n, n);
173         }
174         return M;
175     }
176
177     /**
178      * Returns a m-by-n matrix populated from the specified collection of
179      * {@link Operable} objects (rows first).
180      *
181      * @param m the number of rows.
182      * @param n the number of columns.
183      * @param elements the collection of {@link Operable} objects.
184      * @return the matrix having the specified size and elements.
185      * @throws MatrixException if <code>elements.size() != m * n</code>
186      * @throws ClassCastException if any of the element is not {@link Operable}.
187      */

188     public static <O extends Operable<O>> Matrix<O> valueOf(int m, int n,
189             Collection JavaDoc<O> elements) {
190         if (elements.size() != m * n)
191             throw new MatrixException(m * n + " elements expected but found "
192                     + elements.size());
193         Matrix<O> M = newInstance(m, n);
194         Iterator JavaDoc<O> iterator = elements.iterator();
195         for (int i = 0; i < m; i++) {
196             for (int j = 0; j < n; j++) {
197                 M.o[i * n + j] = iterator.next();
198             }
199         }
200         return M;
201     }
202
203     /**
204      * Returns the number of rows for this matrix.
205      *
206      * @return m, the number of rows.
207      */

208     public final int getNumberOfRows() {
209         return m;
210     }
211
212     /**
213      * Returns the number of columns for this matrix.
214      *
215      * @return n, the number of columns.
216      */

217     public final int getNumberOfColumns() {
218         return n;
219     }
220
221     /**
222      * Indicates if this matrix is square.
223      *
224      * @return <code>nbrOfRows() == nbrOfColumns()</code>
225      */

226     public final boolean isSquare() {
227         return m == n;
228     }
229
230     /**
231      * Returns a single element from this matrix.
232      *
233      * @param i the row index (range [0..m[).
234      * @param j the column index (range [0..n[).
235      * @return the element read at [i,j].
236      * @throws IndexOutOfBoundsException <code>
237      * (i < 0) || (i >= m)) || (j < 0) || (j >= n))</code>
238      */

239     public final O get(int i, int j) {
240         if ((i < 0) || (i >= m) || (j < 0) || (j >= n))
241             throw new IndexOutOfBoundsException JavaDoc("i: " + i + ", j: " + j
242                     + " (matrix[" + m + "," + n + "])");
243         return o[i * n + j];
244     }
245
246     /**
247      * Returns a sub-matrix of this matrix given the range of its rows and
248      * columns indices.
249      *
250      * @param i0 the initial row index.
251      * @param i1 the final row index.
252      * @param j0 the initial column index.
253      * @param j1 the final column index.
254      * @return <code>THIS(i0:i1, j0:j1)</code>
255      */

256     public final Matrix<O> getMatrix(int i0, int i1, int j0, int j1) {
257         int Mm = i1 - i0 + 1;
258         int Mn = j1 - j0 + 1;
259         Matrix<O> M = newInstance(Mm, Mn);
260         for (int i = 0; i < Mm; i++) {
261             for (int j = 0; j < Mn; j++) {
262                 M.o[i * Mn + j] = this.o[(i + i0) * m + j + j0];
263             }
264         }
265         return M;
266     }
267
268     /**
269      * Returns a sub-matrix composed of the specified rows and columns from
270      * this matrix.
271      *
272      * @param rows the indices of the rows to return.
273      * @param columns the indices of the columns to return.
274      * @return the sub-matrix from the specified rows and columns.
275      */

276     public final Matrix<O> getMatrix(int[] rows, int[] columns) {
277         int Mn = rows.length;
278         int Mm = columns.length;
279         Matrix<O> M = newInstance(Mm, Mn);
280         for (int i = 0; i < Mm; i++) {
281             for (int j = 0; j < Mn; j++) {
282                 M.o[i * Mn + j] = this.o[rows[i] * n + columns[j]];
283             }
284         }
285         return M;
286     }
287
288     /**
289      * Returns the {@link LUDecomposition} of this {@link Matrix}.
290      * Numerical stability is guaranteed (through pivoting) if the
291      * {@link Operable} elements of this matrix are derived from
292      * {@link org.jscience.mathematics.numbers.Numeric Numeric}.
293      * For others elements types, numerical stability can be ensured by setting
294      * a local {@link LUDecomposition#setPivotComparator pivot comparator}.
295      *
296      * @return the decomposition of this matrix into a product of upper and
297      * lower triangular matrices.
298      */

299     public final LUDecomposition<O> lu() {
300         return LUDecomposition.valueOf(this);
301     }
302
303     /**
304      * Indicates if this matrix is equal to the object specified.
305      *
306      * @param that the object to compare for equality.
307      * @return <code>true</code> if this matrix and the specified object are
308      * considered equal; <code>false</code> otherwise.
309      */

310     public boolean equals(Object JavaDoc that) {
311         if (this == that) {
312             return true;
313         } else if (that instanceof Matrix) {
314             Matrix M = (Matrix) that;
315             if (M.m != this.m || M.n != this.n) {
316                 return false;
317             } else {
318                 for (int i = m * n; i > 0;) {
319                     if (!this.o[--i].equals(M.o[i])) {
320                         return false;
321                     }
322                 }
323                 return true;
324             }
325         } else {
326             return false;
327         }
328     }
329
330     /**
331      * Returns a hash code value for this matrix.
332      * Equals object have equal hash codes.
333      *
334      * @return this matrix hash code value.
335      * @see #equals
336      */

337     public int hashCode() {
338         int code = 0;
339         for (int i = m * n; i > 0;) {
340             code += o[--i].hashCode();
341         }
342         return code;
343     }
344
345     /**
346      * Returns the negation of this matrix.
347      *
348      * @return <code>-this</code>.
349      */

350     public Matrix<O> opposite() {
351         Matrix<O> M = newInstance(m, n);
352         for (int i = m * n; i > 0;) {
353             M.o[--i] = this.o[i].opposite();
354         }
355         return M;
356     }
357
358     /**
359      * Returns the sum of this matrix with the one specified.
360      *
361      * @param that the matrix to be added.
362      * @return <code>this + that</code>.
363      * @throws MatrixException matrices's dimensions are different.
364      */

365     public Matrix<O> plus(Matrix<O> that) {
366         if ((this.m == that.m) && (this.n == that.n)) {
367             Matrix<O> M = newInstance(m, n);
368             for (int i = m * n; i > 0;) {
369                 M.o[--i] = this.o[i].plus(that.o[i]);
370             }
371             return M;
372         } else {
373             throw new MatrixException();
374         }
375     }
376
377     /**
378      * Returns the difference between this matrix and the one specified.
379      *
380      * @param that the matrix to be subtracted.
381      * @return <code>this - that</code>.
382      * @throws MatrixException matrices's dimensions are different.
383      */

384     public Matrix<O> minus(Matrix<O> that) {
385         if ((this.m == that.m) && (this.n == that.n)) {
386             Matrix<O> M = newInstance(m, n);
387             for (int i = m * n; i > 0;) {
388                 M.o[--i] = this.o[i].plus(that.o[i].opposite());
389             }
390             return M;
391         } else {
392             throw new MatrixException();
393         }
394     }
395
396     /**
397      * Return the product of this matrix with the specified factor.
398      *
399      * @param k the coefficient multiplier.
400      * @return <code>k * M</code>.
401      */

402     public Matrix<O> times(O k) {
403         Matrix<O> M = newInstance(m, n);
404         for (int i = m * n; i > 0;) {
405             M.o[--i] = k.times(this.o[i]);
406         }
407         return M;
408     }
409
410     /**
411      * Returns the product of this matrix with the one specified.
412      *
413      * @param that the matrix multiplier.
414      * @return <code>this * that</code>.
415      * @throws MatrixException <code>M.getRowDimension()
416      * != this.getColumnDimension()</code>.
417      */

418     public Matrix<O> times(Matrix<O> that) {
419         if (this.n == that.m) {
420             Matrix<O> M = newInstance(this.m, that.n);
421             for (int i = 0; i < this.m; i++) {
422                 final int i_m = i * n;
423                 for (int j = 0; j < that.n; j++) {
424                     O sum = this.o[i_m].times(that.o[j]);
425                     for (int k = 1; k < this.n; k++) {
426                         sum = sum.plus(this.o[i_m + k].times(that.o[k * that.n
427                                 + j]));
428                     }
429                     M.o[i * M.n + j] = sum;
430                 }
431             }
432             return M;
433         } else {
434             throw new MatrixException();
435         }
436     }
437
438     /**
439      * Returns this matrix divided by the one specified.
440      *
441      * @param that the matrix divisor.
442      * @return <code>this / that</code>.
443      * @throws MatrixException if that matrix is not square or dimensions
444      * do not match.
445      */

446     public Matrix<O> divide(Matrix<O> that) {
447         return this.times(that.reciprocal());
448     }
449
450     /**
451      * Returns the reciprocal of this matrix (must be square).
452      *
453      * @return <code>1 / this</code>
454      * @throws MatrixException if this matrix is not square.
455      * @see #lu
456      */

457     public Matrix<O> reciprocal() {
458         if (!isSquare())
459             throw new MatrixException("Matrix not square");
460         return lu().inverse();
461     }
462
463     /**
464      * Returns the inverse or pseudo-inverse if this matrix if not square.
465      *
466      * <p> Note: To resolve the equation <code>A * X = B</code>,
467      * it is usually faster to calculate <code>A.lu().solve(B)</code>
468      * rather than <code>A.inverse().times(B)</code>.</p>
469      *
470      * @return the inverse or pseudo-inverse of this matrix.
471      * @see #lu
472      */

473     public Matrix<O> inverse() {
474         if (isSquare())
475             return lu().inverse();
476         Matrix<O> thisTranspose = this.transpose();
477         return (thisTranspose.times(this)).inverse().times(thisTranspose);
478     }
479
480     /**
481      * Returns the linear algebraic matrix tensor product of this matrix
482      * and another.
483      *
484      * @param that the second matrix.
485      * @return the Kronecker Tensor (direct) product of <code>this</code>
486      * and <code>that</code>.
487      * @since January 2002, by Jonathan Grattage (jjg99c@cs.nott.ac.uk).
488      */

489     public Matrix<O> tensor(Matrix<O> that) {
490         Matrix<O> C = newInstance(this.m * that.m, this.n * that.n);
491         boolean endCol = false;
492         int cCount = 0, rCount = 0;
493         int subMatrix = 0, iref = 0, jref = 0;
494         for (int j = 0; j < n; j++) {
495             for (int i = 0; i < m; i++) {
496                 Matrix<O> X = that.times(o[i * this.n + j]);
497                 rCount = subMatrix % m;
498                 if (rCount > 0) {
499                     endCol = true;
500                 }
501                 if ((rCount == 0) && (endCol == true)) {
502                     cCount++;
503                 }
504                 for (int y = 0; y < that.n; y++) {
505                     for (int x = 0; x < that.m; x++) {
506                         iref = x + (rCount * that.m);
507                         jref = y + (cCount * that.m);
508                         C.o[iref * C.n + jref] = X.get(x, y);
509                     }
510                 }
511                 subMatrix++;
512             }
513         }
514         return C;
515     }
516
517     /**
518      * Returns the text representation of this matrix.
519      *
520      * @return the text representation of this matrix.
521      */

522     public Text toText() {
523         TextBuilder cb = TextBuilder.newInstance();
524         cb.append("{");
525         for (int i = 0; i < m; i++) {
526             cb.append("{");
527             for (int j = 0; j < n; j++) {
528                 cb.append(o[i * n + j]);
529                 if (j != n - 1) {
530                     cb.append(", ");
531                 }
532             }
533             if (i != m - 1) {
534                 cb.append("},\n");
535             }
536         }
537         cb.append("}}");
538         return cb.toText();
539     }
540
541     /**
542      * Returns the transpose of this matrix.
543      *
544      * @return <code>A'</code>.
545      */

546     public Matrix<O> transpose() {
547         Matrix<O> M = newInstance(n, m);
548         for (int i = 0; i < m; i++) {
549             for (int j = 0; j < n; j++) {
550                 M.o[j * m + i] = o[i * n + j];
551             }
552         }
553         return M;
554     }
555
556     /**
557      * Returns the determinant of this matrix. This method uses the matrix
558      * LU decomposition to guarantee correct results even for
559      * non-commutative operables (the famous formula: <i>a00·a11-a10·a01</i>
560      * for 2x2 matrices is incorrect when operables are non-commutative).
561      *
562      * @return <code>lu().determinant()</code>
563      * @throws MatrixException matrix is not square.
564      */

565     public O determinant() {
566         return (O) lu().determinant();
567     }
568
569     /**
570      * Returns the cofactor of an element in this matrix. It is the value
571      * obtained by evaluating the determinant formed by the elements not in
572      * that particular row or column.
573      *
574      * @param i the row index.
575      * @param j the column index.
576      * @return the cofactor of <code>THIS[i,j]</code>.
577      * @throws MatrixException matrix is not square or its dimension
578      * is less than 2.
579      */

580     public O cofactor(int i, int j) {
581         Matrix<O> M = newInstance(m - 1, n - 1);
582         int row = 0;
583         for (int k1 = 0; k1 < m; k1++) {
584             if (k1 == i) {
585                 continue;
586             }
587             int column = 0;
588             for (int k2 = 0; k2 < n; k2++) {
589                 if (k2 == j) {
590                     continue;
591                 }
592                 M.o[row * M.n + column] = o[k1 * n + k2];
593                 column++;
594             }
595             row++;
596         }
597         return M.determinant();
598     }
599
600     /**
601      * Returns the trace of this matrix.
602      *
603      * @return the sum of the diagonal elements.
604      */

605     public O trace() {
606         O sum = o[0];
607         for (int i = MathLib.min(m, n); i > 1;) {
608             sum = sum.plus(o[--i * n + i]);
609         }
610         return sum;
611     }
612
613     /**
614      * Returns the adjoint of this matrix. It is obtained by replacing each
615      * element in this matrix with its cofactor and applying a + or - sign
616      * according (-1)**(i+j), and then finding the transpose of the resulting
617      * matrix.
618      *
619      * @return the adjoint of this matrix.
620      * @throws MatrixException if this matrix is not square or if
621      * its dimension is less than 2.
622      */

623     public Matrix<O> adjoint() {
624         Matrix<O> M = newInstance(m, n);
625         for (int i = 0; i < m; i++) {
626             for (int j = 0; j < n; j++) {
627                 M.o[i * n + j] = ((i + j) % 2 == 0) ? this.cofactor(i, j)
628                         : this.cofactor(i, j).opposite();
629             }
630         }
631         return M.transpose();
632     }
633
634     /**
635      * Returns this matrix raised at the specified exponent.
636      *
637      * @param exp the exponent.
638      * @return <code>this<sup>exp</sup></code>
639      * @throws MatrixException if this matrix is not square.
640      */

641     public Matrix<O> pow(int exp) {
642         if (exp > 0) {
643             PoolContext.enter();
644             try {
645                 Matrix<O> pow2 = this;
646                 Matrix<O> result = null;
647                 while (exp >= 1) { // Iteration.
648
if ((exp & 1) == 1) {
649                         result = (result == null) ? pow2 : result.times(pow2);
650                     }
651                     pow2 = pow2.times(pow2);
652                     exp >>>= 1;
653                 }
654                 result.export();
655                 return result;
656             } finally {
657                 PoolContext.exit();
658             }
659         } else if (exp == 0) {
660             return this.times(this.inverse()); // Identity.
661
} else {
662             return this.pow(-exp).inverse();
663         }
664     }
665
666     // Overrides.
667
public boolean move(ObjectSpace os) {
668         if (super.move(os)) {
669             for (int i = m * n; i > 0;) {
670                 o[--i].move(os);
671             }
672             return true;
673         }
674         return false;
675     }
676
677     /**
678      * Returns a m-by-n matrix filled with <code>null</code> elements.
679      *
680      * @param m the number of rows.
681      * @param n the number of columns.
682      * @return a m-by-n matrix non-initialized (a {@link Vector} instance
683      * if <code>n == 1</code>).
684      */

685     static <O extends Operable<O>> Matrix<O> newInstance(int m, int n) {
686         if (n == 1)
687             return Vector.newInstance(m);
688         Matrix M;
689         final int size = n * m;
690         if (size <= 1 << 3) {
691             M = FACTORY_3.object();
692         } else if (size <= 1 << 6) {
693             M = FACTORY_6.object();
694         } else if (size <= 1 << 9) {
695             M = FACTORY_9.object();
696         } else if (size <= 1 << 12) {
697             M = FACTORY_12.object();
698         } else if (size <= 1 << 15) {
699             M = FACTORY_15.object();
700         } else if (size <= 1 << 18) {
701             M = FACTORY_18.object();
702         } else if (size <= 1 << 21) {
703             M = FACTORY_21.object();
704         } else if (size <= 1 << 24) {
705             M = FACTORY_24.object();
706         } else if (size <= 1 << 27) {
707             M = FACTORY_27.object();
708         } else if (size <= 1 << 30) {
709             M = FACTORY_30.object();
710         } else {
711             throw new UnsupportedOperationException JavaDoc("Matrix too large");
712         }
713         M.m = m;
714         M.n = n;
715         return M;
716     }
717
718     // TBD: Use recursive structures (North, East, South, West)
719
// instead of large arrays.
720

721     private static final Factory<Matrix> FACTORY_3 = new Factory<Matrix>() {
722         protected Matrix create() {
723             return new Matrix(1 << 3);
724         }
725     };
726
727     private static final Factory<Matrix> FACTORY_6 = new Factory<Matrix>() {
728         protected Matrix create() {
729             return new Matrix(1 << 6);
730         }
731     };
732
733     private static final Factory<Matrix> FACTORY_9 = new Factory<Matrix>() {
734         protected Matrix create() {
735             return new Matrix(1 << 9);
736         }
737     };
738
739     private static final Factory<Matrix> FACTORY_12 = new Factory<Matrix>() {
740         protected Matrix create() {
741             return new Matrix(1 << 12);
742         }
743     };
744
745     private static final Factory<Matrix> FACTORY_15 = new Factory<Matrix>() {
746         protected Matrix create() {
747             return new Matrix(1 << 15);
748         }
749     };
750
751     private static final Factory<Matrix> FACTORY_18 = new Factory<Matrix>() {
752         protected Matrix create() {
753             return new Matrix(1 << 18);
754         }
755     };
756
757     private static final Factory<Matrix> FACTORY_21 = new Factory<Matrix>() {
758         protected Matrix create() {
759             return new Matrix(1 << 21);
760         }
761     };
762
763     private static final Factory<Matrix> FACTORY_24 = new Factory<Matrix>() {
764         protected Matrix create() {
765             return new Matrix(1 << 24);
766         }
767     };
768
769     private static final Factory<Matrix> FACTORY_27 = new Factory<Matrix>() {
770         protected Matrix create() {
771             return new Matrix(1 << 27);
772         }
773     };
774
775     private static final Factory<Matrix> FACTORY_30 = new Factory<Matrix>() {
776         protected Matrix create() {
777             return new Matrix(1 << 30);
778         }
779     };
780
781     private static final long serialVersionUID = 1L;
782
783 }
Popular Tags