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.jsci;
025    
026    import org.ujmp.core.Coordinates;
027    import org.ujmp.core.Matrix;
028    import org.ujmp.core.calculation.Calculation.Ret;
029    import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix2D;
030    import org.ujmp.core.exceptions.MatrixException;
031    import org.ujmp.core.interfaces.Wrapper;
032    
033    import JSci.maths.matrices.AbstractDoubleMatrix;
034    import JSci.maths.matrices.AbstractDoubleSquareMatrix;
035    import JSci.maths.matrices.DoubleMatrix;
036    import JSci.maths.matrices.DoubleSquareMatrix;
037    
038    public class JSciDenseDoubleMatrix2D extends AbstractDenseDoubleMatrix2D
039                    implements Wrapper<AbstractDoubleMatrix> {
040            private static final long serialVersionUID = -4314440110211101868L;
041    
042            private AbstractDoubleMatrix matrix = null;
043    
044            public JSciDenseDoubleMatrix2D(Matrix source) throws MatrixException {
045                    this(source.getSize());
046                    for (long[] c : source.availableCoordinates()) {
047                            setDouble(source.getAsDouble(c), c);
048                    }
049            }
050    
051            public JSciDenseDoubleMatrix2D(long... size) {
052                    if (Coordinates.product(size) != 0) {
053                            if (size[ROW] == size[COLUMN]) {
054                                    this.matrix = new DoubleSquareMatrix((int) size[ROW]);
055                            } else {
056                                    this.matrix = new DoubleMatrix((int) size[ROW],
057                                                    (int) size[COLUMN]);
058                            }
059                    }
060            }
061    
062            public JSciDenseDoubleMatrix2D(AbstractDoubleMatrix m) {
063                    this.matrix = m;
064            }
065    
066            public double getDouble(long row, long column) {
067                    return matrix.getElement((int) row, (int) column);
068            }
069    
070            public double getDouble(int row, int column) {
071                    return matrix.getElement(row, column);
072            }
073    
074            public long[] getSize() {
075                    return matrix == null ? Coordinates.ZERO2D : new long[] {
076                                    matrix.rows(), matrix.columns() };
077            }
078    
079            public void setDouble(double value, long row, long column) {
080                    matrix.setElement((int) row, (int) column, value);
081            }
082    
083            public void setDouble(double value, int row, int column) {
084                    matrix.setElement(row, column, value);
085            }
086    
087            public Matrix transpose() {
088                    return new JSciDenseDoubleMatrix2D((AbstractDoubleMatrix) matrix
089                                    .transpose());
090            }
091    
092            public Matrix inv() {
093                    if (matrix instanceof DoubleSquareMatrix) {
094                            return new JSciDenseDoubleMatrix2D(((DoubleSquareMatrix) matrix)
095                                            .inverse());
096                    } else {
097                            throw new MatrixException("only allowed for square matrices");
098                    }
099            }
100    
101            public Matrix chol() {
102                    if (matrix instanceof DoubleSquareMatrix) {
103                            AbstractDoubleSquareMatrix[] chol = ((DoubleSquareMatrix) matrix)
104                                            .choleskyDecompose();
105                            return new JSciDenseDoubleMatrix2D(chol[0]);
106                    } else {
107                            throw new MatrixException("only allowed for square matrices");
108                    }
109            }
110    
111            public Matrix[] lu() {
112                    if (matrix instanceof DoubleSquareMatrix) {
113                            AbstractDoubleSquareMatrix[] lu = ((DoubleSquareMatrix) matrix)
114                                            .luDecompose();
115                            Matrix l = new JSciDenseDoubleMatrix2D(lu[0]);
116                            Matrix u = new JSciDenseDoubleMatrix2D(lu[1]);
117                            Matrix p = new JSciDenseDoubleMatrix2D(getRowCount(), getRowCount());
118                            p.eye(Ret.ORIG);
119                            return new Matrix[] { l, u, p };
120                    } else {
121                            throw new MatrixException("only allowed for square matrices");
122                    }
123            }
124    
125            public Matrix[] qr() {
126                    if (matrix instanceof DoubleSquareMatrix) {
127                            AbstractDoubleSquareMatrix[] qr = ((DoubleSquareMatrix) matrix)
128                                            .qrDecompose();
129                            Matrix q = new JSciDenseDoubleMatrix2D(qr[0]);
130                            Matrix r = new JSciDenseDoubleMatrix2D(qr[1]);
131                            return new Matrix[] { q, r };
132                    } else {
133                            throw new MatrixException("only allowed for square matrices");
134                    }
135            }
136    
137            public Matrix[] svd() {
138                    if (matrix instanceof DoubleSquareMatrix) {
139                            AbstractDoubleSquareMatrix[] svd = ((DoubleSquareMatrix) matrix)
140                                            .singularValueDecompose();
141                            Matrix u = new JSciDenseDoubleMatrix2D(svd[0]);
142                            Matrix s = new JSciDenseDoubleMatrix2D(svd[1]);
143                            Matrix v = new JSciDenseDoubleMatrix2D(svd[2]);
144                            return new Matrix[] { u, s, v };
145                    } else {
146                            throw new MatrixException("only allowed for square matrices");
147                    }
148            }
149    
150            public Matrix mtimes(Matrix m) {
151                    if (m instanceof JSciDenseDoubleMatrix2D) {
152                            return new JSciDenseDoubleMatrix2D(matrix
153                                            .multiply(((JSciDenseDoubleMatrix2D) m).matrix));
154                    } else {
155                            return super.mtimes(m);
156                    }
157            }
158    
159            public AbstractDoubleMatrix getWrappedObject() {
160                    return matrix;
161            }
162    
163            public void setWrappedObject(AbstractDoubleMatrix object) {
164                    this.matrix = object;
165            }
166    
167    }