b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2vector_compressed.H
1//------------------------------------------------------------------------
2// b2vector_compressed.H --
3//
4// A framework for generic linear algebraic (matrix) computations.
5//
6// written by Mathias Doreille
7//
8// Copyright (c) 2004-2012 SMR Engineering & Development SA
9// 2502 Bienne, Switzerland
10//
11// All Rights Reserved. Proprietary source code. The contents of
12// this file may not be disclosed to third parties, copied or
13// duplicated in any form, in whole or in part, without the prior
14// written permission of SMR.
15//------------------------------------------------------------------------
16
17#ifndef __B2VECTOR_COMPRESSED_H__
18#define __B2VECTOR_COMPRESSED_H__
19
20#include "b2linear_algebra_def.H"
21
22namespace b2000 { namespace b2linalg {
23
24struct Vcompressed {
25 typedef Vcompressed base;
26 typedef Vcompressed_scale_constref const_base;
27 typedef Vcompressed copy;
28};
29
30template <typename T>
31class Vector<T, Vcompressed> {
32public:
33 Vector(size_t s_ = 0) : s(s_) {}
34
35 Vector(const Vector& v_) : s(v_.s), index(v_.index), v(v_.v) {}
36
37 template <typename T1>
38 Vector(const Vector<T1, Vcompressed>& v_)
39 : s(v_.s), index(v_.index), v(v_.v.begin(), v_.v.end()) {}
40
41 template <typename T1>
42 Vector& operator=(const Vector<T1, Vcompressed>& v_) {
43 s = v_.s;
44 index = v_.index;
45 v.assign(v_.v.begin(), v_.v.end());
46 return *this;
47 }
48
49 Vector& operator=(const Vector<T, Vdense>& v_) {
50 s = v_.size();
51 size_t nb_nz = 0;
52 for (typename Vector<T, Vdense>::const_iterator i = v_.begin(); i != v_.end(); ++i) {
53 if (*i != T(0)) { ++nb_nz; }
54 }
55 index.resize(nb_nz);
56 v.resize(nb_nz);
57 nb_nz = 0;
58 for (typename Vector<T, Vdense>::const_iterator i = v_.begin(); i != v_.end(); ++i) {
59 if (*i != T(0)) {
60 index[nb_nz] = i - v_.begin();
61 v[nb_nz] = *i;
62 ++nb_nz;
63 }
64 }
65 return *this;
66 }
67
68 size_t size() const { return s; }
69
70 size_t get_nb_nonzero() const { return index.size(); }
71
72 bool is_null() const { return this == &null; }
73
74 void set_zero() {
75 index.clear();
76 v.clear();
77 }
78
79 void resize(size_t s_, size_t snn) {
80 s = s_;
81 index.resize(snn);
82 v.resize(snn);
83 }
84
85 void get_value(size_t*& index_, T*& value_) {
86 index_ = &index[0];
87 value_ = &v[0];
88 }
89
90 auto& get_index() const { return index; }
91
92 Vector& operator=(
93 const Vector<T, MVProd<Mcompressed_col_st_constref, Vcompressed_scale_constref> >& v_) {
94 if (v_.m.trans) { UnimplementedError() << THROW; }
95
96 std::vector<size_t> vtmp_index;
97 std::vector<T> vtmp_value;
98 if (v_.v.v == &v[0]) {
99 vtmp_index.swap(index);
100 vtmp_value.swap(v);
101 } else {
102 resize(v_.size(), 0);
103 }
104
105 size_t* tmp_index = TemporaryBuffer<size_t>::get(v_.m.size1());
106 const size_t end_list_flag = v_.m.size1();
107 T* tmp_value = TemporaryBuffer<T>::get(v_.m.size1());
108 size_t end_list = end_list_flag;
109
110 T scale = v_.scale * v_.m.scale * v_.v.scale;
111
112 const size_t* b_rowind_begin = v_.v.index;
113 const size_t* const b_rowind_end = b_rowind_begin + v_.v.snn;
114 const T* b_value_begin = v_.v.v;
115 while (b_rowind_begin != b_rowind_end) {
116 const size_t* a_rowind_begin = v_.m.index + v_.m.si[*b_rowind_begin];
117 const size_t* const a_rowind_end = v_.m.index + v_.m.si[*b_rowind_begin + 1];
118 const T* a_value_begin = v_.m.m + v_.m.si[*b_rowind_begin++];
119 const T b_value_begin_v = *b_value_begin++;
120 while (a_rowind_begin != a_rowind_end) {
121 tmp_value[*a_rowind_begin] += *a_value_begin++ * b_value_begin_v;
122 if (!(std::numeric_limits<size_t>::max() - tmp_index[*a_rowind_begin])) {
123 tmp_index[*a_rowind_begin] = end_list;
124 end_list = *a_rowind_begin;
125 }
126 ++a_rowind_begin;
127 }
128 }
129 std::vector<std::pair<size_t, T> > res_tmp;
130 while (end_list != end_list_flag) {
131 res_tmp.push_back(std::pair<size_t, T>(end_list, tmp_value[end_list]));
132 const size_t end_list_next = tmp_index[end_list];
133 tmp_index[end_list] = std::numeric_limits<size_t>::max();
134 tmp_value[end_list] = T(0);
135 end_list = end_list_next;
136 }
137 std::sort(res_tmp.begin(), res_tmp.end(), CompareFirstOfPair());
138
139 v.reserve(res_tmp.size());
140 for (typename std::vector<std::pair<size_t, T> >::iterator i = res_tmp.begin();
141 i != res_tmp.end(); ++i) {
142 index.push_back(i->first);
143 v.push_back(i->second * scale);
144 }
145
146 return *this;
147 }
148
149 Vector& operator=(
150 const Vector<
151 T, MVProd<Mstructured_constref<Mpacked_st_constref>, Vcompressed_scale_constref> >&
152 v_) {
153 v.clear();
154 const size_t* rowind1 = v_.m.index;
155 size_t i1 = 0;
156 const size_t i1_end = v_.m.m.s;
157 size_t i2 = 0;
158 const size_t i2_end = v_.v.snn;
159 for (;;) {
160 if (rowind1[i1] < rowind1[i2]) {
161 if (++i1 == i1_end) { break; }
162 } else if (rowind1[i1] > rowind1[i2]) {
163 if (++i2 == i2_end) { break; }
164 } else {
165 v.resize(v_.m.m.s);
166 const T v2 = v_.v[i2];
167 for (size_t i = 0; i != v.size(); ++i) { v[i] += v_.m.m(i, rowind1[i1]) * v2; }
168 if (++i1 == i1_end) { break; }
169 if (++i2 == i2_end) { break; }
170 }
171 }
172 if (!v.empty()) {
173 s = v_.m.s;
174 index.assign(v_.m.index, v_.m.index + v.size());
175 }
176 return *this;
177 }
178
179 Vector& operator=(
180 const Vector<
181 T, MVProd<Mstructured_constref<Mpacked_st_constref>, Vincrement_scale_constref> >&
182 v_) {
183 s = v_.m.s;
184 v.resize(v_.m.m.s);
185 index.assign(v_.m.index, v_.m.index + v.size());
186 Vector<T> vb(v_.m.m.s);
187 for (size_t i = 0; i != vb.size(); ++i) { vb[i] = v_.v[index[i]]; }
188 Vector<T, Vincrement_ref> va(index.size(), &v[0]);
189 va = v_.scale * (v_.m.m * vb);
190 return *this;
191 }
192
193 T operator[](size_t i) const {
194 const std::vector<size_t>::const_iterator ii = std::find(index.begin(), index.end(), i);
195 if (ii == index.end()) { return 0; }
196 return v[ii - index.begin()];
197 }
198
199 static Vector null;
200
201 friend logging::Logger& operator<<(logging::Logger& l, const Vector& v) {
202 l << "compressed vector ";
203 l.write(v.s, &v.index[0], 1, "index");
204 l.write(v.s, &v.v[0], 1, "value");
205 return l;
206 }
207
208private:
209 MVFRIEND;
210 size_t s;
211 std::vector<size_t> index;
212 std::vector<T> v;
213};
214
215template <typename T>
216Vector<T, Vcompressed> Vector<T, Vcompressed>::null;
217
218struct Vcompressed_scale_constref {
219 typedef Vcompressed_scale_constref base;
220 typedef Vcompressed_scale_constref const_base;
221 typedef Vcompressed copy;
222};
223
224template <typename T>
225class Vector<T, Vcompressed_scale_constref> {
226public:
227 Vector() : s(0), snn(0), scale(1), index(0), v(0) {}
228
229 Vector(const Vector& v_) : s(v_.s), snn(v_.snn), scale(v_.scale), index(v_.index), v(v_.v) {}
230
231 Vector(const Vector<T, Vcompressed>& v_)
232 : s(v_.s), snn(v_.index.size()), scale(1), index(&v_.index[0]), v(&v_.v[0]) {}
233
234 Vector(size_t s_, size_t snn_, const size_t* index_, const T* value_, T scale_)
235 : s(s_), snn(snn_), scale(scale_), index(index_), v(value_) {}
236
237 size_t size() const { return s; }
238
239 size_t get_nb_nonzero() const { return snn; }
240
241 bool is_null() const { return this == &null; }
242
243 T operator[](size_t i) const {
244 const size_t* ii = std::find(index, index + snn, i);
245 if (ii == index + snn) { return 0; }
246 return v[ii - index];
247 }
248
249 Vector& operator*=(T scale_) {
250 scale *= scale_;
251 return *this;
252 }
253
254 Vector operator*(T scale_) { return Vector(s, snn, index, v, scale * scale_); }
255
256 static Vector null;
257
258private:
259 MVFRIEND;
260 size_t s;
261 size_t snn;
262 T scale;
263 const size_t* index;
264 const T* v;
265};
266
267template <typename T>
268Vector<T, Vcompressed_scale_constref> Vector<T, Vcompressed_scale_constref>::null;
269
270}} // namespace b2000::b2linalg
271
272#endif
#define THROW
Definition b2exception.H:198
static T * get(size_t size)
Definition b2linear_algebra_utils.H:50
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314