11#ifndef FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_
12#define FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_
19#include <Eigen/Sparse>
22#include <CGAL/Epick_d.h>
23#include <CGAL/point_generators_d.h>
25#include <boost/math/constants/constants.hpp>
29namespace coxeter_triangulation {
41Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) {
42 typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> Kernel;
43 typedef typename Kernel::Point_d Point_d;
44 if (d == 1)
return Eigen::VectorXd::Constant(1, 1.0);
47 std::uniform_real_distribution<double> unif(0., 2 * boost::math::constants::pi<double>());
48 std::random_device rand_dev;
49 std::mt19937 rand_engine(rand_dev());
50 double alpha = unif(rand_engine);
53 rot << std::cos(alpha), -std::sin(alpha), std::sin(alpha), cos(alpha);
56 Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d - 1);
57 Eigen::MatrixXd rot(d, d);
58 Point_d v = *CGAL::Random_points_on_sphere_d<Point_d>(d, 1);
59 for (std::size_t i = 0; i < d; ++i) rot(i, 0) = v[i];
60 for (std::size_t i = 0; i < d - 1; ++i)
61 for (std::size_t j = 1; j < d - 1; ++j) rot(i, j) = low_dim_rot(i, j - 1);
62 for (std::size_t j = 1; j < d; ++j) rot(d - 1, j) = 0;
63 rot = rot.householderQr()