Loading...
Searching...
No Matches
EigenFunctions.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12License
13 This file is part of ITHACA-FV
14 ITHACA-FV is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18 ITHACA-FV is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public License
23 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
24Class
25 EigenFunctions
26Description
27 Set of routines to manipulate Eigen c++ objects
28SourceFiles
29 EigenFunctions.C
30\*---------------------------------------------------------------------------*/
31
36
37#ifndef EigenFunctions_H
38#define EigenFunctions_H
39#include <mutex>
40#pragma GCC diagnostic push
41#pragma GCC diagnostic ignored "-Wold-style-cast"
42#include <Eigen/Eigen>
43#include <unsupported/Eigen/SparseExtra>
44#include <unsupported/Eigen/CXX11/Tensor>
45#pragma GCC diagnostic pop
46#include "fvCFD.H"
47
48
49// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50
51
52/*---------------------------------------------------------------------------*\
53 Namespace EigenFunctions Declaration
54\*---------------------------------------------------------------------------*/
55
56
58namespace EigenFunctions
59{
60//--------------------------------------------------------------------------
69template <typename T>
70Eigen::SparseMatrix<T> vectorize(Eigen::SparseMatrix<T>& Matrix);
71
72//--------------------------------------------------------------------------
83template <typename T>
84T max(Eigen::SparseMatrix<T>& mat, label& ind_row, label& ind_col);
85
86//--------------------------------------------------------------------------
97template <typename T>
98T min(Eigen::SparseMatrix<T>& mat, label& ind_row, label& ind_col);
99
100//--------------------------------------------------------------------------
106void sortEigenvalues(Eigen::VectorXd& eigenvalues,
107 Eigen::MatrixXd& eigenvectors);
108
109//--------------------------------------------------------------------------
121template <typename T>
122Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> innerProduct(
123 List <Eigen::SparseMatrix<T >>& A, List <Eigen::SparseMatrix<T >>& B);
124
125//--------------------------------------------------------------------------
137template <typename T>
138Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> innerProduct(
139 List <Eigen::SparseMatrix<T >>& A, Eigen::SparseMatrix<T>& B);
140
141//--------------------------------------------------------------------------
154template <typename T>
155T innerProduct(Eigen::SparseMatrix<T>& A, Eigen::SparseMatrix<T>& B);
156
157//--------------------------------------------------------------------------
171template <typename T>
172Eigen::SparseMatrix<T> MVproduct(List<Eigen::SparseMatrix<T >>& A,
173 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C);
174
175//--------------------------------------------------------------------------
189template <typename T>
190Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> MVproduct(
191 const std::vector< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& A,
192 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C);
193
194//--------------------------------------------------------------------------
208template <typename T>
209List<Eigen::SparseMatrix<T >> MMproduct(List<Eigen::SparseMatrix<T >>& A,
210 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C);
211
212//--------------------------------------------------------------------------
221template <typename T>
222T condNumber(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& A);
223
224//--------------------------------------------------------------------------
235Eigen::VectorXd ExpSpaced(double first, double last, int n);
236
237//--------------------------------------------------------------------------
246template <typename T>
247Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> vectorTensorProduct(
248 const Eigen::Matrix<T, Eigen::Dynamic, 1>& g,
249 const Eigen::Tensor<T, 3 >& c,
250 const Eigen::Matrix<T, Eigen::Dynamic, 1>& a);
251
252
253//------------------------------------------------------------------------------
261Eigen::VectorXd repeatElements(Eigen::VectorXd input, int n);
262
263//------------------------------------------------------------------------------
273Eigen::VectorXd reorderVectorFromDim(Eigen::VectorXd input, int dim);
274
275};
276
277template <typename T>
278Eigen::SparseMatrix<T> EigenFunctions::vectorize(Eigen::SparseMatrix<T>&
279 Matrix)
280{
281 typedef Eigen::Triplet<double> Trip;
282 std::vector<Trip> tripletList;
283 tripletList.reserve(Matrix.nonZeros());
284 Eigen::SparseMatrix<T> vec;
285 vec.resize(1, Matrix.size());
286 vec.reserve(Matrix.nonZeros());
287
288 for (label k = 0; k < Matrix.outerSize(); ++k)
289 {
290 for (Eigen::SparseMatrix<double>::InnerIterator it(Matrix, k); it; ++it)
291 {
292 tripletList.push_back(Trip(0, it.row() + it.col() * Matrix.rows(), it.value()));
293 }
294 }
295
296 vec.setFromTriplets(tripletList.begin(), tripletList.end());
297}
298
299template <typename T>
300T EigenFunctions::max(Eigen::SparseMatrix<T>& mat, label& ind_row,
301 label& ind_col)
302{
303 label i = 0;
304 T max = 0;
305
306 for (label k = 0; k < mat.outerSize(); ++k)
307 {
308 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
309 {
310 if (max < it.value() || i == 0)
311 {
312 max = it.value();
313 ind_row = it.row();
314 ind_col = it.col();
315 i++;
316 }
317 }
318 }
319
320 return max;
321}
322
323template <typename T>
324T EigenFunctions::min(Eigen::SparseMatrix<T>& mat, label& ind_row,
325 label& ind_col)
326{
327 label i = 0;
328 T min = 0;
329
330 for (label k = 0; k < mat.outerSize(); ++k)
331 {
332 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
333 {
334 if (min > it.value() || i == 0)
335 {
336 min = it.value();
337 ind_row = it.row();
338 ind_col = it.col();
339 i++;
340 }
341 }
342 }
343
344 return min;
345}
346
347template <typename T>
348Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
349 List <Eigen::SparseMatrix<T >>& A, List <Eigen::SparseMatrix<T >>& B)
350{
351 label rows = A.size();
352 label cols = B.size();
353 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
354 out.resize(rows, cols);
355
356 for (label i = 0; i < rows; i++)
357 {
358 for (label j = 0; j < cols; j++)
359 {
360 out(i, j) = innerProduct(A[i], B[j]);
361 }
362 }
363
364 return out;
365}
366
367template <typename T>
368Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
369 List<Eigen::SparseMatrix<T >>& A, Eigen::SparseMatrix<T>& B)
370{
371 label rows = A.size();
372 label cols = 1;
373 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
374 out.resize(rows, cols);
375
376 for (label i = 0; i < rows; i++)
377 {
378 out(i, 0) = innerProduct(A[i], B);
379 }
380
381 return out;
382}
383
384template <typename T>
385T EigenFunctions::innerProduct(Eigen::SparseMatrix<T>& A,
386 Eigen::SparseMatrix<T>& B)
387{
388 T res = 0;
389
390 for (label k = 0; k < A.cols(); k++)
391 {
392 res += A.col(k).dot(B.col(k));
393 }
394
395 return res;
396}
397
398template <typename T>
399Eigen::SparseMatrix<T> EigenFunctions::MVproduct(List<Eigen::SparseMatrix<T >>&
400 A
401 , Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C)
402{
403 Eigen::SparseMatrix<T> out;
404 out = A[0] * C(0);
405
406 for (label i = 1; i < A.size(); i++)
407 {
408 out += A[i] * C(i);
409 }
410
411 return out;
412}
413
414template <typename T>
415Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::MVproduct(
416 const std::vector< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& A,
417 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C)
418{
419 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
420 out = A[0] * C(0);
421
422 for (label i = 1; i < A.size(); i++)
423 {
424 out += A[i] * C(i);
425 }
426
427 return out;
428}
429
430
431
432template <typename T>
433List<Eigen::SparseMatrix<T >> EigenFunctions::MMproduct(
434 List<Eigen::SparseMatrix<T >>& A,
435 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C)
436{
437 List<Eigen::SparseMatrix<T >> out;
438 out.resize(C.cols());
439 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> col;
440
441 for (label i = 0; i < C.cols(); i++)
442 {
443 col = C.col(i);
444 out[i] = MVproduct(A, col);
445 }
446
447 return out;
448}
449
450template <typename T>
451T EigenFunctions::condNumber(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>&
452 A)
453{
454 Eigen::JacobiSVD<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >> svd(A);
455 T cond = svd.singularValues()(0) / svd.singularValues()(
456 svd.singularValues().size() - 1);
457 return cond;
458}
459
460// Additional Eigen Functions
461namespace Eigen
462{
463using namespace Eigen;
464
465template<typename VectorType>
466bool saveMarketVector (const VectorType & vec, const std::string & filename,
467 label prec, std::_Ios_Fmtflags outytpe = std::ios_base::scientific)
468{
469 typedef typename VectorType::Scalar Scalar;
470 std::ofstream out(filename.c_str(), std::ios::out);
471
472 if (!out)
473 {
474 return false;
475 }
476
477 out.flags(outytpe);
478 out.precision(prec);
479
480 if (internal::is_same<Scalar, std::complex<float >>::value
481 || internal::is_same<Scalar, std::complex<double >>::value)
482 {
483 out << "%%MatrixMarket matrix array complex general\n";
484 }
485 else
486 {
487 out << "%%MatrixMarket matrix array real general\n";
488 }
489
490 out << vec.size() << " " << 1 << "\n";
491
492 for (label i = 0; i < vec.size(); i++)
493 {
494 internal::putDenseElt(vec(i), out);
495 }
496
497 out.close();
498 return true;
499}
500
501template<typename VectorType>
502Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
503 Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
504{
505 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
506 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
507 VectorType, /* scalar element type */
508 Eigen::Dynamic, /* num_rows is a run-time value */
509 Eigen::Dynamic, /* num_cols is a run-time value */
510 Eigen::ColMajor /* tensorflow::Tensor is always row-major */ >> (
511 t2.data(), /* ptr to data */
512 t2.dimensions()[0], /* num_rows */
513 t2.dimensions()[1] /* num_cols */);
514 return m;
515}
516
517template<typename VectorType>
518Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
519 const Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
520{
521 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
522 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
523 VectorType, /* scalar element type */
524 Eigen::Dynamic, /* num_rows is a run-time value */
525 Eigen::Dynamic, /* num_cols is a run-time value */
526 Eigen::ColMajor /* tensorflow::Tensor is always row-major */ >> (
527 t2.data(), /* ptr to data */
528 t2.dimensions()[0], /* num_rows */
529 t2.dimensions()[1] /* num_cols */);
530 return m;
531}
532
533}
534
535
536
537
538
539#endif
540
541
Namespace to perform operation on Eigen objects.
Eigen::VectorXd repeatElements(Eigen::VectorXd input, int n)
Repeat each element n times after themselves.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > vectorTensorProduct(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &g, const Eigen::Tensor< T, 3 > &c, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &a)
A function that computes the product of g.T c a, where c is a third dim tensor.
Eigen::SparseMatrix< T > MVproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix-Vector product between a list of sparse matrices and a vector of coefficients.
Eigen::VectorXd reorderVectorFromDim(Eigen::VectorXd input, int dim)
Changes the order of the vector's elements given a dimension.
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM).
Eigen::VectorXd ExpSpaced(double first, double last, int n)
Returns exponentially spaced vector.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > innerProduct(List< Eigen::SparseMatrix< T > > &A, List< Eigen::SparseMatrix< T > > &B)
Perform Frobenius inner Product between two list of sparse matrices A and B.
Eigen::SparseMatrix< T > vectorize(Eigen::SparseMatrix< T > &Matrix)
Vectorize a Sparse Matrix.
void sortEigenvalues(Eigen::VectorXd &eigenvalues, Eigen::MatrixXd &eigenvectors)
sort eigenvalues
T condNumber(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &A)
Conditioning number of a dense matrix.
List< Eigen::SparseMatrix< T > > MMproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix - Dense Matrix product between a list of sparse matrices and a dense matrix.
T min(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the minimum of a sparse Matrix (Useful for DEIM).