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