GetFEM  5.5
gmm_dense_sylvester.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2003-2026 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program. If not, see https://www.gnu.org/licenses/.
19 
20  As a special exception, you may use this file as it is a part of a free
21  software library without restriction. Specifically, if other files
22  instantiate templates or use macros or inline functions from this file,
23  or you compile this file and link it with other files to produce an
24  executable, this file does not by itself cause the resulting executable
25  to be covered by the GNU Lesser General Public License. This exception
26  does not however invalidate any other reasons why the executable file
27  might be covered by the GNU Lesser General Public License.
28 
29 ===========================================================================*/
30 
31 /** @file gmm_dense_sylvester.h
32  @author Yves Renard <Yves.Renard@insa-lyon.fr>
33  @date June 5, 2003.
34  @brief Sylvester equation solver.
35 */
36 #ifndef GMM_DENSE_SYLVESTER_H
37 #define GMM_DENSE_SYLVESTER_H
38 
39 #include "gmm_kernel.h"
40 
41 namespace gmm {
42 
43  /* ********************************************************************* */
44  /* Kronecker system matrix. */
45  /* ********************************************************************* */
46  template <typename MAT1, typename MAT2, typename MAT3>
47  void kron(const MAT1 &m1, const MAT2 &m2, const MAT3 &m3_,
48  bool init = true) {
49  MAT3 &m3 = const_cast<MAT3 &>(m3_);
50  size_type m = mat_nrows(m1), n = mat_ncols(m1);
51  size_type l = mat_nrows(m2), k = mat_ncols(m2);
52 
53  GMM_ASSERT2(mat_nrows(m3) == m*l && mat_ncols(m3) == n*k,
54  "dimensions mismatch");
55 
56  for (size_type i = 0; i < m; ++i)
57  for (size_type j = 0; j < m; ++j)
58  if (init)
59  gmm::copy(gmm::scaled(m2, m1(i,j)),
60  gmm::sub_matrix(m3, sub_interval(l*i, l),
61  sub_interval(k*j, k)));
62  else
63  gmm::add(gmm::scaled(m2, m1(i,j)),
64  gmm::sub_matrix(m3, sub_interval(l*i, l),
65  sub_interval(k*j, k)));
66  }
67 
68 
69  /* ********************************************************************* */
70  /* Copy a matrix into a vector. */
71  /* ********************************************************************* */
72 
73  template <typename MAT, typename VECT>
74  colmatrix_to_vector(const MAT &A, VECT &v, col_major) {
75  size_type m = mat_nrows(A), n = mat_ncols(A);
76  GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch");
77  for (size_type i = 0; i < n; ++i)
78  gmm::copy(mat_col(A, i), sub_vector(v, sub_interval(i*m, m)));
79  }
80 
81  template <typename MAT, typename VECT>
82  colmatrix_to_vector(const MAT &A, VECT &v, row_and_col)
83  { colmatrix_to_vector(A, v, col_major()); }
84 
85  template <typename MAT, typename VECT>
86  colmatrix_to_vector(const MAT &A, VECT &v, col_and_row)
87  { colmatrix_to_vector(A, v, col_major()); }
88 
89  template <typename MAT, typename VECT>
90  colmatrix_to_vector(const MAT &A, VECT &v, row_major) {
91  size_type m = mat_nrows(mat), n = mat_ncols(A);
92  GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch");
93  for (size_type i = 0; i < m; ++i)
94  gmm::copy(mat_row(A, i), sub_vector(v, sub_slice(i, n, m)));
95  }
96 
97  template <typename MAT, typename VECT> inline
98  colmatrix_to_vector(const MAT &A, const VECT &v_) {
99  VECT &v = const_cast<VECT &>(v_);
100  colmatrix_to_vector(A, v, typename linalg_traits<MAT>::sub_orientation());
101  }
102 
103 
104  /* ********************************************************************* */
105  /* Copy a vector into a matrix. */
106  /* ********************************************************************* */
107 
108  template <typename MAT, typename VECT>
109  vector_to_colmatrix(const VECT &v, MAT &A, col_major) {
110  size_type m = mat_nrows(A), n = mat_ncols(A);
111  GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch");
112  for (size_type i = 0; i < n; ++i)
113  gmm::copy(sub_vector(v, sub_interval(i*m, m)), mat_col(A, i));
114  }
115 
116  template <typename MAT, typename VECT>
117  vector_to_colmatrix(const VECT &v, MAT &A, row_and_col)
118  { vector_to_colmatrix(v, A, col_major()); }
119 
120  template <typename MAT, typename VECT>
121  vector_to_colmatrix(const VECT &v, MAT &A, col_and_row)
122  { vector_to_colmatrix(v, A, col_major()); }
123 
124  template <typename MAT, typename VECT>
125  vector_to_colmatrix(const VECT &v, MAT &A, row_major) {
126  size_type m = mat_nrows(mat), n = mat_ncols(A);
127  GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch");
128  for (size_type i = 0; i < m; ++i)
129  gmm::copy(sub_vector(v, sub_slice(i, n, m)), mat_row(A, i));
130  }
131 
132  template <typename MAT, typename VECT> inline
133  vector_to_colmatrix(const VECT &v, const MAT &A_) {
134  MAT &A = const_cast<MAT &>(A_);
135  vector_to_colmatrix(v, A, typename linalg_traits<MAT>::sub_orientation());
136  }
137 
138  /* ********************************************************************* */
139  /* Solve sylvester equation. */
140  /* ********************************************************************* */
141 
142  // very prohibitive solver, to be replaced ...
143  template <typename MAT1, typename MAT2, typename MAT3, typename MAT4 >
144  void sylvester(const MAT1 &m1, const MAT2 &m2, const MAT3 &m3,
145  const MAT4 &m4_) {
146  typedef typename linalg_traits<Mat>::value_type T;
147 
148  MAT3 &m4 = const_cast<MAT4 &>(m4_);
149  size_type m = mat_nrows(m1), n = mat_ncols(m1);
150  size_type l = mat_nrows(m2), k = mat_ncols(m2);
151 
152  GMM_ASSERT2(m == n && l == k && m == mat_nrows(m3) &&
153  l == mat_ncols(m3) && m == mat_nrows(m4) && l == mat_ncols(m4),
154  "dimensions mismatch");
155 
156  gmm::dense_matrix<T> akronb(m*l, m*l);
157  gmm::dense_matrix<T> idm(m, m), idl(l,l);
158  gmm::copy(identity_matrix(), idm);
159  gmm::copy(identity_matrix(), idl);
160  std::vector<T> x(m*l), c(m*l);
161 
162  kron(idl, m1, akronb);
163  kron(gmm::transposed(m2), idm, akronb, false);
164 
165  colmatrix_to_vector(m3, c);
166  lu_solve(akronb, c, x);
167  vector_to_colmatrix(x, m4);
168 
169  }
170 }
171 
172 #endif
173 
void copy(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:976
void add(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:1275
void lu_solve(const DenseMatrix &LU, const Pvector &pvector, VectorX &x, const VectorB &b)
LU Solve : Solve equation Ax=b, given an LU factored matrix.
Definition: gmm_dense_lu.h:129
Include the base gmm files.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48