AuD
Lecture 'Algorithmen und Datenstrukturen' (code examples)
SparseMatrixCS.java
Go to the documentation of this file.
1package aud.graph.matrix;
2
3import java.util.Map;
4import java.util.TreeMap;
5import java.util.SortedMap;
6import java.io.*;
7
8import aud.Vector;
9import aud.util.Colormap;
10import aud.util.SVGViewer;
11
36public class SparseMatrixCS<T> {
37
38 protected TreeMap<Coordinate,T> mat_;
39
42 public SparseMatrixCS() {
43 mat_=new TreeMap<Coordinate,T>();
44 }
47 mat_=new TreeMap<Coordinate,T>(other.mat_);
48 }
49
51 public int nnz() { return mat_.size(); }
52
54 public int getNumRows() {
55 int imax=0;
56 for (Coordinate c : mat_.keySet()) {
57 if (c.i>imax)
58 imax=c.i;
59 }
60 return imax;
61 }
63 public int getMinRowIndex() {
64 int imin=Integer.MAX_VALUE;
65 for (Coordinate c : mat_.keySet()) {
66 if (c.i<imin)
67 imin=c.i;
68 }
69 return (imin==Integer.MAX_VALUE) ? 0 : imin;
70 }
72 public int getNumColumns() { return mat_.size()==0 ? 0 : mat_.lastKey().j; }
74 public int getMinColumnIndex() { return mat_.size()==0 ? 0 : mat_.firstKey().j; }
75
80 TreeMap<Coordinate,T> check(int i,int j) {
81 if (!(0<=i && 0<=j))
82 throw new IndexOutOfBoundsException();
83 return mat_;
84 }
85
90 public T get(int i,int j) {
91 return check(i,j).get(new Coordinate(i,j));
92 }
93
102 public T set(int i,int j,T data) { return _set(i,j,data); }
103
105 T _set(int i,int j,T data) {
106 T e=get(i,j);
107
108 if (e!=data) {
109 Coordinate key=new Coordinate(i,j);
110
111 if (data==null)
112 mat_.remove(key);
113 else
114 mat_.put(key,data);
115 }
116 return e;
117 }
118
122 @SuppressWarnings("unchecked")
123 public Vector<T> getColumnEntries(int j) {
124 SortedMap<Coordinate,T> sub=
125 check(1,j).subMap(new Coordinate(-1,j),
126 new Coordinate(Integer.MAX_VALUE,j));
127 Object[] a=sub.values().toArray();
128 Vector<T> v=new Vector<T>();
129 v.reserve(a.length);
130 for (int i=0;i<a.length;++i)
131 v.push_back((T) a[i]);
132 return v;
133 }
134
138 public int[] getColumnRowIndices(int j) {
139 SortedMap<Coordinate,T> sub=
140 check(1,j).subMap(new Coordinate(-1,j),
141 new Coordinate(Integer.MAX_VALUE,j));
142 int[] idx=new int[sub.size()];
143 int i=0;
144 for (Coordinate c : sub.keySet()) {
145 idx[i++]=c.i;
146 }
147 assert(i==idx.length);
148 return idx;
149 }
150
155 public int columnDegree(int j) { return getColumnEntries(j).size(); }
156
157
161 for (Map.Entry<Coordinate,T> entry : mat_.entrySet()) {
162 Coordinate c=entry.getKey();
163 m.mat_.put(new Coordinate(c.j,c.i),entry.getValue());
164 }
165 return m;
166 }
167
175 for (Map.Entry<Coordinate,T> entry : mat_.entrySet())
176 m.mat_.put(entry.getKey(),1);
177 return m;
178 }
179
180 //
181 // helpers
182 //
183
188 public int[] getRowIndices() {
189 int[] ri=new int[nnz()];
190 int i=0;
191 for (Map.Entry<Coordinate,T> entry : mat_.entrySet())
192 ri[i++]=entry.getKey().i;
193 return ri;
194 }
198 public int[] getColumnIndices() {
199 int[] ci=new int[nnz()];
200 int i=0;
201 for (Map.Entry<Coordinate,T> entry : mat_.entrySet())
202 ci[i++]=entry.getKey().j;
203 return ci;
204 }
207 @SuppressWarnings("unchecked")
208 public T[] getValues() {
209 T[] values=(T[]) new Object[nnz()];
210 int i=0;
211 for (Map.Entry<Coordinate,T> entry : mat_.entrySet())
212 values[i++]=entry.getValue();
213 return values;
214 }
215
216 @Override public String toString() {
217 String rv="[";
218 for (Map.Entry<Coordinate,T> entry : mat_.entrySet()) {
219 rv+=entry+" ";
220 }
221 return rv.trim()+"]";
222 }
223
224 //
225 // visualize matrix in various ways
226 //
227
229 public String toLaTeX(String name) {
230 String rv="\\matrix ("+name+") [matrix of math nodes]\n{\n";
231 int m=getNumRows(),n=getNumColumns();
232 Class<?> intclass=Integer.valueOf(1).getClass();
233 for (int i=getMinRowIndex();i<=m;++i) {
234 for (int j=getMinColumnIndex();j<=n;++j) {
235 T v=get(i,j);
236 if (v!=null) {
237 rv+=" ";
238 rv+=(v.getClass()==intclass) ? v.toString() : "1";
239 }
240 if (j!=n)
241 rv+=" &";
242 }
243 rv+=" \\\\\n";
244 }
245 rv+="};\n";
246 return rv;
247 }
248
249 public File renderSpySVG(File svgfile,Colormap<T> colormap) {
250 if (colormap==null)
251 colormap=new Colormap<T>();
252
253 try {
254 FileOutputStream f=new FileOutputStream(svgfile);
255
256 // write header
257 float sz=5.0f; // cell size
258 float r=2.0f; // radius
259 float w=(getNumColumns()+1)*sz, h=(getNumRows()+1)*sz;
260
261 String buf=
262 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
263 "<svg xmlns=\"http://www.w3.org/2000/svg\"\n"+
264 " width=\""+w+"mm\"\n"+
265 " height=\""+h+"mm\"\n"+
266 " version=\"1.1\"\n>\n\n";
267 f.write(buf.getBytes());
268
269 // rulers
270 f.write(("<line x1=\""+0+"mm\" y1=\""+(sz-r)+
271 "mm\" x2=\""+w+"mm\" y2=\""+(sz-r)+"mm\" "+
272 "style=\"stroke:#000000;stroke-width:1pt\"/>\n").getBytes());
273 for (int i=1;i<=getNumColumns();++i) {
274 float x=sz*(0.5f+i);
275 f.write(("<line x1=\""+x+"mm\" y1=\""+(r)+
276 "mm\" x2=\""+x+"mm\" y2=\""+(r+r)+"mm\" "+
277 "style=\"stroke:#000000;stroke-width:1pt\"/>\n").getBytes());
278 }
279 f.write(("<line x1=\""+(sz-r)+"mm\" y1=\""+0+
280 "mm\" x2=\""+(sz-r)+"mm\" y2=\""+h+"mm\" "+
281 "style=\"stroke:#000000;stroke-width:1pt\"/>\n").getBytes());
282 for (int i=1;i<=getNumRows();++i) {
283 float y=sz*(0.5f+i);
284 f.write(("<line x1=\""+(r)+"mm\" y1=\""+y+
285 "mm\" x2=\""+(r+r)+"mm\" y2=\""+(y)+"mm\" "+
286 "style=\"stroke:#000000;stroke-width:1pt\"/>\n").getBytes());
287 }
288 f.write("\n\n".getBytes());
289
290 // data
291 for (Map.Entry<Coordinate,T> entry : mat_.entrySet()) {
292 float x=sz*(0.5f+entry.getKey().j), y=sz*(0.5f+entry.getKey().i);
293 String fill=String.format("%06x",colormap.getRGB(entry.getValue()));
294
295 buf="<circle style=\"fill:#"+fill+";stroke:#000000;stroke-width:0px\" "+
296 "r=\""+r+"mm\" cx=\""+x+"mm\" cy=\""+y+"mm\"/>\n";
297 f.write(buf.getBytes());
298 }
299
300 f.write("</svg>\n".getBytes());
301 f.close();
302 } catch (IOException e) {
303 System.err.println("ERROR: "+e.getMessage());
304 return null; // note: probably triggers NullPointerException
305 }
306 return svgfile;
307 }
308
309 public String spyTikZ(boolean rulers,Colormap<T> colormap) {
310 if (colormap==null)
311 colormap=new Colormap<T>();
312
313 String s="\\begin{tikzpicture}[dot/.style={draw=none,fill=c},scale=1]\n";
314
315 if (rulers) {
316 s+=" \\foreach \\y in {0,...,"+(getNumRows()-1)+"} {\n"+
317 " \\draw (-2.5pt,-\\y) -- (2.5pt,-\\y);\n"+
318 " \\node[left] at (-1ex,-\\y-0.5) {{\\scriptsize \\y}};\n"+
319 " }\n"+
320 " \\draw (0,0) -- (0,-"+getNumRows()+");\n\n"
321 ;
322 s+=" \\foreach \\x in {1,...,"+(getNumColumns())+"} {\n"+
323 " \\draw (\\x,-2.5pt) -- (\\x,2.5pt);\n"+
324 " \\node[above] at (\\x-0.5,0) {{\\scriptsize \\x}};\n"+
325 " }\n"+
326 " \\draw (0,0) -- ("+(getNumColumns())+",0);\n\n"
327 ;
328 }
329
330 float sz=1;
331 for (Map.Entry<Coordinate,T> entry : mat_.entrySet()) {
332 int rgb=colormap.getRGB(entry.getValue());
333 float r=(float) (rgb>>16)/255.0f;
334 float g=(float) ((rgb>> 8)&0xff)/255.0f;
335 float b=(float) (rgb&0xff)/255.0f;
336 s+=" \\definecolor{c}{rgb}{"+r+","+g+","+b+"}\n";
337 float x=sz*(-0.5f+entry.getKey().j), y=-sz*(-0.5f+entry.getKey().i);
338 s+=" \\draw[dot] ("+x+","+y+") circle (0.4" +
339 ");\n";
340 }
341
342 s+="\\end{tikzpicture}\n";
343 return s;
344 }
345
348 public SVGViewer spy(String caption,Colormap<T> colormap) {
349 File tmp=null;
350 try {
351 tmp=File.createTempFile("aud-","svg");
352 }
353 catch (IOException e) {
354 System.err.println("ERROR: "+e.getMessage());
355 System.exit(-1);
356 }
357 tmp.deleteOnExit();
358 renderSpySVG(tmp,colormap!=null ? colormap: new Colormap<T>());
359
360 SVGViewer v=SVGViewer.displayWindow(tmp,caption!=null ? caption : "spy");
361
362 return v;
363 }
364}
Implementation of an array-based vector.
Definition: Vector.java:44
void push_back(T obj)
insert new entry obj at the end [O(1) for sufficient capacity]
Definition: Vector.java:155
void reserve(int n)
Ensure capacity for n entries.
Definition: Vector.java:120
Row/column coordinates (i,j).
Definition: Coordinate.java:11
Simple sparse matrix data structure.
int[] getRowIndices()
Get array of row indices.
int getMinColumnIndex()
get minimum row index [O(1)]
int getNumRows()
computes from maximium row index [O(nnz)]
int[] getColumnRowIndices(int j)
get row indices in column j as array
int getMinRowIndex()
get minimum row index [O(nnz)]
int columnDegree(int j)
get number of nonzero entries in column j
int getNumColumns()
computed from maximum column index [O(1)]
SVGViewer spy(String caption, Colormap< T > colormap)
render spy plot in new window
SparseMatrixCS< Integer > spones()
Get nonzero pattern.
SparseMatrixCS(SparseMatrixCS< T > other)
copy constructor
String spyTikZ(boolean rulers, Colormap< T > colormap)
SparseMatrixCS()
create empty matrix with "arbitrarily growing" dimensions
Vector< T > getColumnEntries(int j)
get entries in column j as array
File renderSpySVG(File svgfile, Colormap< T > colormap)
TreeMap< Coordinate, T > mat_
String toLaTeX(String name)
get LaTeX code for displaying (TikZ) matrix
SparseMatrixCS< T > getTransposed()
get transposed matrix
int nnz()
get number of nonzero entries
int[] getColumnIndices()
Get array of column indices in same order as for getRowIndices.
T[] getValues()
Get array of values in same order as for getRowIndices.
simple interface for color map
Definition: Colormap.java:4
int getRGB(T data)
Map data to rgb color.
Definition: Colormap.java:9
Simple SVG viewer based on Batik's SVGCanvas.
Definition: SVGViewer.java:33
static SVGViewer displayWindow(File file, String caption)
create new SVGViewer (toplevel window) and display file
Definition: SVGViewer.java:106
utilities (not related to AuD lecture)
Definition: Colormap.java:1
AuD lecture: Data structures, algorithms, examples.
Definition: A234Tree.java:1