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.ojalgo;
025    
026    import java.io.IOException;
027    import java.io.ObjectInputStream;
028    import java.io.ObjectOutputStream;
029    
030    import org.ojalgo.access.Access2D;
031    import org.ojalgo.array.ArrayUtils;
032    import org.ojalgo.function.implementation.PrimitiveFunction;
033    import org.ojalgo.matrix.BasicMatrix;
034    import org.ojalgo.matrix.PrimitiveMatrix;
035    import org.ojalgo.matrix.decomposition.LUDecomposition;
036    import org.ojalgo.matrix.store.MatrixStore;
037    import org.ojalgo.matrix.store.OjalgoUtil;
038    import org.ojalgo.matrix.store.PhysicalStore;
039    import org.ojalgo.matrix.store.PrimitiveDenseStore;
040    import org.ujmp.core.Matrix;
041    import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
042    import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix2D;
043    import org.ujmp.core.exceptions.MatrixException;
044    import org.ujmp.core.interfaces.HasColumnMajorDoubleArray1D;
045    import org.ujmp.core.interfaces.Wrapper;
046    import org.ujmp.ojalgo.calculation.Chol;
047    import org.ujmp.ojalgo.calculation.Eig;
048    import org.ujmp.ojalgo.calculation.Inv;
049    import org.ujmp.ojalgo.calculation.InvSPD;
050    import org.ujmp.ojalgo.calculation.LU;
051    import org.ujmp.ojalgo.calculation.QR;
052    import org.ujmp.ojalgo.calculation.SVD;
053    import org.ujmp.ojalgo.calculation.Solve;
054    
055    public class OjalgoDenseDoubleMatrix2D extends AbstractDenseDoubleMatrix2D
056                    implements Wrapper<MatrixStore<Double>> {
057    
058            private static final long serialVersionUID = 6628172130438716653L;
059    
060            private transient PrimitiveDenseStore matrix;
061    
062            public OjalgoDenseDoubleMatrix2D(final long... size) {
063                    matrix = (PrimitiveDenseStore) PrimitiveDenseStore.FACTORY.makeZero(
064                                    (int) size[ROW], (int) size[COLUMN]);
065            }
066    
067            public OjalgoDenseDoubleMatrix2D(final Matrix m) {
068                    if (m instanceof HasColumnMajorDoubleArray1D) {
069                            final double[] data = ((HasColumnMajorDoubleArray1D) m)
070                                            .getColumnMajorDoubleArray1D();
071                            this.matrix = OjalgoUtil.linkToArray((int) m.getRowCount(), (int) m
072                                            .getColumnCount(), data);
073                    } else if (m instanceof DenseDoubleMatrix2D) {
074                            this.matrix = (PrimitiveDenseStore) PrimitiveDenseStore.FACTORY
075                                            .makeZero((int) m.getRowCount(), (int) m.getColumnCount());
076                            final DenseDoubleMatrix2D m2 = (DenseDoubleMatrix2D) m;
077                            for (int r = (int) m.getRowCount(); --r >= 0;) {
078                                    for (int c = (int) m.getColumnCount(); --c >= 0;) {
079                                            matrix.set(r, c, m2.getDouble(r, c));
080                                    }
081                            }
082                    } else {
083                            this.matrix = (PrimitiveDenseStore) PrimitiveDenseStore.FACTORY
084                                            .makeZero((int) m.getRowCount(), (int) m.getColumnCount());
085                            for (final long[] c : m.availableCoordinates()) {
086                                    this.setDouble(m.getAsDouble(c), c);
087                            }
088                    }
089            }
090    
091            public OjalgoDenseDoubleMatrix2D(final MatrixStore<Double> m) {
092                    this.setWrappedObject(m);
093            }
094    
095            @Override
096            public Matrix chol() {
097                    return Chol.INSTANCE.calc(this);
098            }
099    
100            @Override
101            public Matrix divide(final double factor) throws MatrixException {
102                    final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
103                                    .makeEmpty((int) this.getRowCount(), (int) this
104                                                    .getColumnCount());
105    
106                    retVal.fillMatching(matrix, PrimitiveFunction.DIVIDE, factor);
107    
108                    return new OjalgoDenseDoubleMatrix2D(retVal);
109            }
110    
111            @Override
112            public Matrix divide(final Matrix m) throws MatrixException {
113                    if (m instanceof OjalgoDenseDoubleMatrix2D) {
114    
115                            final PrimitiveDenseStore tmpArg = ((OjalgoDenseDoubleMatrix2D) m)
116                                            .getWrappedObject();
117    
118                            final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
119                                            .makeEmpty((int) this.getRowCount(), (int) this
120                                                            .getColumnCount());
121    
122                            retVal.fillMatching(matrix, PrimitiveFunction.DIVIDE, tmpArg);
123    
124                            return new OjalgoDenseDoubleMatrix2D(retVal);
125    
126                    } else {
127    
128                            return super.divide(m);
129                    }
130            }
131    
132            @Override
133            public Matrix[] eig() {
134                    return Eig.INSTANCE.calc(this);
135            }
136    
137            public final BasicMatrix getBasicMatrix() {
138                    return new PrimitiveMatrix(matrix);
139            }
140    
141            public double getDouble(final int row, final int column) {
142                    return matrix.doubleValue(row, column);
143            }
144    
145            public double getDouble(final long row, final long column) {
146                    return matrix.doubleValue((int) row, (int) column);
147            }
148    
149            public long[] getSize() {
150                    return new long[] { matrix.getRowDim(), matrix.getColDim() };
151            }
152    
153            public PrimitiveDenseStore getWrappedObject() {
154                    return matrix;
155            }
156    
157            @Override
158            public Matrix inv() {
159                    return Inv.INSTANCE.calc(this);
160            }
161    
162            @Override
163            public Matrix invSPD() {
164                    return InvSPD.INSTANCE.calc(this);
165            }
166    
167            public double det() {
168                    final org.ojalgo.matrix.decomposition.LU<Double> lu = LUDecomposition
169                                    .makePrimitive();
170                    lu.compute(matrix);
171                    return lu.getDeterminant();
172            }
173    
174            @Override
175            public Matrix[] lu() {
176                    return LU.INSTANCE.calc(this);
177            }
178    
179            @Override
180            public Matrix minus(final double factor) throws MatrixException {
181                    final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
182                                    .makeEmpty((int) this.getRowCount(), (int) this
183                                                    .getColumnCount());
184    
185                    retVal.fillMatching(matrix, PrimitiveFunction.SUBTRACT, factor);
186    
187                    return new OjalgoDenseDoubleMatrix2D(retVal);
188            }
189    
190            @Override
191            public Matrix minus(final Matrix m) throws MatrixException {
192                    if (m instanceof OjalgoDenseDoubleMatrix2D) {
193    
194                            final PrimitiveDenseStore tmpArg = ((OjalgoDenseDoubleMatrix2D) m)
195                                            .getWrappedObject();
196    
197                            final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
198                                            .makeEmpty((int) this.getRowCount(), (int) this
199                                                            .getColumnCount());
200    
201                            retVal.fillMatching(matrix, PrimitiveFunction.SUBTRACT, tmpArg);
202    
203                            return new OjalgoDenseDoubleMatrix2D(retVal);
204    
205                    } else {
206    
207                            return super.minus(m);
208                    }
209            }
210    
211            @Override
212            public Matrix mtimes(final Matrix m) {
213                    if (m instanceof OjalgoDenseDoubleMatrix2D) {
214                            final PrimitiveDenseStore mo = ((OjalgoDenseDoubleMatrix2D) m)
215                                            .getWrappedObject();
216                            final PrimitiveDenseStore result = (PrimitiveDenseStore) matrix
217                                            .multiplyRight(mo);
218                            return new OjalgoDenseDoubleMatrix2D(result);
219                    } else {
220                            return super.mtimes(m);
221                    }
222            }
223    
224            @Override
225            public Matrix plus(final double factor) throws MatrixException {
226                    final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
227                                    .makeEmpty((int) this.getRowCount(), (int) this
228                                                    .getColumnCount());
229    
230                    retVal.fillMatching(matrix, PrimitiveFunction.ADD, factor);
231    
232                    return new OjalgoDenseDoubleMatrix2D(retVal);
233            }
234    
235            @Override
236            public Matrix plus(final Matrix m) throws MatrixException {
237                    if (m instanceof OjalgoDenseDoubleMatrix2D) {
238    
239                            final PrimitiveDenseStore tmpArg = ((OjalgoDenseDoubleMatrix2D) m)
240                                            .getWrappedObject();
241    
242                            final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
243                                            .makeEmpty((int) this.getRowCount(), (int) this
244                                                            .getColumnCount());
245    
246                            retVal.fillMatching(matrix, PrimitiveFunction.ADD, tmpArg);
247    
248                            return new OjalgoDenseDoubleMatrix2D(retVal);
249    
250                    } else {
251    
252                            return super.plus(m);
253                    }
254            }
255    
256            @Override
257            public Matrix[] qr() {
258                    return QR.INSTANCE.calc(this);
259            }
260    
261            public void setDouble(final double value, final int row, final int column) {
262                    matrix.set(row, column, value);
263            }
264    
265            public void setDouble(final double value, final long row, final long column) {
266                    matrix.set((int) row, (int) column, value);
267            }
268    
269            public void setWrappedObject(final MatrixStore<Double> object) {
270                    if (object instanceof PrimitiveDenseStore) {
271                            matrix = (PrimitiveDenseStore) object;
272                    } else {
273                            matrix = (PrimitiveDenseStore) PrimitiveDenseStore.FACTORY
274                                            .copy(object);
275                    }
276            }
277    
278            @Override
279            public Matrix solve(final Matrix b) {
280                    return Solve.INSTANCE.calc(this, b);
281            }
282    
283            @Override
284            public Matrix[] svd() {
285                    return SVD.INSTANCE.calc(this);
286            }
287    
288            @Override
289            public Matrix times(final double factor) throws MatrixException {
290                    final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
291                                    .makeEmpty((int) this.getRowCount(), (int) this
292                                                    .getColumnCount());
293    
294                    retVal.fillMatching(matrix, PrimitiveFunction.MULTIPLY, factor);
295    
296                    return new OjalgoDenseDoubleMatrix2D(retVal);
297            }
298    
299            @Override
300            public Matrix times(final Matrix m) throws MatrixException {
301                    if (m instanceof OjalgoDenseDoubleMatrix2D) {
302    
303                            final PrimitiveDenseStore tmpArg = ((OjalgoDenseDoubleMatrix2D) m)
304                                            .getWrappedObject();
305    
306                            final PhysicalStore<Double> retVal = PrimitiveDenseStore.FACTORY
307                                            .makeEmpty((int) this.getRowCount(), (int) this
308                                                            .getColumnCount());
309    
310                            retVal.fillMatching(matrix, PrimitiveFunction.MULTIPLY, tmpArg);
311    
312                            return new OjalgoDenseDoubleMatrix2D(retVal);
313    
314                    } else {
315    
316                            return super.times(m);
317                    }
318            }
319    
320            @Override
321            public double[][] toDoubleArray() throws MatrixException {
322                    return ArrayUtils.toRawCopyOf((Access2D<Double>) matrix);
323            }
324    
325            @Override
326            public Matrix transpose() {
327                    return new OjalgoDenseDoubleMatrix2D(matrix.transpose());
328            }
329    
330            private void readObject(final ObjectInputStream s) throws IOException,
331                            ClassNotFoundException {
332                    s.defaultReadObject();
333                    final double[][] data = (double[][]) s.readObject();
334                    matrix = (PrimitiveDenseStore) PrimitiveDenseStore.FACTORY
335                                    .copy(ArrayUtils.wrapAccess2D(data));
336            }
337    
338            private void writeObject(final ObjectOutputStream s) throws IOException {
339                    s.defaultWriteObject();
340                    s.writeObject(this.toDoubleArray());
341            }
342    
343    }