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.jmatio;
025    
026    import java.io.IOException;
027    import java.io.ObjectInputStream;
028    import java.io.ObjectOutputStream;
029    
030    import org.ujmp.core.Coordinates;
031    import org.ujmp.core.Matrix;
032    import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix;
033    import org.ujmp.core.exceptions.MatrixException;
034    import org.ujmp.core.interfaces.Wrapper;
035    import org.ujmp.core.util.MathUtil;
036    
037    import com.jmatio.types.MLDouble;
038    
039    public class MLDoubleMatrix extends AbstractDenseDoubleMatrix implements Wrapper<MLDouble> {
040            private static final long serialVersionUID = 5687213209146399315L;
041    
042            private transient MLDouble matrix = null;
043    
044            private int[] pack = null;
045    
046            public MLDoubleMatrix(Matrix m) {
047                    if (m.getAnnotation() != null) {
048                            setAnnotation(m.getAnnotation().clone());
049                            this.matrix = new MLDouble(m.getLabel(), MathUtil.toIntArray(m.getSize()));
050                    } else {
051                            this.matrix = new MLDouble("matrix" + System.nanoTime(), MathUtil.toIntArray(m
052                                            .getSize()));
053                    }
054                    init();
055                    for (long[] c : m.availableCoordinates()) {
056                            setAsDouble(m.getAsDouble(c), c);
057                    }
058            }
059    
060            public MLDoubleMatrix(long... size) {
061                    if (Coordinates.product(size) > 0) {
062                            this.matrix = new MLDouble("matrix" + System.nanoTime(), MathUtil.toIntArray(size));
063                            init();
064                    }
065            }
066    
067            private void init() {
068                    int[] dims = matrix.getDimensions();
069                    pack = new int[matrix.getNDimensions()];
070                    pack[0] = 1;
071                    for (int i = 1; i < pack.length; i++) {
072                            pack[i] = dims[i - 1] * pack[i - 1];
073                    }
074            }
075    
076            int getIndex(long... coords) {
077                    int index = 0;
078                    for (int x = 0; x < coords.length; x++) {
079                            index += coords[x] * pack[x];
080                    }
081                    return index;
082            }
083    
084            public MLDoubleMatrix(MLDouble matrix) {
085                    this.matrix = matrix;
086                    setLabel(matrix.getName());
087                    init();
088            }
089    
090            public long[] getSize() {
091                    return matrix == null ? Coordinates.ZERO2D : MathUtil.toLongArray(matrix.getDimensions());
092            }
093    
094            // access to matrix data must be synchronized
095            public synchronized double getDouble(long... coordinates) {
096                    return matrix.get(getIndex(coordinates));
097            }
098    
099            // access to matrix data must be synchronized
100            public synchronized void setDouble(double value, long... coordinates) {
101                    matrix.set(value, getIndex(coordinates));
102            }
103    
104            public MLDouble getWrappedObject() {
105                    return matrix;
106            }
107    
108            public void setWrappedObject(MLDouble object) {
109                    this.matrix = object;
110            }
111    
112            private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
113                    s.defaultReadObject();
114                    String name = (String) s.readObject();
115                    double[][] values = (double[][]) s.readObject();
116                    matrix = new MLDouble(name, values);
117            }
118    
119            private void writeObject(ObjectOutputStream s) throws IOException, MatrixException {
120                    s.defaultWriteObject();
121                    s.writeObject(matrix.name);
122                    s.writeObject(this.toDoubleArray());
123            }
124    
125    }