PolyFEM
Loading...
Searching...
No Matches
MatrixUtils.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <Eigen/Dense>
6#include <Eigen/Sparse>
7
8namespace polyfem
9{
10 namespace utils
11 {
12 // Show some stats about the matrix M: det, singular values, condition number, etc
13 void show_matrix_stats(const Eigen::MatrixXd &M);
14
15 template <typename T>
16 T matrix_inner_product(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &A, const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &B)
17 {
18 return (A.array() * B.array()).sum();
19 }
20
21 template <typename T, int rows, int cols, int option, int maxRow, int maxCol>
22 T determinant(const Eigen::Matrix<T, rows, cols, option, maxRow, maxCol> &mat)
23 {
24 assert(mat.rows() == mat.cols());
25
26 if (mat.rows() == 1)
27 return mat(0);
28 else if (mat.rows() == 2)
29 return mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
30 else if (mat.rows() == 3)
31 return mat(0, 0) * (mat(1, 1) * mat(2, 2) - mat(1, 2) * mat(2, 1)) - mat(0, 1) * (mat(1, 0) * mat(2, 2) - mat(1, 2) * mat(2, 0)) + mat(0, 2) * (mat(1, 0) * mat(2, 1) - mat(1, 1) * mat(2, 0));
32
33 assert(false);
34 return T(0);
35 }
36
37 template <typename T>
38 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> inverse(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> &mat)
39 {
40 assert(mat.rows() == mat.cols());
41
42 if (mat.rows() == 1)
43 {
44 Eigen::Matrix<T, 1, 1> inv;
45 inv(0, 0) = T(1.) / mat(0);
46
47 return inv;
48 }
49 else if (mat.rows() == 2)
50 {
51 Eigen::Matrix<T, 2, 2> inv;
52 T det = determinant(mat);
53 inv(0, 0) = mat(1, 1) / det;
54 inv(0, 1) = -mat(0, 1) / det;
55 inv(1, 0) = -mat(1, 0) / det;
56 inv(1, 1) = mat(0, 0) / det;
57
58 return inv;
59 }
60 else if (mat.rows() == 3)
61 {
62 Eigen::Matrix<T, 3, 3> inv;
63 T det = determinant(mat);
64 inv(0, 0) = (-mat(1, 2) * mat(2, 1) + mat(1, 1) * mat(2, 2)) / det;
65 inv(0, 1) = (mat(0, 2) * mat(2, 1) - mat(0, 1) * mat(2, 2)) / det;
66 inv(0, 2) = (-mat(0, 2) * mat(1, 1) + mat(0, 1) * mat(1, 2)) / det;
67 inv(1, 0) = (mat(1, 2) * mat(2, 0) - mat(1, 0) * mat(2, 2)) / det;
68 inv(1, 1) = (-mat(0, 2) * mat(2, 0) + mat(0, 0) * mat(2, 2)) / det;
69 inv(1, 2) = (mat(0, 2) * mat(1, 0) - mat(0, 0) * mat(1, 2)) / det;
70 inv(2, 0) = (-mat(1, 1) * mat(2, 0) + mat(1, 0) * mat(2, 1)) / det;
71 inv(2, 1) = (mat(0, 1) * mat(2, 0) - mat(0, 0) * mat(2, 1)) / det;
72 inv(2, 2) = (-mat(0, 1) * mat(1, 0) + mat(0, 0) * mat(1, 1)) / det;
73
74 return inv;
75 }
76
77 assert(false);
78 Eigen::Matrix<T, 1, 1> inv;
79 inv(0, 0) = T(0);
80 return inv;
81 }
82
83 inline Eigen::SparseMatrix<double> sparse_identity(int rows, int cols)
84 {
85 Eigen::SparseMatrix<double> I(rows, cols);
86 I.setIdentity();
87 return I;
88 }
89
91 Eigen::VectorXd flatten(const Eigen::MatrixXd &X);
92
94 Eigen::MatrixXd unflatten(const Eigen::VectorXd &x, int dim);
95
96 void vector2matrix(const Eigen::VectorXd &vec, Eigen::MatrixXd &mat);
97
101 Eigen::SparseMatrix<double> lump_matrix(const Eigen::SparseMatrix<double> &M);
102
107 Eigen::SparseMatrix<double> lump_matrix_hrz(const Eigen::SparseMatrix<double> &M);
108
116 const int full_size,
117 const int reduced_size,
118 const std::vector<int> &removed_vars,
119 const StiffnessMatrix &full,
120 StiffnessMatrix &reduced);
121
128 Eigen::MatrixXd reorder_matrix(
129 const Eigen::MatrixXd &in,
130 const Eigen::VectorXi &in_to_out,
131 int out_blocks = -1,
132 const int block_size = 1);
133
140 Eigen::MatrixXd unreorder_matrix(
141 const Eigen::MatrixXd &out,
142 const Eigen::VectorXi &in_to_out,
143 int in_blocks = -1,
144 const int block_size = 1);
145
150 Eigen::MatrixXi map_index_matrix(
151 const Eigen::MatrixXi &in,
152 const Eigen::VectorXi &index_mapping);
153
154 template <typename DstMat, typename SrcMat>
155 void append_rows(DstMat &dst, const SrcMat &src)
156 {
157 if (src.rows() == 0)
158 return;
159 if (dst.cols() == 0)
160 dst.resize(dst.rows(), src.cols());
161 assert(dst.cols() == src.cols());
162 dst.conservativeResize(dst.rows() + src.rows(), dst.cols());
163 dst.bottomRows(src.rows()) = src;
164 }
165
166 template <typename DstMat>
167 void append_rows_of_zeros(DstMat &dst, const size_t n_zero_rows)
168 {
169 assert(dst.cols() > 0);
170 if (n_zero_rows == 0)
171 return;
172 dst.conservativeResize(dst.rows() + n_zero_rows, dst.cols());
173 dst.bottomRows(n_zero_rows).setZero();
174 }
175
176 void scatter_matrix(const int n_dofs,
177 const int dim,
178 const Eigen::MatrixXd &A,
179 const Eigen::MatrixXd &b,
180 const std::vector<int> &local_to_global,
181 StiffnessMatrix &Aout,
182 Eigen::MatrixXd &bout);
183
184 void scatter_matrix_col(const int n_dofs,
185 const int dim,
186 const Eigen::MatrixXd &A,
187 const Eigen::MatrixXd &b,
188 const std::vector<int> &local_to_global,
189 StiffnessMatrix &Aout,
190 Eigen::MatrixXd &bout);
191
192 void scatter_matrix(const int n_dofs,
193 const int dim,
194 const std::vector<long> &shape,
195 const std::vector<int> &rows,
196 const std::vector<int> &cols,
197 const std::vector<double> &vals,
198 const Eigen::MatrixXd &b,
199 const std::vector<int> &local_to_global,
200 StiffnessMatrix &Aout,
201 Eigen::MatrixXd &bout);
202
203 void scatter_matrix_col(const int n_dofs,
204 const int dim,
205 const std::vector<long> &shape,
206 const std::vector<int> &rows,
207 const std::vector<int> &cols,
208 const std::vector<double> &vals,
209 const Eigen::MatrixXd &b,
210 const std::vector<int> &local_to_global,
211 StiffnessMatrix &Aout,
212 Eigen::MatrixXd &bout);
213 } // namespace utils
214} // namespace polyfem
Eigen::MatrixXd vec
Definition Assembler.cpp:75
ElementAssemblyValues vals
Definition Assembler.cpp:25
int x
T matrix_inner_product(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &A, const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &B)
Eigen::SparseMatrix< double > lump_matrix(const Eigen::SparseMatrix< double > &M)
Lump each row of a matrix into the diagonal.
void show_matrix_stats(const Eigen::MatrixXd &M)
Eigen::MatrixXd reorder_matrix(const Eigen::MatrixXd &in, const Eigen::VectorXi &in_to_out, int out_blocks=-1, const int block_size=1)
Reorder row blocks in a matrix.
Eigen::SparseMatrix< double > lump_matrix_hrz(const Eigen::SparseMatrix< double > &M)
Lump a (mass) matrix HRZ-style: keep the diagonal, scaled by a common factor so the total (sum of all...
Eigen::SparseMatrix< double > sparse_identity(int rows, int cols)
void vector2matrix(const Eigen::VectorXd &vec, Eigen::MatrixXd &mat)
void scatter_matrix(const int n_dofs, const int dim, const Eigen::MatrixXd &A, const Eigen::MatrixXd &b, const std::vector< int > &local_to_global, StiffnessMatrix &Aout, Eigen::MatrixXd &bout)
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > inverse(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > &mat)
Eigen::MatrixXd unreorder_matrix(const Eigen::MatrixXd &out, const Eigen::VectorXi &in_to_out, int in_blocks=-1, const int block_size=1)
Undo the reordering of row blocks in a matrix.
Eigen::MatrixXd unflatten(const Eigen::VectorXd &x, int dim)
Unflatten rowwises, so every dim elements in x become a row.
void append_rows_of_zeros(DstMat &dst, const size_t n_zero_rows)
void append_rows(DstMat &dst, const SrcMat &src)
void scatter_matrix_col(const int n_dofs, const int dim, const Eigen::MatrixXd &A, const Eigen::MatrixXd &b, const std::vector< int > &local_to_global, StiffnessMatrix &Aout, Eigen::MatrixXd &bout)
Eigen::VectorXd flatten(const Eigen::MatrixXd &X)
Flatten rowwises.
Eigen::MatrixXi map_index_matrix(const Eigen::MatrixXi &in, const Eigen::VectorXi &index_mapping)
Map the entrys of an index matrix to new indices.
void full_to_reduced_matrix(const int full_size, const int reduced_size, const std::vector< int > &removed_vars, const StiffnessMatrix &full, StiffnessMatrix &reduced)
Map a full size matrix to a reduced one by dropping rows and columns.
T determinant(const Eigen::Matrix< T, rows, cols, option, maxRow, maxCol > &mat)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:24