001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.matrix;
025    
026    import java.io.File;
027    import java.io.IOException;
028    import java.io.OutputStream;
029    import java.io.Writer;
030    import java.lang.reflect.Constructor;
031    import java.lang.reflect.Method;
032    import java.math.BigDecimal;
033    import java.math.BigInteger;
034    import java.util.ArrayList;
035    import java.util.Arrays;
036    import java.util.Collection;
037    import java.util.Date;
038    import java.util.Iterator;
039    import java.util.List;
040    import java.util.regex.Pattern;
041    
042    import javax.swing.JFrame;
043    
044    import org.ujmp.core.Coordinates;
045    import org.ujmp.core.Matrix;
046    import org.ujmp.core.MatrixFactory;
047    import org.ujmp.core.annotation.Annotation;
048    import org.ujmp.core.annotation.DefaultAnnotation;
049    import org.ujmp.core.bigdecimalmatrix.BigDecimalMatrix;
050    import org.ujmp.core.bigdecimalmatrix.calculation.ToBigDecimalMatrix;
051    import org.ujmp.core.bigintegermatrix.BigIntegerMatrix;
052    import org.ujmp.core.bigintegermatrix.calculation.ToBigIntegerMatrix;
053    import org.ujmp.core.booleanmatrix.BooleanMatrix;
054    import org.ujmp.core.booleanmatrix.calculation.And;
055    import org.ujmp.core.booleanmatrix.calculation.Eq;
056    import org.ujmp.core.booleanmatrix.calculation.Ge;
057    import org.ujmp.core.booleanmatrix.calculation.Gt;
058    import org.ujmp.core.booleanmatrix.calculation.Le;
059    import org.ujmp.core.booleanmatrix.calculation.Lt;
060    import org.ujmp.core.booleanmatrix.calculation.Ne;
061    import org.ujmp.core.booleanmatrix.calculation.Not;
062    import org.ujmp.core.booleanmatrix.calculation.Or;
063    import org.ujmp.core.booleanmatrix.calculation.ToBooleanMatrix;
064    import org.ujmp.core.booleanmatrix.calculation.Xor;
065    import org.ujmp.core.bytematrix.ByteMatrix;
066    import org.ujmp.core.bytematrix.calculation.ToByteMatrix;
067    import org.ujmp.core.calculation.Calculation;
068    import org.ujmp.core.calculation.Calculation.Ret;
069    import org.ujmp.core.charmatrix.CharMatrix;
070    import org.ujmp.core.charmatrix.calculation.ToCharMatrix;
071    import org.ujmp.core.datematrix.DateMatrix;
072    import org.ujmp.core.datematrix.calculation.ToDateMatrix;
073    import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
074    import org.ujmp.core.doublematrix.DoubleMatrix;
075    import org.ujmp.core.doublematrix.calculation.ToDoubleMatrix;
076    import org.ujmp.core.doublematrix.calculation.basic.Atimes;
077    import org.ujmp.core.doublematrix.calculation.basic.Divide;
078    import org.ujmp.core.doublematrix.calculation.basic.Minus;
079    import org.ujmp.core.doublematrix.calculation.basic.Mtimes;
080    import org.ujmp.core.doublematrix.calculation.basic.Plus;
081    import org.ujmp.core.doublematrix.calculation.basic.Times;
082    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Abs;
083    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Exp;
084    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Log;
085    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Log10;
086    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Log2;
087    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Power;
088    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Sign;
089    import org.ujmp.core.doublematrix.calculation.entrywise.basic.Sqrt;
090    import org.ujmp.core.doublematrix.calculation.entrywise.creators.Eye;
091    import org.ujmp.core.doublematrix.calculation.entrywise.creators.Ones;
092    import org.ujmp.core.doublematrix.calculation.entrywise.creators.Rand;
093    import org.ujmp.core.doublematrix.calculation.entrywise.creators.Randn;
094    import org.ujmp.core.doublematrix.calculation.entrywise.creators.Zeros;
095    import org.ujmp.core.doublematrix.calculation.entrywise.hyperbolic.Cosh;
096    import org.ujmp.core.doublematrix.calculation.entrywise.hyperbolic.Sinh;
097    import org.ujmp.core.doublematrix.calculation.entrywise.hyperbolic.Tanh;
098    import org.ujmp.core.doublematrix.calculation.entrywise.rounding.Ceil;
099    import org.ujmp.core.doublematrix.calculation.entrywise.rounding.Floor;
100    import org.ujmp.core.doublematrix.calculation.entrywise.rounding.Round;
101    import org.ujmp.core.doublematrix.calculation.entrywise.trigonometric.Cos;
102    import org.ujmp.core.doublematrix.calculation.entrywise.trigonometric.Sin;
103    import org.ujmp.core.doublematrix.calculation.entrywise.trigonometric.Tan;
104    import org.ujmp.core.doublematrix.calculation.general.decomposition.Chol;
105    import org.ujmp.core.doublematrix.calculation.general.decomposition.Eig;
106    import org.ujmp.core.doublematrix.calculation.general.decomposition.Ginv;
107    import org.ujmp.core.doublematrix.calculation.general.decomposition.Inv;
108    import org.ujmp.core.doublematrix.calculation.general.decomposition.InvSPD;
109    import org.ujmp.core.doublematrix.calculation.general.decomposition.LU;
110    import org.ujmp.core.doublematrix.calculation.general.decomposition.Pinv;
111    import org.ujmp.core.doublematrix.calculation.general.decomposition.Princomp;
112    import org.ujmp.core.doublematrix.calculation.general.decomposition.QR;
113    import org.ujmp.core.doublematrix.calculation.general.decomposition.SVD;
114    import org.ujmp.core.doublematrix.calculation.general.decomposition.Solve;
115    import org.ujmp.core.doublematrix.calculation.general.decomposition.SolveSPD;
116    import org.ujmp.core.doublematrix.calculation.general.misc.Center;
117    import org.ujmp.core.doublematrix.calculation.general.misc.DiscretizeToColumns;
118    import org.ujmp.core.doublematrix.calculation.general.misc.FadeIn;
119    import org.ujmp.core.doublematrix.calculation.general.misc.FadeOut;
120    import org.ujmp.core.doublematrix.calculation.general.misc.Normalize;
121    import org.ujmp.core.doublematrix.calculation.general.misc.Standardize;
122    import org.ujmp.core.doublematrix.calculation.general.misc.TfIdf;
123    import org.ujmp.core.doublematrix.calculation.general.missingvalues.AddMissing;
124    import org.ujmp.core.doublematrix.calculation.general.missingvalues.CountMissing;
125    import org.ujmp.core.doublematrix.calculation.general.missingvalues.Impute;
126    import org.ujmp.core.doublematrix.calculation.general.missingvalues.Impute.ImputationMethod;
127    import org.ujmp.core.doublematrix.calculation.general.statistical.Corrcoef;
128    import org.ujmp.core.doublematrix.calculation.general.statistical.Cov;
129    import org.ujmp.core.doublematrix.calculation.general.statistical.Cumprod;
130    import org.ujmp.core.doublematrix.calculation.general.statistical.Cumsum;
131    import org.ujmp.core.doublematrix.calculation.general.statistical.Diff;
132    import org.ujmp.core.doublematrix.calculation.general.statistical.IndexOfMax;
133    import org.ujmp.core.doublematrix.calculation.general.statistical.IndexOfMin;
134    import org.ujmp.core.doublematrix.calculation.general.statistical.Max;
135    import org.ujmp.core.doublematrix.calculation.general.statistical.Mean;
136    import org.ujmp.core.doublematrix.calculation.general.statistical.Min;
137    import org.ujmp.core.doublematrix.calculation.general.statistical.MutualInformation;
138    import org.ujmp.core.doublematrix.calculation.general.statistical.Prod;
139    import org.ujmp.core.doublematrix.calculation.general.statistical.Std;
140    import org.ujmp.core.doublematrix.calculation.general.statistical.Sum;
141    import org.ujmp.core.doublematrix.calculation.general.statistical.Var;
142    import org.ujmp.core.enums.FileFormat;
143    import org.ujmp.core.enums.ValueType;
144    import org.ujmp.core.exceptions.MatrixException;
145    import org.ujmp.core.floatmatrix.FloatMatrix;
146    import org.ujmp.core.floatmatrix.calculation.ToFloatMatrix;
147    import org.ujmp.core.interfaces.GUIObject;
148    import org.ujmp.core.interfaces.HasColumnMajorDoubleArray1D;
149    import org.ujmp.core.interfaces.HasLabel;
150    import org.ujmp.core.interfaces.HasRowMajorDoubleArray2D;
151    import org.ujmp.core.intmatrix.IntMatrix;
152    import org.ujmp.core.intmatrix.calculation.Discretize;
153    import org.ujmp.core.intmatrix.calculation.ToIntMatrix;
154    import org.ujmp.core.intmatrix.calculation.Discretize.DiscretizationMethod;
155    import org.ujmp.core.io.ExportMatrix;
156    import org.ujmp.core.listmatrix.DefaultListMatrix;
157    import org.ujmp.core.listmatrix.ListMatrix;
158    import org.ujmp.core.longmatrix.LongMatrix;
159    import org.ujmp.core.longmatrix.calculation.ToLongMatrix;
160    import org.ujmp.core.mapmatrix.DefaultMapMatrix;
161    import org.ujmp.core.mapmatrix.MapMatrix;
162    import org.ujmp.core.matrix.factory.MatrixFactoryRoot;
163    import org.ujmp.core.objectmatrix.ObjectMatrix;
164    import org.ujmp.core.objectmatrix.calculation.Bootstrap;
165    import org.ujmp.core.objectmatrix.calculation.Convert;
166    import org.ujmp.core.objectmatrix.calculation.Deletion;
167    import org.ujmp.core.objectmatrix.calculation.ExtractAnnotation;
168    import org.ujmp.core.objectmatrix.calculation.Fill;
169    import org.ujmp.core.objectmatrix.calculation.Flipdim;
170    import org.ujmp.core.objectmatrix.calculation.IncludeAnnotation;
171    import org.ujmp.core.objectmatrix.calculation.Replace;
172    import org.ujmp.core.objectmatrix.calculation.Reshape;
173    import org.ujmp.core.objectmatrix.calculation.Selection;
174    import org.ujmp.core.objectmatrix.calculation.Shuffle;
175    import org.ujmp.core.objectmatrix.calculation.Sortrows;
176    import org.ujmp.core.objectmatrix.calculation.Squeeze;
177    import org.ujmp.core.objectmatrix.calculation.Swap;
178    import org.ujmp.core.objectmatrix.calculation.ToObjectMatrix;
179    import org.ujmp.core.objectmatrix.calculation.Transpose;
180    import org.ujmp.core.objectmatrix.calculation.Tril;
181    import org.ujmp.core.objectmatrix.calculation.Triu;
182    import org.ujmp.core.objectmatrix.calculation.Unique;
183    import org.ujmp.core.objectmatrix.calculation.UniqueValueCount;
184    import org.ujmp.core.objectmatrix.factory.DefaultDenseObjectMatrixFactory;
185    import org.ujmp.core.setmatrix.DefaultSetMatrix;
186    import org.ujmp.core.setmatrix.SetMatrix;
187    import org.ujmp.core.shortmatrix.ShortMatrix;
188    import org.ujmp.core.shortmatrix.calculation.ToShortMatrix;
189    import org.ujmp.core.stringmatrix.StringMatrix;
190    import org.ujmp.core.stringmatrix.calculation.LowerCase;
191    import org.ujmp.core.stringmatrix.calculation.RemovePunctuation;
192    import org.ujmp.core.stringmatrix.calculation.RemoveWords;
193    import org.ujmp.core.stringmatrix.calculation.ReplaceRegex;
194    import org.ujmp.core.stringmatrix.calculation.Stem;
195    import org.ujmp.core.stringmatrix.calculation.ToStringMatrix;
196    import org.ujmp.core.stringmatrix.calculation.UpperCase;
197    import org.ujmp.core.util.CoordinateIterator;
198    import org.ujmp.core.util.DecompositionOps;
199    import org.ujmp.core.util.MathUtil;
200    import org.ujmp.core.util.StringUtil;
201    import org.ujmp.core.util.UJMPFormat;
202    import org.ujmp.core.util.UJMPSettings;
203    
204    public abstract class AbstractMatrix extends Number implements Matrix {
205            private static final long serialVersionUID = 5264103919889924711L;
206    
207            public static MatrixFactoryRoot factory = new DefaultDenseObjectMatrixFactory();
208    
209            private static long runningId = 0;
210    
211            static {
212                    try {
213                            runningId = 31 * System.nanoTime() + System.currentTimeMillis();
214                    } catch (Throwable t) {
215                    }
216                    try {
217                            DecompositionOps.init();
218                    } catch (Throwable t) {
219                    }
220                    try {
221                            UJMPSettings.initialize();
222                    } catch (Throwable t) {
223                    }
224                    try {
225                            long mem = Runtime.getRuntime().maxMemory();
226                            if (mem < 133234688) {
227                                    System.err.println("Available memory is very low: " + (mem / 1000000) + "M");
228                                    System.err
229                                                    .println("Invoke Java with the parameter -Xmx512M to increase available memory");
230                            }
231                    } catch (Throwable t) {
232                    }
233            }
234    
235            private transient GUIObject guiObject = null;
236    
237            private final long id;
238    
239            private Annotation annotation = null;
240    
241            public AbstractMatrix() {
242                    id = runningId++;
243            }
244    
245            public Iterable<long[]> allCoordinates() {
246                    return new CoordinateIterator(getSize());
247            }
248    
249            public final long getCoreObjectId() {
250                    return id;
251            }
252    
253            public double getAsDouble(long... coordinates) {
254                    return MathUtil.getDouble(getAsObject(coordinates));
255            }
256    
257            public void setAsDouble(double v, long... coordinates) {
258                    setAsObject(v, coordinates);
259            }
260    
261            public final Object getPreferredObject(long... coordinates) throws MatrixException {
262                    return MathUtil.getPreferredObject(getAsObject(coordinates));
263            }
264    
265            public final Object getMatrixAnnotation() {
266                    return annotation == null ? null : annotation.getMatrixAnnotation();
267            }
268    
269            public ValueType getValueType() {
270                    return ValueType.OBJECT;
271            }
272    
273            public final void setMatrixAnnotation(Object value) {
274                    if (annotation == null) {
275                            annotation = new DefaultAnnotation(getSize());
276                    }
277                    annotation.setMatrixAnnotation(value);
278            }
279    
280            public final Object getAxisAnnotation(int axis, long... position) {
281                    return annotation == null ? null : annotation.getAxisAnnotation(axis, position);
282            }
283    
284            public final Object getAxisAnnotation(int axis) {
285                    return annotation == null ? null : annotation.getAxisAnnotation(axis);
286            }
287    
288            public final void setAxisAnnotation(int axis, Object label, long... position) {
289                    if (annotation == null) {
290                            annotation = new DefaultAnnotation(getSize());
291                    }
292                    annotation.setAxisAnnotation(axis, label, position);
293            }
294    
295            public final void setAxisAnnotation(int axis, Object label) {
296                    if (annotation == null) {
297                            annotation = new DefaultAnnotation(getSize());
298                    }
299                    annotation.setAxisAnnotation(axis, label);
300            }
301    
302            public final GUIObject getGUIObject() {
303                    if (guiObject == null) {
304                            try {
305                                    Class<?> c = Class.forName("org.ujmp.gui.MatrixGUIObject");
306                                    Constructor<?> con = c.getConstructor(new Class<?>[] { Matrix.class });
307                                    guiObject = (GUIObject) con.newInstance(new Object[] { this });
308                            } catch (Exception e) {
309                                    throw new MatrixException("cannot create matrix gui object", e);
310                            }
311                    }
312                    return guiObject;
313            }
314    
315            public final boolean containsMissingValues() throws MatrixException {
316                    for (long[] c : allCoordinates()) {
317                            double v = getAsDouble(c);
318                            if (MathUtil.isNaNOrInfinite(v)) {
319                                    return true;
320                            }
321                    }
322                    return false;
323            }
324    
325            public final double getEuklideanValue() throws MatrixException {
326                    double sum = 0.0;
327                    for (long[] c : allCoordinates()) {
328                            sum += Math.pow(getAsDouble(c), 2.0);
329                    }
330                    return Math.sqrt(sum);
331            }
332    
333            public Matrix clone() {
334                    return copy();
335            }
336    
337            public final Matrix select(Ret returnType, long[]... selection) throws MatrixException {
338                    return new Selection(this, selection).calc(returnType);
339            }
340    
341            public final Matrix select(Ret returnType, Collection<? extends Number>... selection)
342                            throws MatrixException {
343                    return new Selection(this, selection).calc(returnType);
344            }
345    
346            public Matrix selectRows(Ret returnType, long... rows) throws MatrixException {
347                    return select(returnType, rows, null);
348            }
349    
350            public final Matrix select(Ret returnType, String selection) throws MatrixException {
351                    return new Selection(this, selection).calc(returnType);
352            }
353    
354            public Matrix selectColumns(Ret returnType, long... columns) throws MatrixException {
355                    return select(returnType, null, columns);
356            }
357    
358            @SuppressWarnings("unchecked")
359            public final Matrix selectRows(Ret returnType, Collection<? extends Number> rows)
360                            throws MatrixException {
361                    return select(returnType, rows, null);
362            }
363    
364            @SuppressWarnings("unchecked")
365            public final Matrix selectColumns(Ret returnType, Collection<? extends Number> columns)
366                            throws MatrixException {
367                    return select(returnType, null, columns);
368            }
369    
370            public Matrix impute(Ret returnType, ImputationMethod method, Object... parameters)
371                            throws MatrixException {
372                    return new Impute(this, method, parameters).calc(returnType);
373            }
374    
375            public Matrix discretize(Ret returnType, int dimension, DiscretizationMethod method,
376                            int numberOfBins) throws MatrixException {
377                    return new Discretize(this, dimension, method, numberOfBins).calc(returnType);
378            }
379    
380            public Matrix indexOfMax(Ret returnType, int dimension) throws MatrixException {
381                    return new IndexOfMax(dimension, this).calc(returnType);
382            }
383    
384            public Matrix indexOfMin(Ret returnType, int dimension) throws MatrixException {
385                    return new IndexOfMin(dimension, this).calc(returnType);
386            }
387    
388            public Matrix standardize(Ret returnType, int dimension) throws MatrixException {
389                    return new Standardize(dimension, this).calc(returnType);
390            }
391    
392            public Matrix normalize(Ret returnType, int dimension) throws MatrixException {
393                    return new Normalize(dimension, this).calc(returnType);
394            }
395    
396            public Matrix atimes(Ret returnType, boolean ignoreNaN, Matrix matrix) throws MatrixException {
397                    return new Atimes(ignoreNaN, this, matrix).calc(returnType);
398            }
399    
400            public Matrix inv() throws MatrixException {
401                    return Inv.INSTANCE.calc(this);
402            }
403    
404            public Matrix invSymm() throws MatrixException {
405                    return Inv.INSTANCE.calc(this);
406            }
407    
408            public Matrix invSPD() throws MatrixException {
409                    return InvSPD.INSTANCE.calc(this);
410            }
411    
412            public Matrix solve(Matrix b) {
413                    return Solve.INSTANCE.calc(this, b);
414            }
415    
416            public Matrix solveSymm(Matrix b) {
417                    return Solve.INSTANCE.calc(this, b);
418            }
419    
420            public Matrix solveSPD(Matrix b) {
421                    return SolveSPD.INSTANCE.calc(this, b);
422            }
423    
424            public Matrix ginv() throws MatrixException {
425                    return new Ginv(this).calcNew();
426            }
427    
428            public Matrix princomp() throws MatrixException {
429                    return new Princomp(this).calcNew();
430            }
431    
432            public Matrix pinv() throws MatrixException {
433                    return new Pinv(this).calcNew();
434            }
435    
436            public Matrix center(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
437                    return new Center(ignoreNaN, dimension, this).calc(returnType);
438            }
439    
440            /**
441             * @deprecated Please do not use this method anymore, it will be removed.
442             *             use <code>matrix.clone()</code> instead
443             */
444            public Matrix copy() throws MatrixException {
445                    return Convert.calcNew(this);
446            }
447    
448            public boolean isResizable() {
449                    return false;
450            }
451    
452            public final Matrix convert(ValueType newValueType) throws MatrixException {
453                    return Convert.calcNew(newValueType, this);
454            }
455    
456            public final Matrix replaceRegex(Ret returnType, Pattern search, String replacement)
457                            throws MatrixException {
458                    return new ReplaceRegex(this, search, replacement).calc(returnType);
459            }
460    
461            public final Matrix replace(Ret returnType, Object search, Object replacement)
462                            throws MatrixException {
463                    return new Replace(this, search, replacement).calc(returnType);
464            }
465    
466            public final Matrix replaceRegex(Ret returnType, String search, String replacement)
467                            throws MatrixException {
468                    return new ReplaceRegex(this, search, replacement).calc(returnType);
469            }
470    
471            public Matrix times(double factor) throws MatrixException {
472                    Matrix result = MatrixFactory.like(this);
473                    Matrix.timesScalar.calc(this, factor, result);
474                    return result;
475            }
476    
477            public Matrix times(Matrix m) throws MatrixException {
478                    Matrix result = MatrixFactory.like(this);
479                    Matrix.timesMatrix.calc(this, m, result);
480                    return result;
481            }
482    
483            public Matrix divide(Matrix m) throws MatrixException {
484                    Matrix result = MatrixFactory.like(this);
485                    Matrix.divideMatrix.calc(this, m, result);
486                    return result;
487            }
488    
489            public Matrix divide(double divisor) throws MatrixException {
490                    Matrix result = MatrixFactory.like(this);
491                    Matrix.divideScalar.calc(this, divisor, result);
492                    return result;
493            }
494    
495            public Matrix divide(Ret returnType, boolean ignoreNaN, double factor) throws MatrixException {
496                    return new Divide(ignoreNaN, this, factor).calc(returnType);
497            }
498    
499            public Matrix times(Ret returnType, boolean ignoreNaN, double factor) throws MatrixException {
500                    return new Times(ignoreNaN, this, factor).calc(returnType);
501            }
502    
503            public Matrix times(Ret returnType, boolean ignoreNaN, Matrix factor) throws MatrixException {
504                    return new Times(ignoreNaN, this, factor).calc(returnType);
505            }
506    
507            public Matrix divide(Ret returnType, boolean ignoreNaN, Matrix factor) throws MatrixException {
508                    return new Divide(ignoreNaN, this, factor).calc(returnType);
509            }
510    
511            public final Matrix power(Ret returnType, double power) throws MatrixException {
512                    return new Power(this, power).calc(returnType);
513            }
514    
515            public final Matrix power(Ret returnType, Matrix power) throws MatrixException {
516                    return new Power(this, power).calc(returnType);
517            }
518    
519            public final Matrix gt(Ret returnType, Matrix matrix) throws MatrixException {
520                    return new Gt(this, matrix).calc(returnType);
521            }
522    
523            public final Matrix gt(Ret returnType, double value) throws MatrixException {
524                    return new Gt(this, value).calc(returnType);
525            }
526    
527            public final Matrix and(Ret returnType, Matrix matrix) throws MatrixException {
528                    return new And(this, matrix).calc(returnType);
529            }
530    
531            public final Matrix and(Ret returnType, boolean value) throws MatrixException {
532                    return new And(this, value).calc(returnType);
533            }
534    
535            public final Matrix or(Ret returnType, Matrix matrix) throws MatrixException {
536                    return new Or(this, matrix).calc(returnType);
537            }
538    
539            public final Matrix or(Ret returnType, boolean value) throws MatrixException {
540                    return new Or(this, value).calc(returnType);
541            }
542    
543            public final Matrix xor(Ret returnType, Matrix matrix) throws MatrixException {
544                    return new Xor(this, matrix).calc(returnType);
545            }
546    
547            public final Matrix xor(Ret returnType, boolean value) throws MatrixException {
548                    return new Xor(this, value).calc(returnType);
549            }
550    
551            public final Matrix not(Ret returnType) throws MatrixException {
552                    return new Not(this).calc(returnType);
553            }
554    
555            public final Matrix lt(Ret returnType, Matrix matrix) throws MatrixException {
556                    return new Lt(this, matrix).calc(returnType);
557            }
558    
559            public final Matrix lt(Ret returnType, double value) throws MatrixException {
560                    return new Lt(this, value).calc(returnType);
561            }
562    
563            public final Matrix ge(Ret returnType, Matrix matrix) throws MatrixException {
564                    return new Ge(this, matrix).calc(returnType);
565            }
566    
567            public final Matrix ge(Ret returnType, double value) throws MatrixException {
568                    return new Ge(this, value).calc(returnType);
569            }
570    
571            public final Matrix le(Ret returnType, Matrix matrix) throws MatrixException {
572                    return new Le(this, matrix).calc(returnType);
573            }
574    
575            public final Matrix le(Ret returnType, double value) throws MatrixException {
576                    return new Le(this, value).calc(returnType);
577            }
578    
579            public final Matrix eq(Ret returnType, Matrix matrix) throws MatrixException {
580                    return new Eq(this, matrix).calc(returnType);
581            }
582    
583            public final Matrix eq(Ret returnType, Object value) throws MatrixException {
584                    return new Eq(this, value).calc(returnType);
585            }
586    
587            public final Matrix ne(Ret returnType, Matrix matrix) throws MatrixException {
588                    return new Ne(this, matrix).calc(returnType);
589            }
590    
591            public final Matrix ne(Ret returnType, Object value) throws MatrixException {
592                    return new Ne(this, value).calc(returnType);
593            }
594    
595            public long getValueCount() {
596                    return Coordinates.product(getSize());
597            }
598    
599            public final long[] getCoordinatesOfMaximum() throws MatrixException {
600                    double max = -Double.MAX_VALUE;
601                    long[] maxc = Coordinates.copyOf(getSize());
602                    Arrays.fill(maxc, -1);
603                    for (long[] c : allCoordinates()) {
604                            double v = getAsDouble(c);
605                            if (v > max) {
606                                    max = v;
607                                    maxc = Coordinates.copyOf(c);
608                            }
609                    }
610                    return maxc;
611            }
612    
613            public final long[] getCoordinatesOfMinimum() throws MatrixException {
614                    double min = Double.MAX_VALUE;
615                    long[] minc = Coordinates.copyOf(getSize());
616                    Arrays.fill(minc, -1);
617                    for (long[] c : allCoordinates()) {
618                            double v = getAsDouble(c);
619                            if (v < min) {
620                                    min = v;
621                                    minc = Coordinates.copyOf(c);
622                            }
623                    }
624                    return minc;
625            }
626    
627            public Iterable<long[]> selectedCoordinates(String selection) throws MatrixException {
628                    return select(Ret.LINK, selection).allCoordinates();
629            }
630    
631            public Iterable<long[]> selectedCoordinates(long[]... selection) throws MatrixException {
632                    return select(Ret.LINK, selection).allCoordinates();
633            }
634    
635            public boolean isTransient() {
636                    return false;
637            }
638    
639            public Iterable<long[]> nonZeroCoordinates() {
640                    return availableCoordinates();
641            }
642    
643            public Iterable<long[]> availableCoordinates() {
644                    return allCoordinates();
645            }
646    
647            public double[][] toDoubleArray() throws MatrixException {
648                    final int rows = (int) getRowCount();
649                    final int columns = (int) getColumnCount();
650                    final double[][] values = new double[rows][columns];
651                    if (this instanceof HasColumnMajorDoubleArray1D) {
652                            final double[] m = ((HasColumnMajorDoubleArray1D) this).getColumnMajorDoubleArray1D();
653                            for (int r = 0; r < rows; r++) {
654                                    final double[] valuesr = values[r];
655                                    for (int c = 0; c < columns; c++) {
656                                            valuesr[c] = m[c * rows + r];
657                                    }
658                            }
659                    } else if (this instanceof HasRowMajorDoubleArray2D) {
660                            final double[][] m = ((HasRowMajorDoubleArray2D) this).getRowMajorDoubleArray2D();
661                            for (int r = 0; r < rows; r++) {
662                                    System.arraycopy(m[r], 0, values[r], 0, columns);
663                            }
664                    } else if (this instanceof DenseDoubleMatrix2D) {
665                            final DenseDoubleMatrix2D m = (DenseDoubleMatrix2D) this;
666                            for (int r = 0; r < rows; r++) {
667                                    final double[] valuesr = values[r];
668                                    for (int c = 0; c < columns; c++) {
669                                            valuesr[c] = m.getDouble(r, c);
670                                    }
671                            }
672                    } else {
673                            for (int r = 0; r < rows; r++) {
674                                    final double[] valuesr = values[r];
675                                    for (int c = 0; c < columns; c++) {
676                                            valuesr[c] = getAsDouble(r, c);
677                                    }
678                            }
679                    }
680                    return values;
681            }
682    
683            public Object[][] toObjectArray() throws MatrixException {
684                    int r = (int) getRowCount();
685                    int c = (int) getColumnCount();
686                    Object[][] values = new Object[r][c];
687                    for (int i = 0; i < r; i++) {
688                            for (int j = 0; j < c; j++) {
689                                    values[i][j] = getAsObject(i, j);
690                            }
691                    }
692                    return values;
693            }
694    
695            public int[][] toIntArray() throws MatrixException {
696                    int r = (int) getRowCount();
697                    int c = (int) getColumnCount();
698                    int[][] values = new int[r][c];
699                    for (int i = 0; i < r; i++) {
700                            for (int j = 0; j < c; j++) {
701                                    values[i][j] = getAsInt(i, j);
702                            }
703                    }
704                    return values;
705            }
706    
707            public long[][] toLongArray() throws MatrixException {
708                    int r = (int) getRowCount();
709                    int c = (int) getColumnCount();
710                    long[][] values = new long[r][c];
711                    for (int i = 0; i < r; i++) {
712                            for (int j = 0; j < c; j++) {
713                                    values[i][j] = getAsLong(i, j);
714                            }
715                    }
716                    return values;
717            }
718    
719            public short[][] toShortArray() throws MatrixException {
720                    int r = (int) getRowCount();
721                    int c = (int) getColumnCount();
722                    short[][] values = new short[r][c];
723                    for (int i = 0; i < r; i++) {
724                            for (int j = 0; j < c; j++) {
725                                    values[i][j] = getAsShort(i, j);
726                            }
727                    }
728                    return values;
729            }
730    
731            public char[][] toCharArray() throws MatrixException {
732                    int r = (int) getRowCount();
733                    int c = (int) getColumnCount();
734                    char[][] values = new char[r][c];
735                    for (int i = 0; i < r; i++) {
736                            for (int j = 0; j < c; j++) {
737                                    values[i][j] = getAsChar(i, j);
738                            }
739                    }
740                    return values;
741            }
742    
743            public String[][] toStringArray() throws MatrixException {
744                    int r = (int) getRowCount();
745                    int c = (int) getColumnCount();
746                    String[][] values = new String[r][c];
747                    for (int i = 0; i < r; i++) {
748                            for (int j = 0; j < c; j++) {
749                                    values[i][j] = getAsString(i, j);
750                            }
751                    }
752                    return values;
753            }
754    
755            public byte[][] toByteArray() throws MatrixException {
756                    int r = (int) getRowCount();
757                    int c = (int) getColumnCount();
758                    byte[][] values = new byte[r][c];
759                    for (int i = 0; i < r; i++) {
760                            for (int j = 0; j < c; j++) {
761                                    values[i][j] = getAsByte(i, j);
762                            }
763                    }
764                    return values;
765            }
766    
767            public boolean[][] toBooleanArray() throws MatrixException {
768                    int r = (int) getRowCount();
769                    int c = (int) getColumnCount();
770                    boolean[][] values = new boolean[r][c];
771                    for (int i = 0; i < r; i++) {
772                            for (int j = 0; j < c; j++) {
773                                    values[i][j] = getAsBoolean(i, j);
774                            }
775                    }
776                    return values;
777            }
778    
779            public float[][] toFloatArray() throws MatrixException {
780                    int r = (int) getRowCount();
781                    int c = (int) getColumnCount();
782                    float[][] values = new float[r][c];
783                    for (int i = 0; i < r; i++) {
784                            for (int j = 0; j < c; j++) {
785                                    values[i][j] = getAsFloat(i, j);
786                            }
787                    }
788                    return values;
789            }
790    
791            public Date[][] toDateArray() throws MatrixException {
792                    int r = (int) getRowCount();
793                    int c = (int) getColumnCount();
794                    Date[][] values = new Date[r][c];
795                    for (int i = 0; i < r; i++) {
796                            for (int j = 0; j < c; j++) {
797                                    values[i][j] = getAsDate(i, j);
798                            }
799                    }
800                    return values;
801            }
802    
803            public BigDecimal[][] toBigDecimalArray() throws MatrixException {
804                    int r = (int) getRowCount();
805                    int c = (int) getColumnCount();
806                    BigDecimal[][] values = new BigDecimal[r][c];
807                    for (int i = 0; i < r; i++) {
808                            for (int j = 0; j < c; j++) {
809                                    values[i][j] = getAsBigDecimal(i, j);
810                            }
811                    }
812                    return values;
813            }
814    
815            public BigInteger[][] toBigIntegerArray() throws MatrixException {
816                    int r = (int) getRowCount();
817                    int c = (int) getColumnCount();
818                    BigInteger[][] values = new BigInteger[r][c];
819                    for (int i = 0; i < r; i++) {
820                            for (int j = 0; j < c; j++) {
821                                    values[i][j] = getAsBigInteger(i, j);
822                            }
823                    }
824                    return values;
825            }
826    
827            public final Matrix sqrt(Ret returnType) throws MatrixException {
828                    return new Sqrt(this).calc(returnType);
829            }
830    
831            public final Matrix round(Ret returnType) throws MatrixException {
832                    return new Round(this).calc(returnType);
833            }
834    
835            public final Matrix ceil(Ret returnType) throws MatrixException {
836                    return new Ceil(this).calc(returnType);
837            }
838    
839            public final Matrix extractAnnotation(Ret returnType, int dimension) throws MatrixException {
840                    return new ExtractAnnotation(this, dimension).calc(returnType);
841            }
842    
843            public final Matrix includeAnnotation(Ret returnType, int dimension) throws MatrixException {
844                    return new IncludeAnnotation(this, dimension).calc(returnType);
845            }
846    
847            public final Matrix floor(Ret returnType) throws MatrixException {
848                    return new Floor(this).calc(returnType);
849            }
850    
851            public final JFrame showGUI() {
852                    try {
853                            Class<?> c = Class.forName("org.ujmp.gui.util.FrameManager");
854                            Method method = c.getMethod("showFrame", new Class[] { GUIObject.class });
855                            Object o = method.invoke(null, new Object[] { getGUIObject() });
856                            return (JFrame) o;
857                    } catch (Exception e) {
858                            throw new MatrixException("cannot show GUI", e);
859                    }
860            }
861    
862            public void notifyGUIObject() {
863                    if (guiObject != null) {
864                            guiObject.fireValueChanged();
865                    }
866            }
867    
868            public Matrix mtimes(Matrix matrix) throws MatrixException {
869                    Matrix result = MatrixFactory.like(this, getRowCount(), matrix.getColumnCount());
870                    Matrix.mtimes.calc(this, matrix, result);
871                    return result;
872            }
873    
874            public Matrix mtimes(Ret returnType, boolean ignoreNaN, Matrix matrix) throws MatrixException {
875                    return new Mtimes(ignoreNaN, this, matrix).calc(returnType);
876            }
877    
878            public Matrix mtimes(double value) throws MatrixException {
879                    return times(value);
880            }
881    
882            public Matrix mtimes(Ret returnType, boolean ignoreNaN, double value) throws MatrixException {
883                    return times(returnType, ignoreNaN, value);
884            }
885    
886            public boolean getAsBoolean(long... coordinates) throws MatrixException {
887                    return MathUtil.getBoolean(getAsObject(coordinates));
888            }
889    
890            public void setAsBoolean(boolean value, long... coordinates) throws MatrixException {
891                    setAsDouble(value ? 1.0 : 0.0, coordinates);
892            }
893    
894            public int getAsInt(long... coordinates) throws MatrixException {
895                    return (int) getAsDouble(coordinates);
896            }
897    
898            public void setAsInt(int value, long... coordinates) throws MatrixException {
899                    setAsDouble(value, coordinates);
900            }
901    
902            public byte getAsByte(long... coordinates) throws MatrixException {
903                    return (byte) getAsDouble(coordinates);
904            }
905    
906            public void setAsByte(byte value, long... coordinates) throws MatrixException {
907                    setAsDouble(value, coordinates);
908            }
909    
910            public char getAsChar(long... coordinates) throws MatrixException {
911                    return (char) getAsDouble(coordinates);
912            }
913    
914            public BigInteger getAsBigInteger(long... coordinates) throws MatrixException {
915                    return MathUtil.getBigInteger(getAsObject(coordinates));
916            }
917    
918            public BigDecimal getAsBigDecimal(long... coordinates) throws MatrixException {
919                    return MathUtil.getBigDecimal(getAsObject(coordinates));
920            }
921    
922            public void setAsChar(char value, long... coordinates) throws MatrixException {
923                    setAsDouble(value, coordinates);
924            }
925    
926            public void setAsBigDecimal(BigDecimal value, long... coordinates) throws MatrixException {
927                    if (value == null) {
928                            setAsDouble(Double.NaN, coordinates);
929                    } else {
930                            setAsDouble(value.doubleValue(), coordinates);
931                    }
932            }
933    
934            public void setAsBigInteger(BigInteger value, long... coordinates) throws MatrixException {
935                    if (value == null) {
936                            setAsLong(0l, coordinates);
937                    } else {
938                            setAsLong(value.longValue(), coordinates);
939                    }
940            }
941    
942            public float getAsFloat(long... coordinates) throws MatrixException {
943                    return (float) getAsDouble(coordinates);
944            }
945    
946            public void setAsFloat(float value, long... coordinates) throws MatrixException {
947                    setAsDouble(value, coordinates);
948            }
949    
950            public short getAsShort(long... coordinates) throws MatrixException {
951                    return (short) getAsDouble(coordinates);
952            }
953    
954            public Matrix getAsMatrix(long... coordinates) throws MatrixException {
955                    return MathUtil.getMatrix(getAsObject(coordinates));
956            }
957    
958            public void setAsMatrix(Matrix m, long... coordinates) throws MatrixException {
959                    setAsObject(m, coordinates);
960            }
961    
962            public void setAsShort(short value, long... coordinates) throws MatrixException {
963                    setAsDouble(value, coordinates);
964            }
965    
966            public long getAsLong(long... coordinates) throws MatrixException {
967                    return (long) getAsDouble(coordinates);
968            }
969    
970            public void setAsLong(long value, long... coordinates) throws MatrixException {
971                    setAsDouble(value, coordinates);
972            }
973    
974            public Date getAsDate(long... coordinates) throws MatrixException {
975                    return MathUtil.getDate(getAsObject(coordinates));
976            }
977    
978            public void setAsDate(Date date, long... coordinates) throws MatrixException {
979                    setAsObject(date, coordinates);
980            }
981    
982            public final Matrix delete(Ret returnType, String selection) throws MatrixException {
983                    return new Deletion(this, selection).calc(returnType);
984            }
985    
986            public final Matrix delete(Ret returnType, Collection<? extends Number>... selection)
987                            throws MatrixException {
988                    return new Deletion(this, selection).calc(returnType);
989            }
990    
991            public final Matrix delete(Ret returnType, long[]... selection) throws MatrixException {
992                    return new Deletion(this, selection).calc(returnType);
993            }
994    
995            public final Matrix deleteRows(Ret returnType, long... rows) throws MatrixException {
996                    return delete(returnType, rows, new long[] {});
997            }
998    
999            @SuppressWarnings("unchecked")
1000            public final Matrix deleteRows(Ret returnType, Collection<? extends Number> rows)
1001                            throws MatrixException {
1002                    return delete(returnType, rows, new ArrayList<Long>());
1003            }
1004    
1005            @SuppressWarnings("unchecked")
1006            public final Matrix deleteColumns(Ret returnType, Collection<? extends Number> columns)
1007                            throws MatrixException {
1008                    return delete(returnType, new ArrayList<Long>(), columns);
1009            }
1010    
1011            public final Matrix deleteColumns(Ret returnType, long... columns) throws MatrixException {
1012                    return delete(returnType, new long[] {}, columns);
1013            }
1014    
1015            public Matrix minus(Ret returnType, boolean ignoreNaN, double v) throws MatrixException {
1016                    return new Minus(ignoreNaN, this, v).calc(returnType);
1017            }
1018    
1019            public Matrix minus(Ret returnType, boolean ignoreNaN, Matrix m) throws MatrixException {
1020                    return new Minus(ignoreNaN, this, m).calc(returnType);
1021            }
1022    
1023            public Matrix plus(Ret returnType, boolean ignoreNaN, double v) throws MatrixException {
1024                    return new Plus(ignoreNaN, this, v).calc(returnType);
1025            }
1026    
1027            public Matrix plus(Ret returnType, boolean ignoreNaN, Matrix m) throws MatrixException {
1028                    return new Plus(ignoreNaN, this, m).calc(returnType);
1029            }
1030    
1031            public Matrix transpose() throws MatrixException {
1032                    Matrix result = null;
1033                    try {
1034                            result = this.getClass().getConstructor(long[].class).newInstance(
1035                                            Coordinates.transpose(getSize()));
1036                    } catch (Exception e) {
1037                            result = Matrix.factory.zeros(Coordinates.transpose(getSize()));
1038                    }
1039                    Matrix.transpose.calc(this, result);
1040                    return result;
1041            }
1042    
1043            public Matrix transpose(Ret returnType) throws MatrixException {
1044                    return new Transpose(this).calc(returnType);
1045            }
1046    
1047            public Matrix mean(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
1048                    return new Mean(dimension, ignoreNaN, this).calc(returnType);
1049            }
1050    
1051            public Matrix var(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
1052                    return new Var(dimension, ignoreNaN, this).calc(returnType);
1053            }
1054    
1055            public Matrix std(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
1056                    return new Std(dimension, ignoreNaN, this).calc(returnType);
1057            }
1058    
1059            public long getColumnCount() {
1060                    return getSize(COLUMN);
1061            }
1062    
1063            public long getRowCount() {
1064                    return getSize(ROW);
1065            }
1066    
1067            public long getZCount() {
1068                    return getSize(Z);
1069            }
1070    
1071            public final long getSize(int dimension) {
1072                    return getSize()[dimension];
1073            }
1074    
1075            public Matrix prod(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
1076                    return new Prod(dimension, ignoreNaN, this).calc(returnType);
1077            }
1078    
1079            public Matrix diff(Ret returnType, int dimension, boolean ignoreNaN) throws MatrixException {
1080                    return new Diff(dimension, ignoreNaN, this).calc(returnType);
1081            }
1082    
1083            public final Matrix sum(Ret returnType, int dimension, boolean ignoreNaN)
1084                            throws MatrixException {
1085                    return new Sum(dimension, ignoreNaN, this).calc(returnType);
1086            }
1087    
1088            public final Matrix sign(Ret returnType) throws MatrixException {
1089                    return new Sign(this).calc(returnType);
1090            }
1091    
1092            public String toString() {
1093                    return UJMPFormat.getMultiLineInstance().format(this);
1094            }
1095    
1096            public final int getDimensionCount() {
1097                    return getSize().length;
1098            }
1099    
1100            public final Matrix ones(Ret ret) throws MatrixException {
1101                    return new Ones(this).calc(ret);
1102            }
1103    
1104            public final Matrix fill(Ret ret, Object value) throws MatrixException {
1105                    return new Fill(this, value).calc(ret);
1106            }
1107    
1108            public final Matrix zeros(Ret ret) throws MatrixException {
1109                    return new Zeros(this).calc(ret);
1110            }
1111    
1112            public final Matrix eye(Ret ret) throws MatrixException {
1113                    return new Eye(this).calc(ret);
1114            }
1115    
1116            public Matrix plus(double value) throws MatrixException {
1117                    Matrix result = MatrixFactory.like(this);
1118                    Matrix.plusScalar.calc(this, value, result);
1119                    return result;
1120            }
1121    
1122            public Matrix plus(Matrix m) throws MatrixException {
1123                    Matrix result = MatrixFactory.like(this);
1124                    Matrix.plusMatrix.calc(this, m, result);
1125                    return result;
1126            }
1127    
1128            public Matrix minus(double value) throws MatrixException {
1129                    Matrix result = MatrixFactory.like(this);
1130                    Matrix.minusScalar.calc(this, value, result);
1131                    return result;
1132            }
1133    
1134            public Matrix minus(Matrix m) throws MatrixException {
1135                    Matrix result = MatrixFactory.like(this);
1136                    Matrix.minusMatrix.calc(this, m, result);
1137                    return result;
1138            }
1139    
1140            public void clear() {
1141                    new Zeros(this).calc(Ret.ORIG);
1142            }
1143    
1144            public final Matrix rand(Ret ret) throws MatrixException {
1145                    return new Rand(this).calc(ret);
1146            }
1147    
1148            public final Matrix randn(Ret ret) throws MatrixException {
1149                    return new Randn(this).calc(ret);
1150            }
1151    
1152            // TODO: this should also work for objects and Strings
1153            public final int compareTo(Matrix m) {
1154                    double v1 = getMeanValue();
1155                    double v2 = m.getMeanValue();
1156                    return new Double(v1).compareTo(v2);
1157            }
1158    
1159            public int rank() throws MatrixException {
1160                    int rank = 0;
1161    
1162                    Matrix[] usv = svd();
1163                    Matrix s = usv[1];
1164    
1165                    for (int i = (int) Math.min(s.getSize(ROW), s.getSize(COLUMN)); --i >= 0;) {
1166                            if (Math.abs(s.getAsDouble(i, i)) > UJMPSettings.getTolerance()) {
1167                                    rank++;
1168                            }
1169                    }
1170    
1171                    return rank;
1172            }
1173    
1174            public final boolean isSPD() {
1175                    if (getDimensionCount() != 2) {
1176                            return false;
1177                    }
1178                    if (!isSquare()) {
1179                            return false;
1180                    }
1181                    return new Chol.CholMatrix(this).isSPD();
1182            }
1183    
1184            public final boolean isSymmetric() {
1185                    if (getDimensionCount() != 2) {
1186                            throw new MatrixException("only supported for 2d matrices");
1187                    }
1188                    if (isSquare()) {
1189                            return false;
1190                    }
1191    
1192                    if (this instanceof DenseDoubleMatrix2D) {
1193                            DenseDoubleMatrix2D m = (DenseDoubleMatrix2D) this;
1194                            for (long r = getRowCount(); --r >= 0;) {
1195                                    for (long c = getColumnCount(); --c >= 0;) {
1196                                            if (m.getDouble(r, c) != m.getDouble(c, r)) {
1197                                                    return false;
1198                                            }
1199                                    }
1200                            }
1201                    } else {
1202                            for (long[] c : availableCoordinates()) {
1203                                    Object o1 = getAsObject(c);
1204                                    Object o2 = getAsObject(Coordinates.transpose(c));
1205                                    if (!MathUtil.equals(o1, o2)) {
1206                                            return false;
1207                                    }
1208                            }
1209                    }
1210    
1211                    return true;
1212            }
1213    
1214            public boolean isEmpty() throws MatrixException {
1215                    for (long[] c : availableCoordinates()) {
1216                            if (getAsDouble(c) != 0.0) {
1217                                    return false;
1218                            }
1219                    }
1220                    return true;
1221            }
1222    
1223            public final Matrix abs(Ret returnType) throws MatrixException {
1224                    return new Abs(this).calc(returnType);
1225            }
1226    
1227            public final Matrix log(Ret returnType) throws MatrixException {
1228                    return new Log(this).calc(returnType);
1229            }
1230    
1231            public final Matrix exp(Ret returnType) throws MatrixException {
1232                    return new Exp(this).calc(returnType);
1233            }
1234    
1235            public final Matrix sortrows(Ret returnType, long column, boolean reverse)
1236                            throws MatrixException {
1237                    return new Sortrows(this, column, reverse).calc(returnType);
1238            }
1239    
1240            public final Matrix cumsum(boolean ignoreNaN) throws MatrixException {
1241                    return new Cumsum(this, ignoreNaN).calcNew();
1242            }
1243    
1244            public final Matrix cumprod(boolean ignoreNaN) throws MatrixException {
1245                    return new Cumprod(this, ignoreNaN).calcNew();
1246            }
1247    
1248            public final Matrix log2(Ret returnType) throws MatrixException {
1249                    return new Log2(this).calc(returnType);
1250            }
1251    
1252            public final Matrix log10(Ret returnType) throws MatrixException {
1253                    return new Log10(this).calc(returnType);
1254            }
1255    
1256            public final boolean isDiagonal() throws MatrixException {
1257                    if (!isSquare()) {
1258                            return false;
1259                    }
1260                    for (long[] c : allCoordinates()) {
1261                            double v = getAsDouble(c);
1262                            if (v != 0.0) {
1263                                    for (int i = 1; i < c.length; i++) {
1264                                            if (c[i - 1] != c[i]) {
1265                                                    return false;
1266                                            }
1267                                    }
1268                            }
1269                    }
1270                    return true;
1271            }
1272    
1273            public final boolean isSquare() {
1274                    return getDimensionCount() == 2 && getColumnCount() == getRowCount();
1275            }
1276    
1277            public double euklideanDistanceTo(Matrix m, boolean ignoreNaN) throws MatrixException {
1278                    return minkowskiDistanceTo(m, 2, ignoreNaN);
1279            }
1280    
1281            public double det() throws MatrixException {
1282                    if (getDimensionCount() != 2 || !isSquare()) {
1283                            throw new MatrixException("only supported for 2d square matrices");
1284                    }
1285                    return new LU.LUMatrix(this).det();
1286            }
1287    
1288            public boolean isSingular() throws MatrixException {
1289                    if (getDimensionCount() != 2 || !isSquare()) {
1290                            throw new MatrixException("only supported for 2d square matrices");
1291                    }
1292                    return !new LU.LUMatrix(this).isNonsingular();
1293            }
1294    
1295            public double manhattenDistanceTo(Matrix m, boolean ignoreNaN) throws MatrixException {
1296                    return minkowskiDistanceTo(m, 1, ignoreNaN);
1297            }
1298    
1299            public double minkowskiDistanceTo(Matrix m, double p, boolean ignoreNaN) throws MatrixException {
1300                    double sum = 0.0;
1301                    if (ignoreNaN) {
1302                            for (long[] c : allCoordinates()) {
1303                                    sum += MathUtil.ignoreNaN(Math
1304                                                    .pow(Math.abs((getAsDouble(c)) - m.getAsDouble(c)), p));
1305                            }
1306                    } else {
1307                            for (long[] c : allCoordinates()) {
1308                                    sum += Math.pow(Math.abs((getAsDouble(c)) - m.getAsDouble(c)), p);
1309                            }
1310                    }
1311                    return Math.pow(sum, 1 / p);
1312            }
1313    
1314            public double chebyshevDistanceTo(Matrix m, boolean ignoreNaN) throws MatrixException {
1315                    double max = 0.0;
1316                    if (ignoreNaN) {
1317                            for (long[] c : allCoordinates()) {
1318                                    double v = MathUtil.ignoreNaN(Math.abs((getAsDouble(c) - m.getAsDouble(c))));
1319                                    max = v > max ? v : max;
1320                            }
1321                    } else {
1322                            for (long[] c : allCoordinates()) {
1323                                    double v = Math.abs((getAsDouble(c) - m.getAsDouble(c)));
1324                                    max = v > max ? v : max;
1325                            }
1326                    }
1327                    return max;
1328            }
1329    
1330            public Matrix min(Ret returnType, int dimension) throws MatrixException {
1331                    return new Min(dimension, this).calc(returnType);
1332            }
1333    
1334            public Matrix max(Ret returnType, int dimension) throws MatrixException {
1335                    return new Max(dimension, this).calc(returnType);
1336            }
1337    
1338            public final Matrix addMissing(Ret returnType, int dimension, double... percentMissing)
1339                            throws MatrixException {
1340                    return new AddMissing(dimension, this, percentMissing).calc(returnType);
1341            }
1342    
1343            public Matrix countMissing(Ret returnType, int dimension) throws MatrixException {
1344                    return new CountMissing(dimension, this).calc(returnType);
1345            }
1346    
1347            public final boolean isScalar() {
1348                    return Coordinates.product(getSize()) == 1;
1349            }
1350    
1351            public final boolean isRowVector() {
1352                    return getColumnCount() == 1 && getRowCount() != 1;
1353            }
1354    
1355            public final boolean isColumnVector() {
1356                    return getColumnCount() != 1 && getRowCount() == 1;
1357            }
1358    
1359            public final boolean isMultidimensionalMatrix() {
1360                    return getColumnCount() != 1 && getRowCount() != 1;
1361            }
1362    
1363            public Matrix sinh(Ret returnType) throws MatrixException {
1364                    return new Sinh(this).calc(returnType);
1365            }
1366    
1367            public Matrix cosh(Ret returnType) throws MatrixException {
1368                    return new Cosh(this).calc(returnType);
1369            }
1370    
1371            public Matrix tanh(Ret returnType) throws MatrixException {
1372                    return new Tanh(this).calc(returnType);
1373            }
1374    
1375            public Matrix sin(Ret returnType) throws MatrixException {
1376                    return new Sin(this).calc(returnType);
1377            }
1378    
1379            public Matrix cos(Ret returnType) throws MatrixException {
1380                    return new Cos(this).calc(returnType);
1381            }
1382    
1383            public Matrix tril(Ret returnType, int k) throws MatrixException {
1384                    return new Tril(this, k).calc(returnType);
1385            }
1386    
1387            public Matrix triu(Ret returnType, int k) throws MatrixException {
1388                    return new Triu(this, k).calc(returnType);
1389            }
1390    
1391            public Matrix tan(Ret returnType) throws MatrixException {
1392                    return new Tan(this).calc(returnType);
1393            }
1394    
1395            public Matrix cov(Ret returnType, boolean ignoreNaN) throws MatrixException {
1396                    return new Cov(ignoreNaN, this).calc(returnType);
1397            }
1398    
1399            public Matrix corrcoef(Ret returnType, boolean ignoreNaN) throws MatrixException {
1400                    return new Corrcoef(ignoreNaN, this).calc(returnType);
1401            }
1402    
1403            public Matrix mutualInf(Ret returnType) throws MatrixException {
1404                    return new MutualInformation(this).calc(returnType);
1405            }
1406    
1407            public Matrix pairedTTest(Ret returnType) throws MatrixException {
1408                    try {
1409                            Class<?> c = Class.forName("org.ujmp.commonsmath.PairedTTest");
1410                            Constructor<?> con = c.getConstructor(Matrix.class);
1411                            Calculation calc = (Calculation) con.newInstance(this);
1412                            return calc.calc(returnType);
1413                    } catch (Exception e) {
1414                            throw new MatrixException("could not calculate", e);
1415                    }
1416            }
1417    
1418            public Matrix bootstrap(Ret returnType) throws MatrixException {
1419                    return new Bootstrap(this).calc(returnType);
1420            }
1421    
1422            public Matrix lowerCase(Ret returnType) throws MatrixException {
1423                    return new LowerCase(this).calc(returnType);
1424            }
1425    
1426            public Matrix upperCase(Ret returnType) throws MatrixException {
1427                    return new UpperCase(this).calc(returnType);
1428            }
1429    
1430            public Matrix tfIdf(boolean calculateTf, boolean calculateIdf, boolean normalize)
1431                            throws MatrixException {
1432                    return new TfIdf(this, calculateTf, calculateIdf, normalize).calc(Ret.NEW);
1433            }
1434    
1435            public Matrix removePunctuation(Ret ret) throws MatrixException {
1436                    return new RemovePunctuation(this).calc(ret);
1437            }
1438    
1439            public Matrix stem(Ret ret) throws MatrixException {
1440                    return new Stem(this).calc(ret);
1441            }
1442    
1443            public Matrix removeWords(Ret ret, Collection<String> words) throws MatrixException {
1444                    return new RemoveWords(this, words).calc(ret);
1445            }
1446    
1447            public Matrix unique(Ret returnType) throws MatrixException {
1448                    return new Unique(this).calc(returnType);
1449            }
1450    
1451            public Matrix uniqueValueCount(Ret returnType, int dimension) throws MatrixException {
1452                    return new UniqueValueCount(this, dimension).calc(returnType);
1453            }
1454    
1455            public Matrix bootstrap(Ret returnType, int count) throws MatrixException {
1456                    return new Bootstrap(this, count).calc(returnType);
1457            }
1458    
1459            public Matrix transpose(Ret returnType, int dimension1, int dimension2) throws MatrixException {
1460                    return new Transpose(this, dimension1, dimension2).calc(returnType);
1461            }
1462    
1463            public Matrix swap(Ret returnType, int dimension, long pos1, long pos2) throws MatrixException {
1464                    return new Swap(dimension, pos1, pos2, this).calc(returnType);
1465            }
1466    
1467            public Matrix flipdim(Ret returnType, int dimension) throws MatrixException {
1468                    return new Flipdim(dimension, this).calc(returnType);
1469            }
1470    
1471            public final Matrix shuffle(Ret returnType) throws MatrixException {
1472                    return new Shuffle(this).calc(returnType);
1473            }
1474    
1475            public final double trace() throws MatrixException {
1476                    double sum = 0.0;
1477                    for (long i = Math.min(getRowCount(), getColumnCount()); --i >= 0;) {
1478                            sum += getAsDouble(i, i);
1479                    }
1480                    return sum;
1481            }
1482    
1483            public final void exportToFile(File file, Object... parameters) throws MatrixException,
1484                            IOException {
1485                    ExportMatrix.toFile(file, this, parameters);
1486            }
1487    
1488            public final void exportToClipboard(FileFormat format, Object... parameters)
1489                            throws MatrixException, IOException {
1490                    ExportMatrix.toClipboard(format, this, parameters);
1491            }
1492    
1493            public final void exportToFile(String file, Object... parameters) throws MatrixException,
1494                            IOException {
1495                    ExportMatrix.toFile(file, this, parameters);
1496            }
1497    
1498            public final void exportToFile(FileFormat format, String filename, Object... parameters)
1499                            throws MatrixException, IOException {
1500                    ExportMatrix.toFile(format, filename, this, parameters);
1501            }
1502    
1503            public final void exportToFile(FileFormat format, File file, Object... parameters)
1504                            throws MatrixException, IOException {
1505                    ExportMatrix.toFile(format, file, this, parameters);
1506            }
1507    
1508            public final void exportToStream(FileFormat format, OutputStream outputStream,
1509                            Object... parameters) throws MatrixException, IOException {
1510                    ExportMatrix.toStream(format, outputStream, this, parameters);
1511            }
1512    
1513            public final void exportToWriter(FileFormat format, Writer writer, Object... parameters)
1514                            throws MatrixException, IOException {
1515                    ExportMatrix.toWriter(format, writer, this, parameters);
1516            }
1517    
1518            public final void setLabel(String label) {
1519                    setMatrixAnnotation(label);
1520            }
1521    
1522            public final String getLabel() {
1523                    Object o = getMatrixAnnotation();
1524                    if (o == null) {
1525                            return null;
1526                    }
1527                    if (o instanceof String) {
1528                            return (String) o;
1529                    }
1530                    if (o instanceof HasLabel) {
1531                            return ((HasLabel) o).getLabel();
1532                    }
1533                    return o.toString();
1534            }
1535    
1536            public void setAsString(String string, long... coordinates) throws MatrixException {
1537                    setAsObject(string, coordinates);
1538            }
1539    
1540            public boolean isReadOnly() {
1541                    return false;
1542            }
1543    
1544            public String getAsString(long... coordinates) throws MatrixException {
1545                    return StringUtil.convert(getAsObject(coordinates));
1546            }
1547    
1548            public final double getMaxValue() throws MatrixException {
1549                    return Max.calc(this);
1550            }
1551    
1552            public final double getMinValue() throws MatrixException {
1553                    return Min.calc(this);
1554            }
1555    
1556            public final double getMeanValue() throws MatrixException {
1557                    return Mean.calc(this);
1558            }
1559    
1560            public final double getStdValue() throws MatrixException {
1561                    return std(Ret.NEW, Matrix.ALL, true).getEuklideanValue();
1562            }
1563    
1564            public final double getValueSum() throws MatrixException {
1565                    double sum = 0.0;
1566                    for (long[] c : allCoordinates()) {
1567                            sum += getAsDouble(c);
1568                    }
1569                    return sum;
1570            }
1571    
1572            public final double getAbsoluteValueSum() throws MatrixException {
1573                    double sum = 0.0;
1574                    for (long[] c : allCoordinates()) {
1575                            sum += Math.abs(getAsDouble(c));
1576                    }
1577                    return sum;
1578            }
1579    
1580            public final String getColumnLabel(long col) {
1581                    if (getDimensionCount() != 2) {
1582                            throw new MatrixException("This function is only supported for 2D matrices");
1583                    }
1584                    return StringUtil.convert(getAxisAnnotation(ROW, new long[] { 0, col }));
1585            }
1586    
1587            public final String getRowLabel(long row) {
1588                    if (getDimensionCount() != 2) {
1589                            throw new MatrixException("This function is only supported for 2D matrices");
1590                    }
1591                    return StringUtil.convert(getAxisAnnotation(COLUMN, new long[] { row, 0 }));
1592            }
1593    
1594            public final long getRowForLabel(Object object) {
1595                    if (getDimensionCount() != 2) {
1596                            throw new MatrixException("This function is only supported for 2D matrices");
1597                    }
1598                    return getPositionForLabel(COLUMN, object)[ROW];
1599            }
1600    
1601            public final long getColumnForLabel(Object object) {
1602                    if (getDimensionCount() != 2) {
1603                            throw new MatrixException("This function is only supported for 2D matrices");
1604                    }
1605                    return getPositionForLabel(ROW, object)[COLUMN];
1606            }
1607    
1608            public final long[] getPositionForLabel(int dimension, Object label) {
1609                    if (annotation == null) {
1610                            long[] t = Coordinates.copyOf(getSize());
1611                            t[dimension] = -1;
1612                            return t;
1613                    } else {
1614                            return annotation.getPositionForLabel(dimension, label);
1615                    }
1616            }
1617    
1618            public final Object getRowObject(long row) {
1619                    if (getDimensionCount() != 2) {
1620                            throw new MatrixException("This function is only supported for 2D matrices");
1621                    }
1622                    return getAxisAnnotation(COLUMN, new long[] { row, 0 });
1623            }
1624    
1625            public final Object getColumnObject(long col) {
1626                    if (getDimensionCount() != 2) {
1627                            throw new MatrixException("This function is only supported for 2D matrices");
1628                    }
1629                    return getAxisAnnotation(ROW, new long[] { 0, col });
1630            }
1631    
1632            public final void setColumnLabel(long col, String label) {
1633                    if (getDimensionCount() != 2) {
1634                            throw new MatrixException("This function is only supported for 2D matrices");
1635                    }
1636                    setAxisAnnotation(ROW, label, new long[] { 0, col });
1637            }
1638    
1639            public final void setRowLabel(long row, String label) {
1640                    if (getDimensionCount() != 2) {
1641                            throw new MatrixException("This function is only supported for 2D matrices");
1642                    }
1643                    setAxisAnnotation(COLUMN, label, new long[] { row, 0 });
1644            }
1645    
1646            public final void setRowObject(long row, Object label) {
1647                    if (getDimensionCount() != 2) {
1648                            throw new MatrixException("This function is only supported for 2D matrices");
1649                    }
1650                    setAxisAnnotation(COLUMN, label, new long[] { row, 0 });
1651            }
1652    
1653            public final void setColumnObject(long col, Object label) {
1654                    if (getDimensionCount() != 2) {
1655                            throw new MatrixException("This function is only supported for 2D matrices");
1656                    }
1657                    setAxisAnnotation(ROW, label, new long[] { 0, col });
1658            }
1659    
1660            public final double getAbsoluteValueMean() throws MatrixException {
1661                    return getAbsoluteValueSum() / getValueCount();
1662            }
1663    
1664            public final Matrix toRowVector(Ret returnType) throws MatrixException {
1665                    if (isRowVector()) {
1666                            return this;
1667                    } else if (isColumnVector()) {
1668                            return transpose(returnType);
1669                    } else {
1670                            return reshape(returnType, Coordinates.product(getSize()), 1);
1671                    }
1672            }
1673    
1674            public final Matrix toColumnVector(Ret returnType) throws MatrixException {
1675                    if (isColumnVector()) {
1676                            return this;
1677                    } else if (isRowVector()) {
1678                            return transpose(returnType);
1679                    } else {
1680                            return reshape(returnType, 1, (int) Coordinates.product(getSize()));
1681                    }
1682            }
1683    
1684            public Matrix replaceMissingBy(Matrix matrix) throws MatrixException {
1685                    Matrix ret = Matrix.factory.zeros(getSize());
1686                    for (long[] c : allCoordinates()) {
1687                            double v = getAsDouble(c);
1688                            if (MathUtil.isNaNOrInfinite(v)) {
1689                                    ret.setAsDouble(matrix.getAsDouble(c), c);
1690                            } else {
1691                                    ret.setAsDouble(getAsDouble(c), c);
1692                            }
1693                    }
1694                    return ret;
1695            }
1696    
1697            public final Matrix deleteColumnsWithMissingValues(Ret returnType) throws MatrixException {
1698                    Matrix mv = countMissing(Ret.NEW, Matrix.ROW);
1699                    List<Long> sel = new ArrayList<Long>();
1700                    for (long c = 0; c < mv.getColumnCount(); c++) {
1701                            if (mv.getAsDouble(0, c) == 0.0)
1702                                    sel.add(c);
1703                    }
1704                    long[] longsel = new long[sel.size()];
1705                    for (int i = sel.size(); --i >= 0;) {
1706                            longsel[i] = sel.get(i);
1707                    }
1708                    return selectColumns(returnType, longsel);
1709            }
1710    
1711            public final Matrix deleteRowsWithMissingValues(Ret returnType, long threshold)
1712                            throws MatrixException {
1713                    Matrix mv = countMissing(Ret.NEW, Matrix.COLUMN);
1714                    List<Long> sel = new ArrayList<Long>();
1715                    for (long r = 0; r < mv.getRowCount(); r++) {
1716                            if (mv.getAsLong(r, 0) < threshold)
1717                                    sel.add(r);
1718                    }
1719                    if (sel.isEmpty()) {
1720                            return MatrixFactory.emptyMatrix();
1721                    } else {
1722                            return selectRows(returnType, sel);
1723                    }
1724            }
1725    
1726            public final Matrix appendHorizontally(Matrix m) throws MatrixException {
1727                    return append(COLUMN, m);
1728            }
1729    
1730            public Iterable<Object> allValues() {
1731                    return new Iterable<Object>() {
1732    
1733                            public Iterator<Object> iterator() {
1734                                    return new Iterator<Object>() {
1735    
1736                                            private Iterator<long[]> it = allCoordinates().iterator();
1737    
1738                                            public boolean hasNext() {
1739                                                    return it.hasNext();
1740                                            }
1741    
1742                                            public Object next() {
1743                                                    return getAsObject(it.next());
1744                                            }
1745    
1746                                            public void remove() {
1747                                                    it.remove();
1748                                            }
1749                                    };
1750                            }
1751                    };
1752            }
1753    
1754            public final Matrix appendVertically(Matrix m) throws MatrixException {
1755                    return append(ROW, m);
1756            }
1757    
1758            public final Matrix append(int dimension, Matrix m) throws MatrixException {
1759                    return MatrixFactory.concat(dimension, this, m);
1760            }
1761    
1762            public final Matrix discretizeToColumns(long column) throws MatrixException {
1763                    return new DiscretizeToColumns(this, false, column).calc(Ret.NEW);
1764            }
1765    
1766            public final Matrix subMatrix(Ret returnType, long startRow, long startColumn, long endRow,
1767                            long endColumn) throws MatrixException {
1768                    long[] rows = MathUtil.sequenceLong(startRow, endRow);
1769                    long[] columns = MathUtil.sequenceLong(startColumn, endColumn);
1770                    return select(returnType, rows, columns);
1771            }
1772    
1773            public Matrix[] svd() throws MatrixException {
1774                    return SVD.INSTANCE.calc(this);
1775            }
1776    
1777            public Matrix[] eig() throws MatrixException {
1778                    return Eig.INSTANCE.calc(this);
1779            }
1780    
1781            public Matrix[] eigSymm() throws MatrixException {
1782                    return Eig.INSTANCE.calc(this);
1783            }
1784    
1785            public Matrix[] qr() throws MatrixException {
1786                    return QR.INSTANCE.calc(this);
1787            }
1788    
1789            public Matrix[] lu() throws MatrixException {
1790                    return LU.INSTANCE.calc(this);
1791            }
1792    
1793            public Matrix chol() throws MatrixException {
1794                    return Chol.INSTANCE.calc(this);
1795            }
1796    
1797            public final String exportToString(FileFormat format, Object... parameters)
1798                            throws MatrixException, IOException {
1799                    return ExportMatrix.toString(format, this, parameters);
1800            }
1801    
1802            public void setSize(long... size) {
1803                    throw new MatrixException("operation not possible: cannot change size of matrix");
1804            }
1805    
1806            public final Matrix reshape(Ret returnType, long... newSize) {
1807                    return new Reshape(this, newSize).calc(returnType);
1808            }
1809    
1810            public final Matrix squeeze(Ret returnType) {
1811                    return new Squeeze(this).calc(returnType);
1812            }
1813    
1814            public final double doubleValue() throws MatrixException {
1815                    if (isScalar()) {
1816                            return getAsDouble(0, 0);
1817                    }
1818                    return getMeanValue();
1819            }
1820    
1821            public final int intValue() throws MatrixException {
1822                    if (isScalar()) {
1823                            return getAsInt(0, 0);
1824                    }
1825                    return (int) getMeanValue();
1826            }
1827    
1828            public final char charValue() throws MatrixException {
1829                    if (isScalar()) {
1830                            return getAsChar(0, 0);
1831                    }
1832                    return (char) getMeanValue();
1833            }
1834    
1835            public final BigInteger bigIntegerValue() throws MatrixException {
1836                    if (isScalar()) {
1837                            return getAsBigInteger(0, 0);
1838                    }
1839                    return BigInteger.valueOf((long) getMeanValue());
1840            }
1841    
1842            public final BigDecimal bigDecimalValue() throws MatrixException {
1843                    if (isScalar()) {
1844                            return getAsBigDecimal(0, 0);
1845                    }
1846                    return BigDecimal.valueOf(getMeanValue());
1847            }
1848    
1849            public final Matrix fadeIn(Ret ret, int dimension) throws MatrixException {
1850                    return new FadeIn(dimension, this).calc(ret);
1851            }
1852    
1853            public final Matrix fadeOut(Ret ret, int dimension) throws MatrixException {
1854                    return new FadeOut(dimension, this).calc(ret);
1855            }
1856    
1857            public final float floatValue() throws MatrixException {
1858                    if (isScalar()) {
1859                            return getAsFloat(0, 0);
1860                    }
1861                    return (float) getMeanValue();
1862            }
1863    
1864            public final long longValue() throws MatrixException {
1865                    if (isScalar()) {
1866                            return getAsLong(0, 0);
1867                    }
1868                    return (long) getMeanValue();
1869            }
1870    
1871            public final Date dateValue() throws MatrixException {
1872                    if (isScalar()) {
1873                            return getAsDate(0, 0);
1874                    }
1875                    return MathUtil.getDate(getMeanValue());
1876            }
1877    
1878            public final boolean booleanValue() throws MatrixException {
1879                    if (isScalar()) {
1880                            return getAsBoolean(0, 0);
1881                    }
1882                    return getMeanValue() != 0;
1883            }
1884    
1885            public final String stringValue() throws MatrixException {
1886                    if (isScalar()) {
1887                            return getAsString(0, 0);
1888                    } else {
1889                            return toString();
1890                    }
1891            }
1892    
1893            public final double getRMS() throws MatrixException {
1894                    double sum = 0.0;
1895                    long count = 0;
1896                    for (long[] c : allCoordinates()) {
1897                            sum += Math.pow(getAsDouble(c), 2.0);
1898                            count++;
1899                    }
1900                    sum /= count;
1901                    return Math.sqrt(sum);
1902            }
1903    
1904            public final Annotation getAnnotation() {
1905                    return annotation;
1906            }
1907    
1908            public final void setAnnotation(Annotation annotation) {
1909                    this.annotation = annotation;
1910            }
1911    
1912            public final boolean equalsAnnotation(Object o) {
1913                    if (this == o) {
1914                            return true;
1915                    }
1916                    if (o instanceof Matrix) {
1917                            Matrix m = (Matrix) o;
1918                            Annotation a1 = getAnnotation();
1919                            Annotation a2 = m.getAnnotation();
1920                            if (a1 != null) {
1921                                    if (!a1.equals(a2)) {
1922                                            return false;
1923                                    }
1924                            } else if (a2 != null) {
1925                                    return false;
1926                            }
1927                    }
1928                    return true;
1929            }
1930    
1931            public final boolean equals(Object o) {
1932                    return equalsContent(o) && equalsAnnotation(o);
1933            }
1934    
1935            public final boolean equalsContent(Object o) {
1936                    try {
1937                            if (this == o) {
1938                                    return true;
1939                            }
1940                            if (o instanceof Matrix) {
1941                                    Matrix m = (Matrix) o;
1942                                    if (!Coordinates.equals(getSize(), m.getSize())) {
1943                                            return false;
1944                                    }
1945                                    if (isSparse() && m.isSparse()) {
1946                                            for (long[] c : availableCoordinates()) {
1947                                                    Object o1 = getAsObject(c);
1948                                                    Object o2 = m.getAsObject(c);
1949                                                    if ((o1 == null && o2 != null) || (o1 != null && o2 == null)) {
1950                                                            return false;
1951                                                    }
1952                                                    if (o1 != null && o2 != null) {
1953                                                            if (!o1.equals(o2)) {
1954                                                                    return false;
1955                                                            }
1956                                                    } else {
1957                                                            return false;
1958                                                    }
1959                                            }
1960                                            for (long[] c : m.availableCoordinates()) {
1961                                                    Object o1 = getAsObject(c);
1962                                                    Object o2 = m.getAsObject(c);
1963                                                    if ((o1 == null && o2 != null) || (o1 != null && o2 == null)) {
1964                                                            return false;
1965                                                    }
1966                                                    if (o1 != null && o2 != null) {
1967                                                            if (!o1.equals(o2)) {
1968                                                                    return false;
1969                                                            }
1970                                                    } else {
1971                                                            return false;
1972                                                    }
1973                                            }
1974                                    } else {
1975                                            for (long[] c : allCoordinates()) {
1976                                                    Object o1 = getAsObject(c);
1977                                                    Object o2 = m.getAsObject(c);
1978                                                    if ((o1 == null && o2 != null) || (o1 != null && o2 == null)) {
1979                                                            return false;
1980                                                    }
1981                                                    if (o1 != null && o2 != null) {
1982                                                            if (o1.getClass().equals(o2.getClass())) {
1983                                                                    if (!o1.equals(o2)) {
1984                                                                            return false;
1985                                                                    }
1986                                                            } else {
1987                                                                    if (!MathUtil.equals(o1, o2)) {
1988                                                                            return false;
1989                                                                    }
1990                                                            }
1991                                                    } else if (o1 == null && o2 == null) {
1992                                                    } else {
1993                                                            return false;
1994                                                    }
1995                                            }
1996                                    }
1997                                    return true;
1998                            }
1999                            return false;
2000                    } catch (Exception e) {
2001                            throw new MatrixException("could not compare", e);
2002                    }
2003            }
2004    
2005            public final BooleanMatrix toBooleanMatrix() {
2006                    return new ToBooleanMatrix(this).calcLink();
2007            }
2008    
2009            public final ByteMatrix toByteMatrix() {
2010                    return new ToByteMatrix(this).calcLink();
2011            }
2012    
2013            public final CharMatrix toCharMatrix() {
2014                    return new ToCharMatrix(this).calcLink();
2015            }
2016    
2017            public final DateMatrix toDateMatrix() {
2018                    return new ToDateMatrix(this).calcLink();
2019            }
2020    
2021            public final DoubleMatrix toDoubleMatrix() {
2022                    return new ToDoubleMatrix(this).calcLink();
2023            }
2024    
2025            public final FloatMatrix toFloatMatrix() {
2026                    return new ToFloatMatrix(this).calcLink();
2027            }
2028    
2029            public final IntMatrix toIntMatrix() {
2030                    return new ToIntMatrix(this).calcLink();
2031            }
2032    
2033            public final LongMatrix toLongMatrix() {
2034                    return new ToLongMatrix(this).calcLink();
2035            }
2036    
2037            public final BigDecimalMatrix toBigDecimalMatrix() {
2038                    return new ToBigDecimalMatrix(this).calcLink();
2039            }
2040    
2041            public final BigIntegerMatrix toBigIntegerMatrix() {
2042                    return new ToBigIntegerMatrix(this).calcLink();
2043            }
2044    
2045            public final ObjectMatrix toObjectMatrix() {
2046                    return new ToObjectMatrix(this).calcLink();
2047            }
2048    
2049            public final ShortMatrix toShortMatrix() {
2050                    return new ToShortMatrix(this).calcLink();
2051            }
2052    
2053            public final StringMatrix toStringMatrix() {
2054                    return new ToStringMatrix(this).calcLink();
2055            }
2056    
2057            public double norm1() {
2058                    long rows = getRowCount();
2059                    long cols = getColumnCount();
2060                    double max = 0;
2061                    for (long c = 0; c < cols; c++) {
2062                            double sum = 0;
2063                            for (long r = 0; r < rows; r++) {
2064                                    sum += Math.abs(getAsDouble(r, c));
2065                            }
2066                            max = Math.max(max, sum);
2067                    }
2068                    return max;
2069            }
2070    
2071            public double norm2() {
2072                    return svd()[1].getAsDouble(0, 0);
2073            }
2074    
2075            public double normInf() {
2076                    long rows = getRowCount();
2077                    long cols = getColumnCount();
2078                    double max = 0;
2079                    for (long r = 0; r < rows; r++) {
2080                            double sum = 0;
2081                            for (long c = 0; c < cols; c++) {
2082                                    sum += Math.abs(getAsDouble(r, c));
2083                            }
2084                            max = Math.max(max, sum);
2085                    }
2086                    return max;
2087            }
2088    
2089            public double normF() {
2090                    long rows = getRowCount();
2091                    long cols = getColumnCount();
2092                    double result = 0;
2093                    for (long ro = 0; ro < rows; ro++) {
2094                            for (long c = 0; c < cols; c++) {
2095                                    double b = getAsDouble(ro, c);
2096                                    double temp = 0.0;
2097                                    if (Math.abs(result) > Math.abs(b)) {
2098                                            temp = b / result;
2099                                            temp = Math.abs(result) * Math.sqrt(1 + temp * temp);
2100                                    } else if (b != 0) {
2101                                            temp = result / b;
2102                                            temp = Math.abs(b) * Math.sqrt(1 + temp * temp);
2103                                    } else {
2104                                            temp = 0.0;
2105                                    }
2106                                    result = temp;
2107                            }
2108                    }
2109                    return result;
2110            }
2111    
2112            public ListMatrix<?> toListMatrix() {
2113                    if (this instanceof ListMatrix<?>) {
2114                            return (ListMatrix<?>) this;
2115                    } else {
2116                            ListMatrix<Object> list = new DefaultListMatrix<Object>();
2117                            for (int row = 0; row < getRowCount(); row++) {
2118                                    list.add(getAsObject(row, 0));
2119                            }
2120                            return list;
2121                    }
2122            }
2123    
2124            public SetMatrix<?> toSetMatrix() {
2125                    if (this instanceof SetMatrix<?>) {
2126                            return (SetMatrix<?>) this;
2127                    } else {
2128                            SetMatrix<Object> set = new DefaultSetMatrix<Object>();
2129                            for (int row = 0; row < getRowCount(); row++) {
2130                                    set.add(getAsObject(row, 0));
2131                            }
2132                            return set;
2133                    }
2134            }
2135    
2136            public MapMatrix<?, ?> toMapMatrix() {
2137                    if (this instanceof MapMatrix<?, ?>) {
2138                            return (MapMatrix<?, ?>) this;
2139                    } else {
2140                            MapMatrix<Object, Object> map = new DefaultMapMatrix<Object, Object>();
2141                            for (int row = 0; row < getRowCount(); row++) {
2142                                    map.put(getAsObject(row, 0), getAsObject(row, 1));
2143                            }
2144                            return map;
2145                    }
2146            }
2147    
2148            public final boolean isSparse() {
2149                    switch (getStorageType()) {
2150                    case DENSE:
2151                            return false;
2152                    case SET:
2153                            return false;
2154                    case TREE:
2155                            return true;
2156                    case MAP:
2157                            return false;
2158                    case LIST:
2159                            return false;
2160                    case SPARSE:
2161                            return true;
2162                    case GRAPH:
2163                            return true;
2164                    default:
2165                            throw new MatrixException("unknown storage type: " + getStorageType());
2166                    }
2167            }
2168    
2169            public boolean containsBigInteger(BigInteger v) {
2170                    for (long[] c : availableCoordinates()) {
2171                            if (v.equals(getAsBigInteger(c))) {
2172                                    return true;
2173                            }
2174                    }
2175                    return false;
2176            }
2177    
2178            public boolean containsBigDecimal(BigDecimal v) {
2179                    for (long[] c : availableCoordinates()) {
2180                            if (v.equals(getAsBigDecimal(c))) {
2181                                    return true;
2182                            }
2183                    }
2184                    return false;
2185            }
2186    
2187            public boolean containsDate(Date v) {
2188                    for (long[] c : availableCoordinates()) {
2189                            if (v.equals(getAsDate(c))) {
2190                                    return true;
2191                            }
2192                    }
2193                    return false;
2194            }
2195    
2196            public boolean containsObject(Object o) {
2197                    for (long[] c : availableCoordinates()) {
2198                            if (o.equals(getAsObject(c))) {
2199                                    return true;
2200                            }
2201                    }
2202                    return false;
2203            }
2204    
2205            public boolean containsString(String s) {
2206                    for (long[] c : availableCoordinates()) {
2207                            if (s.equals(getAsString(c))) {
2208                                    return true;
2209                            }
2210                    }
2211                    return false;
2212            }
2213    
2214            public boolean containsBoolean(boolean v) {
2215                    for (long[] c : availableCoordinates()) {
2216                            if (getAsBoolean(c) == v) {
2217                                    return true;
2218                            }
2219                    }
2220                    return false;
2221            }
2222    
2223            public boolean containsByte(byte v) {
2224                    for (long[] c : availableCoordinates()) {
2225                            if (getAsByte(c) == v) {
2226                                    return true;
2227                            }
2228                    }
2229                    return false;
2230            }
2231    
2232            public boolean containsChar(char v) {
2233                    for (long[] c : availableCoordinates()) {
2234                            if (getAsChar(c) == v) {
2235                                    return true;
2236                            }
2237                    }
2238                    return false;
2239            }
2240    
2241            public boolean containsDouble(double v) {
2242                    for (long[] c : availableCoordinates()) {
2243                            if (getAsDouble(c) == v) {
2244                                    return true;
2245                            }
2246                    }
2247                    return false;
2248            }
2249    
2250            public boolean containsFloat(float v) {
2251                    for (long[] c : availableCoordinates()) {
2252                            if (getAsFloat(c) == v) {
2253                                    return true;
2254                            }
2255                    }
2256                    return false;
2257            }
2258    
2259            public boolean containsInt(int v) {
2260                    for (long[] c : availableCoordinates()) {
2261                            if (getAsInt(c) == v) {
2262                                    return true;
2263                            }
2264                    }
2265                    return false;
2266            }
2267    
2268            public boolean containsLong(long v) {
2269                    for (long[] c : availableCoordinates()) {
2270                            if (getAsLong(c) == v) {
2271                                    return true;
2272                            }
2273                    }
2274                    return false;
2275            }
2276    
2277            public boolean containsShort(short v) {
2278                    for (long[] c : availableCoordinates()) {
2279                            if (getAsShort(c) == v) {
2280                                    return true;
2281                            }
2282                    }
2283                    return false;
2284            }
2285    
2286            public boolean containsNull() {
2287                    for (long[] c : allCoordinates()) {
2288                            if (getAsDouble(c) == 0.0) {
2289                                    return true;
2290                            }
2291                    }
2292                    return false;
2293            }
2294    
2295            public MatrixFactoryRoot getFactory() {
2296                    return factory;
2297            }
2298    
2299    }