b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2vector_increment.H
1//------------------------------------------------------------------------
2// b2vector_increment.H --
3//
4// A framework for generic linear algebraic (matrix) computations.
5//
6// written by Mathias Doreille
7//
8// Copyright (c) 2004-2012,2017
9// SMR Engineering & Development SA
10// 2502 Bienne, Switzerland
11//
12// All Rights Reserved. Proprietary source code. The contents of
13// this file may not be disclosed to third parties, copied or
14// duplicated in any form, in whole or in part, without the prior
15// written permission of SMR.
16//------------------------------------------------------------------------
17
18#ifndef __B2VECTOR_INCREMENT_H__
19#define __B2VECTOR_INCREMENT_H__
20
21#include "b2linear_algebra_def.H"
22
23namespace b2000 { namespace b2linalg {
24
25struct Vincrement_constref {
26 typedef Vincrement_scale_constref base;
27 typedef Vincrement_scale_constref const_base;
28 typedef Vdense copy;
29};
30
31template <typename T>
32class Vector<T, Vincrement_constref> {
33public:
34 Vector() : s(0), v(0), incr(0) {}
35
36 Vector(size_t s_, const T* v_, size_t incr_ = 1) : s(s_), v(v_), incr(incr_) {}
37
38 Vector(const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr) {}
39
40 Vector(const Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
41
42 Vector(const Vector<T, Vdense_constref>& v_) : s(v_.s), v(v_.v), incr(1) {}
43
44 Vector(const std::vector<T>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
45
46 bool is_null() const { return v == 0; }
47
48 size_t size() const { return s; }
49
50 const T& operator[](size_t i) const { return v[i * incr]; }
51
52 Vector<T, Vincrement_constref> operator()(const Interval& i) const {
53 return Vector<T, Vincrement_constref>(i.size(), &v[i[0] * incr], incr);
54 }
55
56 Vector<T, Vincrement_constref> operator()(const Slice& i) const {
57 return Vector<T, Vincrement_constref>(i.size(), &v[i[0] * incr], i.increment() * incr);
58 }
59
60 T norm2() const { return blas::nrm2(s, v, incr); }
61
62 static Vector null;
63
64 friend logging::Logger& operator<<(logging::Logger& l, const Vector& v) {
65 l << "vector ";
66 l.write(v.s, v.v, v.incr);
67 return l;
68 }
69
70private:
71 size_t s;
72 const T* v;
73 size_t incr;
74 MVFRIEND;
75};
76
77template <typename T>
78Vector<T, Vincrement_constref> Vector<T, Vincrement_constref>::null;
79
80struct Vincrement_ref {
81 typedef Vincrement_ref base;
82 typedef Vincrement_scale_constref const_base;
83 typedef Vdense copy;
84};
85
86template <typename T>
87class Vector<T, Vincrement_ref> {
88public:
89 Vector() : s(0), v(0), incr(0) {}
90
91 Vector(size_t s_, T* v_, size_t incr_ = 1) : s(s_), v(v_), incr(incr_) {}
92
93 Vector(const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr) {}
94
95 Vector(Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
96
97 Vector(Vector<T, Vdense_ref>& v_) : s(v_.size()), v(v_.v), incr(1) {}
98
99 bool is_null() const { return v == 0; }
100
101 size_t size() const { return s; }
102
103 void set_zero() {
104 T const* vv_end = v + s * incr;
105 for (T* vv = v; vv != vv_end; vv += incr) { *vv = T(0); }
106 }
107
108 const T& operator[](size_t i) const { return v[i * incr]; }
109
110 T& operator[](size_t i) { return v[i * incr]; }
111
112 Vector<T, Vincrement_ref> operator()(const Interval& i) {
113 return Vector<T, Vincrement_ref>(i.size(), &v[i[0] * incr], incr);
114 }
115
116 Vector<T, Vincrement_ref> operator()(const Slice& i) {
117 return Vector<T, Vincrement_ref>(i.size(), &v[i[0] * incr], i.increment() * incr);
118 }
119
120 template <typename STORAGE>
121 Vector& operator+=(const Vector<T, STORAGE>& v_) {
122 *this = *this + v_;
123 return *this;
124 }
125
126 template <typename STORAGE>
127 Vector& operator-=(const Vector<T, STORAGE>& v_) {
128 *this = *this - v_;
129 return *this;
130 }
131
132 Vector& operator=(const Vector& v_) {
133 if (s != v_.s) {
134 Exception() << "The two vectors do not have the same size, " << s << " and " << v_.s
135 << "." << THROW;
136 }
137 if (v_.v != v || v_.incr != incr) { blas::copy(s, v_.v, v_.incr, v, incr); }
138 return *this;
139 }
140
141 template <typename T1>
142 Vector& operator=(const Vector<T1, Vdense>& v_) {
143 if (s != v_.size()) {
144 Exception() << "The two vectors do not have the same size, " << s << " and "
145 << v_.size() << "." << THROW;
146 }
147 if (incr == 1) {
148 std::copy(&v_[0], &v_[0] + s, v);
149 } else {
150 T* out = v;
151 T* out_end = out + s * incr;
152 const T1* in = &v_[0];
153 for (; out < out_end; ++in, out += incr) { *out = *in; }
154 }
155 return *this;
156 }
157
158 template <typename T1>
159 Vector& operator=(const Vector<T1, Vincrement_ref>& v_) {
160 if (s != v_.s) {
161 Exception() << "The two vectors do not have the same size, " << s << " and " << v_.s
162 << "." << THROW;
163 }
164 if (v_.incr == 1 && incr == 1) {
165 std::copy(v_.v, v_.v + s, v);
166 } else {
167 T* out = v;
168 T* out_end = out + s * incr;
169 const T1* in = v_.v;
170 for (; out < out_end; in += v_.incr, out += incr) { *out = *in; }
171 }
172 return *this;
173 }
174
175 Vector& operator=(const Vector<T, Vincrement_scale_constref>& v_) {
176 if (s != v_.s) {
177 Exception() << "The two vectors do not have the same size, " << s << " and " << v_.s
178 << "." << THROW;
179 }
180 if (v_.v != v || v_.incr != incr) { blas::copy(s, v_.v, v_.incr, v, incr); }
181 if (v_.scale != T(1)) { blas::scal(s, v_.scale, v, incr); }
182 return *this;
183 }
184
185 template <typename T1>
186 Vector& operator=(const Vector<T1, Vincrement_scale_constref>& v_) {
187 if (s != v_.s) {
188 Exception() << "The two vectors do not have the same size, " << s << " and " << v_.s
189 << "." << THROW;
190 }
191 if (v_.incr == 1 && incr == 1) {
192 std::copy(v_.v, v_.v + s, v);
193 } else {
194 T* out = v;
195 T* out_end = out + s * incr;
196 const T1* in = v_.v;
197 for (; out < out_end; in += v_.incr, out += incr) { *out = *in; }
198 }
199 if (v_.scale != T(1)) { blas::scal(s, v_.scale, v, incr); }
200 return *this;
201 }
202
203 Vector& operator=(
204 const Vector<T, Sum<Vincrement_scale_constref, Vincrement_scale_constref> >& v_) {
205 if (s != v_.size()) {
206 Exception() << "The two vectors do not have the same size, " << s << " and "
207 << v_.size() << "." << THROW;
208 }
209 (*this) = v_.scale * v_.v1;
210 blas::axpy(s, v_.v2.scale * v_.scale, v_.v2.v, v_.v2.incr, v, incr);
211 return *this;
212 }
213
214 Vector& operator=(
215 const Vector<T, Sum<Vincrement_scale_constref, Vcompressed_scale_constref> >& v_) {
216 if (s != v_.size()) {
217 Exception() << "The two vectors do not have the same size, " << s << " and "
218 << v_.size() << "." << THROW;
219 }
220 (*this) = v_.scale * v_.v1;
221 const size_t* index = v_.v2.index;
222 const size_t* index_end = index + v_.v2.snn;
223 const T* value = v_.v2.v;
224 T scale = v_.scale * v_.v2.scale;
225 for (; index != index_end; ++index, ++value) { v[*index] += scale * *value; }
226 return *this;
227 }
228
229 Vector& operator=(
230 const Vector<T, MVProd<Mrectangle_increment_st_constref, Vincrement_scale_constref> >&
231 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 blas::gemv(
237 v_.m.trans ? 't' : 'n', v_.m.trans ? v_.m.size2() : v_.m.size1(),
238 v_.m.trans ? v_.m.size1() : v_.m.size2(), v_.scale * v_.v.scale * v_.m.scale, v_.m.m,
239 v_.m.ldm, v_.v.v, v_.v.incr, 0, v, incr);
240 return *this;
241 }
242
243 Vector& operator=(
244 const Vector<
245 T, Sum<Vincrement_scale_constref,
246 MVProd<Mrectangle_increment_st_constref, Vincrement_scale_constref> > >&
247 v_) {
248 if (s != v_.size()) {
249 Exception() << "The two vectors do not have the same size, " << s << " and "
250 << v_.size() << "." << THROW;
251 }
252 if (v_.v1.v != v || v_.v1.incr != incr) { blas::copy(s, v_.v1.v, v_.v1.incr, v, incr); }
253 blas::gemv(
254 v_.v2.m.trans ? 't' : 'n', v_.v2.m.trans ? v_.v2.m.size2() : v_.v2.m.size1(),
255 v_.v2.m.trans ? v_.v2.m.size1() : v_.v2.m.size2(),
256 v_.scale * v_.v2.v.scale * v_.v2.m.scale, v_.v2.m.m, v_.v2.m.ldm, v_.v2.v.v,
257 v_.v2.v.incr, v_.scale * v_.v1.scale, v, incr);
258 return *this;
259 }
260
261 Vector& operator=(
262 const Vector<
263 T, Sum<Vincrement_scale_constref,
264 MVProd<Mrectangle_increment_st_constref, Vcompressed_scale_constref> > >&
265 v_) {
266 if (s != v_.size()) {
267 Exception() << "The two vectors do not have the same size, " << s << " and "
268 << v_.size() << "." << THROW;
269 }
270
271 const T scale = v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
272 if (v_.v2.m.trans) {
273 const T* m = v_.v2.m.m;
274 for (size_t i = 0; i != s; ++i) {
275 T tmp = 0;
276 for (size_t j = 0; j != v_.v2.v.snn; ++j) {
277 tmp += m[v_.v2.v.index[j]] * v_.v2.v.v[j];
278 }
279 v[i] = v_.scale * (v_.v1[i] + scale * tmp);
280 m += v_.v2.m.ldm;
281 }
282 } else {
284 }
285 return *this;
286 }
287
288 Vector& operator=(
289 const Vector<T, MVProd<Mpacked_st_constref, Vincrement_scale_constref> >& v_) {
290 if (s != v_.size()) {
291 Exception() << "The two vectors do not have the same size, " << s << " and "
292 << v_.size() << "." << THROW;
293 }
294 blas::spmv(
295 v_.m.upper ? 'u' : 'l', v_.m.size1(), v_.scale * v_.v.scale * v_.m.scale, v_.m.m,
296 v_.v.v, v_.v.incr, 0, v, incr);
297 return *this;
298 }
299
300 Vector& operator=(const Vector<
301 T, Sum<Vincrement_scale_constref,
302 MVProd<Mpacked_st_constref, Vincrement_scale_constref> > >& v_) {
303 if (s != v_.size()) {
304 Exception() << "The two vectors do not have the same size, " << s << " and "
305 << v_.size() << "." << THROW;
306 }
307 if (v_.v1.v != v || v_.v1.incr != incr) { blas::copy(s, v_.v1.v, v_.v1.incr, v, incr); }
308 blas::spmv(
309 v_.v2.m.upper ? 'u' : 'l', v_.v2.m.size1(), v_.scale * v_.v2.v.scale * v_.v2.m.scale,
310 v_.v2.m.m, v_.v2.v.v, v_.v2.v.incr, v_.scale * v_.v1.scale, v, incr);
311 return *this;
312 }
313
314 Vector& operator=(
315 const Vector<T, MVProd<Mcompressed_col_st_constref, Vincrement_scale_constref> >& v_) {
316 if (s != v_.size()) {
317 Exception() << "The two vectors do not have the same size, " << s << " and "
318 << v_.size() << "." << THROW;
319 }
320
321 const size_t* colind_begin = v_.m.si;
322 const size_t* rowind_begin = v_.m.index + *colind_begin;
323 const T* value_begin = v_.m.m + *colind_begin;
324 T scale = v_.scale * v_.v.scale * v_.m.scale;
325 if (v_.m.trans) {
326 T* result_begin = v;
327 const T* const result_end = v + s * incr;
328 while (result_begin != result_end) {
329 const size_t* const rowind_end = v_.m.index + *++colind_begin;
330 T val = T(0);
331 while (rowind_begin != rowind_end) {
332 val += *value_begin++ * v_.v[*rowind_begin++];
333 }
334 *result_begin = scale * val;
335 result_begin += incr;
336 }
337 } else {
338 set_zero();
339 const T* input_begin = v_.v.v;
340 const T* const input_end = input_begin + v_.v.s * v_.v.incr;
341 while (input_begin != input_end) {
342 const size_t* const rowind_end = v_.m.index + *++colind_begin;
343 const T val = scale * *input_begin;
344 input_begin += v_.v.incr;
345 while (rowind_begin != rowind_end) {
346 (*this)[*rowind_begin++] += *value_begin++ * val;
347 }
348 }
349 }
350 return *this;
351 }
352
353 Vector& operator=(
354 const Vector<
355 T, Sum<Vincrement_scale_constref,
356 MVProd<Mcompressed_col_st_constref, Vcompressed_scale_constref> > >& v_) {
357 if (s != v_.size()) {
358 Exception() << "The two vectors do not have the same size, " << s << " and "
359 << v_.size() << "." << THROW;
360 }
361
362 T scale = v_.scale * v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
363 if (v_.v2.m.trans) {
365 } else {
366 *this = v_.scale * v_.v1;
367 for (size_t i = 0; i != v_.v2.v.snn; ++i) {
368 size_t j = v_.v2.m.si[v_.v2.v.index[i]];
369 const size_t j_end = v_.v2.m.si[v_.v2.v.index[i] + 1];
370 const T val = scale * v_.v2.v.v[i];
371 for (; j != j_end; ++j) { (*this)[v_.v2.m.index[j]] += v_.v2.m.m[j] * val; }
372 }
373 }
374 return *this;
375 }
376
377 Vector& operator=(const Vector<
378 T, MVProd<
379 MMProd<Mcompressed_col_st_constref, Mcompressed_col_st_constref>,
380 Vincrement_scale_constref> >& v_) {
381 if (s != v_.size()) {
382 Exception() << "The two vectors do not have the same size, " << s << " and "
383 << v_.size() << "." << THROW;
384 }
385 if (v_.m.m1.trans || !v_.m.m2.trans) {
386 Vector<T, Vdense> tmp;
387 tmp = v_.m.m2 * v_.v;
388 *this = (v_.scale * v_.m.scale) * (v_.m.m1 * tmp);
389 return *this;
390 }
391
392 const size_t* rowind_begin_1 = v_.m.m1.index;
393 const T* value_begin_1 = v_.m.m1.m;
394 const size_t* colind_begin_1 = v_.m.m1.si;
395 const size_t* rowind_begin_2 = v_.m.m2.index;
396 const T* value_begin_2 = v_.m.m2.m;
397 const size_t* colind_begin_2 = v_.m.m2.si;
398 T scale = v_.scale * v_.v.scale * v_.m.scale * v_.m.m1.scale * v_.m.m2.scale;
399 set_zero();
400 for (size_t i = 0; i != size(); ++i) {
401 T val = T(0);
402 const size_t* rowind_end = v_.m.m2.index + *++colind_begin_2;
403 while (rowind_begin_2 != rowind_end) {
404 val += *value_begin_2++ * v_.v[*rowind_begin_2++];
405 }
406 val *= scale;
407 rowind_end = v_.m.m1.index + *++colind_begin_1;
408 while (rowind_begin_1 != rowind_end) {
409 (*this)[*rowind_begin_1++] += *value_begin_1++ * val;
410 }
411 }
412 return *this;
413 }
414
415 Vector& operator=(const Vector<
416 T, MVProd<
417 Msub_constref<Mcompressed_col_constref, Index, Index>,
418 Vincrement_scale_constref> >& v_) {
419 if (s != v_.size()) {
420 Exception() << "The two vectors do not have the same size, " << s << " and "
421 << v_.size() << "." << THROW;
422 }
423 if (!v_.m.index1.is_all()) { UnimplementedError() << THROW; }
424
425 const T* value_begin = v_.m.m.m;
426 const size_t* colind_begin = &v_.m.index2[0];
427 T scale = v_.scale * v_.v.scale;
428 set_zero();
429 const T* input_begin = v_.v.v;
430 const T* const input_end = input_begin + v_.v.s * v_.v.incr;
431 while (input_begin != input_end) {
432 const size_t* rowind_begin = v_.m.m.index + v_.m.m.si[*colind_begin];
433 const size_t* const rowind_end = v_.m.m.index + v_.m.m.si[*colind_begin++ + 1];
434 const T val = scale * *input_begin;
435 input_begin += v_.v.incr;
436 while (rowind_begin != rowind_end) { (*this)[*rowind_begin++] += *value_begin++ * val; }
437 }
438 return *this;
439 }
440
441 Vector& operator=(
442 const Vector<
443 T, Sum<Vincrement_scale_constref,
444 MVProd<Mcompressed_col_st_constref, Vincrement_scale_constref> > >& v_) {
445 if (s != v_.size()) {
446 Exception() << "The two vectors do not have the same size, " << s << " and "
447 << v_.size() << "." << THROW;
448 }
449
450 (*this) = v_.scale * v_.v1;
451 const size_t* colind_begin = v_.v2.m.si;
452 const size_t* rowind_begin = v_.v2.m.index + *colind_begin;
453 const T* value_begin = v_.v2.m.m + *colind_begin;
454 T scale = v_.scale * v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
455 if (v_.v2.m.trans) {
456 T* result_begin = v;
457 const T* const result_end = v + s * incr;
458 while (result_begin != result_end) {
459 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
460 T val = T(0);
461 while (rowind_begin != rowind_end) {
462 val += *value_begin++ * v_.v2.v[*rowind_begin++];
463 }
464 *result_begin += scale * val;
465 result_begin += incr;
466 }
467 } else {
468 const T* input_begin = v_.v2.v.v;
469 const T* const input_end = input_begin + v_.v2.v.s * v_.v2.v.incr;
470 while (input_begin != input_end) {
471 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
472 const T val = scale * *input_begin;
473 input_begin += v_.v2.v.incr;
474 while (rowind_begin != rowind_end) {
475 (*this)[*rowind_begin++] += *value_begin++ * val;
476 }
477 }
478 }
479 return *this;
480 }
481
482 Vector& operator=(
483 const Vector<
484 T, Sum<Vincrement_scale_constref,
485 MVProd<Msym_compressed_col_st_constref, Vincrement_scale_constref> > >& v_) {
486 if (s != v_.size()) {
487 Exception() << "The two vectors do not have the same size, " << s << " and "
488 << v_.size() << "." << THROW;
489 }
490
491 *this = v_.scale * v_.v1;
492
493 T scale = v_.scale * v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
494 const size_t* colind_begin = v_.v2.m.si;
495 const size_t* rowind_begin = v_.v2.m.index + *colind_begin;
496 const T* value_begin = v_.v2.m.m + *colind_begin;
497 {
498 T* result_begin = v;
499 const T* const result_end = v + s * incr;
500 while (result_begin != result_end) {
501 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
502 T val = T(0);
503 while (rowind_begin != rowind_end) {
504 val += *value_begin++ * v_.v2.v[*rowind_begin++];
505 }
506 *result_begin += scale * val;
507 result_begin += incr;
508 }
509 }
510 colind_begin = v_.v2.m.si;
511 rowind_begin = v_.v2.m.index + *colind_begin;
512 value_begin = v_.v2.m.m + *colind_begin;
513 {
514 const T* input_begin = v_.v2.v.v;
515 const T* const input_end = input_begin + v_.v2.v.s * v_.v2.v.incr;
516 size_t i = 0;
517 while (input_begin != input_end) {
518 const size_t* const rowind_end = v_.v2.m.index + *++colind_begin;
519 const T val = scale * *input_begin;
520 input_begin += v_.v2.v.incr;
521 if (rowind_begin < rowind_end && *rowind_begin == i) {
522 ++rowind_begin;
523 ++value_begin;
524 }
525 ++i;
526 while (rowind_begin < rowind_end) {
527 (*this)[*rowind_begin++] += *value_begin++ * val;
528 }
529 }
530 }
531
532 return *this;
533 }
534
535 Vector& operator=(
536 const Vector<T, MVProd<Msym_compressed_col_st_constref, Vincrement_scale_constref> >&
537 v_) {
538 if (s != v_.size()) {
539 Exception() << "The two vectors do not have the same size, " << s << " and "
540 << v_.size() << "." << THROW;
541 }
542
543 T scale = v_.scale * v_.v.scale * v_.m.scale;
544 const size_t* colind_begin = v_.m.si;
545 const size_t* rowind_begin = v_.m.index + *colind_begin;
546 const T* value_begin = v_.m.m + *colind_begin;
547 {
548 T* result_begin = v;
549 const T* const result_end = v + s * incr;
550 while (result_begin != result_end) {
551 const size_t* const rowind_end = v_.m.index + *++colind_begin;
552 T val = T(0);
553 while (rowind_begin != rowind_end) {
554 val += *value_begin++ * v_.v[*rowind_begin++];
555 }
556 *result_begin = scale * val;
557 result_begin += incr;
558 }
559 }
560 colind_begin = v_.m.si;
561 rowind_begin = v_.m.index + *colind_begin;
562 value_begin = v_.m.m + *colind_begin;
563 {
564 const T* input_begin = v_.v.v;
565 const T* const input_end = input_begin + v_.v.s * v_.v.incr;
566 size_t i = 0;
567 while (input_begin != input_end) {
568 const size_t* const rowind_end = v_.m.index + *++colind_begin;
569 const T val = scale * *input_begin;
570 input_begin += v_.v.incr;
571 if (rowind_begin < rowind_end && *rowind_begin == i) {
572 ++rowind_begin;
573 ++value_begin;
574 }
575 ++i;
576 while (rowind_begin < rowind_end) {
577 (*this)[*rowind_begin++] += *value_begin++ * val;
578 }
579 }
580 }
581 return *this;
582 }
583
584 Vector& operator=(
585 const Vector<
586 T, MVProd<
587 MMProd<Msym_compressed_col_st_constref, Msym_compressed_col_st_constref>,
588 Vincrement_scale_constref> >& v_) {
590 return *this;
591 }
592
593 Vector& operator=(const Vector<
594 T, MVProd<
595 Minverse_constref<Msym_compressed_col_update_inv>,
596 Vincrement_scale_constref> >& v_) {
597 if (s != v_.size()) {
598 Exception() << "The two vectors do not have the same size, " << s << " and "
599 << v_.size() << "." << THROW;
600 }
601 if (incr != 1 || v_.scale != T(1)) { UnimplementedError() << THROW; }
602 v_.m.m.resolve(s, 1, v_.v.v, s, v, s, ' ', v_.m.null_space, v_.m.max_null_space_vector);
603 return *this;
604 }
605
606 Vector& operator=(
607 const Vector<
608 T,
609 MVProd<Minverse_constref<Mcompressed_col_update_inv>, Vincrement_scale_constref> >&
610 v_) {
611 if (s != v_.size()) {
612 Exception() << "The two vectors do not have the same size, " << s << " and "
613 << v_.size() << "." << THROW;
614 }
615 if (incr != 1 || v_.scale != T(1)) { UnimplementedError() << THROW; }
616 v_.m.m.resolve(s, 1, v_.v.v, s, v, s, ' ', v_.m.null_space, v_.m.max_null_space_vector);
617 return *this;
618 }
619
620 Vector& operator=(const Vector<
621 T, MVProd<
622 Minverse_constref<Msym_compressed_col_update_inv_ext>,
623 Vincrement_scale_constref> >& v_) {
624 if (s != v_.size()) {
625 Exception() << "The two vectors do not have the same size, " << s << " and "
626 << v_.size() << "." << THROW;
627 }
628 if (incr != 1 || v_.scale != T(1)) { UnimplementedError() << THROW; }
629 v_.m.m.resolve(
630 s, 1, v_.v.v, s, v, s, 0, 0, 0, ' ', v_.m.null_space, v_.m.max_null_space_vector);
631 return *this;
632 }
633
634 Vector& operator=(const Vector<
635 T, MVProd<
636 Minverse_constref<Mcompressed_col_update_inv_ext>,
637 Vincrement_scale_constref> >& v_) {
638 if (s != v_.size()) {
639 Exception() << "The two vectors do not have the same size, " << s << " and "
640 << v_.size() << "." << THROW;
641 }
642 if (incr != 1 || v_.scale != T(1)) { UnimplementedError() << THROW; }
643 v_.m.m.resolve(
644 s, 1, v_.v.v, s, v, s, 0, 0, 0, ' ', v_.m.null_space, v_.m.max_null_space_vector);
645 return *this;
646 }
647
648 Vector& operator=(const Vector<
649 T, MVProd<
650 Minverse_ext_constref<Msym_compressed_col_update_inv_ext>,
651 Vincrement_scale_constref> >& v_) {
652 if (s != v_.size()) {
653 Exception() << "The two vectors do not have the same size, " << s << " and "
654 << v_.size() << "." << THROW;
655 }
656 if (incr != 1 || v_.scale != T(1) || v_.v.scale != T(1)) { UnimplementedError() << THROW; }
657 v_.m.m.resolve(
658 s, 1, v_.v.v, s, v, s, v_.m.a, v_.m.b, v_.m.c, ' ', v_.m.null_space,
659 v_.m.max_null_space_vector);
660 return *this;
661 }
662
663 Vector& operator=(const Vector<
664 T, MVProd<
665 Minverse_ext_constref<Mcompressed_col_update_inv_ext>,
666 Vincrement_scale_constref> >& v_) {
667 if (s != v_.size()) {
668 Exception() << "The two vectors do not have the same size, " << s << " and "
669 << v_.size() << "." << THROW;
670 }
671 if (incr != 1 || v_.scale != T(1) || v_.v.scale != T(1)) { UnimplementedError() << THROW; }
672 v_.m.m.resolve(
673 s, 1, v_.v.v, s, v, s, v_.m.a, v_.m.b, v_.m.c, ' ', v_.m.null_space,
674 v_.m.max_null_space_vector);
675 return *this;
676 }
677
678 Vector& operator=(
679 const Vector<
680 T,
681 MVProd<Minverse_constref<Mcompressed_col_st_constref>, Vincrement_scale_constref> >&
682 v_) {
683 if (s != v_.size()) {
684 Exception() << "The two vectors do not have the same size, " << s << " and "
685 << v_.size() << "." << THROW;
686 }
687 if (incr != 1 || v_.scale != T(1) || v_.v.scale != T(1)) { UnimplementedError() << THROW; }
688 (*this) = v_.v;
689 if (v_.m.trans) {
690 for (size_t i = 0; i < size(); ++i) {
691 size_t ii = v_.m.si[i + 1] - 1;
692 T piv = ((*this)[i] /= v_.m.m[ii]);
693 for (size_t j = v_.m.si[i]; j < ii; ++j) {
694 (*this)[v_.m.index[j]] -= v_.m.m[j] * piv;
695 }
696 }
697 } else {
698 for (size_t j = size(); j > 0;) {
699 size_t jj = v_.m.si[j] - 1;
700 T piv = ((*this)[j] /= v_.m.m[jj]);
701 for (size_t i = v_.m.si[--j]; i < jj; ++i) {
702 (*this)[v_.m.index[i]] -= v_.m.m[i] * piv;
703 }
704 }
705 }
706 return *this;
707 }
708
709 Vector& operator=(const Vector<T, Vcompressed_scale_constref>& v_) {
710 if (s != v_.size()) {
711 Exception() << "The two vectors do not have the same size, " << s << " and "
712 << v_.size() << "." << THROW;
713 }
714 std::fill_n(v, s, 0);
715 for (size_t i = 0; i != v_.snn; ++i) { v[v_.index[i]] = v_.scale * v_.v[i]; }
716 return *this;
717 }
718
719 Vector& operator=(const Vector<T, Vindex_ref>& v_) {
720 if (s != v_.size()) {
721 Exception() << "The two vectors do not have the same size, " << s << " and "
722 << v_.size() << "." << THROW;
723 }
724 for (size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
725 return *this;
726 }
727
728 Vector& operator=(const Vector<T, Vindex_constref>& v_) {
729 if (s != v_.size()) {
730 Exception() << "The two vectors do not have the same size, " << s << " and "
731 << v_.size() << "." << THROW;
732 }
733 for (size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
734 return *this;
735 }
736
737 Vector& operator=(const Vector<T, Vindex_scale_constref>& v_) {
738 if (s != v_.size()) {
739 Exception() << "The two vectors do not have the same size, " << s << " and "
740 << v_.size() << "." << THROW;
741 }
742 for (size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
743 return *this;
744 }
745
746 Vector& operator=(
747 const Vector<
748 T, Sum<Vincrement_scale_constref,
749 MVProd<Mrectangle_increment_st_constref, Vindex_scale_constref> > >& v_) {
750 if (s != v_.size()) {
751 Exception() << "The two vectors do not have the same size, " << s << " and "
752 << v_.size() << "." << THROW;
753 }
754 Vector<T, Vdense> tmp(v_.v2.v);
755 *this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
756 return *this;
757 }
758
759 Vector& operator=(
760 const Vector<
761 T, Sum<Vindex_scale_constref,
762 MVProd<Mrectangle_increment_st_constref, Vindex_scale_constref> > >& v_) {
763 if (s != v_.size()) {
764 Exception() << "The two vectors do not have the same size, " << s << " and "
765 << v_.size() << "." << THROW;
766 }
767 Vector<T, Vdense> tmp(v_.v2.v);
768 *this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
769 return *this;
770 }
771
772 Vector& operator=(const Vector<T, MVProd<Mpacked_st_constref, Vindex_scale_constref> >& v_) {
773 if (s != v_.size()) {
774 Exception() << "The two vectors do not have the same size, " << s << " and "
775 << v_.size() << "." << THROW;
776 }
777 Vector<T, Vdense> tmp(v_.v);
778 *this = v_.scale * (v_.m * tmp);
779 return *this;
780 }
781
782 Vector& operator+=(const Vector<T, MVProd<Mpacked_st_constref, Vindex_scale_constref> >& v_) {
783 if (s != v_.size()) {
784 Exception() << "The two vectors do not have the same size, " << s << " and "
785 << v_.size() << "." << THROW;
786 }
787 Vector<T, Vdense> tmp(v_.v);
788 *this += v_.scale * (v_.m * tmp);
789 return *this;
790 }
791
792 Vector& operator=(const Vector<
793 T, Sum<Vincrement_scale_constref,
794 MVProd<Mpacked_st_constref, Vindex_scale_constref> > >& v_) {
795 if (s != v_.size()) {
796 Exception() << "The two vectors do not have the same size, " << s << " and "
797 << v_.size() << "." << THROW;
798 }
799 Vector<T, Vdense> tmp(v_.v2.v);
800 *this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
801 return *this;
802 }
803
804 Vector& operator=(const Vector<
805 T, Sum<Vindex_scale_constref,
806 MVProd<Mpacked_st_constref, Vindex_scale_constref> > >& v_) {
807 if (s != v_.size()) {
808 Exception() << "The two vectors do not have the same size, " << s << " and "
809 << v_.size() << "." << THROW;
810 }
811 Vector<T, Vdense> tmp(v_.v2.v);
812 *this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
813 return *this;
814 }
815
816 Vector& operator=(const Vector<T, MVProd<Mrectangle_inv, Vincrement_scale_constref> >& v_) {
817 if (v_.scale != 1) { UnimplementedError() << THROW; }
818 *this = v_.v;
819 v_.m.resolve(*this);
820 return *this;
821 }
822
823 static Vector null;
824
825 friend logging::Logger& operator<<(logging::Logger& l, const Vector& v) {
826 l << "vector ";
827 l.write(v.s, v.v, v.incr);
828 return l;
829 }
830
831private:
832 size_t s;
833 T* v;
834 size_t incr;
835 MVFRIEND;
836};
837
838template <typename T>
839Vector<T, Vincrement_ref> Vector<T, Vincrement_ref>::null;
840
841struct Vincrement_scale_constref {
842 typedef Vincrement_scale_constref base;
843 typedef Vincrement_scale_constref const_base;
844 typedef Vdense copy;
845};
846
847template <typename T>
848class Vector<T, Vincrement_scale_constref> {
849public:
850 Vector() : s(0), v(0), incr(0), scale(0) {}
851
852 Vector(size_t s_, const T* v_, size_t incr_ = 1, T scale_ = T(1))
853 : s(s_), v(v_), incr(incr_), scale(scale_) {}
854
855 Vector(const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(v_.scale) {}
856
857 Vector(const Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1), scale(1) {}
858
859 Vector(const Vector<T, Vdense_ref>& v_) : s(v_.s), v(v_.v), incr(1), scale(1) {}
860
861 Vector(const Vector<T, Vdense_constref>& v_) : s(v_.s), v(v_.v), incr(1), scale(1) {}
862
863 Vector(const Vector<T, Vincrement_ref>& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(1) {}
864
865 Vector(const Vector<T, Vincrement_constref>& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(1) {}
866
867 bool is_null() const { return v == 0; }
868
869 size_t size() const { return s; }
870
871 T operator[](size_t i) const { return scale * v[i * incr]; }
872
873 Vector operator()(const Interval& i) const {
874 return Vector(i.size(), &v[i[0] * incr], incr, scale);
875 }
876
877 Vector operator()(const Slice& i) const {
878 return Vector(i.size(), &v[i[0] * incr], i.increment() * incr, scale);
879 }
880
881 T operator*(const Vector<T, Vincrement_scale_constref>& v_) const {
882 if (s != v_.s) { Exception() << "The two vectors do not have the same size." << THROW; }
883 return blas::dot(s, v, incr, v_.v, v_.incr) * scale * v_.scale;
884 }
885
886 Vector& operator*(T scale_) {
887 scale *= scale_;
888 return *this;
889 }
890
891 static Vector null;
892
893private:
894 size_t s;
895 const T* v;
896 size_t incr;
897 T scale;
898 MVFRIEND;
899};
900
901template <typename T>
902Vector<T, Vincrement_scale_constref> Vector<T, Vincrement_scale_constref>::null;
903
904template <>
905inline b2000::csda<double> Vector<b2000::csda<double>, Vincrement_constref>::norm2() const {
906 b2000::csda<double> n = 0;
907 for (size_t i = 0; i != size(); ++i) { n += std::norm(v[i]); }
908 return n;
909}
910
911}} // namespace b2000::b2linalg
912
913#endif
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314