random_matrix_helper.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
6 // Copyright (C) 2021 Kolja Brix <kolja.brix@rwth-aachen.de>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_RANDOM_MATRIX_HELPER
13 #define EIGEN_RANDOM_MATRIX_HELPER
14 
15 #include <typeinfo>
16 #include <Eigen/QR> // required for createRandomPIMatrixOfRank and generateRandomMatrixSvs
17 
18 // Forward declarations to avoid ICC warnings
19 #if EIGEN_COMP_ICC
20 
21 namespace Eigen {
22 
23 template <typename MatrixType>
25 
26 template <typename PermutationVectorType>
27 void randomPermutationVector(PermutationVectorType& v, Index size);
28 
29 template <typename MatrixType>
31 
32 template <typename MatrixType, typename RealScalarVectorType>
33 void generateRandomMatrixSvs(const RealScalarVectorType& svs, const Index rows, const Index cols, MatrixType& M);
34 
35 template <typename VectorType, typename RealScalar>
36 VectorType setupRandomSvs(const Index dim, const RealScalar max);
37 
38 template <typename VectorType, typename RealScalar>
39 VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max);
40 
41 } // end namespace Eigen
42 
43 #endif // EIGEN_COMP_ICC
44 
45 namespace Eigen {
46 
59 template <typename MatrixType>
62  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
63 
65  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
66  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
67 
68  if (desired_rank == 0) {
69  m.setZero(rows, cols);
70  return;
71  }
72 
73  if (desired_rank == 1) {
74  // here we normalize the vectors to get a partial isometry
75  m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
76  return;
77  }
78 
79  MatrixAType a = MatrixAType::Random(rows, rows);
80  MatrixType d = MatrixType::Identity(rows, cols);
81  MatrixBType b = MatrixBType::Random(cols, cols);
82 
83  // set the diagonal such that only desired_rank non-zero entries remain
84  const Index diag_size = (std::min)(d.rows(), d.cols());
85  if (diag_size != desired_rank)
86  d.diagonal().segment(desired_rank, diag_size - desired_rank) = VectorType::Zero(diag_size - desired_rank);
87 
90  m = qra.householderQ() * d * qrb.householderQ();
91 }
92 
100 template <typename PermutationVectorType>
101 void randomPermutationVector(PermutationVectorType& v, Index size) {
102  typedef typename PermutationVectorType::Scalar Scalar;
103  v.resize(size);
104  for (Index i = 0; i < size; ++i) v(i) = Scalar(i);
105  if (size == 1) return;
106  for (Index n = 0; n < 3 * size; ++n) {
107  Index i = internal::random<Index>(0, size - 1);
108  Index j;
109  do j = internal::random<Index>(0, size - 1);
110  while (j == i);
111  std::swap(v(i), v(j));
112  }
113 }
114 
125 template <typename MatrixType>
129 
130  MatrixType v = MatrixType::Identity(dim, dim);
131  VectorType h = VectorType::Zero(dim);
132  for (Index i = 0; i < dim; ++i) {
133  v.col(i).tail(dim - i - 1) = VectorType::Random(dim - i - 1);
134  h(i) = 2 / v.col(i).tail(dim - i).squaredNorm();
135  }
136 
138  return MatrixType(HSeq);
139 }
140 
168 template <typename MatrixType, typename RealScalarVectorType>
169 void generateRandomMatrixSvs(const RealScalarVectorType& svs, const Index rows, const Index cols, MatrixType& M) {
170  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
172  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
173  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
174 
175  const Index min_dim = (std::min)(rows, cols);
176 
177  const MatrixAType U = generateRandomUnitaryMatrix<MatrixAType>(rows);
178  const MatrixBType V = generateRandomUnitaryMatrix<MatrixBType>(cols);
179 
180  M = U.block(0, 0, rows, min_dim) * svs.asDiagonal() * V.block(0, 0, cols, min_dim).transpose();
181 }
182 
199 template <typename VectorType, typename RealScalar>
201  VectorType svs = max / RealScalar(2) * (VectorType::Random(dim) + VectorType::Ones(dim));
202  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
203  return svs;
204 }
205 
224 template <typename VectorType, typename RealScalar>
226  VectorType svs = VectorType::Random(dim);
227  if (dim == 0) return svs;
228  if (dim == 1) {
229  svs(0) = min;
230  return svs;
231  }
232  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
233 
234  // scale to range [min, max]
235  const RealScalar c_min = svs(dim - 1), c_max = svs(0);
236  svs = (svs - VectorType::Constant(dim, c_min)) / (c_max - c_min);
237  return min * (VectorType::Ones(dim) - svs) + max * svs;
238 }
239 
240 } // end namespace Eigen
241 
242 #endif // EIGEN_RANDOM_MATRIX_HELPER
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
MatrixXcd V
Definition: EigenSolver_EigenSolver_MatrixType.cpp:15
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Scalar * b
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Householder QR decomposition of a matrix.
Definition: HouseholderQR.h:59
HouseholderSequenceType householderQ() const
Definition: HouseholderQR.h:160
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition: HouseholderSequence.h:117
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
#define min(a, b)
Definition: datatypes.h:22
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
const Scalar * a
Definition: level2_cplx_impl.h:32
int * m
Definition: level2_cplx_impl.h:294
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType &m)
Definition: random_matrix_helper.h:60
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
CleanedUpDerType< DerType >::type() min(const AutoDiffScalar< DerType > &x, const T &y)
Definition: AutoDiffScalar.h:494
CleanedUpDerType< DerType >::type() max(const AutoDiffScalar< DerType > &x, const T &y)
Definition: AutoDiffScalar.h:499
void randomPermutationVector(PermutationVectorType &v, Index size)
Definition: random_matrix_helper.h:101
VectorType setupRandomSvs(const Index dim, const RealScalar max)
Definition: random_matrix_helper.h:200
MatrixType generateRandomUnitaryMatrix(const Index dim)
Definition: random_matrix_helper.h:126
VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max)
Definition: random_matrix_helper.h:225
void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType &M)
Definition: random_matrix_helper.h:169
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53
double Zero
Definition: pseudosolid_node_update_elements.cc:35
Definition: ForwardDeclarations.h:21
Definition: fft_test_shared.h:66
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2