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.vecmath;
025    
026    import javax.vecmath.GMatrix;
027    import javax.vecmath.GVector;
028    
029    import org.ujmp.core.Matrix;
030    import org.ujmp.core.calculation.Calculation.Ret;
031    import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
032    import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix2D;
033    import org.ujmp.core.exceptions.MatrixException;
034    import org.ujmp.core.interfaces.Wrapper;
035    
036    public class VecMathDenseDoubleMatrix2D extends AbstractDenseDoubleMatrix2D
037                    implements Wrapper<GMatrix> {
038            private static final long serialVersionUID = 3792684800581150214L;
039    
040            private GMatrix matrix = null;
041    
042            public VecMathDenseDoubleMatrix2D(GMatrix m) {
043                    this.matrix = m;
044            }
045    
046            public VecMathDenseDoubleMatrix2D(long... size) {
047                    this.matrix = new GMatrix((int) size[ROW], (int) size[COLUMN]);
048                    // matrix is not empty by default!
049                    for (int r = 0; r < size[ROW]; r++) {
050                            for (int c = 0; c < size[COLUMN]; c++) {
051                                    setDouble(0.0, r, c);
052                            }
053                    }
054            }
055    
056            public VecMathDenseDoubleMatrix2D(Matrix source) throws MatrixException {
057                    this(source.getSize());
058                    for (long[] c : source.availableCoordinates()) {
059                            setAsDouble(source.getAsDouble(c), c);
060                    }
061            }
062    
063            public double getDouble(long row, long column) {
064                    return matrix.getElement((int) row, (int) column);
065            }
066    
067            public double getDouble(int row, int column) {
068                    return matrix.getElement(row, column);
069            }
070    
071            public long[] getSize() {
072                    return new long[] { matrix.getNumRow(), matrix.getNumCol() };
073            }
074    
075            public void setDouble(double value, long row, long column) {
076                    matrix.setElement((int) row, (int) column, value);
077            }
078    
079            public void setDouble(double value, int row, int column) {
080                    matrix.setElement(row, column, value);
081            }
082    
083            public GMatrix getWrappedObject() {
084                    return matrix;
085            }
086    
087            public void setWrappedObject(GMatrix object) {
088                    this.matrix = object;
089            }
090    
091            public VecMathDenseDoubleMatrix2D transpose() {
092                    GMatrix m = (GMatrix) matrix.clone();
093                    m.transpose();
094                    return new VecMathDenseDoubleMatrix2D(m);
095            }
096    
097            public Matrix plus(Matrix m) {
098                    if (m instanceof VecMathDenseDoubleMatrix2D) {
099                            GMatrix result = (GMatrix) matrix.clone();
100                            result.add(((VecMathDenseDoubleMatrix2D) m).matrix);
101                            return new VecMathDenseDoubleMatrix2D(result);
102                    } else {
103                            return super.plus(m);
104                    }
105            }
106    
107            public Matrix minus(Matrix m) {
108                    if (m instanceof VecMathDenseDoubleMatrix2D) {
109                            GMatrix result = (GMatrix) matrix.clone();
110                            result.sub(((VecMathDenseDoubleMatrix2D) m).matrix);
111                            return new VecMathDenseDoubleMatrix2D(result);
112                    } else {
113                            return super.minus(m);
114                    }
115            }
116    
117            public Matrix mtimes(Matrix m) {
118                    if (m instanceof VecMathDenseDoubleMatrix2D) {
119                            GMatrix result = new GMatrix(matrix.getNumRow(), (int) m
120                                            .getColumnCount());
121                            result.mul(matrix, ((VecMathDenseDoubleMatrix2D) m).matrix);
122                            return new VecMathDenseDoubleMatrix2D(result);
123                    } else {
124                            return super.mtimes(m);
125                    }
126            }
127    
128            public DenseDoubleMatrix2D inv() {
129                    GMatrix m = (GMatrix) matrix.clone();
130                    m.invert();
131                    return new VecMathDenseDoubleMatrix2D(m);
132            }
133    
134            // in S all entries on the diagonal are 1
135            public Matrix[] svd() {
136                    GMatrix m = (GMatrix) matrix.clone();
137                    int nrows = (int) getRowCount();
138                    int ncols = (int) getColumnCount();
139                    GMatrix u = new GMatrix(nrows, nrows);
140                    GMatrix s = new GMatrix(nrows, ncols);
141                    GMatrix v = new GMatrix(ncols, ncols);
142                    m.SVD(u, s, v);
143                    Matrix U = new VecMathDenseDoubleMatrix2D(u);
144                    Matrix S = new VecMathDenseDoubleMatrix2D(s);
145                    Matrix V = new VecMathDenseDoubleMatrix2D(v);
146                    return new Matrix[] { U, S, V };
147            }
148    
149            // non-singular matrices only
150            public Matrix[] lu() {
151                    if (isSquare()) {
152                            GMatrix m = (GMatrix) matrix.clone();
153                            GMatrix lu = (GMatrix) matrix.clone();
154                            GVector piv = new GVector(matrix.getNumCol());
155                            m.LUD(lu, piv);
156                            Matrix l = new VecMathDenseDoubleMatrix2D(lu).tril(Ret.NEW, 0);
157                            for (int i = (int) l.getRowCount() - 1; i != -1; i--) {
158                                    l.setAsDouble(1, i, i);
159                            }
160                            Matrix u = new VecMathDenseDoubleMatrix2D(lu).triu(Ret.NEW, 0);
161                            VecMathDenseDoubleMatrix2D p = new VecMathDenseDoubleMatrix2D(
162                                            getSize());
163                            for (int i = piv.getSize() - 1; i != -1; i--) {
164                                    p.setDouble(1, i, (int) piv.getElement(i));
165                            }
166                            return new Matrix[] { l, u, p };
167                    } else {
168                            throw new MatrixException("only allowed for square matrices");
169                    }
170            }
171    
172    }