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.core.objectmatrix.impl;
025    
026    import java.util.ArrayList;
027    import java.util.HashMap;
028    import java.util.List;
029    import java.util.Map;
030    
031    import org.ujmp.core.Coordinates;
032    import org.ujmp.core.Matrix;
033    import org.ujmp.core.calculation.Calculation.Ret;
034    import org.ujmp.core.exceptions.MatrixException;
035    import org.ujmp.core.interfaces.Wrapper;
036    import org.ujmp.core.objectmatrix.stub.AbstractSparseObjectMatrix2D;
037    import org.ujmp.core.util.MathUtil;
038    
039    public class DefaultSparseRowObjectMatrix2D extends AbstractSparseObjectMatrix2D implements
040                    Wrapper<Map<Long, Matrix>> {
041            private static final long serialVersionUID = -5291604525500706427L;
042    
043            private long[] size = new long[] { 1, 1 };
044    
045            private Map<Long, Matrix> rows = new HashMap<Long, Matrix>();
046    
047            public DefaultSparseRowObjectMatrix2D(long... size) {
048                    setSize(size);
049            }
050    
051            public DefaultSparseRowObjectMatrix2D(Matrix m) {
052                    setSize(m.getSize());
053                    for (long[] c : m.availableCoordinates()) {
054                            setObject(m.getAsObject(c), c);
055                    }
056            }
057    
058            public Object getObject(long row, long column) throws MatrixException {
059                    Matrix m = rows.get(row);
060                    return m == null ? null : m.getAsObject(0, column);
061            }
062    
063            public Object getObject(int row, int column) throws MatrixException {
064                    Matrix m = rows.get(row);
065                    return m == null ? null : m.getAsObject(0, column);
066            }
067    
068            // TODO: this is certainly not the optimal way to do it!
069    
070            public Iterable<long[]> availableCoordinates() {
071                    List<long[]> coordinates = new ArrayList<long[]>();
072                    for (Long r : rows.keySet()) {
073                            Matrix m = rows.get(r);
074                            for (long[] c : m.availableCoordinates()) {
075                                    coordinates.add(Coordinates.plus(c, new long[] { r, 0 }));
076                            }
077                    }
078                    return coordinates;
079            }
080    
081            public boolean contains(long... coordinates) {
082                    if (Coordinates.isSmallerThan(coordinates, size)) {
083                            return getObject(coordinates) != null;
084                    } else {
085                            return false;
086                    }
087            }
088    
089            public double getAsDouble(long... coordinates) throws MatrixException {
090                    return MathUtil.getDouble(getObject(coordinates));
091            }
092    
093            public void setAsDouble(double value, long... coordinates) throws MatrixException {
094                    setObject(value, coordinates);
095            }
096    
097            public void setObject(Object o, long row, long column) throws MatrixException {
098                    Matrix m = rows.get(row);
099                    if (m == null) {
100                            // TODO: there should be a faster implementation than this:
101                            m = new DefaultSparseObjectMatrix((long) 1, getColumnCount());
102                            rows.put(row, m);
103                    }
104                    m.setAsObject(o, 0, column);
105            }
106    
107            public void setObject(Object o, int row, int column) throws MatrixException {
108                    setObject(o, (long) row, (long) column);
109            }
110    
111            public long[] getSize() {
112                    return size;
113            }
114    
115            public void setSize(long... size) {
116                    if (this.size[COLUMN] != size[COLUMN]) {
117                            for (Matrix m : rows.values()) {
118                                    m.setSize(1, size[COLUMN]);
119                            }
120                    }
121                    this.size = size;
122            }
123    
124            public Matrix getRow(long row) {
125                    return rows.get(row);
126            }
127    
128            public Matrix max(Ret returnType, int dimension) throws MatrixException {
129                    if (returnType == Ret.NEW) {
130    
131                            if (dimension == ROW) {
132                                    Matrix ret = Matrix.factory.zeros(1, getColumnCount());
133                                    for (long[] c : availableCoordinates()) {
134                                            double v = getAsDouble(c);
135                                            if (v > ret.getAsDouble(0, c[COLUMN])) {
136                                                    ret.setAsDouble(v, 0, c[COLUMN]);
137                                            }
138                                    }
139                                    return ret;
140                            } else if (dimension == COLUMN) {
141                                    Matrix ret = Matrix.factory.zeros(getRowCount(), 1);
142                                    for (long[] c : availableCoordinates()) {
143                                            double v = getAsDouble(c);
144                                            if (v > ret.getAsDouble(c[ROW], 0)) {
145                                                    ret.setAsDouble(v, c[ROW], 0);
146                                            }
147                                    }
148                                    return ret;
149                            }
150    
151                    }
152                    throw new MatrixException("not supported");
153            }
154    
155            public Matrix selectRows(Ret returnType, long... rows) throws MatrixException {
156                    if (returnType == Ret.LINK && rows.length == 1) {
157                            return getRow(rows[0]);
158                    }
159                    return super.selectRows(returnType, rows);
160            }
161    
162            public Map<Long, Matrix> getWrappedObject() {
163                    return rows;
164            }
165    
166            public void setWrappedObject(Map<Long, Matrix> object) {
167                    this.rows = object;
168            }
169    
170    }