Adaptagrams
sparse_matrix.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libcola - A library providing force-directed network layout using the
5  * stress-majorization method subject to separation constraints.
6  *
7  * Copyright (C) 2006-2008 Monash University
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  * See the file LICENSE.LGPL distributed with the library.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * Author(s): Tim Dwyer
20 */
21 
22 /*
23  * Yale Sparse Matrix implementation (from Wikipedia definition).
24  * It stores an initial sparse n×n matrix M in row form using three arrays, A,
25  * IA, JA. NZ denotes the number of nonzero entries in matrix M. The array A
26  * then is of length NZ and holds all nonzero entries of M. The array IA stores
27  * at IA(i) the position of the first element of row i in the sparse array A.
28  * The length of row i is determined by IA(i+1) - IA(i). Therefore IA needs to
29  * be of length N + 1. In array JA, the column index of the element A(j) is
30  * stored. JA is of length NZ.
31  */
32 #ifndef _SPARSE_MATRIX_H
33 #define _SPARSE_MATRIX_H
34 
35 #include <valarray>
36 #include <map>
37 #include <cstdio>
38 
39 #include "libvpsc/assertions.h"
40 
41 namespace cola {
42 struct SparseMap {
43  SparseMap(unsigned n = 0) : n(n) {};
44  unsigned n;
45  typedef std::pair<unsigned, unsigned> SparseIndex;
46  typedef std::map<SparseIndex,double> SparseLookup;
47  typedef SparseLookup::const_iterator ConstIt;
48  SparseLookup lookup;
49  double& operator[](const SparseIndex& k) {
50  return lookup[k];
51  }
52  double& operator()(const unsigned i, const unsigned j) {
53  return lookup[std::make_pair(i,j)];
54  }
55  double getIJ(const unsigned i, const unsigned j) const {
56  COLA_ASSERT(i<n);
57  COLA_ASSERT(j<n);
58  ConstIt v=lookup.find(std::make_pair(i,j));
59  if(v!=lookup.end()) {
60  return v->second;
61  }
62  return 0;
63  }
64  size_t nonZeroCount() const {
65  return lookup.size();
66  }
67  void resize(unsigned n) {
68  this->n = n;
69  }
70  void clear() {
71  lookup.clear();
72  }
73 };
74 /*
75  * Yale Sparse Matrix implementation (from Wikipedia definition).
76  * It stores an initial sparse n×n matrix M in row form using three arrays, A,
77  * IA, JA. NZ denotes the number of nonzero entries in matrix M. The array A
78  * then is of length NZ and holds all nonzero entries of M. The array IA stores
79  * at IA(i) the position of the first element of row i in the sparse array A.
80  * The length of row i is determined by IA(i+1) - IA(i). Therefore IA needs to
81  * be of length N + 1. In array JA, the column index of the element A(j) is
82  * stored. JA is of length NZ.
83  */
84 class SparseMatrix {
85 public:
86  SparseMatrix(SparseMap const & m)
87  : n(m.n), NZ((unsigned)m.nonZeroCount()), sparseMap(m),
88  A(std::valarray<double>(NZ)), IA(std::valarray<unsigned>(n+1)), JA(std::valarray<unsigned>(NZ)) {
89  unsigned cnt=0;
90  int lastrow=-1;
91  for(SparseMap::ConstIt i=m.lookup.begin(); i!=m.lookup.end(); i++) {
92  SparseMap::SparseIndex p = i->first;
93  COLA_ASSERT(p.first<n);
94  COLA_ASSERT(p.second<n);
95  A[cnt]=i->second;
96  if((int)p.first!=lastrow) {
97  for(unsigned r=lastrow+1;r<=p.first;r++) {
98  IA[r]=cnt;
99  }
100  lastrow=p.first;
101  }
102  JA[cnt]=p.second;
103  cnt++;
104  }
105  for(unsigned r=lastrow+1;r<=n;r++) {
106  IA[r]=NZ;
107  }
108  }
109  void rightMultiply(std::valarray<double> const & v, std::valarray<double> & r) const {
110  COLA_ASSERT(v.size()>=n);
111  COLA_ASSERT(r.size()>=n);
112  for(unsigned i=0;i<n;i++) {
113  r[i]=0;
114  for(unsigned j=IA[i];j<IA[i+1];j++) {
115  r[i]+=A[j]*v[JA[j]];
116  }
117  }
118  }
119  double getIJ(const unsigned i, const unsigned j) const {
120  return sparseMap.getIJ(i,j);
121  }
122  void print() const {
123  for(unsigned i=0;i<n;i++) {
124  for(unsigned j=0;j<n;j++) {
125  printf("%f ",getIJ(i,j));
126  }
127  printf("\n");
128  }
129  }
130  unsigned rowSize() const {
131  return n;
132  }
133 private:
134  const unsigned n,NZ;
135  SparseMap const & sparseMap;
136  std::valarray<double> A;
137  std::valarray<unsigned> IA, JA;
138 };
139 } //namespace cola
140 #endif /* _SPARSE_MATRIX_H */
libcola: Force-directed network layout subject to separation constraints library. ...
Definition: box.cpp:25