cgv
Loading...
Searching...
No Matches
sparse_mat.h
1#pragma once
2#include <cgv/math/vec.h>
3#include <cgv/math/mat.h>
4
5namespace cgv {
6namespace math {
7
8
9
10template <typename T>
11class sparse_mat;
12
13template <typename T>
14void Ax(const sparse_mat<T>& A, const vec<T>&v, vec<T>& r);
15
16
17
18/*
19* A sparse matrix column compressed form.
20*/
21template <typename T>
23{
24
25private:
26
27 //number of rows
28 unsigned _nrows;
29 //number of columns
30 unsigned _ncols;
31
32 //column start indices in compressed form
33 vec<unsigned> _cols;
34 //row indices of data
35 vec<unsigned> _rows;
36 //values of matrix entries
37 vec<T> _data;
38
39public:
40 sparse_mat(const mat<T>& m, T eps=0)
41 {
42 compress(m,eps);
43 }
44
45 //return number of rows
46 unsigned nrows() const
47 {
48 return _nrows;
49 }
50
51 //returns number of columns
52 unsigned ncols() const
53 {
54 return _ncols;
55 }
56
57 //return number of non zero elements
58 unsigned num_non_zeros() const
59 {
60 return _data.size();
61 }
62
63 //cast conversion into full matrix
64 operator mat<T>()
65 {
66 mat<T> m(_nrows,_ncols);
67 m.zeros();
68 for(unsigned j = 0; j < _ncols; j++)
69 for(unsigned i = _cols(j);i < _cols(j+1); i++)
70 m( _rows(i),j)=_data(i);
71 return m;
72 }
73
74
75 //compress
76 void compress(const mat<T>& m, T eps=0)
77 {
78 _nrows = m.nrows();
79 _ncols = m.ncols();
80 _cols.resize(m.ncols()+1);
81
82 unsigned nz = 0;
83 for(unsigned i =0; i < m.nrows(); i++)
84 {
85 for(unsigned j =0; j < m.ncols(); j++)
86 {
87 if(m(i,j) > eps)
88 nz++;
89 }
90 }
91
92 _rows.resize(nz);
93 _data.resize(nz);
94
95 nz=0;
96 for(unsigned j =0; j < m.ncols(); j++)
97 {
98
99 _cols[j]=nz;
100 for(unsigned i =0; i < m.nrows(); i++)
101 {
102
103 if(m(i,j) > eps)
104 {
105 _data(nz) = m(i,j);
106 _rows(nz) = i;
107 nz++;
108 }
109 }
110 }
111 _cols[m.ncols()]=nz;
112
113 }
114
115
118 {
119 assert(_ncols == v.size());
120 vec<T> r;
121 r.zeros(_nrows);
122 unsigned c;
123 for(c = 0; c < _ncols;c++)
124 for(unsigned i = _cols(c); i < _cols(c+1);i++)
125 r(_rows(i)) += _data(i)*v(c);
126
127
128
129 return r;
130 }
131
132
133 //in place multiplication with scalar s
134 sparse_mat<T>& operator*=(const T& s)
135 {
136 _data*=s;
137
138 return *this;
139 }
140
141 sparse_mat<T> operator*(const T& s)
142 {
143 sparse_mat<T> m = *this;
144 m*=s;
145 return m;
146 }
147
148 sparse_mat<T>& operator/=(const T& s)
149 {
150 _data*=s;
151
152 return *this;
153 }
154
155 sparse_mat<T> operator/(const T& s)
156 {
157 sparse_mat<T> m = *this;
158 m/=s;
159 return m;
160 }
161
162
165 {
166 vec<unsigned> _colsnew(_nrows+1);
167 _colsnew.zeros();
168 vec<unsigned> _rowsnew(_data.size());
169 vec<T>_datanew(_data.size());
170 vec<unsigned>_colsnew2(_nrows+1);
171 vec<unsigned> _rowsnew2(_data.size());
172
173 for(unsigned c = 0; c < _ncols; c++)
174 for(unsigned i = _cols[c]; i < _cols[c+1]; i++)
175 {
176 _colsnew(_rows(i))++;
177 _rowsnew(i) = c;
178 }
179
180 unsigned sum = 0;
181 for(unsigned i = 0; i < _colsnew.size();i++)
182 {
183 unsigned temp = _colsnew(i);
184 _colsnew(i) = sum;
185 _colsnew2(i) = sum;
186
187 sum+=temp;
188
189 }
190
191 _datanew = _data;
192 _cols= _colsnew;
193
194
195 for(unsigned i = 0; i < _data.size();i++)
196 {
197 unsigned idx =_colsnew(_rows(i));
198
199 _data(idx)= _datanew(i);
200 _rowsnew2(idx)= _rowsnew(i);
201 _colsnew(_rows(i))++;
202 }
203
204 _rows = _rowsnew2;
205
206 unsigned t = _nrows;
207 _nrows = _ncols;
208 _ncols = t;
209
210 }
211
212
213
214 friend std::ostream& operator<< <T>(std::ostream& out, sparse_mat& sm);
215
216 friend void Ax<T>(const sparse_mat<T>& A,const vec<T>&v, vec<T>& r);
217
218 friend void Atx<T>(const sparse_mat<T>& A,const vec<T>&v, vec<T>& r);
219
220 friend bool low_tri_solve(const sparse_mat<T>& L,const vec<T>& b, vec<T>& x);
221
222
223
224
225
226};
227
228template <typename T>
229std::ostream& operator<<(std::ostream& out,sparse_mat<T>& sm)
230{
231 out << sm._nrows <<" "<< sm._ncols << std::endl;
232 out << sm._cols << std::endl;
233 out << sm._rows << std::endl;
234 out << sm._data << std::endl;
235 return out;
236}
237
238template <typename T>
239void Ax(const sparse_mat<T>& A, const vec<T>&v, vec<T>& r)
240{
241 assert(A._ncols == v.size());
242 r.zeros(A._nrows);
243 unsigned c;
244 for(c = 0; c < A._ncols;c++)
245 for(unsigned i = A._cols(c); i < A._cols(c+1);i++)
246 r(A._rows(i)) += A._data(i)*v(c);
247
248
249};
250
251
252template <typename T>
253void Atx(const sparse_mat<T>& A, const vec<T>&v, vec<T>& r)
254{
255 assert(A._nrows == v.size());
256 r.zeros(A._ncols);
257 unsigned c;
258 for(c = 0; c < A._ncols;c++)
259 for(unsigned i = A._cols(c); i < A._cols(c+1);i++)
260 r(c) += A._data(i)*v(A._rows(i));
261
262}
263
264template <typename T>
265sparse_mat<T> transpose(const sparse_mat<T>& sm)
266{
267 sparse_mat<T> m = sm;
268
269 m.transpose();
270 return m;
271}
272
273
274template <typename T>
275sparse_mat<T> operator*(const T& s,const sparse_mat<T>& m)
276{
277 return m*s;
278}
279
280template <typename T>
281bool low_tri_solve(const sparse_mat<T>& L,const vec<T>& b, vec<T>& x)
282{
283 x=b;
284 for(unsigned j = 0; j < x.size(); j++)
285 {
286 //not lower triangular or singular
287 if(L._data(L.rows(L._cols(j))) != j )
288 return false;
289
290 x(j) =x(j) / L._data(_cols(j));
291 for(unsigned i= L._cols(j)+1; i < L._cols(j+1);i++)
292 x(i) = x(i) - L._data(i)*x(j);
293
294 }
295 return true;
296}
297
298
299
300
301
302}
303}
304
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
unsigned ncols() const
number of columns
Definition mat.h:546
void zeros()
set zero matrix
Definition mat.h:1030
unsigned nrows() const
number of rows
Definition mat.h:540
void transpose()
transpose matrix
Definition sparse_mat.h:164
vec< T > operator*(const vec< T > &v)
matrix vector product
Definition sparse_mat.h:117
A column vector class.
Definition vec.h:28
void resize(unsigned dim)
resize the vector
Definition vec.h:496
unsigned size() const
number of elements
Definition vec.h:59
void zeros()
fill the vector with zeros
Definition vec.h:470
the cgv namespace
Definition print.h:11