21#ifndef __B2MATRIX_OPERATION_H__ 
   22#define __B2MATRIX_OPERATION_H__ 
   27#include "b2linear_algebra_def.H" 
   28#include "b2linear_algebra_utils.H" 
   30namespace b2000::b2linalg {
 
   32template <
typename T, 
typename STORAGE1, 
typename STORAGE2>
 
   33class Matrix<T, Sum<STORAGE1, STORAGE2> > {
 
   35    Matrix(
const Matrix<T, STORAGE1>& m1_, 
const Matrix<T, STORAGE2>& m2_, T scale_ = T(1))
 
   36        : m1(m1_), m2(m2_), scale(scale_), trans(false) {
 
   37        if (m1.size() != m2.size()) {
 
   38            Exception() << 
"The two matrices do not have the same size." << 
THROW;
 
   42    std::pair<size_t, size_t> size()
 const {
 
   44            return std::pair<size_t, size_t>(m1.size2(), m1.size1());
 
   50    size_t size1()
 const {
 
   58    size_t size2()
 const {
 
   66    T operator()(
size_t i, 
size_t j)
 const {
 
   68            return scale * (m1(j, i) + m2(j, i));
 
   70            return scale * (m1(i, j) + m2(i, j));
 
   74    Matrix& operator*(T t) {
 
   80        trans = trans ? false : 
true;
 
   85    Matrix<T, STORAGE1> m1;
 
   86    Matrix<T, STORAGE2> m2;
 
   92template <
typename T1, 
typename T2>
 
   94    using const_base = MMProd;
 
   97template <
typename T, 
typename STORAGE1, 
typename STORAGE2>
 
   98class Matrix<T, MMProd<STORAGE1, STORAGE2> > {
 
  100    Matrix(
const Matrix<T, STORAGE1>& m1_, 
const Matrix<T, STORAGE2>& m2_, T scale_ = T(1))
 
  101        : m1(m1_), m2(m2_), scale(scale_), trans(false) {
 
  102        if (m1.size2() != m2.size1()) {
 
  103            Exception() << 
"Matrix-matrix inner product: The number of columns of the " 
  105                        << m1.size1() << 
" x " << m1.size2()
 
  106                        << 
") differs from the number of rows of the second matrix (" << m2.size1()
 
  107                        << 
" x " << m2.size2() << 
")." << 
THROW;
 
  111    std::pair<size_t, size_t> size()
 const {
 
  112        return std::pair<size_t, size_t>(m1.size1(), m2.size2());
 
  115    size_t size1()
 const { 
return m1.size1(); }
 
  117    size_t size2()
 const { 
return m2.size2(); }
 
  119    T operator()(
size_t i, 
size_t j)
 const {
 
  121            return scale * transpose(m1)[i] * m2[j];
 
  123            return scale * transpose(m1)[j] * m2[i];
 
  127    Matrix& operator*(T t) {
 
  132    Matrix& transpose() {
 
  133        trans = trans ? false : 
true;
 
  138    Matrix<T, STORAGE1> m1;
 
  139    Matrix<T, STORAGE2> m2;
 
  145template <
typename T1, 
typename S1, 
typename T2, 
typename S2>
 
  146inline void copy_m(
const Matrix<T1, S1>& a, Matrix<T2, S2>& b) {
 
  147    b.resize(a.size1(), a.size2());
 
  148    for (
size_t i = 0; i != a.size1(); ++i) {
 
  149        for (
size_t j = 0; j != a.size2(); ++j) { b(i, j) = a(i, j); }
 
  153template <
typename T1, 
typename S1, 
typename T2, 
typename S2>
 
  154inline void copy_vm(
const std::vector<Matrix<T1, S1> >& a, std::vector<Matrix<T2, S2> >& b) {
 
  156    for (
size_t i = 0; i != a.size(); ++i) { copy_m(a[i], b[i]); }
 
  159template <
typename T, 
typename STORAGE>
 
  160Matrix<T, typename STORAGE::const_base> transposed(
const Matrix<T, STORAGE>& m) {
 
  161    return Matrix<T, typename STORAGE::const_base>(m).transpose();
 
  164template <
typename T, 
typename STORAGE1, 
typename STORAGE2>
 
  165Matrix<T, Sum<typename STORAGE1::const_base, typename STORAGE2::const_base> > operator+(
 
  166      const Matrix<T, STORAGE1>& m1, 
const Matrix<T, STORAGE2>& m2) {
 
  167    return Matrix<T, Sum<typename STORAGE1::const_base, typename STORAGE2::const_base> >(m1, m2);
 
  170template <
typename T, 
typename STORAGE1, 
typename STORAGE2>
 
  171Matrix<T, Sum<typename STORAGE1::const_base, typename STORAGE2::const_base> > operator-(
 
  172      const Matrix<T, STORAGE1>& m1, 
const Matrix<T, STORAGE2>& m2) {
 
  173    return Matrix<T, Sum<typename STORAGE1::const_base, typename STORAGE2::const_base> >(m1, -m2);
 
  176template <
typename T, 
typename STORAGE1, 
typename STORAGE2>
 
  177Matrix<T, MMProd<typename STORAGE1::const_base, typename STORAGE2::const_base> > operator*(
 
  178      const Matrix<T, STORAGE1>& m1, 
const Matrix<T, STORAGE2>& m2) {
 
  179    return Matrix<T, MMProd<typename STORAGE1::const_base, typename STORAGE2::const_base> >(m1, m2);
 
  182template <
typename T, 
typename STORAGE>
 
  183Matrix<T, typename STORAGE::const_base> operator*(T t, 
const Matrix<T, STORAGE>& m) {
 
  184    return Matrix<T, typename STORAGE::const_base>(m) * t;
 
  187template <
typename T, 
typename STORAGE>
 
  188Matrix<T, typename STORAGE::const_base> operator*(
const Matrix<T, STORAGE>& m, T t) {
 
  189    return Matrix<T, typename STORAGE::const_base>(m) * t;
 
  192template <
typename T, 
typename STORAGE>
 
  193Matrix<T, typename STORAGE::const_base> operator-(
const Matrix<T, STORAGE>& m) {
 
  194    return Matrix<T, typename STORAGE::const_base>(m) * T(-1);
 
  197template <
typename MTYPE, 
typename INDEX1, 
typename INDEX2>
 
  198struct Msub_constref {
 
  199    using base = Msub_constref;
 
  200    using const_base = Msub_constref;
 
  203template <
typename T, 
typename MTYPE, 
typename INDEX1, 
typename INDEX2>
 
  204class Matrix<T, Msub_constref<MTYPE, INDEX1, INDEX2> > {
 
  206    Matrix(
const Matrix<T, MTYPE> m_, 
const INDEX1& index1_, 
const INDEX2& index2_)
 
  207        : m(m_), index1(index1_), index2(index2_) {}
 
  209    std::pair<size_t, size_t> size()
 const {
 
  210        return std::pair<size_t, size_t>(
 
  211              index1.is_all() ? m.size1() : index1.size(),
 
  212              index2.is_all() ? m.size2() : index2.size());
 
  215    size_t size1()
 const { 
return index1.is_all() ? m.size1() : index1.size(); }
 
  217    size_t size2()
 const { 
return index2.is_all() ? m.size2() : index2.size(); }
 
  219    T operator()(
size_t i, 
size_t j)
 const {
 
  220        return m(index1.is_all() ? i : index1[i], index2.is_all() ? j : index2[j]);
 
  225    const Matrix<T, MTYPE> m;
 
  226    const INDEX1& index1;
 
  227    const INDEX2& index2;
 
  230template <
typename MTYPE>
 
  231struct Minverse_constref {
 
  232    using base = Minverse_constref;
 
  233    using const_base = Minverse_constref;
 
  236template <
typename T, 
typename MTYPE>
 
  237class Matrix<T, Minverse_constref<MTYPE> > {
 
  240          const Matrix<T, MTYPE>& m_, Matrix<T>& null_space_ = Matrix<T>::null,
 
  241          ssize_t max_null_space_vector_ = 0)
 
  242        : m(m_), null_space(null_space_), max_null_space_vector(max_null_space_vector_) {}
 
  244    Matrix(
const Matrix& m_)
 
  245        : m(m_.m), null_space(m_.null_space), max_null_space_vector(m_.max_null_space_vector) {}
 
  247    std::pair<size_t, size_t> size()
 const { 
return m.size(); }
 
  249    size_t size1()
 const { 
return m.size1(); }
 
  251    size_t size2()
 const { 
return m.size2(); }
 
  254    const Matrix<T, MTYPE>& m;
 
  255    Matrix<T>& null_space;
 
  256    ssize_t max_null_space_vector;
 
  260template <
typename T, 
typename MTYPE>
 
  261Matrix<T, Minverse_constref<MTYPE> > inverse(
 
  262      const Matrix<T, MTYPE>& m, Matrix<T, Mrectangle>& null_space = Matrix<T, Mrectangle>::null,
 
  263      ssize_t max_null_space_vector = 0) {
 
  264    return Matrix<T, Minverse_constref<MTYPE> >(m, null_space, max_null_space_vector);
 
  267template <
typename MTYPE>
 
  268struct Minverse_ext_constref {
 
  269    using base = Minverse_ext_constref;
 
  270    using const_base = Minverse_ext_constref;
 
  273template <
typename T, 
typename MTYPE>
 
  274class Matrix<T, Minverse_ext_constref<MTYPE> > {
 
  277          const Matrix<T, MTYPE>& m_, 
const T* a_, 
const T* b_, 
const T* c_,
 
  278          Matrix<T>& null_space_ = Matrix<T>::null, ssize_t max_null_space_vector_ = 0)
 
  283          null_space(null_space_),
 
  284          max_null_space_vector(max_null_space_vector_) {}
 
  286    Matrix(
const Matrix& m_)
 
  291          null_space(m_.null_space),
 
  292          max_null_space_vector(m_.max_null_space_vector) {}
 
  294    std::pair<size_t, size_t> size()
 const { 
return m.size(); }
 
  296    size_t size1()
 const { 
return m.size1(); }
 
  298    size_t size2()
 const { 
return m.size2(); }
 
  301    const Matrix<T, MTYPE>& m;
 
  305    Matrix<T>& null_space;
 
  306    ssize_t max_null_space_vector;
 
  310template <
typename T, 
typename MTYPE, 
typename MTYPEA, 
typename MTYPEB, 
typename MTYPEC>
 
  311Matrix<T, Minverse_ext_constref<MTYPE> > update_extension_and_inverse(
 
  312      const Matrix<T, MTYPE>& m, 
const Matrix<T, MTYPEA>& a, 
const Matrix<T, MTYPEB>& b,
 
  313      const Matrix<T, MTYPEC>& c, Matrix<T, Mrectangle>& null_space = Matrix<T, Mrectangle>::null,
 
  314      ssize_t max_null_space_vector = 0) {
 
  315    return Matrix<T, Minverse_ext_constref<MTYPE> >(
 
  316          m, &a(0, 0), &b(0, 0), &c(0, 0), null_space, max_null_space_vector);
 
  319template <
typename T, 
typename MTYPE, 
typename MTYPEA, 
typename MTYPEB>
 
  320Matrix<T, Minverse_ext_constref<MTYPE> > update_extension_and_inverse(
 
  321      const Matrix<T, MTYPE>& m, 
const Vector<T, MTYPEA>& a, 
const Vector<T, MTYPEB>& b, 
const T& c,
 
  322      Matrix<T, Mrectangle>& null_space = Matrix<T, Mrectangle>::null,
 
  323      ssize_t max_null_space_vector = 0) {
 
  324    return Matrix<T, Minverse_ext_constref<MTYPE> >(
 
  325          m, &a[0], &b[0], &c, null_space, max_null_space_vector);
 
  347template <
typename T, 
typename TYPE>
 
  349      const Matrix<T, TYPE>& m, std::ostream& out, std::string seperator = 
", ",
 
  350      std::string row_sep = 
"\n",
 
  351      std::pair<std::string, std::string> row_enclosure =
 
  352            std::pair<std::string, std::string>(
"", 
""),
 
  353      std::pair<std::string, std::string> mat_enclosure =
 
  354            std::pair<std::string, std::string>(
"", 
"")) {
 
  355    size_t n_rows = m.size1();
 
  356    size_t n_cols = m.size2();
 
  358    out << mat_enclosure.first;
 
  359    for (
size_t i = 0; i < n_rows; ++i) {
 
  360        out << row_enclosure.first;
 
  361        for (
size_t j = 0; j < n_cols - 1; ++j) { out << m(i, j) << seperator; }
 
  363        out << m(i, n_cols - 1) << row_enclosure.second;
 
  365        if (i < n_rows - 1) { out << row_sep; }
 
  367    out << mat_enclosure.second;
 
  371template <
typename T, 
typename TYPE>
 
  372std::ostream& operator<<(std::ostream& out, 
const Matrix<T, TYPE>& m) {
 
  373    const auto closures = std::pair<std::string, std::string>(
"( ", 
" )");
 
  374    print(m, out, 
", ", 
",\n", closures, closures);
 
  384template <
typename T, 
typename TYPE>
 
  386      const Matrix<T, TYPE>& m, std::string matrixname, std::filesystem::path filepath,
 
  387      std::streamsize precision = 16) {
 
  388    std::ofstream out(filepath);
 
  389    out.precision(precision);
 
  390    out << 
"# " << matrixname << 
" with (" << m.size1() << 
" x " << m.size2() << 
") DoF\n";
 
  395template <
typename ATYPE, 
typename BTYPE>
 
  397    using base = Eigenvector;
 
  398    using const_base = Eigenvector;
 
  401template <
typename T, 
typename ATYPE, 
typename BTYPE>
 
  402class Matrix<T, Eigenvector<ATYPE, BTYPE> > {
 
  405          const Matrix<T, ATYPE>& a_, 
const char type_a_, 
const Matrix<T, BTYPE>& b_,
 
  406          const char type_b_, Vector<T, Vdense_ref> eigenvalue_, 
const char which_[2], T sigma_,
 
  407          int ncv_, 
double tol_, 
int maxit_, 
const Vector<T, Vdense_constref> starting_eigenvector_)
 
  412          eigenvalue(eigenvalue_),
 
  417          starting_eigenvector(starting_eigenvector_) {
 
  418        if (!b.is_null() && a.size() != b.size()) {
 
  419            Exception() << 
"Eigenvalue extraction: Matrix A and B do not have same size." << 
THROW;
 
  421        if (!starting_eigenvector.is_null() && starting_eigenvector.size() != a.size1()) {
 
  422            Exception() << 
"Eigenvalue extraction: Eigenvalue start vector size != matrix size." 
  425        strcpy(which, which_);
 
  426        if (tol < 0) { tol = 0; }
 
  429    std::pair<size_t, size_t> size()
 const {
 
  430        return std::pair<size_t, size_t>(a.size1(), eigenvalue.size());
 
  433    size_t size1()
 const { 
return a.size1(); }
 
  435    size_t size2()
 const { 
return eigenvalue.size(); }
 
  437    void resolve(Matrix<T, Mrectangle_increment_ref>& eigenvector);
 
  440    const Matrix<T, ATYPE>& a;
 
  442    const Matrix<T, BTYPE>& b;
 
  444    Vector<T, Vdense_ref> eigenvalue;
 
  450    Vector<T, Vdense_constref> starting_eigenvector;
 
  455              Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {}
 
  456        virtual void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {}
 
  458              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {}
 
  461    struct OPS1 : 
public OP {
 
  462        OPS1(
const Matrix<T, ATYPE>& a_) : a(a_) {}
 
  463        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  466        const Matrix<T, ATYPE>& a;
 
  469    struct OPS1i : 
public OP {
 
  470        OPS1i(
const Matrix<T, ATYPE>& a_) : a(a_) {}
 
  471        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  475              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  476            for (
size_t i = 0; i != eigenvalue.size(); ++i) {
 
  477                eigenvalue[i] = T(1) / eigenvalue[i];
 
  480        const Matrix<T, ATYPE>& a;
 
  483    struct OPS2 : 
public OP {
 
  484        OPS2(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  485        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  489        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = b * x; }
 
  490        const Matrix<T, ATYPE>& a;
 
  491        const Matrix<T, BTYPE>& b;
 
  494    struct OPS2i : 
public OP {
 
  495        OPS2i(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  496        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  500        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = a * x; }
 
  502              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  503            for (
size_t i = 0; i != eigenvalue.size(); ++i) {
 
  504                eigenvalue[i] = T(1) / eigenvalue[i];
 
  507        const Matrix<T, ATYPE>& a;
 
  508        const Matrix<T, BTYPE>& b;
 
  511    struct OPS3_0 : 
public OP {
 
  512        OPS3_0(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  513        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  521        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = b * x; }
 
  522        const Matrix<T, ATYPE>& a;
 
  523        const Matrix<T, BTYPE>& b;
 
  526    struct OPS3 : 
public OP {
 
  527        OPS3(
const Matrix<T, ATYPE>& a, 
const Matrix<T, BTYPE>& b_, T sigma) : b(b_), m(a) {
 
  529                for (
size_t i = 0; i != a.size1(); ++i) { m(i, i) -= sigma; }
 
  534        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  542        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = b * x; }
 
  543        const Matrix<T, BTYPE>& b;
 
  544        Matrix<T, typename ATYPE::inverse> m;
 
  547    struct OPS4 : 
public OP {
 
  548        OPS4(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_, T sigma) : a(a_), b(b_), m(a) {
 
  550                for (
size_t i = 0; i != a.size1(); ++i) { m(i, i) -= sigma; }
 
  555        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  563        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = a * x; }
 
  564        const Matrix<T, ATYPE>& a;
 
  565        const Matrix<T, BTYPE>& b;
 
  566        Matrix<T, typename ATYPE::inverse> m;
 
  569    struct OPS5 : 
public OP {
 
  570        OPS5(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_, T sigma_)
 
  571            : sigma(sigma_), a(a_), b(b_), m(a) {
 
  573                for (
size_t i = 0; i != a.size1(); ++i) { m(i, i) -= sigma; }
 
  578        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  587        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) { y = b * x; }
 
  589        const Matrix<T, ATYPE>& a;
 
  590        const Matrix<T, BTYPE>& b;
 
  591        Matrix<T, typename ATYPE::inverse> m;
 
  594    struct OPNN1 : 
public OP {
 
  595        OPNN1(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  596        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  601              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  602            for (
size_t i = 0; i != eigenvalue.size(); ++i) {
 
  603                eigenvalue[i] = T(1) / eigenvalue[i];
 
  606        const Matrix<T, ATYPE>& a;
 
  607        const Matrix<T, BTYPE>& b;
 
  610    struct OPNN1_shift : 
public OP {
 
  611        OPNN1_shift(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_, T sigma_)
 
  612            : sigma(sigma_), a(a_), b(b_), m(a) {
 
  614                for (
size_t i = 0; i != a.size1(); ++i) { m(i, i) -= sigma; }
 
  619        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  624              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  625            std::vector<std::pair<double, size_t> > tmp;
 
  626            for (
size_t i = 0; i != eigenvalue.size(); ++i) {
 
  627                eigenvalue[i] = sigma + T(1) / eigenvalue[i];
 
  628                tmp.push_back(std::pair<double, size_t>(b2000::real(eigenvalue[i]), tmp.size()));
 
  630            std::sort(tmp.begin(), tmp.end(), CompareFirstOfPair());
 
  631            Vector<T, Vdense> eigenvalue_tmp(eigenvalue.size());
 
  632            Matrix<T, Mrectangle> eigenvector_tmp(eigenvector.size1(), eigenvector.size2());
 
  633            for (
size_t i = 0; i != eigenvalue.size(); ++i) {
 
  634                eigenvalue_tmp[i] = eigenvalue[tmp[i].second];
 
  635                eigenvector_tmp[i] = eigenvector[tmp[i].second];
 
  637            eigenvalue = eigenvalue_tmp;
 
  638            eigenvector = Matrix<T, Mrectangle_increment_constref>(eigenvector_tmp);
 
  641        const Matrix<T, ATYPE>& a;
 
  642        const Matrix<T, BTYPE>& b;
 
  643        Matrix<T, typename ATYPE::inverse> m;
 
  646    struct OPNN2 : 
public OP {
 
  647        OPNN2(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  648        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  653        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {
 
  654            y = b * transposed(b) * x;
 
  657              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  658            Matrix<T, Mrectangle> tmp;
 
  660            eigenvector = transposed(b) * tmp;
 
  662        const Matrix<T, ATYPE>& a;
 
  663        const Matrix<T, BTYPE>& b;
 
  666    struct OPNN3 : 
public OP {
 
  667        OPNN3(
const Matrix<T, ATYPE>& a, 
const Matrix<T, BTYPE>& b_, T sigma) : b(b_), m(a) {
 
  669                for (
size_t i = 0; i != a.size1(); ++i) { m(i, i) -= sigma; }
 
  674        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  676                y = b * transposed(b) * x;
 
  684        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {
 
  685            y = b * transposed(b) * x;
 
  688              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  689            Matrix<T, Mrectangle> tmp;
 
  691            eigenvector = transposed(b) * tmp;
 
  693        const Matrix<T, BTYPE>& b;
 
  694        Matrix<T, typename ATYPE::inverse> m;
 
  697    struct OPNN3_0 : 
public OP {
 
  698        OPNN3_0(
const Matrix<T, ATYPE>& a_, 
const Matrix<T, BTYPE>& b_) : a(a_), b(b_) {}
 
  699        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
  701                y = b * transposed(b) * x;
 
  709        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {
 
  710            y = b * transposed(b) * x;
 
  713              Vector<T, Vdense_ref> eigenvalue, Matrix<T, Mrectangle_increment_ref> eigenvector) {
 
  714            Matrix<T, Mrectangle> tmp;
 
  716            eigenvector = transposed(b) * tmp;
 
  718        const Matrix<T, ATYPE>& a;
 
  719        const Matrix<T, BTYPE>& b;
 
  723template <
typename T, 
typename ATYPE, 
typename BTYPE>
 
  724void Matrix<T, Eigenvector<ATYPE, BTYPE> >::resolve(
 
  725      Matrix<T, Mrectangle_increment_ref>& eigenvector) {
 
  726    size_t size_ = a.size1();
 
  727    std::unique_ptr<OP> op;
 
  732            eigenvector(0, 0) = 1;
 
  733            eigenvalue[0] = a(0, 0);
 
  737        if (strcmp(which, 
"RA") == 0) {
 
  742                    op = std::unique_ptr<OP>(
new OPS1i(a));
 
  748                op = std::unique_ptr<OP>(
new OPS3(a, Matrix<T, BTYPE>::null, sigma));
 
  750        } 
else if (strcmp(which, 
"LA") == 0) {
 
  755                    op = std::unique_ptr<OP>(
new OPS1i(a));
 
  761                op = std::unique_ptr<OP>(
new OPS3(a, Matrix<T, BTYPE>::null, sigma));
 
  763        } 
else if (strcmp(which, 
"SM") == 0) {
 
  768                    op = std::unique_ptr<OP>(
new OPS1i(a));
 
  774                op = std::unique_ptr<OP>(
new OPS3(a, Matrix<T, BTYPE>::null, sigma));
 
  778            op = std::unique_ptr<OP>(
new OPS1(a));
 
  782            eigenvector(0, 0) = 1.0 / b(0, 0);
 
  783            eigenvalue[0] = a(0, 0) * eigenvector(0, 0);
 
  787        if (strcmp(which, 
"RA") == 0) {
 
  790                if ((type_b == 
'S' || type_b == 
'P') && type_a != 
'N') {
 
  792                    op = std::unique_ptr<OP>(
new OPS3_0(a, b));
 
  793                } 
else if ((type_a == 
'S' || type_a == 
'P') && type_b != 
'N') {
 
  795                    op = std::unique_ptr<OP>(
new OPS2i(a, b));
 
  796                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  800                    op = std::unique_ptr<OP>(
new OPNN1(a, b));
 
  805                if ((type_b == 
'S' || type_b == 
'P') && type_a != 
'N') {
 
  807                    op = std::unique_ptr<OP>(
new OPS3(a, b, sigma));
 
  808                } 
else if ((type_a == 
'S' || type_a == 
'P') && type_b != 
'N') {
 
  810                    op = std::unique_ptr<OP>(
new OPS4(a, b, sigma));
 
  811                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  815                    op = std::unique_ptr<OP>(
new OPNN1_shift(a, b, sigma));
 
  820        } 
else if (strcmp(which, 
"LA") == 0) {
 
  825                    op = std::unique_ptr<OP>(
new OPS2i(a, b));
 
  826                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  830                    op = std::unique_ptr<OP>(
new OPNN1(a, b));
 
  835                if (type_b == 
'S' || type_b == 
'P') {
 
  837                    op = std::unique_ptr<OP>(
new OPS3(a, b, sigma));
 
  838                } 
else if (type_a == 
'S' || type_a == 
'P') {
 
  840                    op = std::unique_ptr<OP>(
new OPS4(a, b, sigma));
 
  841                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  845                    op = std::unique_ptr<OP>(
new OPNN1_shift(a, b, sigma));
 
  850        } 
else if (strcmp(which, 
"SM") == 0) {
 
  853                if (type_b == 
'S' || type_b == 
'P') {
 
  855                    op = std::unique_ptr<OP>(
new OPS3_0(a, b));
 
  856                } 
else if (type_a == 
'S' || type_a == 
'P') {
 
  858                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  861                    op = std::unique_ptr<OP>(
new OPNN1(a, b));
 
  866                if (type_b == 
'S' || type_b == 
'P') {
 
  868                    op = std::unique_ptr<OP>(
new OPS3(a, b, sigma));
 
  869                } 
else if (type_a == 
'S' || type_a == 
'P') {
 
  871                    op = std::unique_ptr<OP>(
new OPS4(a, b, sigma));
 
  872                } 
else if (type_a == 
'N' && type_b == 
'N') {
 
  875                    op = std::unique_ptr<OP>(
new OPNN1_shift(a, b, sigma));
 
  883                op = std::unique_ptr<OP>(
new OPS2(a, b));
 
  891    Vector<T, Vdense> resid(size_);
 
  892    if (ncv == -1) { ncv = std::min(size_, eigenvalue.size() * 2 + 1); }
 
  893    if (
int(eigenvalue.size()) >= ncv) {
 
  894        Exception() << 
"Eigenvalue extraction: Number of required eigenvalues (" 
  895                    << eigenvalue.size() << 
") must be < number of DOFs (" << size_
 
  896                    << 
") of reduced system." << 
THROW;
 
  898    std::vector<T> vv(size_ * ncv);
 
  899    int iparam[11] = {1, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0};
 
  900    if (maxit > 0) { iparam[2] = maxit; }
 
  903    std::vector<T> workd(size_ * 3);
 
  904    size_t lworkl = ncv * (3 * ncv + 8);
 
  905    std::vector<T> workl(lworkl);
 
  906    std::vector<T> rwork(ncv);
 
  908    if (starting_eigenvector.is_null()) {
 
  912        resid = starting_eigenvector;
 
  917              ido, bmat, size_, which, eigenvalue.size(), tol, &resid[0], ncv, &vv[0], size_,
 
  918              iparam, ipntr, &workd[0], &workl[0], lworkl, &rwork[0], info);
 
  922                      Vector<T, Vdense_ref>(size_, &workd[ipntr[0] - 1]),
 
  923                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]),
 
  924                      Vector<T, Vdense_constref>(size_, 0));
 
  928                      Vector<T, Vdense_ref>(size_, &workd[ipntr[0] - 1]),
 
  929                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]),
 
  930                      Vector<T, Vdense_constref>(size_, &workd[ipntr[2] - 1]));
 
  934                      Vector<T, Vdense_constref>(size_, &workd[ipntr[0] - 1]),
 
  935                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]));
 
  948                           << 
"Eigenvalue extraction: Maximum number of iterations reached.\n" 
  949                           << 
"All possible eigenvalues (" << int(iparam[4]) << 
") have been found." 
  950                           << logging::LOGFLUSH;
 
  953                    if (
size_t(ncv) == size_) {
 
  954                        Exception() << 
"Eigenvalue extraction: No shifts could be applied during a " 
  956                                    << 
"of the implicitly restarted Arnoldi iteration." << 
THROW;
 
  959                           << 
"Eigenvalue extraction: No shifts could be applied during a cycle\n" 
  960                           << 
"of the implicitly restarted Arnoldi iteration. Retry by increasing " 
  962                           << logging::LOGFLUSH;
 
  963                    ncv = std::min(size_, ncv + eigenvalue.size());
 
  964                    vv.resize(size_ * ncv);
 
  965                    lworkl = ncv * (3 * ncv + 8);
 
  966                    workl.resize(lworkl);
 
  972                    if (
size_t(iparam[4]) < eigenvalue.size() + 2) {
 
  973                        Exception() << 
"Eigenvalue extraction: Could not build an Arnoldi " 
  975                                    << 
"All possible eigenvalues (" << int(iparam[4])
 
  976                                    << 
") have been found." << 
THROW;
 
  979                           << 
"Eigenvalue extraction: Could not build an Arnoldi factorization.\n" 
  980                              "Retry by reducing the NCV" 
  981                           << logging::LOGFLUSH;
 
  982                    ncv = std::min(
int(size_), iparam[4]);
 
  983                    vv.resize(size_ * ncv);
 
  984                    lworkl = ncv * (3 * ncv + 8);
 
  985                    workl.resize(lworkl);
 
  991                    Exception() << 
"Eigenvalue extraction: arpack eigenvalue extraction failed, " 
  993                                << 
info << 
".\nPossible reason: B matrix is 0." << 
THROW;
 
  998    std::vector<int> select(ncv);
 
  999    std::vector<T> D(eigenvalue.size() + 1);
 
 1001          eigenvector.is_null() ? 0 : 1, 
"A", &select[0], &D[0], eigenvector.m, eigenvector.ldm,
 
 1002          sigma, bmat, size_, which, eigenvalue.size(), tol, &resid[0], ncv, &vv[0], size_, iparam,
 
 1003          ipntr, &workd[0], &workl[0], lworkl, &rwork[0], 
info);
 
 1004    std::copy(D.begin(), D.end() - 1, eigenvalue.v);
 
 1006        Exception() << 
"Eigenvalue extraction: arpack eigenvalue extraction failed, eupd error=" 
 1009    op->end(eigenvalue, eigenvector);
 
 1012template <
typename T, 
typename ATYPE, 
typename VTYPE1>
 
 1013Matrix<T, Eigenvector<ATYPE, ATYPE> > eigenvector(
 
 1014      const Matrix<T, ATYPE>& a, 
char type_a, Vector<T, VTYPE1>& eigenvalue,
 
 1015      const char which[2] = 
"SM", T sigma = 0, 
int ncv = -1, 
double tol = -1, 
int maxit = -1) {
 
 1016    return Matrix<T, Eigenvector<ATYPE, ATYPE> >(
 
 1017          a, type_a, Matrix<T, ATYPE>::null, 
' ', eigenvalue, which, sigma, ncv, tol, maxit,
 
 1018          Vector<T, Vdense_constref>::null);
 
 1021template <
typename T, 
typename ATYPE, 
typename VTYPE1, 
typename VTYPE2>
 
 1022Matrix<T, Eigenvector<ATYPE, ATYPE> > eigenvector(
 
 1023      const Matrix<T, ATYPE>& a, 
char type_a, Vector<T, VTYPE1>& eigenvalue,
 
 1024      const char which[2] = 
"SM", T sigma = 0, 
int ncv = -1, 
double tol = -1, 
int maxit = -1,
 
 1025      const Vector<T, VTYPE2>& starting_eigenvector = Vector<T, VTYPE2>::null) {
 
 1026    return Matrix<T, Eigenvector<ATYPE, ATYPE> >(
 
 1027          a, type_a, Matrix<T, ATYPE>::null, 
' ', eigenvalue, which, sigma, ncv, tol, maxit,
 
 1028          starting_eigenvector.is_null()
 
 1029                ? Vector<T, Vdense_constref>::null
 
 1030                : 
static_cast<const Vector<T, Vdense_constref>&
>(starting_eigenvector));
 
 1055template <
typename T, 
typename ATYPE, 
typename BTYPE, 
typename VTYPE1>
 
 1056Matrix<T, Eigenvector<ATYPE, BTYPE> > eigenvector(
 
 1057      const Matrix<T, ATYPE>& a, 
char type_a, 
const Matrix<T, BTYPE>& b, 
char type_b,
 
 1058      Vector<T, VTYPE1>& eigenvalue, 
const char which[2] = 
"SM", T sigma = 0, 
int ncv = -1,
 
 1059      double tol = -1, 
int maxit = -1) {
 
 1060    return Matrix<T, Eigenvector<ATYPE, BTYPE> >(
 
 1061          a, type_a, b, type_b, eigenvalue, which, sigma, ncv, tol, maxit,
 
 1062          Vector<T, Vdense_constref>::null);
 
 1065template <
typename T, 
typename ATYPE, 
typename BTYPE, 
typename VTYPE1>
 
 1066Matrix<T, Eigenvector<ATYPE, BTYPE> > eigenvector(
 
 1067      const Matrix<T, ATYPE>& a, 
char type_a, 
const std::vector<Matrix<T, BTYPE> >& b, 
char type_b,
 
 1068      Vector<T, VTYPE1>& eigenvalue, 
const char which[2] = 
"SM", T sigma = 0, 
int ncv = -1,
 
 1069      double tol = -1, 
int maxit = -1) {
 
 1070    return Matrix<T, Eigenvector<ATYPE, BTYPE> >(
 
 1071          a, type_a, b, type_b, eigenvalue, which, sigma, ncv, tol, maxit,
 
 1072          Vector<T, Vdense_constref>::null);
 
 1075template <
typename T, 
typename ATYPE, 
typename BTYPE, 
typename VTYPE1, 
typename VTYPE2>
 
 1076Matrix<T, Eigenvector<ATYPE, BTYPE> > eigenvector(
 
 1077      const Matrix<T, ATYPE>& a, 
char type_a, 
const Matrix<T, BTYPE>& b, 
char type_b,
 
 1078      Vector<T, VTYPE1>& eigenvalue, 
const char which[2] = 
"SM", T sigma = 0, 
int ncv = -1,
 
 1079      double tol = -1, 
int maxit = -1,
 
 1080      const Vector<T, VTYPE2>& starting_eigenvector = Vector<T, VTYPE2>::null) {
 
 1081    return Matrix<T, Eigenvector<ATYPE, BTYPE> >(
 
 1082          a, type_a, b, type_b, eigenvalue, which, sigma, ncv, tol, maxit,
 
 1083          starting_eigenvector.is_null()
 
 1084                ? Vector<T, Vdense_constref>::null
 
 1085                : 
static_cast<const Vector<T, Vdense_constref>&
>(starting_eigenvector));
 
 1088template <
typename ATYPE, 
typename BTYPE>
 
 1089struct PolyEigenvector {
 
 1090    using base = PolyEigenvector;
 
 1091    using const_base = PolyEigenvector;
 
 1094template <
typename T, 
typename ATYPE, 
typename BTYPE>
 
 1095class Matrix<T, PolyEigenvector<ATYPE, BTYPE> > {
 
 1098          const Matrix<T, ATYPE>& a_, 
const char type_a_, 
const std::vector<Matrix<T, BTYPE> >& b_,
 
 1099          const char type_b_, Vector<T, Vdense_ref> eigenvalue_r,
 
 1100          Vector<T, Vdense_ref> eigenvalue_i, 
const char which_[2], T sigma_, 
int ncv_, 
double tol_,
 
 1101          int maxit_, 
const Vector<T, Vdense_constref> starting_eigenvector_)
 
 1106          eigenvaluer(eigenvalue_r),
 
 1107          eigenvaluei(eigenvalue_i),
 
 1112          starting_eigenvector(starting_eigenvector_) {
 
 1113        for (
size_t i = 0; i != b.size(); ++i) {
 
 1114            if (a.size() != b[i].size()) {
 
 1115                Exception() << 
"The two matrices are not of the same size." << 
THROW;
 
 1118        if (!starting_eigenvector.is_null()
 
 1119            && starting_eigenvector.size() != a.size1() * b.size()) {
 
 1120            Exception() << 
"The starting eigenvalue vector is not of the same size than the matrix." 
 1123        strcpy(which, which_);
 
 1124        if (tol < 0) { tol = 0; }
 
 1127    std::pair<size_t, size_t> size()
 const {
 
 1128        return std::pair<size_t, size_t>(a.size1(), eigenvaluer.size());
 
 1131    size_t size1()
 const { 
return a.size1(); }
 
 1133    size_t size2()
 const { 
return eigenvaluer.size(); }
 
 1135    void resolve(Matrix<T, Mrectangle_increment_ref>& eigenvector);
 
 1138    const Matrix<T, ATYPE>& a;
 
 1140    const std::vector<Matrix<T, BTYPE> >& b;
 
 1142    Vector<T, Vdense_ref> eigenvaluer;
 
 1143    Vector<T, Vdense_ref> eigenvaluei;
 
 1149    Vector<T, Vdense_constref> starting_eigenvector;
 
 1154              Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {}
 
 1155        virtual void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {}
 
 1157              Vector<T, Vdense_ref> eigenvaluer, Vector<T, Vdense_ref> eigenvaluei,
 
 1158              Matrix<T, Mrectangle_increment_ref> eigenvector) {}
 
 1161    struct OP1 : 
public OP {
 
 1162        OP1(
const Matrix<T, ATYPE>& a_, 
const std::vector<Matrix<T, BTYPE> >& b_) : a(a_), b(b_) {}
 
 1163        void op(Vector<T, Vdense_ref> x, Vector<T, Vdense_ref> y, Vector<T, Vdense_constref> Bx) {
 
 1164            size_t s = a.size1();
 
 1165            y(Interval(0, s)) = b[0] * x(Interval(0, s));
 
 1166            for (
size_t i = 1; i < b.size(); ++i) {
 
 1167                y(Interval(0, s)) += b[i] * x(Interval(i * s, (i + 1) * s));
 
 1169            for (
size_t i = 1; i < b.size(); ++i) {
 
 1170                y(Interval(i * s, (i + 1) * s)) = x(Interval((i - 1) * s, i * s));
 
 1172            y(Interval(0, s)) = inverse(a) * y(Interval(0, s));
 
 1174        void prod_b(Vector<T, Vdense_constref> x, Vector<T, Vdense_ref> y) {
 
 1175            size_t s = a.size1();
 
 1176            y(Interval(0, s)) = a * x(Interval(0, s));
 
 1177            y(Interval(s, y.size())) = x(Interval(s, x.size()));
 
 1179        const Matrix<T, ATYPE>& a;
 
 1180        const std::vector<Matrix<T, BTYPE> >& b;
 
 1184template <
typename T, 
typename ATYPE, 
typename BTYPE>
 
 1185void Matrix<T, PolyEigenvector<ATYPE, BTYPE> >::resolve(
 
 1186      Matrix<T, Mrectangle_increment_ref>& eigenvector) {
 
 1187    size_t size_ = a.size1() * b.size();
 
 1188    if (eigenvaluer.size() > size_ - 2) {
 
 1191                             << eigenvaluer.size() << 
" is too large for the size " << size_
 
 1192                             << 
" of problem." << 
THROW;
 
 1194    std::unique_ptr<OP> op;
 
 1199    if (sigma == T(0)) {
 
 1200        if (type_a == 
'P') {
 
 1203            op = std::unique_ptr<OP>(
new OP1(a, b));
 
 1204            if (strcmp(which, 
"SM") == 0) {
 
 1205                strcpy(which, 
"LM");
 
 1206            } 
else if (strcmp(which, 
"RA") == 0) {
 
 1207                strcpy(which, 
"LR");
 
 1219    Vector<T, Vdense> resid(size_);
 
 1220    if (ncv == -1) { ncv = std::min(size_, eigenvaluer.size() * 2 + 1); }
 
 1221    std::vector<T> vv(size_ * (ncv + 1));
 
 1222    int iparam[11] = {1, 0, 300, 1, 0, 0, 0, 0, 0, 0, 0};
 
 1223    if (maxit > 0) { iparam[2] = maxit; }
 
 1226    std::vector<T> workd(size_ * 3);
 
 1227    size_t lworkl = ncv * (3 * ncv + 8);
 
 1228    std::vector<T> workl(lworkl);
 
 1229    std::vector<T> rwork(ncv);
 
 1231    if (starting_eigenvector.is_null()) {
 
 1235        resid = starting_eigenvector;
 
 1240              ido, bmat, size_, which, eigenvaluer.size(), tol, &resid[0], ncv, &vv[0], size_,
 
 1241              iparam, ipntr, &workd[0], &workl[0], lworkl, &rwork[0], info);
 
 1245                      Vector<T, Vdense_ref>(size_, &workd[ipntr[0] - 1]),
 
 1246                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]),
 
 1247                      Vector<T, Vdense_constref>(size_, 0));
 
 1251                      Vector<T, Vdense_ref>(size_, &workd[ipntr[0] - 1]),
 
 1252                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]),
 
 1253                      Vector<T, Vdense_constref>(size_, &workd[ipntr[2] - 1]));
 
 1257                      Vector<T, Vdense_constref>(size_, &workd[ipntr[0] - 1]),
 
 1258                      Vector<T, Vdense_ref>(size_, &workd[ipntr[1] - 1]));
 
 1271                           << 
"Eigenvalue extraction: Maximum number of iterations reached\n." 
 1272                           << 
"All possible eigenvalues (" << int(iparam[4]) << 
") have been found." 
 1273                           << logging::LOGFLUSH;
 
 1276                    if (
size_t(ncv) == size_) {
 
 1277                        Exception() << 
"Eigenvalue extraction: No shifts could be applied during a " 
 1279                                    << 
"of the implicitly restarted Arnoldi iteration." << 
THROW;
 
 1282                           << 
"Eigenvalue extraction: No shifts could be applied during a cycle of " 
 1284                           << 
"restarted Arnoldi iteration. Retry by increasing NCV." 
 1285                           << logging::LOGFLUSH;
 
 1286                    ncv = std::min(size_, ncv + eigenvaluer.size());
 
 1287                    vv.resize(size_ * ncv);
 
 1288                    lworkl = ncv * (3 * ncv + 8);
 
 1289                    workl.resize(lworkl);
 
 1295                    if (
size_t(iparam[4]) < eigenvaluer.size() + 2) {
 
 1296                        Exception() << 
"Eigenvalue extraction: Could not build an Arnoldi " 
 1298                                    << 
"All possible eigenvalues (" << int(iparam[4])
 
 1299                                    << 
") have been found." << 
THROW;
 
 1302                           << 
"Eigenvalue extraction: Could not build an Arnoldi factorization.\n" 
 1303                              " Retry by reducing the NCV" 
 1304                           << logging::LOGFLUSH;
 
 1305                    ncv = std::min(
int(size_), iparam[4]);
 
 1306                    vv.resize(size_ * ncv);
 
 1307                    lworkl = ncv * (3 * ncv + 8);
 
 1308                    workl.resize(lworkl);
 
 1314                    Exception() << 
"Eigenvalue extraction: arpack subroutine aupd error=" << 
info 
 1315                                << 
".\nPossible reason: B matrix is 0." << 
THROW;
 
 1319    } 
while (ido != 99);
 
 1320    std::vector<int> select(ncv);
 
 1321    std::vector<T> Dr(eigenvaluer.size() + 1);
 
 1322    std::vector<T> Di(eigenvaluei.size() + 1);
 
 1323    std::vector<T> workev(3 * ncv);
 
 1324    Matrix<T, Mrectangle> eigenvector_tmp(size_, eigenvaluer.size() + 1);
 
 1326          eigenvector.is_null() ? 0 : 1, 
"A", &select[0], &Dr[0], &Di[0], &eigenvector_tmp.m[0],
 
 1327          size_, sigma, 0, &workev[0], bmat, size_, which, eigenvaluer.size(), tol, &resid[0], ncv,
 
 1328          &vv[0], size_, iparam, ipntr, &workd[0], &workl[0], lworkl, &rwork[0], 
info);
 
 1331          eigenvector_tmp(Interval(0, eigenvector.size1()), Interval(0, eigenvector.size2()));
 
 1333        for (
size_t i = 0; i != eigenvaluer.size(); ++i) {
 
 1334            const double d = 1 / (Dr[i] * Dr[i] + Di[i] * Di[i]);
 
 1335            eigenvaluer[i] = Dr[i] * d;
 
 1336            eigenvaluei[i] = -Di[i] * d;
 
 1339        std::copy(Dr.begin(), Dr.end() - 1, eigenvaluer.v);
 
 1340        std::copy(Di.begin(), Di.end() - 1, eigenvaluei.v);
 
 1343        Exception() << 
"Eigenvalue extraction: Error with the arpack subroutine eupd, info = " 
 1346    op->end(eigenvaluer, eigenvaluei, eigenvector);
 
 1371template <
typename T, 
typename ATYPE, 
typename BTYPE, 
typename VTYPE1>
 
 1372Matrix<T, PolyEigenvector<ATYPE, BTYPE> > eigenvector(
 
 1373      const Matrix<T, ATYPE>& a, 
char type_a, 
const std::vector<Matrix<T, BTYPE> >& b, 
char type_b,
 
 1374      Vector<T, VTYPE1>& eigenvalue_r, Vector<T, VTYPE1>& eigenvalue_i, 
const char which[2] = 
"SM",
 
 1375      T sigma = 0, 
int ncv = -1, 
double tol = -1, 
int maxit = -1) {
 
 1376    return Matrix<T, PolyEigenvector<ATYPE, BTYPE> >(
 
 1377          a, type_a, b, type_b, eigenvalue_r, eigenvalue_i, which, sigma, ncv, tol, maxit,
 
 1378          Vector<T, Vdense_constref>::null);
 
 1381template <
typename T>
 
 1382void copy_real(
const Matrix<b2000::csda<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1383    out.resize(in.size());
 
 1384    const b2000::csda<T>* pin = &in(0, 0);
 
 1385    T* pout = &out(0, 0);
 
 1386    const T* pout_end = pout + out.size1() * out.size2();
 
 1387    for (; pout != pout_end; ++pin, ++pout) { *pout = real(*pin); }
 
 1390template <
typename T>
 
 1391void copy_real(
const Matrix<std::complex<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1392    out.resize(in.size());
 
 1393    const std::complex<T>* pin = &in(0, 0);
 
 1394    T* pout = &out(0, 0);
 
 1395    const T* pout_end = pout + out.size1() * out.size2();
 
 1396    for (; pout != pout_end; ++pin, ++pout) { *pout = real(*pin); }
 
 1399template <
typename T>
 
 1400void copy_imag(
const Matrix<b2000::csda<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1401    out.resize(in.size());
 
 1402    const b2000::csda<T>* pin = &in(0, 0);
 
 1403    T* pout = &out(0, 0);
 
 1404    const T* pout_end = pout + out.size1() * out.size2();
 
 1405    for (; pout != pout_end; ++pin, ++pout) { *pout = imag(*pin); }
 
 1408template <
typename T>
 
 1409void copy_imag(
const Matrix<std::complex<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1410    out.resize(in.size());
 
 1411    const std::complex<T>* pin = &in(0, 0);
 
 1412    T* pout = &out(0, 0);
 
 1413    const T* pout_end = pout + out.size1() * out.size2();
 
 1414    for (; pout != pout_end; ++pin, ++pout) { *pout = imag(*pin); }
 
 1417template <
typename T>
 
 1418void copy(
const Matrix<b2000::csda<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1419    out.resize(in.size());
 
 1420    const b2000::csda<T>* pin = &in(0, 0);
 
 1421    T* pout = &out(0, 0);
 
 1422    const T* pout_end = pout + out.size1() * out.size2();
 
 1423    for (; pout != pout_end; ++pin, ++pout) { *pout = real(*pin); }
 
 1426template <
typename T>
 
 1427void copy(
const Matrix<std::complex<T>, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
 1428    out.resize(in.size());
 
 1429    const std::complex<T>* pin = &in(0, 0);
 
 1430    T* pout = &out(0, 0);
 
 1431    const T* pout_end = pout + out.size1() * out.size2();
 
 1432    for (; pout != pout_end; ++pin, ++pout) { *pout = real(*pin); }
 
 1435template <
typename T>
 
 1436void copy(
const Matrix<T, Mrectangle_constref>& in, Matrix<b2000::csda<T>, Mrectangle>& out) {
 
 1437    out.resize(in.size());
 
 1438    const T* pin = &in(0, 0);
 
 1439    b2000::csda<T>* pout = &out(0, 0);
 
 1440    const b2000::csda<T>* pout_end = pout + out.size1() * out.size2();
 
 1441    for (; pout != pout_end; ++pin, ++pout) { *pout = b2000::csda<T>(*pin); }
 
 1444template <
typename T>
 
 1445void copy(
const Matrix<T, Mrectangle_constref>& in, Matrix<std::complex<T>, Mrectangle>& out) {
 
 1446    out.resize(in.size());
 
 1447    const T* pin = &in(0, 0);
 
 1448    std::complex<T>* pout = &out(0, 0);
 
 1449    const std::complex<T>* pout_end = pout + out.size1() * out.size2();
 
 1450    for (; pout != pout_end; ++pin, ++pout) { *pout = std::complex<T>(*pin); }
 
 1453template <
typename T>
 
 1454void copy(
const Matrix<T, Mrectangle_constref>& in, Matrix<T, Mrectangle>& out) {
 
#define THROW
Definition b2exception.H:198
 
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829
 
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314