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.orbital;
025    
026    import java.io.IOException;
027    import java.io.ObjectInputStream;
028    import java.io.ObjectOutputStream;
029    
030    import orbital.math.LUDecomposition;
031    import orbital.math.Real;
032    import orbital.math.Values;
033    
034    import org.ujmp.core.Matrix;
035    import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix2D;
036    import org.ujmp.core.exceptions.MatrixException;
037    import org.ujmp.core.interfaces.Wrapper;
038    
039    public class OrbitalDenseDoubleMatrix2D extends AbstractDenseDoubleMatrix2D
040                    implements Wrapper<orbital.math.Matrix> {
041    
042            private static final long serialVersionUID = 3094717557850722162L;
043    
044            private transient orbital.math.Matrix matrix = null;
045    
046            public OrbitalDenseDoubleMatrix2D(final long... size) {
047                    matrix = Values.getDefault().ZERO((int) size[ROW], (int) size[COLUMN]);
048            }
049    
050            public OrbitalDenseDoubleMatrix2D(final Matrix m) {
051                    this(m.getSize());
052                    for (final long[] c : m.allCoordinates()) {
053                            setDouble(m.getAsDouble(c), c);
054                    }
055            }
056    
057            public OrbitalDenseDoubleMatrix2D(final orbital.math.Matrix matrix) {
058                    this.matrix = matrix;
059            }
060    
061            public double getDouble(final int row, final int column) {
062                    return ((Real) matrix.get(row, column)).doubleValue();
063            }
064    
065            public double getDouble(final long row, final long column) {
066                    return ((Real) matrix.get((int) row, (int) column)).doubleValue();
067            }
068    
069            public long[] getSize() {
070                    return new long[] { matrix.dimensions()[0], matrix.dimensions()[1] };
071            }
072    
073            public orbital.math.Matrix getWrappedObject() {
074                    return matrix;
075            }
076    
077            @Override
078            public Matrix mtimes(final Matrix m) {
079                    if (m instanceof OrbitalDenseDoubleMatrix2D) {
080                            final orbital.math.Matrix mo = ((OrbitalDenseDoubleMatrix2D) m)
081                                            .getWrappedObject();
082                            final orbital.math.Matrix result = matrix.multiply(mo);
083                            return new OrbitalDenseDoubleMatrix2D(result);
084                    } else {
085                            return super.mtimes(m);
086                    }
087            }
088    
089            public void setDouble(final double value, final int row, final int column) {
090                    matrix.set(row, column, Values.getDefault().valueOf(value));
091            }
092    
093            public void setDouble(final double value, final long row, final long column) {
094                    matrix.set((int) row, (int) column, Values.getDefault().valueOf(value));
095            }
096    
097            public void setWrappedObject(final orbital.math.Matrix object) {
098                    matrix = object;
099            }
100    
101            public Matrix plus(Matrix m) {
102                    if (m instanceof OrbitalDenseDoubleMatrix2D) {
103                            orbital.math.Matrix result = matrix
104                                            .add(((OrbitalDenseDoubleMatrix2D) m).matrix);
105                            return new OrbitalDenseDoubleMatrix2D(result);
106                    } else {
107                            return super.plus(m);
108                    }
109            }
110    
111            public Matrix times(double v) {
112                    orbital.math.Matrix result = matrix.scale(Values.getDefault()
113                                    .valueOf(v));
114                    return new OrbitalDenseDoubleMatrix2D(result);
115            }
116    
117            public Matrix divide(double v) {
118                    orbital.math.Matrix result = matrix.scale(Values.getDefault().valueOf(
119                                    1.0 / v));
120                    return new OrbitalDenseDoubleMatrix2D(result);
121            }
122    
123            public Matrix minus(Matrix m) {
124                    if (m instanceof OrbitalDenseDoubleMatrix2D) {
125                            orbital.math.Matrix result = matrix
126                                            .subtract(((OrbitalDenseDoubleMatrix2D) m).matrix);
127                            return new OrbitalDenseDoubleMatrix2D(result);
128                    } else {
129                            return super.minus(m);
130                    }
131            }
132    
133            @Override
134            public Matrix transpose() {
135                    return new OrbitalDenseDoubleMatrix2D(matrix.transpose());
136            }
137    
138            @Override
139            public Matrix inv() {
140                    return new OrbitalDenseDoubleMatrix2D((orbital.math.Matrix) matrix
141                                    .inverse());
142            }
143    
144            @Override
145            public Matrix[] lu() {
146                    if (isSquare()) {
147                            LUDecomposition lu = LUDecomposition.decompose(matrix);
148                            Matrix l = new OrbitalDenseDoubleMatrix2D(lu.getL());
149                            Matrix u = new OrbitalDenseDoubleMatrix2D(lu.getU());
150                            Matrix p = new OrbitalDenseDoubleMatrix2D(lu.getP());
151                            return new Matrix[] { l, u, p };
152                    } else {
153                            throw new MatrixException("only square matrices allowed");
154                    }
155            }
156    
157            private void readObject(final ObjectInputStream s) throws IOException,
158                            ClassNotFoundException {
159                    s.defaultReadObject();
160                    final double[][] data = (double[][]) s.readObject();
161                    int rows = data.length;
162                    int cols = data[0].length;
163                    matrix = Values.getDefault().ZERO(rows, cols);
164                    for (int r = 0; r < rows; r++) {
165                            for (int c = 0; c < cols; c++) {
166                                    setDouble(data[r][c], r, c);
167                            }
168                    }
169            }
170    
171            private void writeObject(final ObjectOutputStream s) throws IOException {
172                    s.defaultWriteObject();
173                    s.writeObject(this.toDoubleArray());
174            }
175    
176    }