18#ifndef __B2VECTOR_INCREMENT_H__
19#define __B2VECTOR_INCREMENT_H__
21#include "b2linear_algebra_def.H"
23namespace b2000 {
namespace b2linalg {
25struct Vincrement_constref {
26 typedef Vincrement_scale_constref base;
27 typedef Vincrement_scale_constref const_base;
32class Vector<T, Vincrement_constref> {
34 Vector() : s(0), v(0), incr(0) {}
36 Vector(
size_t s_,
const T* v_,
size_t incr_ = 1) : s(s_), v(v_), incr(incr_) {}
38 Vector(
const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr) {}
40 Vector(
const Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
42 Vector(
const Vector<T, Vdense_constref>& v_) : s(v_.s), v(v_.v), incr(1) {}
44 Vector(
const std::vector<T>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
46 bool is_null()
const {
return v == 0; }
48 size_t size()
const {
return s; }
50 const T& operator[](
size_t i)
const {
return v[i * incr]; }
52 Vector<T, Vincrement_constref> operator()(
const Interval& i)
const {
53 return Vector<T, Vincrement_constref>(i.size(), &v[i[0] * incr], incr);
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);
60 T norm2()
const {
return blas::nrm2(s, v, incr); }
64 friend logging::Logger& operator<<(logging::Logger& l,
const Vector& v) {
66 l.write(v.s, v.v, v.incr);
78Vector<T, Vincrement_constref> Vector<T, Vincrement_constref>::null;
80struct Vincrement_ref {
81 typedef Vincrement_ref base;
82 typedef Vincrement_scale_constref const_base;
87class Vector<T, Vincrement_ref> {
89 Vector() : s(0), v(0), incr(0) {}
91 Vector(
size_t s_, T* v_,
size_t incr_ = 1) : s(s_), v(v_), incr(incr_) {}
93 Vector(
const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr) {}
95 Vector(Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1) {}
97 Vector(Vector<T, Vdense_ref>& v_) : s(v_.size()), v(v_.v), incr(1) {}
99 bool is_null()
const {
return v == 0; }
101 size_t size()
const {
return s; }
104 T
const* vv_end = v + s * incr;
105 for (T* vv = v; vv != vv_end; vv += incr) { *vv = T(0); }
108 const T& operator[](
size_t i)
const {
return v[i * incr]; }
110 T& operator[](
size_t i) {
return v[i * incr]; }
112 Vector<T, Vincrement_ref> operator()(
const Interval& i) {
113 return Vector<T, Vincrement_ref>(i.size(), &v[i[0] * incr], incr);
116 Vector<T, Vincrement_ref> operator()(
const Slice& i) {
117 return Vector<T, Vincrement_ref>(i.size(), &v[i[0] * incr], i.increment() * incr);
120 template <
typename STORAGE>
121 Vector& operator+=(
const Vector<T, STORAGE>& v_) {
126 template <
typename STORAGE>
127 Vector& operator-=(
const Vector<T, STORAGE>& v_) {
132 Vector& operator=(
const Vector& v_) {
134 Exception() <<
"The two vectors do not have the same size, " << s <<
" and " << v_.s
137 if (v_.v != v || v_.incr != incr) { blas::copy(s, v_.v, v_.incr, v, incr); }
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;
148 std::copy(&v_[0], &v_[0] + s, v);
151 T* out_end = out + s * incr;
152 const T1* in = &v_[0];
153 for (; out < out_end; ++in, out += incr) { *out = *in; }
158 template <
typename T1>
159 Vector& operator=(
const Vector<T1, Vincrement_ref>& v_) {
161 Exception() <<
"The two vectors do not have the same size, " << s <<
" and " << v_.s
164 if (v_.incr == 1 && incr == 1) {
165 std::copy(v_.v, v_.v + s, v);
168 T* out_end = out + s * incr;
170 for (; out < out_end; in += v_.incr, out += incr) { *out = *in; }
175 Vector& operator=(
const Vector<T, Vincrement_scale_constref>& v_) {
177 Exception() <<
"The two vectors do not have the same size, " << s <<
" and " << v_.s
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); }
185 template <
typename T1>
186 Vector& operator=(
const Vector<T1, Vincrement_scale_constref>& v_) {
188 Exception() <<
"The two vectors do not have the same size, " << s <<
" and " << v_.s
191 if (v_.incr == 1 && incr == 1) {
192 std::copy(v_.v, v_.v + s, v);
195 T* out_end = out + s * incr;
197 for (; out < out_end; in += v_.incr, out += incr) { *out = *in; }
199 if (v_.scale != T(1)) { blas::scal(s, v_.scale, v, incr); }
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;
209 (*this) = v_.scale * v_.v1;
210 blas::axpy(s, v_.v2.scale * v_.scale, v_.v2.v, v_.v2.incr, v, incr);
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;
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; }
230 const Vector<T, MVProd<Mrectangle_increment_st_constref, Vincrement_scale_constref> >&
232 if (s != v_.size()) {
233 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
234 << v_.size() <<
"." <<
THROW;
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);
245 T, Sum<Vincrement_scale_constref,
246 MVProd<Mrectangle_increment_st_constref, Vincrement_scale_constref> > >&
248 if (s != v_.size()) {
249 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
250 << v_.size() <<
"." <<
THROW;
252 if (v_.v1.v != v || v_.v1.incr != incr) { blas::copy(s, v_.v1.v, v_.v1.incr, v, incr); }
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);
263 T, Sum<Vincrement_scale_constref,
264 MVProd<Mrectangle_increment_st_constref, Vcompressed_scale_constref> > >&
266 if (s != v_.size()) {
267 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
268 << v_.size() <<
"." <<
THROW;
271 const T scale = v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
273 const T* m = v_.v2.m.m;
274 for (
size_t i = 0; i != s; ++i) {
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];
279 v[i] = v_.scale * (v_.v1[i] + scale * tmp);
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;
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);
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;
307 if (v_.v1.v != v || v_.v1.incr != incr) { blas::copy(s, v_.v1.v, v_.v1.incr, v, incr); }
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);
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;
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;
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;
331 while (rowind_begin != rowind_end) {
332 val += *value_begin++ * v_.v[*rowind_begin++];
334 *result_begin = scale * val;
335 result_begin += incr;
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;
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;
362 T scale = v_.scale * v_.v2.scale * v_.v2.v.scale * v_.v2.m.scale;
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; }
377 Vector& operator=(
const Vector<
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;
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);
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;
400 for (
size_t i = 0; i != size(); ++i) {
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++];
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;
415 Vector& operator=(
const Vector<
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;
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;
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; }
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;
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;
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;
461 while (rowind_begin != rowind_end) {
462 val += *value_begin++ * v_.v2.v[*rowind_begin++];
464 *result_begin += scale * val;
465 result_begin += incr;
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;
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;
491 *
this = v_.scale * v_.v1;
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;
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;
503 while (rowind_begin != rowind_end) {
504 val += *value_begin++ * v_.v2.v[*rowind_begin++];
506 *result_begin += scale * val;
507 result_begin += incr;
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;
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;
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) {
526 while (rowind_begin < rowind_end) {
527 (*this)[*rowind_begin++] += *value_begin++ * val;
536 const Vector<T, MVProd<Msym_compressed_col_st_constref, Vincrement_scale_constref> >&
538 if (s != v_.size()) {
539 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
540 << v_.size() <<
"." <<
THROW;
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;
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;
553 while (rowind_begin != rowind_end) {
554 val += *value_begin++ * v_.v[*rowind_begin++];
556 *result_begin = scale * val;
557 result_begin += incr;
560 colind_begin = v_.m.si;
561 rowind_begin = v_.m.index + *colind_begin;
562 value_begin = v_.m.m + *colind_begin;
564 const T* input_begin = v_.v.v;
565 const T*
const input_end = input_begin + v_.v.s * v_.v.incr;
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) {
576 while (rowind_begin < rowind_end) {
577 (*this)[*rowind_begin++] += *value_begin++ * val;
587 MMProd<Msym_compressed_col_st_constref, Msym_compressed_col_st_constref>,
588 Vincrement_scale_constref> >& v_) {
593 Vector& operator=(
const Vector<
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;
602 v_.m.m.resolve(s, 1, v_.v.v, s, v, s,
' ', v_.m.null_space, v_.m.max_null_space_vector);
609 MVProd<Minverse_constref<Mcompressed_col_update_inv>, Vincrement_scale_constref> >&
611 if (s != v_.size()) {
612 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
613 << v_.size() <<
"." <<
THROW;
616 v_.m.m.resolve(s, 1, v_.v.v, s, v, s,
' ', v_.m.null_space, v_.m.max_null_space_vector);
620 Vector& operator=(
const Vector<
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;
630 s, 1, v_.v.v, s, v, s, 0, 0, 0,
' ', v_.m.null_space, v_.m.max_null_space_vector);
634 Vector& operator=(
const Vector<
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;
644 s, 1, v_.v.v, s, v, s, 0, 0, 0,
' ', v_.m.null_space, v_.m.max_null_space_vector);
648 Vector& operator=(
const Vector<
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;
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);
663 Vector& operator=(
const Vector<
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;
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);
681 MVProd<Minverse_constref<Mcompressed_col_st_constref>, Vincrement_scale_constref> >&
683 if (s != v_.size()) {
684 Exception() <<
"The two vectors do not have the same size, " << s <<
" and "
685 << v_.size() <<
"." <<
THROW;
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;
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;
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;
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]; }
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;
724 for (
size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
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;
733 for (
size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
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;
742 for (
size_t i = 0; i != s; ++i) { v[i] = v_[i]; }
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;
754 Vector<T, Vdense> tmp(v_.v2.v);
755 *
this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
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;
767 Vector<T, Vdense> tmp(v_.v2.v);
768 *
this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
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;
777 Vector<T, Vdense> tmp(v_.v);
778 *
this = v_.scale * (v_.m * tmp);
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;
787 Vector<T, Vdense> tmp(v_.v);
788 *
this += v_.scale * (v_.m * tmp);
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;
799 Vector<T, Vdense> tmp(v_.v2.v);
800 *
this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
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;
811 Vector<T, Vdense> tmp(v_.v2.v);
812 *
this = v_.scale * (v_.v1 + v_.v2.scale * (v_.v2.m * tmp));
816 Vector& operator=(
const Vector<T, MVProd<Mrectangle_inv, Vincrement_scale_constref> >& v_) {
825 friend logging::Logger& operator<<(logging::Logger& l,
const Vector& v) {
827 l.write(v.s, v.v, v.incr);
839Vector<T, Vincrement_ref> Vector<T, Vincrement_ref>::null;
841struct Vincrement_scale_constref {
842 typedef Vincrement_scale_constref base;
843 typedef Vincrement_scale_constref const_base;
848class Vector<T, Vincrement_scale_constref> {
850 Vector() : s(0), v(0), incr(0), scale(0) {}
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_) {}
855 Vector(
const Vector& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(v_.scale) {}
857 Vector(
const Vector<T, Vdense>& v_) : s(v_.size()), v(&v_[0]), incr(1), scale(1) {}
859 Vector(
const Vector<T, Vdense_ref>& v_) : s(v_.s), v(v_.v), incr(1), scale(1) {}
861 Vector(
const Vector<T, Vdense_constref>& v_) : s(v_.s), v(v_.v), incr(1), scale(1) {}
863 Vector(
const Vector<T, Vincrement_ref>& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(1) {}
865 Vector(
const Vector<T, Vincrement_constref>& v_) : s(v_.s), v(v_.v), incr(v_.incr), scale(1) {}
867 bool is_null()
const {
return v == 0; }
869 size_t size()
const {
return s; }
871 T operator[](
size_t i)
const {
return scale * v[i * incr]; }
873 Vector operator()(
const Interval& i)
const {
874 return Vector(i.size(), &v[i[0] * incr], incr, scale);
877 Vector operator()(
const Slice& i)
const {
878 return Vector(i.size(), &v[i[0] * incr], i.increment() * incr, scale);
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;
886 Vector& operator*(T scale_) {
902Vector<T, Vincrement_scale_constref> Vector<T, Vincrement_scale_constref>::null;
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]); }
#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