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.graphmatrix;
025    
026    import java.util.ArrayList;
027    import java.util.List;
028    
029    import org.ujmp.core.Coordinates;
030    import org.ujmp.core.genericmatrix.stub.AbstractSparseGenericMatrix2D;
031    import org.ujmp.core.objectmatrix.SparseObjectMatrix2D;
032    import org.ujmp.core.objectmatrix.factory.SparseObjectMatrix2DFactory;
033    
034    public abstract class AbstractGraphMatrix<N, E> extends AbstractSparseGenericMatrix2D<E> implements
035                    GraphMatrix<N, E> {
036            private static final long serialVersionUID = -4939918585100574441L;
037    
038            public boolean contains(long... coordinates) {
039                    return getEdgeList().contains(new Coordinates(coordinates));
040            }
041    
042            public void removeUndirectedEdge(N node1, N node2) {
043                    long index1 = getIndexOfNode(node1);
044                    long index2 = getIndexOfNode(node2);
045                    removeDirectedEdge(index1, index2);
046                    removeDirectedEdge(index2, index1);
047            }
048    
049            public boolean isConnected(N node1, N node2) {
050                    long index1 = getIndexOfNode(node1);
051                    long index2 = getIndexOfNode(node2);
052                    return isConnected(index1, index2);
053            }
054    
055            public List<N> getParents(long index) {
056                    List<Long> indices = getParentIndices(index);
057                    List<N> objects = new ArrayList<N>(indices.size());
058                    for (int i = 0; i < indices.size(); i++) {
059                            objects.add(getNode(indices.get(i)));
060                    }
061                    return objects;
062            }
063    
064            public List<N> getParents(N node) {
065                    List<Long> indices = getParentIndices(node);
066                    List<N> objects = new ArrayList<N>(indices.size());
067                    for (int i = 0; i < indices.size(); i++) {
068                            objects.add(getNode(indices.get(i)));
069                    }
070                    return objects;
071            }
072    
073            public List<N> getChildren(long index) {
074                    List<Long> indices = getChildIndices(index);
075                    List<N> objects = new ArrayList<N>(indices.size());
076                    for (int i = 0; i < indices.size(); i++) {
077                            objects.add(getNode(indices.get(i)));
078                    }
079                    return objects;
080            }
081    
082            public List<Long> getParentIndices(N node) {
083                    long index = getIndexOfNode(node);
084                    return getParentIndices(index);
085            }
086    
087            public E getEdgeValue(N node1, N node2) {
088                    long index1 = getIndexOfNode(node1);
089                    long index2 = getIndexOfNode(node2);
090                    return getEdgeValue(index1, index2);
091            }
092    
093            public int getDegree(N node) {
094                    return getParentCount(node) + getChildCount(node);
095            }
096    
097            public int getDegree(long nodeIndex) {
098                    return getParentCount(nodeIndex) + getChildCount(nodeIndex);
099            }
100    
101            public void addChild(long nodeIndex, long childIndex) {
102                    addEdge(nodeIndex, childIndex);
103            }
104    
105            public void addParent(long nodeIndex, long parentIndex) {
106                    addEdge(nodeIndex, parentIndex);
107            }
108    
109            public int getChildCount(N node) {
110                    return getChildCount(getIndexOfNode(node));
111            }
112    
113            public void addParent(N node, N parent) {
114                    long parentIndex = getIndexOfNode(node);
115                    long nodeIndex = getIndexOfNode(node);
116                    addParent(nodeIndex, parentIndex);
117            }
118    
119            public int getParentCount(N node) {
120                    long index = getIndexOfNode(node);
121                    return getParentCount(index);
122            }
123    
124            public List<Long> getChildIndices(N node) {
125                    long index = getIndexOfNode(node);
126                    return getChildIndices(index);
127            }
128    
129            public List<N> getChildren(N node) {
130                    List<Long> indices = getChildIndices(node);
131                    List<N> objects = new ArrayList<N>(indices.size());
132                    for (int i = 0; i < indices.size(); i++) {
133                            objects.add(getNode(indices.get(i)));
134                    }
135                    return objects;
136            }
137    
138            public void removeUndirectedEdge(long nodeIndex1, long nodeIndex2) {
139                    removeDirectedEdge(nodeIndex1, nodeIndex2);
140                    removeDirectedEdge(nodeIndex2, nodeIndex1);
141            }
142    
143            public void removeDirectedEdge(N node1, N node2) {
144                    long index1 = getIndexOfNode(node1);
145                    long index2 = getIndexOfNode(node2);
146                    removeDirectedEdge(index1, index2);
147            }
148    
149            public Iterable<long[]> availableCoordinates() {
150                    // TODO: improve
151                    return super.availableCoordinates();
152            }
153    
154            public long[] getSize() {
155                    return new long[] { getNodeList().size(), getNodeList().size() };
156            }
157    
158            public E getObject(long row, long column) {
159                    return getEdgeValue(row, column);
160            }
161    
162            public E getObject(int row, int column) {
163                    return getEdgeValue(row, column);
164            }
165    
166            public long getValueCount() {
167                    return getEdgeList().size();
168            }
169    
170            public final void addDirectedEdge(N node1, N node2) {
171                    long i1 = getIndexOfNode(node1);
172                    long i2 = getIndexOfNode(node2);
173                    addDirectedEdge(i1, i2);
174            }
175    
176            public abstract void addUndirectedEdge(long node1, long node2);
177    
178            public abstract void addDirectedEdge(long node1, long node2);
179    
180            public final void addUndirectedEdge(N node1, N node2) {
181                    long i1 = getIndexOfNode(node1);
182                    long i2 = getIndexOfNode(node2);
183                    addUndirectedEdge(i1, i2);
184            }
185    
186            public final boolean isConnected(long node1, long node2) {
187                    return getObject(node1, node2) != null;
188            }
189    
190            public final long getIndexOfNode(N o) {
191                    return (getNodeList()).indexOf(o);
192            }
193    
194            public void setUndirectedEdge(E value, long node1, long node2) {
195                    setDirectedEdge(value, node1, node2);
196                    setDirectedEdge(value, node2, node1);
197            }
198    
199            // public final void setObject(E v, long... coordinates) {
200            // setDirectedEdge(v, coordinates[ROW], coordinates[COLUMN]);
201            // }
202    
203            public void setDirectedEdge(E edgeObject, N node1, N node2) {
204                    long index1 = getIndexOfNode(node1);
205                    long index2 = getIndexOfNode(node2);
206                    setDirectedEdge(edgeObject, index1, index2);
207            }
208    
209            public void setUndirectedEdge(E edgeObject, N node1, N node2) {
210                    long index1 = getIndexOfNode(node1);
211                    long index2 = getIndexOfNode(node2);
212                    setUndirectedEdge(edgeObject, index1, index2);
213            }
214    
215            public abstract void clear();
216    
217            public final StorageType getStorageType() {
218                    return StorageType.GRAPH;
219            }
220    
221            public SparseObjectMatrix2DFactory getFactory() {
222                    return SparseObjectMatrix2D.factory;
223            }
224    
225    }