21#ifndef __B2MATRIX_PACKED_H__
22#define __B2MATRIX_PACKED_H__
24#include "b2linear_algebra_def.H"
26namespace b2000::b2linalg {
29 using base = Mpacked_ref;
30 using const_base = Mpacked_st_constref;
31 using copy = Mlower_packed;
35class Matrix<T, Mlower_packed> {
39 Matrix(
size_t s_) : s(s_), m(s_ * (s_ + 1) / 2) {}
41 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
43 template <
typename T1>
44 Matrix(
const Matrix<T1, Mlower_packed>& m_)
45 : s(m_.s.begin(), m_.s.end()), m(m_.m.begin(), m_.m.end()) {}
47 template <
typename T1>
48 Matrix& operator=(
const Matrix<T1, Mlower_packed>& m_) {
50 m.assign(m_.m.begin(), m_.m.end());
54 template <
typename STORAGE>
55 Matrix& operator=(
const Matrix<T, STORAGE>& m_) {
56 if (m_.size1() != m_.size2()) { Exception() <<
"The matrix is not symmetric." <<
THROW; }
58 m.resize(s * (s + 1) / 2);
59 Matrix<T, Mpacked_ref> ref(*
this);
64 Matrix& operator=(
const Matrix& m_) {
70 bool is_null()
const {
return this == &null; }
72 void set_zero() { std::fill(m.begin(), m.end(), 0); }
74 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
76 size_t size1()
const {
return s; }
78 size_t size2()
const {
return s; }
80 size_t esize()
const {
return s * (s + 1) / 2; }
82 void resize(
size_t s_) {
84 m.resize(s_ * (s_ + 1) / 2);
87 void resize(
size_t s1,
size_t s2) {
88 if (s1 != s2) { Exception() <<
THROW; }
90 m.resize(s1 * (s1 + 1) / 2);
93 const T& operator()(
size_t i,
size_t j)
const {
95 return m[(2 * s - i - 1) * i / 2 + j];
97 return m[(2 * s - j - 1) * j / 2 + i];
101 T& operator()(
size_t i,
size_t j) {
103 return m[(2 * s - i - 1) * i / 2 + j];
105 return m[(2 * s - j - 1) * j / 2 + i];
111 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
112 l <<
"lower packed matrix ";
113 l.write(m.s * (m.s + 1) / 2, &m.m[0], 1);
124Matrix<T, Mlower_packed> Matrix<T, Mlower_packed>::null;
126struct Mlower_packed_ref {
127 using base = Mpacked_ref;
128 using const_base = Mpacked_st_constref;
129 using copy = Mlower_packed;
133class Matrix<T, Mlower_packed_ref> {
137 Matrix(
size_t s_, T* m_) : s(s_), m(m_) {}
139 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
141 Matrix(Matrix<T, Mlower_packed>& m_) : s(m_.s), m(&m_.m[0]) {}
143 bool is_null()
const {
return m == 0; }
145 void set_zero() { std::fill(m, m + esize(), 0); }
147 Matrix& operator=(
const Matrix& m_) {
148 if (s != m_.s) { Exception() <<
"The two matrix do not have the same size." <<
THROW; }
149 std::copy(m_.m, m_.m + s, m);
153 template <
typename STORAGE>
154 Matrix& operator=(
const Matrix<T, STORAGE>& m_) {
155 Matrix<T, Mpacked_ref> ref(*
this);
160 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
162 size_t size1()
const {
return s; }
164 size_t size2()
const {
return s; }
166 size_t esize()
const {
return s * (s + 1) / 2; }
168 const T& operator()(
size_t i,
size_t j)
const {
170 return m[(2 * s - i - 1) * i / 2 + j];
172 return m[(2 * s - j - 1) * j / 2 + i];
176 T& operator()(
size_t i,
size_t j) {
178 return m[(2 * s - i - 1) * i / 2 + j];
180 return m[(2 * s - j - 1) * j / 2 + i];
186 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
187 l <<
"lower packed matrix ";
188 l.write(m.s * (m.s + 1) / 2, m.m, 1);
199Matrix<T, Mlower_packed_ref> Matrix<T, Mlower_packed_ref>::null;
201struct Mlower_packed_constref {
202 using base = Mpacked_st_constref;
203 using const_base = Mpacked_st_constref;
204 using copy = Mlower_packed;
208class Matrix<T, Mlower_packed_constref> {
212 Matrix(
size_t s_,
const T* m_) : s(s_), m(m_) {}
214 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
216 Matrix(
const Matrix<T, Mlower_packed>& m_) : s(m_.s), m(&m_.m[0]) {}
218 Matrix(
const Matrix<T, Mlower_packed_ref>& m_) : s(m_.s), m(m_.m) {}
220 bool is_null()
const {
return m == 0; }
222 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
224 size_t size1()
const {
return s; }
226 size_t size2()
const {
return s; }
228 size_t esize()
const {
return s * (s + 1) / 2; }
230 const T& operator()(
size_t i,
size_t j)
const {
232 return m[(2 * s - i - 1) * i / 2 + j];
234 return m[(2 * s - j - 1) * j / 2 + i];
240 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
241 l <<
"lower packed matrix ";
242 l.write(m.s * (m.s + 1) / 2, m.m, 1);
253Matrix<T, Mlower_packed_constref> Matrix<T, Mlower_packed_constref>::null;
255struct Mupper_packed {
256 using base = Mpacked_ref;
257 using const_base = Mpacked_st_constref;
258 using copy = Mupper_packed;
262class Matrix<T, Mupper_packed> {
266 Matrix(
size_t s_) : s(s_), m(s_ * (s_ + 1) / 2) {}
268 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
270 template <
typename T1>
271 Matrix(
const Matrix<T1, Mupper_packed>& m_)
272 : s(m_.s.begin(), m_.s.end()), m(m_.m.begin(), m_.m.end()) {}
274 template <
typename T1>
275 Matrix& operator=(
const Matrix<T1, Mupper_packed>& m_) {
277 m.assign(m_.m.begin(), m_.m.end());
281 Matrix& operator=(
const Matrix& m_) {
287 template <
typename STORAGE>
288 Matrix& operator=(
const Matrix<T, STORAGE>& m_) {
289 if (m_.size1() != m_.size2()) { Exception() <<
"The matrix is not symmetric." <<
THROW; }
291 m.resize(s * (s + 1) / 2);
292 Matrix<T, Mpacked_ref> ref(*
this);
297 bool is_null()
const {
return this == &null; }
299 void set_zero() { std::fill(m.begin(), m.end(), 0); }
301 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
303 size_t size1()
const {
return s; }
305 size_t size2()
const {
return s; }
307 size_t esize()
const {
return s * (s + 1) / 2; }
309 void resize(
size_t s1,
size_t s2) {
310 if (s1 != s2) { Exception() <<
THROW; }
312 m.resize(s1 * (s1 + 1) / 2);
315 const T& operator()(
size_t i,
size_t j)
const {
317 return m[i * (i + 1) / 2 + j];
319 return m[j * (j + 1) / 2 + i];
323 T& operator()(
size_t i,
size_t j) {
325 return m[i * (i + 1) / 2 + j];
327 return m[j * (j + 1) / 2 + i];
333 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
334 l <<
"upper packed matrix ";
335 l.write(m.s * (m.s + 1) / 2, &m.m[0], 1);
346Matrix<T, Mupper_packed> Matrix<T, Mupper_packed>::null;
348struct Mupper_packed_ref {
349 using base = Mpacked_ref;
350 using const_base = Mpacked_st_constref;
351 using copy = Mupper_packed;
355class Matrix<T, Mupper_packed_ref> {
359 Matrix(
size_t s_, T* m_) : s(s_), m(m_) {}
361 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
363 Matrix(Matrix<T, Mupper_packed>& m_) : s(m_.s), m(&m_.m[0]) {}
365 bool is_null()
const {
return m == 0; }
367 void set_zero() { std::fill(m, m + esize(), 0); }
369 Matrix& operator=(
const Matrix& m_) {
370 if (s != m_.s) { Exception() <<
"The two matrix do not have the same size." <<
THROW; }
371 std::copy(m_.m, m_.m + s, m);
375 template <
typename STORAGE>
376 Matrix& operator=(
const Matrix<T, STORAGE>& m_) {
377 Matrix<T, Mpacked_ref> ref(*
this);
382 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
384 size_t size1()
const {
return s; }
386 size_t size2()
const {
return s; }
388 size_t esize()
const {
return s * (s + 1) / 2; }
390 const T& operator()(
size_t i,
size_t j)
const {
392 return m[i * (i + 1) / 2 + j];
394 return m[j * (j + 1) / 2 + i];
398 T& operator()(
size_t i,
size_t j) {
400 return m[i * (i + 1) / 2 + j];
402 return m[j * (j + 1) / 2 + i];
408 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
409 l <<
"upper packed matrix ";
410 l.write(m.s * (m.s + 1) / 2, m.m, 1);
421Matrix<T, Mupper_packed_ref> Matrix<T, Mupper_packed_ref>::null;
423struct Mupper_packed_constref {
424 using base = Mpacked_st_constref;
425 using const_base = Mpacked_st_constref;
426 using copy = Mupper_packed;
430class Matrix<T, Mupper_packed_constref> {
434 Matrix(
size_t s_,
const T* m_) : s(s_), m(m_) {}
436 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m) {}
438 Matrix(
const Matrix<T, Mupper_packed>& m_) : s(m_.s), m(&m_.m[0]) {}
440 Matrix(
const Matrix<T, Mupper_packed_ref>& m_) : s(m_.s), m(m_.m) {}
442 bool is_null()
const {
return m == 0; }
444 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
446 size_t size1()
const {
return s; }
448 size_t size2()
const {
return s; }
450 size_t esize()
const {
return s * (s + 1) / 2; }
452 const T& operator()(
size_t i,
size_t j)
const {
454 return m[i * (i + 1) / 2 + j];
456 return m[j * (j + 1) / 2 + i];
462 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
463 l <<
"upper packed matrix ";
464 l.write(m.s * (m.s + 1) / 2, m.m, 1);
475Matrix<T, Mupper_packed_constref> Matrix<T, Mupper_packed_constref>::null;
478 using base = Mpacked_ref;
479 using const_base = Mpacked_st_constref;
480 using copy = Mupper_packed;
484class Matrix<T, Mpacked> {
488 explicit Matrix(
size_t s_,
bool upper_ =
false) : s(s_), m(s_ * (s_ + 1) / 2), upper(upper_) {}
490 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m), upper(m_.upper) {}
492 template <
typename T1>
493 Matrix(
const Matrix<T1, Mpacked>& m_)
494 : s(m_.s.begin(), m_.s.end()), m(m_.m.begin(), m_.m.end()), upper(m_.upper) {}
496 template <
typename T1>
497 Matrix& operator=(
const Matrix<T1, Mpacked>& m_) {
499 m.assign(m_.m.begin(), m_.m.end());
504 double norm_inf()
const {
506 for (
typename std::vector<T>::const_iterator i = m.begin(); i != m.end(); ++i) {
507 res = std::max(res,
norm(*i));
512 void set_zero() { std::fill(m.begin(), m.end(), 0); }
514 bool is_null()
const {
return this == &null; }
516 Matrix& operator=(
const Matrix& m_) {
523 template <
typename STORAGE>
524 Matrix& operator=(
const Matrix<T, STORAGE>& m_) {
526 m.resize(s * (s + 1) / 2);
527 Matrix<T, Mpacked_ref>(*
this) = m_;
531 template <
typename STORAGE>
532 Matrix& operator+=(
const Matrix<T, STORAGE>& m_) {
537 template <
typename STORAGE>
538 Matrix& operator-=(
const Matrix<T, STORAGE>& m_) {
543 Matrix& operator*=(
const T& scalar) {
544 blas::scal(m.size(), scalar, &m[0], 1);
548 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
550 size_t size1()
const {
return s; }
552 size_t size2()
const {
return s; }
554 size_t esize()
const {
return s * (s + 1) / 2; }
556 bool is_upper()
const {
return upper; }
558 void resize(
size_t s_,
bool upper_ =
false) {
560 m.resize(s_ * (s_ + 1) / 2);
564 void resize(
size_t s1,
size_t s2,
bool upper_ =
false) {
565 if (s1 != s2) { Exception() <<
THROW; }
567 m.resize(s1 * (s1 + 1) / 2);
571 const T& operator()(
size_t i,
size_t j)
const {
574 return m[i * (i + 1) / 2 + j];
576 return m[(2 * s - j - 1) * j / 2 + i];
579 return m[j * (j + 1) / 2 + i];
581 return m[(2 * s - i - 1) * i / 2 + j];
585 T& operator()(
size_t i,
size_t j) {
588 return m[i * (i + 1) / 2 + j];
590 return m[(2 * s - j - 1) * j / 2 + i];
593 return m[j * (j + 1) / 2 + i];
595 return m[(2 * s - i - 1) * i / 2 + j];
599 Matrix operator=(
const Matrix<T, Sum<Mpacked_st_constref, Mpacked_st_constref> >& m_) {
601 resize(m_.size1(), m_.size2(), m_.m1.upper);
602 for (
size_t i = 0; i != m.size(); ++i) {
603 m[i] = m_.scale * (m_.m1.scale * m_.m1.m[i] + m_.m2.scale * m_.m2.m[i]);
608 void swap(Matrix& m_) {
611 std::swap(upper, m_.upper);
614 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
616 l <<
"upper packed matrix ";
618 l <<
"lower packed matrix ";
620 l.write(m.s * (m.s + 1) / 2, &m.m[0], 1);
634Matrix<T, Mpacked> Matrix<T, Mpacked>::null;
637 using base = Mpacked_ref;
638 using const_base = Mpacked_st_constref;
639 using copy = Mlower_packed;
643class Matrix<T, Mpacked_ref> {
647 Matrix(
size_t s_, T* m_,
bool upper_) : s(s_), m(m_), upper(upper_) {}
649 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m), upper(m_.upper) {}
651 Matrix(Matrix<T, Mupper_packed>& m_) : s(m_.s), m(&m_.m[0]), upper(true) {}
653 Matrix(Matrix<T, Mupper_packed_ref>& m_) : s(m_.s), m(m_.m), upper(true) {}
655 Matrix(Matrix<T, Mlower_packed>& m_) : s(m_.s), m(&m_.m[0]), upper(false) {}
657 Matrix(Matrix<T, Mlower_packed_ref>& m_) : s(m_.s), m(m_.m), upper(false) {}
659 Matrix(Matrix<T, Mpacked>& m_) : s(m_.s), m(&m_.m[0]), upper(m_.upper) {}
661 bool is_null()
const {
return m == 0; }
663 void set_zero() { std::fill(m, m + esize(), 0); }
665 Matrix& operator=(
const Matrix& m_) {
666 if (s != m_.s) { Exception() <<
"The two matrix do not have the same size." <<
THROW; }
667 if (upper == m_.upper) {
668 std::copy(m_.m, m_.m + s, m);
675 Matrix& operator=(
const Matrix<T, Mrectangle_increment_st_constref>& m_) {
676 if (s != m_.s1 || s != m_.s2) {
677 Exception() <<
"The two matrix do not have the same size." <<
THROW;
682 const double scale = 0.5 * m_.scale;
684 for (
size_t j = 0; j != s; ++j, ++ms2) {
685 const T* ms2_tmp = ms2;
687 for (; i <= j; ++i, ++md, ms2_tmp += m_.ldm) { *md = scale * (ms1[i] + *ms2_tmp); }
691 for (
size_t j = 0; j != s; ++j, ms2 += m_.ldm + 1) {
692 const T* ms2_tmp = ms2;
693 for (
size_t i = j; i != s; ++i, ++md, ms2_tmp += m_.ldm) {
694 *md = scale * (ms1[i] + *ms2_tmp);
702 Matrix& operator=(
const Matrix<T, Mpacked_st_constref>& m_) {
703 if (s != m_.s) { Exception() <<
"The two matrix do not have the same size." <<
THROW; }
704 if (upper == m_.upper) {
705 size_t ss = s * (s + 1) / 2;
706 std::copy(m_.m, m_.m + ss, m);
707 if (m_.scale != T(1)) { blas::scal(ss, T(m_.scale), m, 1); }
714 Matrix& operator=(
const Matrix<
716 MMProd<Mrectangle_increment_st_constref, Mpacked_st_constref>,
717 Mrectangle_increment_st_constref> >& m_) {
718 if (size() != m_.size()) {
719 Exception() <<
"The two matrix do not have the same size." <<
THROW;
721 if (m_.m1.m1.m != m_.m2.m || m_.m1.m1.s1 != m_.m2.s1 || m_.m1.m1.s2 != m_.m2.s2
722 || m_.m1.m1.ldm != m_.m2.ldm || m_.m1.m1.trans == m_.m2.trans) {
727 std::vector<T> tmp(m_.m1.m2.s);
729 const char m_m1_m2_uplo = m_.m1.m2.upper ?
'U' :
'L';
730 const T alpha = m_.m1.m1.scale * m_.m1.m2.scale * m_.m2.scale * m_.scale;
733 for (
size_t j = 0; j != s; ++j) {
735 m_m1_m2_uplo, tmp.size(), 1, m_.m1.m2.m, &m_.m2.m[j], m_.m2.ldm, 0,
738 'N', j + 1, tmp.size(), alpha, &m_.m2.m[0], m_.m2.ldm, &tmp[0], 1, T(0),
743 for (
size_t j = 0; j != s; ++j) {
745 m_m1_m2_uplo, tmp.size(), 1, m_.m1.m2.m, &m_.m2.m[j * m_.m2.ldm], 1, 0,
748 'T', tmp.size(), j + 1, alpha, &m_.m2.m[0], m_.m2.ldm, &tmp[0], 1, T(0),
753 }
else if (m_.m2.trans) {
754 for (
size_t j = 0; j != s; ++j) {
756 m_m1_m2_uplo, tmp.size(), 1, m_.m1.m2.m, &m_.m2.m[j], m_.m2.ldm, 0, &tmp[0],
759 'N', s - j, tmp.size(), alpha, &m_.m2.m[j], m_.m2.ldm, &tmp[0], 1, T(0), ptr,
764 for (
size_t j = 0; j != s; ++j) {
766 m_m1_m2_uplo, tmp.size(), 1, m_.m1.m2.m, &m_.m2.m[j * m_.m2.ldm], 1, 0,
769 'T', tmp.size(), s - j, alpha, &m_.m2.m[j * m_.m2.ldm], m_.m2.ldm, &tmp[0], 1,
780 MMProd<Mrectangle_increment_st_constref, Msym_compressed_col_st_constref>,
781 Mrectangle_increment_st_constref> >& m_) {
782 if (size() != m_.size()) {
783 Exception() <<
"The two matrix do not have the same size." <<
THROW;
785 if (m_.m1.m1.m != m_.m2.m || m_.m1.m1.s1 != m_.m2.s1 || m_.m1.m1.s2 != m_.m2.s2
786 || m_.m1.m1.ldm != m_.m2.ldm || m_.m1.m1.trans == m_.m2.trans) {
793 const T scale = m_.scale * m_.m1.scale * m_.m1.m1.scale;
794 for (
size_t j = 0; j != m_.m2.s2; ++j) {
795 v1 = m_.m1.m2 * m_.m2[j];
797 Vector<T, Vdense_ref> v2(j + 1, m_ptr);
798 v2 = scale * m_.m1.m1(Interval(0, j + 1), Interval(0, v1.size())) * v1;
801 Vector<T, Vdense_ref> v2(s - j, m_ptr);
802 v2 = scale * m_.m1.m1(Interval(j, s), Interval(0, v1.size())) * v1;
809 template <
typename STORAGE>
810 Matrix& operator+=(
const Matrix<T, STORAGE>& m_) {
815 template <
typename STORAGE>
816 Matrix& operator-=(
const Matrix<T, STORAGE>& m_) {
821 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
823 size_t size1()
const {
return s; }
825 size_t size2()
const {
return s; }
827 size_t esize()
const {
return s * (s + 1) / 2; }
829 const T& operator()(
size_t i,
size_t j)
const {
832 return m[i * (i + 1) / 2 + j];
834 return m[(2 * s - j - 1) * j / 2 + i];
837 return m[j * (j + 1) / 2 + i];
839 return m[(2 * s - i - 1) * i / 2 + j];
843 T& operator()(
size_t i,
size_t j) {
846 return m[i * (i + 1) / 2 + j];
848 return m[(2 * s - j - 1) * j / 2 + i];
851 return m[j * (j + 1) / 2 + i];
853 return m[(2 * s - i - 1) * i / 2 + j];
859 friend logging::Logger& operator<<(logging::Logger& l,
const Matrix& m) {
861 l <<
"upper packed matrix ";
863 l <<
"lower packed matrix ";
865 l.write(m.s * (m.s + 1) / 2, m.m, 1);
877Matrix<T, Mpacked_ref> Matrix<T, Mpacked_ref>::null;
879struct Mpacked_st_constref {
880 using base = Mpacked_st_constref;
881 using const_base = Mpacked_st_constref;
882 using copy = Mlower_packed;
886class Matrix<T, Mpacked_st_constref> {
890 Matrix(
size_t s_,
const T* m_,
bool scale_,
bool upper_)
891 : s(s_), m(m_), scale(scale_), upper(upper_) {}
893 Matrix(
const Matrix& m_) : s(m_.s), m(m_.m), scale(m_.scale), upper(m_.upper) {}
895 Matrix(
const Matrix<T, Mupper_packed>& m_) : s(m_.s), m(&m_.m[0]), scale(1), upper(true) {}
897 Matrix(
const Matrix<T, Mupper_packed_ref>& m_) : s(m_.s), m(m_.m), scale(1), upper(true) {}
899 Matrix(
const Matrix<T, Mupper_packed_constref>& m_) : s(m_.s), m(m_.m), scale(1), upper(true) {}
901 Matrix(
const Matrix<T, Mlower_packed>& m_) : s(m_.s), m(&m_.m[0]), scale(1), upper(false) {}
903 Matrix(
const Matrix<T, Mlower_packed_ref>& m_) : s(m_.s), m(m_.m), scale(1), upper(false) {}
905 Matrix(
const Matrix<T, Mlower_packed_constref>& m_)
906 : s(m_.s), m(m_.m), scale(1), upper(false) {}
908 Matrix(
const Matrix<T, Mpacked>& m_) : s(m_.s), m(&m_.m[0]), scale(1), upper(m_.upper) {}
910 Matrix(
const Matrix<T, Mpacked_ref>& m_) : s(m_.s), m(m_.m), scale(1), upper(m_.upper) {}
912 bool is_null()
const {
return m == 0; }
914 std::pair<size_t, size_t> size()
const {
return std::pair<size_t, size_t>(s, s); }
916 size_t size1()
const {
return s; }
918 size_t size2()
const {
return s; }
920 size_t esize()
const {
return s * (s + 1) / 2; }
922 const T& operator()(
size_t i,
size_t j)
const {
925 return m[i * (i + 1) / 2 + j];
927 return m[(2 * s - j - 1) * j / 2 + i];
930 return m[j * (j + 1) / 2 + i];
932 return m[(2 * s - i - 1) * i / 2 + j];
936 Matrix& operator*(T scale_) {
952Matrix<T, Mpacked_st_constref> Matrix<T, Mpacked_st_constref>::null;
csda< T > norm(const csda< T > &a)
Definition b2csda.H:343
#define THROW
Definition b2exception.H:198
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314