9 #include <boost/test/unit_test.hpp>
29 using ScalarsAndFixedSizeSubspaces = std::tuple<
30 std::tuple<float, detail::FixedSizeSubspace<2u, 1u>>,
31 std::tuple<float, detail::FixedSizeSubspace<2u, 2u>>,
32 std::tuple<float, detail::FixedSizeSubspace<3u, 1u>>,
33 std::tuple<float, detail::FixedSizeSubspace<3u, 2u>>,
34 std::tuple<float, detail::FixedSizeSubspace<3u, 3u>>,
35 std::tuple<float, detail::FixedSizeSubspace<6u, 1u>>,
36 std::tuple<float, detail::FixedSizeSubspace<6u, 2u>>,
37 std::tuple<float, detail::FixedSizeSubspace<6u, 4u>>,
38 std::tuple<float, detail::FixedSizeSubspace<8u, 1u>>,
39 std::tuple<float, detail::FixedSizeSubspace<8u, 2u>>,
40 std::tuple<float, detail::FixedSizeSubspace<8u, 4u>>,
41 std::tuple<double, detail::FixedSizeSubspace<2u, 1u>>,
42 std::tuple<double, detail::FixedSizeSubspace<2u, 2u>>,
43 std::tuple<double, detail::FixedSizeSubspace<3u, 1u>>,
44 std::tuple<double, detail::FixedSizeSubspace<3u, 2u>>,
45 std::tuple<double, detail::FixedSizeSubspace<3u, 3u>>,
46 std::tuple<double, detail::FixedSizeSubspace<6u, 1u>>,
47 std::tuple<double, detail::FixedSizeSubspace<6u, 2u>>,
48 std::tuple<double, detail::FixedSizeSubspace<6u, 4u>>,
49 std::tuple<double, detail::FixedSizeSubspace<8u, 1u>>,
50 std::tuple<double, detail::FixedSizeSubspace<8u, 2u>>,
51 std::tuple<double, detail::FixedSizeSubspace<8u, 4u>>
56 template <
typename scalar_t, std::
size_t kSize>
57 Eigen::Matrix<scalar_t, kSize, 1> makeRandomVector() {
58 Eigen::Matrix<scalar_t, kSize, 1>
vec;
64 std::vector<std::size_t> makeMonotonicIndices(std::size_t
n) {
65 std::vector<std::size_t> indices(n);
66 std::iota(indices.begin(), indices.end(), 0
u);
71 template <std::
size_t kSize>
72 std::array<std::size_t, kSize> selectFixedIndices(
73 const std::vector<std::size_t>& fullIndices) {
74 std::array<std::size_t, kSize> indices{};
75 for (
auto i = 0
u;
i < kSize; ++
i) {
76 indices[
i] = fullIndices[
i];
78 std::sort(indices.begin(), indices.end());
84 BOOST_AUTO_TEST_SUITE(UtilitiesSubspace)
99 ScalarsAndFixedSizeSubspaces) {
101 using Scalar = std::tuple_element_t<0, ScalarAndSubspace>;
102 using Subspace = std::tuple_element_t<1, ScalarAndSubspace>;
104 auto x = makeRandomVector<Scalar, Subspace::fullSize()>();
105 auto fullIndices = makeMonotonicIndices(Subspace::fullSize());
113 auto indices = selectFixedIndices<Subspace::size()>(fullIndices);
114 Subspace subspace(indices);
117 BOOST_CHECK_EQUAL(subspace.template projector<Scalar>().transpose(),
118 subspace.template expander<Scalar>());
119 BOOST_CHECK_EQUAL(subspace.template expander<Scalar>().transpose(),
120 subspace.template projector<Scalar>());
122 auto s0 = subspace.projectVector(
x);
123 auto s1 = (subspace.template projector<Scalar>() *
x).eval();
124 for (
auto i = 0
u;
i < subspace.size(); ++
i) {
125 BOOST_TEST_INFO(
"Checking projected subspace component " <<
i);
126 BOOST_CHECK_EQUAL(s0[
i],
x[indices[i]]);
127 BOOST_CHECK_EQUAL(s1[i],
x[indices[i]]);
130 auto y0 = subspace.expandVector(s1);
131 auto y1 = (subspace.template expander<Scalar>() * s0).eval();
132 for (
auto i = 0
u;
i < subspace.fullSize(); ++
i) {
133 BOOST_TEST_INFO(
"Checking expanded fullspace component " <<
i);
134 BOOST_CHECK_EQUAL(y0[
i], subspace.contains(i) ?
x[
i] : 0);
135 BOOST_CHECK_EQUAL(y1[i], subspace.contains(i) ?
x[
i] : 0);
137 }
while (std::next_permutation(fullIndices.begin(), fullIndices.end()));
140 BOOST_AUTO_TEST_SUITE_END()