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