b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2vector_index.H
1//------------------------------------------------------------------------
2// b2vector_index.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_INDEX_H__
18#define __B2VECTOR_INDEX_H__
19
20#include "b2linear_algebra_def.H"
21
22namespace b2000 { namespace b2linalg {
23
24struct Vindex_constref {
25 typedef Vindex_constref base;
26 typedef Vindex_scale_constref const_base;
27 typedef Vdense copy;
28};
29
30template <typename T>
31class Vector<T, Vindex_constref> {
32public:
33 Vector() : s(0), v(0), index(0) {}
34
35 Vector(size_t s_, const T* v_, const size_t* index_) : s(s_), v(v_), index(index_) {}
36
37 Vector(const Vector& v_) : s(v_.s), v(v_.v), index(v_.index) {}
38
39 Vector(const Vector<T, Vindex_ref>& v_) : s(v_.s), v(v_.v), index(v_.index) {}
40
41 bool is_null() const { return v == 0; }
42
43 size_t size() const { return s; }
44
45 const T& operator[](size_t i) const { return v[index[i]]; }
46
47 Vector operator()(const Interval& i) const { return Vector(i.size(), v, index + i[0]); }
48
49 static Vector null;
50
51protected:
52 size_t s;
53 const T* v;
54 const size_t* index;
55 MVFRIEND;
56};
57
58template <typename T>
59Vector<T, Vindex_constref> Vector<T, Vindex_constref>::null;
60
61struct Vindex1_constref {};
62
63template <typename T>
64class Vector<T, Vindex1_constref> : public Vector<T, Vindex_constref> {
65public:
66 Vector(T default_value_ = T(0))
67 : Vector<T, Vindex_constref>(), s_v(0), default_value(default_value_) {}
68
69 Vector(size_t s_, const T* v_, size_t s_v_, const size_t* index_)
70 : Vector<T, Vindex_constref>(s_, v_, index_), s_v(s_v_), default_value(T(0)) {}
71
72 Vector(const Vector& v_)
73 : Vector<T, Vindex_constref>(v_), s_v(v_.s_v), default_value(v_.default_value) {}
74
75 void set_default_value(T default_value_) { default_value = default_value_; }
76
77 const T& operator[](size_t i) const {
78 if (s_v == 0 || Vector<T, Vindex_constref>::index[i] < s_v) {
79 return Vector<T, Vindex_constref>::v[Vector<T, Vindex_constref>::index[i]];
80 }
81 return default_value;
82 }
83
84private:
85 size_t s_v;
86 T default_value;
87};
88
89struct Vindex_ref {
90 typedef Vindex_ref base;
91 typedef Vindex_scale_constref const_base;
92 typedef Vdense copy;
93};
94
95template <typename T>
96class Vector<T, Vindex_ref> {
97public:
98 Vector() : s(0), v(0), index(0) {}
99
100 Vector(size_t s_ = 0, T* v_ = 0, const size_t* index_ = 0) : s(s_), v(v_), index(index_) {}
101
102 Vector(const Vector& v_) : s(v_.s), v(v_.v), index(v_.index) {}
103
104 bool is_null() const { return v == 0; }
105
106 size_t size() const { return s; }
107
108 void set_zero() {
109 for (size_t i = 0; i != s; ++i) { v[i] = T(0); }
110 }
111
112 const T& operator[](size_t i) const { return v[index[i]]; }
113
114 T& operator[](size_t i) { return v[index[i]]; }
115
116 Vector operator()(const Interval& i) const { return Vector(i.size(), v, index + i[0]); }
117
118 Vector& operator=(const Vector& v_) {
119 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
120 for (size_t i = 0; i != s; ++i) { v[index[i]] = v_[v_.index[i]]; }
121 return *this;
122 }
123
124 Vector& operator=(const Vector<T, Vdense>& v_) {
125 if (s != v_.size()) {
126 Exception() << "The two vectors do not have the same size." << THROW;
127 }
128 for (size_t i = 0; i != s; ++i) { v[index[i]] = v_[i]; }
129 return *this;
130 }
131
132 Vector& operator=(const Vector<T, Vindex_scale_constref>& v_) {
133 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
134 if (v_.v == v && v_.index == index && v_.scale == T(1)) { return *this; }
135 for (size_t i = 0; i != s; ++i) { v[index[i]] = v_[i]; }
136 return *this;
137 }
138
139 Vector& operator+=(const Vector<T, Vindex_scale_constref>& v_) {
140 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
141 for (size_t i = 0; i != s; ++i) { v[index[i]] += v_[i]; }
142 return *this;
143 }
144
145 Vector& operator=(const Vector<T, Vincrement_scale_constref>& v_) {
146 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
147 for (size_t i = 0; i != s; ++i) { v[index[i]] = v_[i]; }
148 return *this;
149 }
150
151 Vector& operator+=(const Vector<T, Vincrement_scale_constref>& v_) {
152 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
153 for (size_t i = 0; i != s; ++i) { v[index[i]] += v_[i]; }
154 return *this;
155 }
156
157 Vector& operator+=(const Vector<T, Sum<Vindex_scale_constref, Vindex_scale_constref> >& v_) {
158 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
159 for (size_t i = 0; i != s; ++i) { v[index[i]] += v_[i]; }
160 return *this;
161 }
162
163 Vector& operator=(
164 const Vector<T, MVProd<Mrectangle_increment_st_constref, Vindex_scale_constref> >& v_) {
165 if (s != v_.size()) {
166 Exception() << "The two vectors do not have the same size, " << s << " and "
167 << v_.size() << "." << THROW;
168 }
169 Vector<T, Vdense> tmp1(s);
170 Vector<T, Vdense> tmp2(v_.v);
171 tmp1 = v_.scale * (v_.m * tmp2);
172 *this = tmp1;
173 return *this;
174 }
175
176 Vector& operator+=(
177 const Vector<T, MVProd<Mrectangle_increment_st_constref, Vindex_scale_constref> >& v_) {
178 if (s != v_.size()) {
179 Exception() << "The two vectors do not have the same size, " << s << " and "
180 << v_.size() << "." << THROW;
181 }
182 Vector<T, Vdense> tmp1(s);
183 Vector<T, Vdense> tmp2(v_.v);
184 tmp1 = v_.scale * (v_.m * tmp2);
185 *this += tmp1;
186 return *this;
187 }
188
189 Vector& operator=(
190 const Vector<
191 T, Sum<Vindex_scale_constref,
192 MVProd<Mrectangle_increment_st_constref, Vindex_scale_constref> > >& v_) {
193 if (s != v_.size()) {
194 Exception() << "The two vectors do not have the same size, " << s << " and "
195 << v_.size() << "." << THROW;
196 }
197 Vector<T, Vdense> tmp1(s);
198 Vector<T, Vdense> tmp2(v_.v2.v);
199 tmp1 = (v_.scale * v_.v2.scale) * (v_.v2.m * tmp2);
200 *this = v_.scale * v_.v1;
201 *this += tmp1;
202 return *this;
203 }
204
205 Vector& operator=(const Vector<T, MVProd<Mpacked_st_constref, Vindex_scale_constref> >& v_) {
206 if (s != v_.size()) {
207 Exception() << "The two vectors do not have the same size, " << s << " and "
208 << v_.size() << "." << THROW;
209 }
210 Vector<T, Vdense> tmp1(s);
211 Vector<T, Vdense> tmp2(v_.v);
212 tmp1 = v_.scale * (v_.m * tmp2);
213 *this = tmp1;
214 return *this;
215 }
216
217 Vector& operator+=(const Vector<T, MVProd<Mpacked_st_constref, Vindex_scale_constref> >& v_) {
218 if (s != v_.size()) {
219 Exception() << "The two vectors do not have the same size, " << s << " and "
220 << v_.size() << "." << THROW;
221 }
222 Vector<T, Vdense> tmp1(s);
223 Vector<T, Vdense> tmp2(v_.v);
224 tmp1 = v_.scale * (v_.m * tmp2);
225 *this += tmp1;
226 return *this;
227 }
228
229 Vector& operator=(const Vector<
230 T, Sum<Vindex_scale_constref,
231 MVProd<Mpacked_st_constref, Vindex_scale_constref> > >& v_) {
232 if (s != v_.size()) {
233 Exception() << "The two vectors do not have the same size, " << s << " and "
234 << v_.size() << "." << THROW;
235 }
236 Vector<T, Vdense> tmp1(s);
237 Vector<T, Vdense> tmp2(v_.v2.v);
238 tmp1 = (v_.scale * v_.v2.scale) * (v_.v2.m * tmp2);
239 *this = v_.scale * v_.v1;
240 *this += tmp1;
241 return *this;
242 }
243
244 Vector& operator=(
245 const Vector<T, MVProd<Mcompressed_col_st_constref, Vindex_scale_constref> >& v_) {
246 if (s != v_.size()) {
247 Exception() << "The two vectors do not have the same size, " << s << " and "
248 << v_.size() << "." << THROW;
249 }
250
251 const size_t* colind_begin = v_.m.si;
252 const size_t* rowind_begin = v_.m.index + *colind_begin;
253 const T* value_begin = v_.m.m + *colind_begin;
254 T scale = v_.scale * v_.v.scale * v_.m.scale;
255 if (v_.m.trans) {
256 for (size_t i = 0; i != s; ++i) {
257 const size_t* const rowind_end = v_.m.index + *++colind_begin;
258 T val = T(0);
259 while (rowind_begin != rowind_end) {
260 val += *value_begin++ * v_.v[*rowind_begin++];
261 }
262 (*this)[i] = scale * val;
263 }
264 } else {
265 set_zero();
266 for (size_t i = 0; i != v_.v.s; ++i) {
267 const size_t* const rowind_end = v_.m.index + *++colind_begin;
268 const T val = v_.v[i];
269 while (rowind_begin != rowind_end) {
270 (*this)[*rowind_begin++] += scale * *value_begin++ * val;
271 }
272 }
273 }
274 return *this;
275 }
276
277 Vector& operator=(const Vector<
278 T, Sum<Vindex_scale_constref,
279 MVProd<Mcompressed_col_st_constref, Vindex_scale_constref> > >& v_) {
280 if (s != v_.size()) {
281 Exception() << "The two vectors do not have the same size, " << s << " and "
282 << v_.size() << "." << THROW;
283 }
284
285 (*this) = v_.scale * v_.v1;
286 const size_t* colind_begin = v_.v2.m.si;
287 const size_t* rowind_begin = v_.v2.m.index + *colind_begin;
288 const T* value_begin = v_.v2.m.m + *colind_begin;
289 T scale = v_.scale * v_.v.scale * v_.m.scale;
290 if (v_.m.trans) {
291 for (size_t i = 0; i != s; ++i) {
292 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
293 T val = T(0);
294 while (rowind_begin != rowind_end) {
295 val += *value_begin++ * v_.v2.v[*rowind_begin++];
296 }
297 (*this)[i] += scale * val;
298 }
299 } else {
300 for (size_t i = 0; i != v_.v2.v.s; ++i) {
301 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
302 const T val = v_.v2[i];
303 while (rowind_begin != rowind_end) {
304 (*this)[*rowind_begin++] += scale * *value_begin++ * val;
305 }
306 }
307 }
308 return *this;
309 }
310
311 static Vector null;
312
313private:
314 size_t s;
315 T* v;
316 const size_t* index;
317 MVFRIEND;
318};
319
320template <typename T>
321Vector<T, Vindex_ref> Vector<T, Vindex_ref>::null;
322
323struct Vindex_scale_constref {
324 typedef Vindex_scale_constref base;
325 typedef Vindex_scale_constref const_base;
326 typedef Vdense copy;
327};
328
329template <typename T>
330class Vector<T, Vindex_scale_constref> {
331public:
332 Vector() : s(0), v(0), index(0), scale(0) {}
333
334 Vector(size_t s_, const T* v_, const size_t* index_, T scale_ = T(1))
335 : s(s_), v(v_), index(index_), scale(scale_) {}
336
337 Vector(const Vector& v_) : s(v_.s), v(v_.v), index(v_.index), scale(v_.scale) {}
338
339 Vector(const Vector<T, Vindex_ref>& v_) : s(v_.s), v(v_.v), index(v_.index), scale(1) {}
340
341 Vector(const Vector<T, Vindex_constref>& v_) : s(v_.s), v(v_.v), index(v_.index), scale(1) {}
342
343 bool is_null() const { return v == 0; }
344
345 size_t size() const { return s; }
346
347 const T operator[](size_t i) const { return scale * v[index[i]]; }
348
349 Vector operator()(const Interval& i) const { return Vector(i.size(), v, index + i[0], scale); }
350
351 Vector& operator*(T scale_) {
352 scale *= scale_;
353 return *this;
354 }
355
356 T operator*(const Vector<T, Vincrement_scale_constref>& v_) const {
357 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
358 T tmp = 0;
359 for (size_t i = 0; i != s; ++i) { tmp += v[index[i]] * v_.v[v_.index[i]]; }
360 return tmp * scale * v_.scale;
361 }
362
363 static Vector null;
364
365private:
366 size_t s;
367 const T* v;
368 const size_t* index;
369 T scale;
370 MVFRIEND;
371};
372
373template <typename T>
374Vector<T, Vindex_scale_constref> Vector<T, Vindex_scale_constref>::null;
375
376}} // namespace b2000::b2linalg
377
378#endif
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32