Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-31 08:18:53

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/tools/old/interface.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Utilities/Axis.hpp"
0013 #include "Acts/Utilities/AxisDefinitions.hpp"
0014 #include "Acts/Utilities/MultiAxis.hpp"
0015 #include "ActsTests/CommonHelpers/Assertions.hpp"
0016 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0017 
0018 #include <array>
0019 #include <cstddef>
0020 #include <tuple>
0021 #include <utility>
0022 
0023 using namespace Acts;
0024 using namespace Acts::detail;
0025 
0026 namespace ActsTests {
0027 
0028 BOOST_AUTO_TEST_SUITE(MultiAxisTests)
0029 
0030 BOOST_AUTO_TEST_CASE(test_1d_equidistant) {
0031   using Point = std::array<double, 1>;
0032   using MultiIndex = std::array<std::size_t, 1>;
0033 
0034   const Axis a(0.0, 4.0, 4u);
0035 
0036   const MultiAxis ma(a);
0037 
0038   // test general properties
0039   BOOST_CHECK_EQUAL(ma.getNAxes(), 1u);
0040   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 4u);
0041   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 4u);
0042 
0043   // flat bin index
0044   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-0.3}), 0u);
0045   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-0.}), 1u);
0046   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.}), 1u);
0047   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.7}), 1u);
0048   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1}), 2u);
0049   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.2}), 2u);
0050   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2.}), 3u);
0051   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2.7}), 3u);
0052   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3.}), 4u);
0053   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3.9999}), 4u);
0054   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4.}), 5u);
0055   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4.98}), 5u);
0056 
0057   // flat bin index -> multi bin indices
0058   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == MultiIndex{0});
0059   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == MultiIndex{1});
0060   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == MultiIndex{2});
0061   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == MultiIndex{3});
0062   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == MultiIndex{4});
0063   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == MultiIndex{5});
0064 
0065   // multi bin indices -> flat bin index
0066   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0}), 0u);
0067   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1}), 1u);
0068   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2}), 2u);
0069   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3}), 3u);
0070   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4}), 4u);
0071   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5}), 5u);
0072 
0073   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(ma.getGlobalBinFromPoint({2.7})) ==
0074               MultiIndex{3});
0075 
0076   // inside checks
0077   BOOST_CHECK(!ma.isInside({-2.}));
0078   BOOST_CHECK(ma.isInside({0.}));
0079   BOOST_CHECK(ma.isInside({2.5}));
0080   BOOST_CHECK(!ma.isInside({4.}));
0081   BOOST_CHECK(!ma.isInside({6.}));
0082 
0083   // test some bin centers
0084   CHECK_CLOSE_ABS(ma.getBinCenter({1}), Point{0.5}, 1e-6);
0085   CHECK_CLOSE_ABS(ma.getBinCenter({2}), Point{1.5}, 1e-6);
0086   CHECK_CLOSE_ABS(ma.getBinCenter({3}), Point{2.5}, 1e-6);
0087   CHECK_CLOSE_ABS(ma.getBinCenter({4}), Point{3.5}, 1e-6);
0088 
0089   // test some lower-left bin edges
0090   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1}), Point{0.}, 1e-6);
0091   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2}), Point{1.}, 1e-6);
0092   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({3}), Point{2.}, 1e-6);
0093   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({4}), Point{3.}, 1e-6);
0094 
0095   // test some upper right-bin edges
0096   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1}), Point{1.}, 1e-6);
0097   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({2}), Point{2.}, 1e-6);
0098   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({3}), Point{3.}, 1e-6);
0099   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({4}), Point{4.}, 1e-6);
0100 }
0101 
0102 BOOST_AUTO_TEST_CASE(test_2d_equidistant) {
0103   using Point = std::array<double, 2>;
0104   using MultiIndex = std::array<std::size_t, 2>;
0105 
0106   const Axis a(0.0, 4.0, 4u);
0107   const Axis b(0.0, 3.0, 3u);
0108 
0109   const MultiAxis ma(a, b);
0110 
0111   // test general properties
0112   BOOST_CHECK_EQUAL(ma.getNAxes(), 2u);
0113   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 4u);
0114   BOOST_CHECK_EQUAL(ma.getNBins().at(1), 3u);
0115   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 12u);
0116 
0117   // flat bin index
0118   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, -1}), 0u);
0119   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, 0}), 1u);
0120   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, 1}), 2u);
0121   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, 2}), 3u);
0122   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, 3}), 4u);
0123   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, -1}), 5u);
0124   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0}), 6u);
0125   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 1}), 7u);
0126   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 2}), 8u);
0127   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3}), 9u);
0128   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, -1}), 10u);
0129   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0}), 11u);
0130   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 1}), 12u);
0131   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 2}), 13u);
0132   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3}), 14u);
0133   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, -1}), 15u);
0134   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 0}), 16u);
0135   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 1}), 17u);
0136   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 2}), 18u);
0137   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 3}), 19u);
0138   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, -1}), 20u);
0139   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 0}), 21u);
0140   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 1}), 22u);
0141   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 2}), 23u);
0142   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 3}), 24u);
0143   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4, -1}), 25u);
0144   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4, 0}), 26u);
0145   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4, 1}), 27u);
0146   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4, 2}), 28u);
0147   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4, 3}), 29u);
0148 
0149   // test some arbitrary points
0150   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.2, 0.3}), 11u);
0151   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2.2, 3.3}), 19u);
0152   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.9, 1.8}), 7u);
0153   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3.7, 3.1}), 24u);
0154   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.4, 2.3}), 13u);
0155   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-3, 3}), 4u);
0156   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({8, 1}), 27u);
0157   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, -3}), 10u);
0158   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 11}), 24u);
0159   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-2, -3}), 0u);
0160   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-2, 7}), 04u);
0161   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({12, -1}), 25u);
0162   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({12, 11}), 29u);
0163 
0164   // flat bin index -> multi bin indices
0165   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == (MultiIndex{0, 0}));
0166   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == (MultiIndex{0, 1}));
0167   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == (MultiIndex{0, 2}));
0168   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == (MultiIndex{0, 3}));
0169   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == (MultiIndex{0, 4}));
0170   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == (MultiIndex{1, 0}));
0171   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(6) == (MultiIndex{1, 1}));
0172   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(7) == (MultiIndex{1, 2}));
0173   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(8) == (MultiIndex{1, 3}));
0174   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(9) == (MultiIndex{1, 4}));
0175   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(10) == (MultiIndex{2, 0}));
0176   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(11) == (MultiIndex{2, 1}));
0177   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(12) == (MultiIndex{2, 2}));
0178   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(13) == (MultiIndex{2, 3}));
0179   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(14) == (MultiIndex{2, 4}));
0180   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(15) == (MultiIndex{3, 0}));
0181   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(16) == (MultiIndex{3, 1}));
0182   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(17) == (MultiIndex{3, 2}));
0183   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(18) == (MultiIndex{3, 3}));
0184   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(19) == (MultiIndex{3, 4}));
0185   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(20) == (MultiIndex{4, 0}));
0186   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(21) == (MultiIndex{4, 1}));
0187   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(22) == (MultiIndex{4, 2}));
0188   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(23) == (MultiIndex{4, 3}));
0189   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(24) == (MultiIndex{4, 4}));
0190   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(25) == (MultiIndex{5, 0}));
0191   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(26) == (MultiIndex{5, 1}));
0192   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(27) == (MultiIndex{5, 2}));
0193   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(28) == (MultiIndex{5, 3}));
0194   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(29) == (MultiIndex{5, 4}));
0195 
0196   // local bin indices -> global bin index
0197   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0}), 0u);
0198   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1}), 1u);
0199   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 2}), 2u);
0200   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 3}), 3u);
0201   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 4}), 4u);
0202   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 0}), 5u);
0203   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1}), 6u);
0204   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 2}), 7u);
0205   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 3}), 8u);
0206   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 4}), 9u);
0207   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 0}), 10u);
0208   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 1}), 11u);
0209   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 2}), 12u);
0210   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3}), 13u);
0211   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 4}), 14u);
0212   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0}), 15u);
0213   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 1}), 16u);
0214   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 2}), 17u);
0215   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 3}), 18u);
0216   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 4}), 19u);
0217   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 0}), 20u);
0218   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 1}), 21u);
0219   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 2}), 22u);
0220   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 3}), 23u);
0221   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 4}), 24u);
0222   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 0}), 25u);
0223   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 1}), 26u);
0224   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 2}), 27u);
0225   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 3}), 28u);
0226   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 4}), 29u);
0227 
0228   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(
0229                   ma.getGlobalBinFromPoint({1.2, 0.7})) == (MultiIndex{2, 1}));
0230 
0231   // inside checks
0232   BOOST_CHECK(!ma.isInside({-2., -1}));
0233   BOOST_CHECK(!ma.isInside({-2., 1.}));
0234   BOOST_CHECK(!ma.isInside({-2., 5.}));
0235   BOOST_CHECK(!ma.isInside({1., -1.}));
0236   BOOST_CHECK(!ma.isInside({6., -1.}));
0237   BOOST_CHECK(ma.isInside({0.5, 1.3}));
0238   BOOST_CHECK(!ma.isInside({4., -1.}));
0239   BOOST_CHECK(!ma.isInside({4., 0.3}));
0240   BOOST_CHECK(!ma.isInside({4., 3.}));
0241   BOOST_CHECK(!ma.isInside({-1., 3.}));
0242   BOOST_CHECK(!ma.isInside({2., 3.}));
0243   BOOST_CHECK(!ma.isInside({5., 3.}));
0244 
0245   // test some bin centers
0246   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1}), (Point{0.5, 0.5}), 1e-6);
0247   CHECK_CLOSE_ABS(ma.getBinCenter({2, 3}), (Point{1.5, 2.5}), 1e-6);
0248   CHECK_CLOSE_ABS(ma.getBinCenter({3, 1}), (Point{2.5, 0.5}), 1e-6);
0249   CHECK_CLOSE_ABS(ma.getBinCenter({4, 2}), (Point{3.5, 1.5}), 1e-6);
0250 
0251   // test some lower-left bin edges
0252   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1}), (Point{0., 0.}), 1e-6);
0253   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2, 3}), (Point{1., 2.}), 1e-6);
0254   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({3, 1}), (Point{2., 0.}), 1e-6);
0255   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({4, 2}), (Point{3., 1.}), 1e-6);
0256 
0257   // test some upper right-bin edges
0258   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 1}), (Point{1., 1.}), 1e-6);
0259   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({2, 3}), (Point{2., 3.}), 1e-6);
0260   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({3, 1}), (Point{3., 1.}), 1e-6);
0261   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({4, 2}), (Point{4., 2.}), 1e-6);
0262 }
0263 
0264 BOOST_AUTO_TEST_CASE(test_3d_equidistant) {
0265   using Point = std::array<double, 3>;
0266   using MultiIndex = std::array<std::size_t, 3>;
0267 
0268   const Axis a(0.0, 2.0, 2u);
0269   const Axis b(0.0, 3.0, 3u);
0270   const Axis c(0.0, 2.0, 2u);
0271 
0272   const MultiAxis ma(a, b, c);
0273 
0274   // test general properties
0275   BOOST_CHECK_EQUAL(ma.getNAxes(), 3u);
0276   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 2u);
0277   BOOST_CHECK_EQUAL(ma.getNBins().at(1), 3u);
0278   BOOST_CHECK_EQUAL(ma.getNBins().at(2), 2u);
0279   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 12u);
0280 
0281   // test grid points
0282   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 0}), 25u);
0283   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 1}), 26u);
0284   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 2}), 27u);
0285   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 1, 0}), 29u);
0286   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 1, 1}), 30u);
0287   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 1, 2}), 31u);
0288   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 2, 0}), 33u);
0289   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 2, 1}), 34u);
0290   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 2, 2}), 35u);
0291   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 0}), 37u);
0292   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 1}), 38u);
0293   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 2}), 39u);
0294   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 0}), 45u);
0295   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 1}), 46u);
0296   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 2}), 47u);
0297   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 1, 0}), 49u);
0298   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 1, 1}), 50u);
0299   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 2, 0}), 53u);
0300   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 2, 1}), 54u);
0301   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 2, 2}), 55u);
0302   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 0}), 57u);
0303   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 1}), 58u);
0304   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 2}), 59u);
0305   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 0, 0}), 65u);
0306   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 0, 1}), 66u);
0307   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 0, 2}), 67u);
0308   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 1, 0}), 69u);
0309   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 1, 1}), 70u);
0310   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 1, 2}), 71u);
0311   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 2, 0}), 73u);
0312   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 2, 1}), 74u);
0313   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 2, 2}), 75u);
0314   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 3, 0}), 77u);
0315   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 3, 1}), 78u);
0316   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, 3, 2}), 79u);
0317 
0318   // flat bin index -> multi bin indices
0319   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == (MultiIndex{0, 0, 0}));
0320   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == (MultiIndex{0, 0, 1}));
0321   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == (MultiIndex{0, 0, 2}));
0322   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == (MultiIndex{0, 0, 3}));
0323   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == (MultiIndex{0, 1, 0}));
0324   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == (MultiIndex{0, 1, 1}));
0325   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(6) == (MultiIndex{0, 1, 2}));
0326   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(7) == (MultiIndex{0, 1, 3}));
0327   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(24) == (MultiIndex{1, 1, 0}));
0328   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(25) == (MultiIndex{1, 1, 1}));
0329   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(26) == (MultiIndex{1, 1, 2}));
0330   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(27) == (MultiIndex{1, 1, 3}));
0331   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(52) == (MultiIndex{2, 3, 0}));
0332   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(53) == (MultiIndex{2, 3, 1}));
0333   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(54) == (MultiIndex{2, 3, 2}));
0334   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(55) == (MultiIndex{2, 3, 3}));
0335   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(60) == (MultiIndex{3, 0, 0}));
0336   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(61) == (MultiIndex{3, 0, 1}));
0337   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(62) == (MultiIndex{3, 0, 2}));
0338   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(63) == (MultiIndex{3, 0, 3}));
0339   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(76) == (MultiIndex{3, 4, 0}));
0340   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(77) == (MultiIndex{3, 4, 1}));
0341   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(78) == (MultiIndex{3, 4, 2}));
0342   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(79) == (MultiIndex{3, 4, 3}));
0343 
0344   // multi bin indices -> flat bin index
0345   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 0}), 0u);
0346   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 1}), 1u);
0347   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 2}), 2u);
0348   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 3}), 3u);
0349   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1, 0}), 4u);
0350   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1, 1}), 5u);
0351   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1, 2}), 6u);
0352   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1, 3}), 7u);
0353   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1, 0}), 24u);
0354   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1, 1}), 25u);
0355   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1, 2}), 26u);
0356   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1, 3}), 27u);
0357   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 0}), 52u);
0358   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 1}), 53u);
0359   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 2}), 54u);
0360   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 3}), 55u);
0361   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0, 0}), 60u);
0362   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0, 1}), 61u);
0363   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0, 2}), 62u);
0364   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0, 3}), 63u);
0365   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 4, 0}), 76u);
0366   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 4, 1}), 77u);
0367   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 4, 2}), 78u);
0368   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 4, 3}), 79u);
0369 
0370   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(ma.getGlobalBinFromPoint(
0371                   {1.2, 0.7, 1.4})) == (MultiIndex{2, 1, 2}));
0372 
0373   // inside checks
0374   BOOST_CHECK(!ma.isInside({-2., -1, -2}));
0375   BOOST_CHECK(!ma.isInside({-2., 1., 0.}));
0376   BOOST_CHECK(!ma.isInside({-2., 5., -1}));
0377   BOOST_CHECK(!ma.isInside({1., -1., 1.}));
0378   BOOST_CHECK(!ma.isInside({6., -1., 4.}));
0379   BOOST_CHECK(ma.isInside({0.5, 1.3, 1.7}));
0380   BOOST_CHECK(!ma.isInside({2., -1., -0.4}));
0381   BOOST_CHECK(!ma.isInside({2., 0.3, 3.4}));
0382   BOOST_CHECK(!ma.isInside({2., 3., 0.8}));
0383   BOOST_CHECK(!ma.isInside({-1., 3., 5.}));
0384   BOOST_CHECK(!ma.isInside({2., 3., -1.}));
0385   BOOST_CHECK(!ma.isInside({5., 3., 0.5}));
0386 
0387   // test some bin centers
0388   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1, 1}), (Point{0.5, 0.5, 0.5}), 1e-6);
0389   CHECK_CLOSE_ABS(ma.getBinCenter({2, 3, 2}), (Point{1.5, 2.5, 1.5}), 1e-6);
0390   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1, 2}), (Point{0.5, 0.5, 1.5}), 1e-6);
0391   CHECK_CLOSE_ABS(ma.getBinCenter({2, 2, 1}), (Point{1.5, 1.5, 0.5}), 1e-6);
0392 
0393   // test some lower-left bin edges
0394   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1, 1}), (Point{0., 0., 0.}), 1e-6);
0395   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2, 3, 2}), (Point{1., 2., 1.}), 1e-6);
0396   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1, 2}), (Point{0., 0., 1.}), 1e-6);
0397   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2, 2, 1}), (Point{1., 1., 0.}), 1e-6);
0398 
0399   // test some upper right-bin edges
0400   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{1, 1, 1}}), (Point{{1., 1., 1.}}),
0401                   1e-6);
0402   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{2, 3, 2}}), (Point{{2., 3., 2.}}),
0403                   1e-6);
0404   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{1, 1, 2}}), (Point{{1., 1., 2.}}),
0405                   1e-6);
0406   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{2, 2, 1}}), (Point{{2., 2., 1.}}),
0407                   1e-6);
0408 }
0409 
0410 BOOST_AUTO_TEST_CASE(test_1d_variable) {
0411   using Point = std::array<double, 1>;
0412   using MultiIndex = std::array<std::size_t, 1>;
0413 
0414   const Axis a({0.0, 1.0, 4.0});
0415 
0416   const MultiAxis ma(a);
0417 
0418   // test general properties
0419   BOOST_CHECK_EQUAL(ma.getNAxes(), 1u);
0420   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 2u);
0421   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 2u);
0422 
0423   // flat bin index
0424   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-0.3}), 0u);
0425   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.}), 1u);
0426   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.7}), 1u);
0427   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1}), 2u);
0428   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.2}), 2u);
0429   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2.7}), 2u);
0430   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4.}), 3u);
0431   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({4.98}), 3u);
0432 
0433   // flat bin index -> multi bin indices
0434   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == MultiIndex{0});
0435   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == MultiIndex{1});
0436   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == MultiIndex{2});
0437   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == MultiIndex{3});
0438 
0439   // multi bin indices -> flat bin index
0440   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0}), 0u);
0441   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1}), 1u);
0442   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2}), 2u);
0443   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3}), 3u);
0444 
0445   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(ma.getGlobalBinFromPoint({0.8})) ==
0446               MultiIndex{1});
0447 
0448   // inside checks
0449   BOOST_CHECK(!ma.isInside({-2.}));
0450   BOOST_CHECK(ma.isInside({0.}));
0451   BOOST_CHECK(ma.isInside({2.5}));
0452   BOOST_CHECK(!ma.isInside({4.}));
0453   BOOST_CHECK(!ma.isInside({6.}));
0454 
0455   // test some bin centers
0456   CHECK_CLOSE_ABS(ma.getBinCenter({1}), Point{0.5}, 1e-6);
0457   CHECK_CLOSE_ABS(ma.getBinCenter({2}), Point{2.5}, 1e-6);
0458 
0459   // test some lower-left bin edges
0460   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1}), Point{0.}, 1e-6);
0461   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2}), Point{1.}, 1e-6);
0462 
0463   // test some upper right-bin edges
0464   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1}), Point{1.}, 1e-6);
0465   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({2}), Point{4.}, 1e-6);
0466 }
0467 
0468 BOOST_AUTO_TEST_CASE(test_2d_variable) {
0469   using Point = std::array<double, 2>;
0470   using MultiIndex = std::array<std::size_t, 2>;
0471 
0472   const Axis a({0.0, 0.5, 3.0});
0473   const Axis b({0.0, 1.0, 4.0});
0474 
0475   const MultiAxis ma(a, b);
0476 
0477   // test general properties
0478   BOOST_CHECK_EQUAL(ma.getNAxes(), 2u);
0479   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 2u);
0480   BOOST_CHECK_EQUAL(ma.getNBins().at(1), 2u);
0481   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 4u);
0482 
0483   // test grid points
0484   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0}), 5u);
0485   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 1}), 6u);
0486   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 4}), 7u);
0487   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 0}), 9u);
0488   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 1}), 10u);
0489   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 4}), 11u);
0490   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 0}), 13u);
0491   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 1}), 14u);
0492   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3, 4}), 15u);
0493 
0494   // test some arbitrary points
0495   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.3, 1.2}), 6u);
0496   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3.3, 2.2}), 14u);
0497   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.8, 0.9}), 9u);
0498   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({3.1, 0.7}), 13u);
0499   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2.3, 1.4}), 10u);
0500   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({2, -3}), 8u);
0501   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 8}), 11u);
0502   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-3, 1}), 2u);
0503   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({11, 3}), 14u);
0504   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-3, -2}), 0u);
0505   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({7, -2}), 12u);
0506   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-1, 12}), 3u);
0507   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({11, 12}), 15u);
0508 
0509   // flat bin index -> multi bin indices
0510   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == (MultiIndex{0, 0}));
0511   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == (MultiIndex{0, 1}));
0512   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == (MultiIndex{0, 2}));
0513   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == (MultiIndex{0, 3}));
0514   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == (MultiIndex{1, 0}));
0515   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == (MultiIndex{1, 1}));
0516   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(6) == (MultiIndex{1, 2}));
0517   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(7) == (MultiIndex{1, 3}));
0518   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(8) == (MultiIndex{2, 0}));
0519   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(9) == (MultiIndex{2, 1}));
0520   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(10) == (MultiIndex{2, 2}));
0521   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(11) == (MultiIndex{2, 3}));
0522   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(12) == (MultiIndex{3, 0}));
0523   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(13) == (MultiIndex{3, 1}));
0524   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(14) == (MultiIndex{3, 2}));
0525   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(15) == (MultiIndex{3, 3}));
0526 
0527   // multi bin indices -> flat bin index
0528   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0}), 0u);
0529   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1}), 1u);
0530   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 2}), 2u);
0531   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 3}), 3u);
0532   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 0}), 4u);
0533   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1}), 5u);
0534   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 2}), 6u);
0535   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 3}), 7u);
0536   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 0}), 8u);
0537   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 1}), 9u);
0538   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 2}), 10u);
0539   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3}), 11u);
0540   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0}), 12u);
0541   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 1}), 13u);
0542   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 2}), 14u);
0543   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 3}), 15u);
0544 
0545   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(
0546                   ma.getGlobalBinFromPoint({3.2, 1.8})) == (MultiIndex{3, 2}));
0547 
0548   // inside checks
0549   BOOST_CHECK(!ma.isInside({-2., -1}));
0550   BOOST_CHECK(!ma.isInside({-2., 1.}));
0551   BOOST_CHECK(!ma.isInside({-2., 5.}));
0552   BOOST_CHECK(!ma.isInside({1., -1.}));
0553   BOOST_CHECK(!ma.isInside({6., -1.}));
0554   BOOST_CHECK(ma.isInside({0.5, 1.3}));
0555   BOOST_CHECK(!ma.isInside({3., -1.}));
0556   BOOST_CHECK(!ma.isInside({3., 0.3}));
0557   BOOST_CHECK(!ma.isInside({3., 4.}));
0558   BOOST_CHECK(!ma.isInside({-1., 4.}));
0559   BOOST_CHECK(!ma.isInside({2., 4.}));
0560   BOOST_CHECK(!ma.isInside({5., 4.}));
0561 
0562   // test some bin centers
0563   CHECK_CLOSE_ABS(ma.getBinCenter({{1, 1}}), (Point{0.25, 0.5}), 1e-6);
0564   CHECK_CLOSE_ABS(ma.getBinCenter({{2, 1}}), (Point{1.75, 0.5}), 1e-6);
0565   CHECK_CLOSE_ABS(ma.getBinCenter({{1, 2}}), (Point{0.25, 2.5}), 1e-6);
0566   CHECK_CLOSE_ABS(ma.getBinCenter({{2, 2}}), (Point{1.75, 2.5}), 1e-6);
0567 
0568   // test some lower-left bin edges
0569   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({{1, 1}}), (Point{0., 0.}), 1e-6);
0570   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({{2, 1}}), (Point{0.5, 0.}), 1e-6);
0571   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({{1, 2}}), (Point{0., 1.}), 1e-6);
0572   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({{2, 2}}), (Point{0.5, 1.}), 1e-6);
0573 
0574   // test some upper right-bin edges
0575   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{1, 1}}), (Point{0.5, 1.}), 1e-6);
0576   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{2, 1}}), (Point{3., 1.}), 1e-6);
0577   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{1, 2}}), (Point{0.5, 4.}), 1e-6);
0578   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({{2, 2}}), (Point{3., 4.}), 1e-6);
0579 }
0580 
0581 BOOST_AUTO_TEST_CASE(test_3d_variable) {
0582   using Point = std::array<double, 3>;
0583   using MultiIndex = std::array<std::size_t, 3>;
0584 
0585   const Axis a({0.0, 1.0});
0586   const Axis b({0.0, 0.5, 3.0});
0587   const Axis c({0.0, 0.5, 3.0, 3.3});
0588 
0589   const MultiAxis ma(a, b, c);
0590 
0591   // test general properties
0592   BOOST_CHECK_EQUAL(ma.getNAxes(), 3u);
0593   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 1u);
0594   BOOST_CHECK_EQUAL(ma.getNBins().at(1), 2u);
0595   BOOST_CHECK_EQUAL(ma.getNBins().at(2), 3u);
0596   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 6u);
0597 
0598   // test grid points
0599   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 0}), 26u);
0600   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 0}), 46u);
0601   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0.5, 0}), 31u);
0602   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0.5, 0}), 51u);
0603   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 0}), 36u);
0604   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 0}), 56u);
0605   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 0.5}), 27u);
0606   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 0.5}), 47u);
0607   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0.5, 0.5}), 32u);
0608   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0.5, 0.5}), 52u);
0609   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 0.5}), 37u);
0610   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 0.5}), 57u);
0611   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 3}), 28u);
0612   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 3}), 48u);
0613   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0.5, 3}), 33u);
0614   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0.5, 3}), 53u);
0615   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 3}), 38u);
0616   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 3}), 58u);
0617   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0, 3.3}), 29u);
0618   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0, 3.3}), 49u);
0619   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0.5, 3.3}), 34u);
0620   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0.5, 3.3}), 54u);
0621   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3, 3.3}), 39u);
0622   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3, 3.3}), 59u);
0623 
0624   // flat bin index -> multi bin indices
0625   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == (MultiIndex{0, 0, 0}));
0626   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == (MultiIndex{0, 0, 1}));
0627   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == (MultiIndex{0, 0, 2}));
0628   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == (MultiIndex{0, 0, 3}));
0629   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == (MultiIndex{0, 0, 4}));
0630   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == (MultiIndex{0, 1, 0}));
0631   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(21) == (MultiIndex{1, 0, 1}));
0632   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(22) == (MultiIndex{1, 0, 2}));
0633   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(23) == (MultiIndex{1, 0, 3}));
0634   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(24) == (MultiIndex{1, 0, 4}));
0635   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(25) == (MultiIndex{1, 1, 0}));
0636   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(26) == (MultiIndex{1, 1, 1}));
0637   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(57) == (MultiIndex{2, 3, 2}));
0638   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(58) == (MultiIndex{2, 3, 3}));
0639   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(59) == (MultiIndex{2, 3, 4}));
0640 
0641   // multi bin indices -> flat bin index
0642   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 0}), 0u);
0643   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 0, 0}), 20u);
0644   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 0, 0}), 40u);
0645   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1, 0}), 5u);
0646   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1, 0}), 25u);
0647   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 1, 0}), 45u);
0648   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 3, 1}), 16u);
0649   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 3, 1}), 36u);
0650   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 1}), 56u);
0651   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0, 2}), 2u);
0652   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 0, 2}), 22u);
0653   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 0, 2}), 42u);
0654   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 3, 4}), 19u);
0655   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 3, 4}), 39u);
0656   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3, 4}), 59u);
0657 
0658   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(ma.getGlobalBinFromPoint(
0659                   {1.8, 0.7, 3.2})) == (MultiIndex{2, 2, 3}));
0660 
0661   // inside checks
0662   BOOST_CHECK(!ma.isInside({-2., -1, -2}));
0663   BOOST_CHECK(!ma.isInside({-2., 1., 0.}));
0664   BOOST_CHECK(!ma.isInside({-2., 5., -1}));
0665   BOOST_CHECK(!ma.isInside({1., -1., 1.}));
0666   BOOST_CHECK(!ma.isInside({6., -1., 4.}));
0667   BOOST_CHECK(ma.isInside({0.5, 1.3, 1.7}));
0668   BOOST_CHECK(!ma.isInside({1., -1., -0.4}));
0669   BOOST_CHECK(!ma.isInside({1., 0.3, 3.4}));
0670   BOOST_CHECK(!ma.isInside({1., 3., 0.8}));
0671   BOOST_CHECK(!ma.isInside({-1., 3., 5.}));
0672   BOOST_CHECK(!ma.isInside({2., 3., -1.}));
0673   BOOST_CHECK(!ma.isInside({5., 3., 0.5}));
0674 
0675   // test some bin centers
0676   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1, 1}), (Point{0.5, 0.25, 0.25}), 1e-6);
0677   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1, 2}), (Point{0.5, 0.25, 1.75}), 1e-6);
0678   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1, 3}), (Point{0.5, 0.25, 3.15}), 1e-6);
0679   CHECK_CLOSE_ABS(ma.getBinCenter({1, 2, 1}), (Point{0.5, 1.75, 0.25}), 1e-6);
0680   CHECK_CLOSE_ABS(ma.getBinCenter({1, 2, 2}), (Point{0.5, 1.75, 1.75}), 1e-6);
0681   CHECK_CLOSE_ABS(ma.getBinCenter({1, 2, 3}), (Point{0.5, 1.75, 3.15}), 1e-6);
0682 
0683   // test some lower-left bin edges
0684   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1, 1}), (Point{0., 0., 0.}), 1e-6);
0685   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1, 2}), (Point{0., 0., 0.5}),
0686                   1e-6);
0687   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1, 3}), (Point{0., 0., 3.}), 1e-6);
0688   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 2, 1}), (Point{0., 0.5, 0.}),
0689                   1e-6);
0690   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 2, 2}), (Point{0., 0.5, 0.5}),
0691                   1e-6);
0692   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 2, 3}), (Point{0., 0.5, 3.}),
0693                   1e-6);
0694 
0695   // test some upper right-bin edges
0696   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 1, 1}), (Point{1., 0.5, 0.5}),
0697                   1e-6);
0698   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 1, 2}), (Point{1., 0.5, 3.}),
0699                   1e-6);
0700   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 1, 3}), (Point{1., 0.5, 3.3}),
0701                   1e-6);
0702   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 2, 1}), (Point{1., 3., 0.5}),
0703                   1e-6);
0704   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 2, 2}), (Point{1., 3., 3.}),
0705                   1e-6);
0706   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 2, 3}), (Point{1., 3., 3.3}),
0707                   1e-6);
0708 }
0709 
0710 BOOST_AUTO_TEST_CASE(test_2d_mixed) {
0711   using Point = std::array<double, 2>;
0712   using MultiIndex = std::array<std::size_t, 2>;
0713 
0714   const Axis a(0.0, 1.0, 4u);
0715   const Axis b({0.0, 0.5, 3.0});
0716 
0717   const MultiAxis ma(a, b);
0718 
0719   // test general properties
0720   BOOST_CHECK_EQUAL(ma.getNAxes(), 2u);
0721   BOOST_CHECK_EQUAL(ma.getNBins().at(0), 4u);
0722   BOOST_CHECK_EQUAL(ma.getNBins().at(1), 2u);
0723   BOOST_CHECK_EQUAL(ma.getNTotalBins(), 8u);
0724 
0725   // test grid points
0726   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0}), 5u);
0727   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.25, 0}), 9u);
0728   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 0}), 13u);
0729   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.75, 0}), 17u);
0730   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0}), 21u);
0731   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 0.5}), 6u);
0732   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.25, 0.5}), 10u);
0733   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 0.5}), 14u);
0734   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.75, 0.5}), 18u);
0735   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 0.5}), 22u);
0736   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0, 3}), 7u);
0737   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.25, 3}), 11u);
0738   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.5, 3}), 15u);
0739   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.75, 3}), 19u);
0740   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1, 3}), 23u);
0741 
0742   // test some arbitrary points
0743   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({1.2, 0.3}), 21u);
0744   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.2, 1.3}), 6u);
0745   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.9, 1.8}), 18u);
0746   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.7, 2.1}), 14u);
0747   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.4, 0.3}), 9u);
0748   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-3, 2}), 2u);
0749   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({8, 1}), 22u);
0750   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.1, -3}), 4u);
0751   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({0.8, 11}), 19u);
0752   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-2, -3}), 0u);
0753   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({-2, 7}), 3u);
0754   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({12, -1}), 20u);
0755   BOOST_CHECK_EQUAL(ma.getGlobalBinFromPoint({12, 11}), 23u);
0756 
0757   // flat bin index -> multi bin indices
0758   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(0) == (MultiIndex{0, 0}));
0759   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(1) == (MultiIndex{0, 1}));
0760   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(2) == (MultiIndex{0, 2}));
0761   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(3) == (MultiIndex{0, 3}));
0762   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(4) == (MultiIndex{1, 0}));
0763   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(5) == (MultiIndex{1, 1}));
0764   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(6) == (MultiIndex{1, 2}));
0765   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(7) == (MultiIndex{1, 3}));
0766   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(8) == (MultiIndex{2, 0}));
0767   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(9) == (MultiIndex{2, 1}));
0768   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(10) == (MultiIndex{2, 2}));
0769   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(11) == (MultiIndex{2, 3}));
0770   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(12) == (MultiIndex{3, 0}));
0771   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(13) == (MultiIndex{3, 1}));
0772   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(14) == (MultiIndex{3, 2}));
0773   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(15) == (MultiIndex{3, 3}));
0774   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(16) == (MultiIndex{4, 0}));
0775   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(17) == (MultiIndex{4, 1}));
0776   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(18) == (MultiIndex{4, 2}));
0777   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(19) == (MultiIndex{4, 3}));
0778   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(20) == (MultiIndex{5, 0}));
0779   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(21) == (MultiIndex{5, 1}));
0780   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(22) == (MultiIndex{5, 2}));
0781   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(23) == (MultiIndex{5, 3}));
0782 
0783   // multi bin indices -> flat bin index
0784   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 0}), 0u);
0785   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 1}), 1u);
0786   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 2}), 2u);
0787   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({0, 3}), 3u);
0788   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 0}), 4u);
0789   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 1}), 5u);
0790   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 2}), 6u);
0791   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({1, 3}), 7u);
0792   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 0}), 8u);
0793   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 1}), 9u);
0794   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 2}), 10u);
0795   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({2, 3}), 11u);
0796   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 0}), 12u);
0797   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 1}), 13u);
0798   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 2}), 14u);
0799   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({3, 3}), 15u);
0800   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 0}), 16u);
0801   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 1}), 17u);
0802   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 2}), 18u);
0803   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({4, 3}), 19u);
0804   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 0}), 20u);
0805   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 1}), 21u);
0806   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 2}), 22u);
0807   BOOST_CHECK_EQUAL(ma.getGlobalBinFromLocalBins({5, 3}), 23u);
0808 
0809   BOOST_CHECK(ma.getLocalBinsFromGlobalBin(ma.getGlobalBinFromPoint(
0810                   Point({{1.1, 1.7}}))) == MultiIndex({{5, 2}}));
0811 
0812   // inside checks
0813   BOOST_CHECK(!ma.isInside({-2., -1}));
0814   BOOST_CHECK(!ma.isInside({-2., 1.}));
0815   BOOST_CHECK(!ma.isInside({-2., 5.}));
0816   BOOST_CHECK(!ma.isInside({0.1, -1.}));
0817   BOOST_CHECK(!ma.isInside({6., -1.}));
0818   BOOST_CHECK(ma.isInside({0.5, 1.3}));
0819   BOOST_CHECK(!ma.isInside({1., -1.}));
0820   BOOST_CHECK(!ma.isInside({1., 0.3}));
0821   BOOST_CHECK(!ma.isInside({1., 3.}));
0822   BOOST_CHECK(!ma.isInside({-1., 3.}));
0823   BOOST_CHECK(!ma.isInside({0.2, 3.}));
0824   BOOST_CHECK(!ma.isInside({5., 3.}));
0825 
0826   // test some bin centers
0827   CHECK_CLOSE_ABS(ma.getBinCenter({1, 1}), (Point{0.125, 0.25}), 1e-6);
0828   CHECK_CLOSE_ABS(ma.getBinCenter({1, 2}), (Point{0.125, 1.75}), 1e-6);
0829   CHECK_CLOSE_ABS(ma.getBinCenter({2, 1}), (Point{0.375, 0.25}), 1e-6);
0830   CHECK_CLOSE_ABS(ma.getBinCenter({2, 2}), (Point{0.375, 1.75}), 1e-6);
0831   CHECK_CLOSE_ABS(ma.getBinCenter({3, 1}), (Point{0.625, 0.25}), 1e-6);
0832   CHECK_CLOSE_ABS(ma.getBinCenter({3, 2}), (Point{0.625, 1.75}), 1e-6);
0833   CHECK_CLOSE_ABS(ma.getBinCenter({4, 1}), (Point{0.875, 0.25}), 1e-6);
0834   CHECK_CLOSE_ABS(ma.getBinCenter({4, 2}), (Point{0.875, 1.75}), 1e-6);
0835 
0836   // test some lower-left bin edges
0837   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 1}), (Point{0., 0.}), 1e-6);
0838   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({1, 2}), (Point{0., 0.5}), 1e-6);
0839   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2, 1}), (Point{0.25, 0.}), 1e-6);
0840   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({2, 2}), (Point{0.25, 0.5}), 1e-6);
0841   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({3, 1}), (Point{0.5, 0.}), 1e-6);
0842   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({3, 2}), (Point{0.5, 0.5}), 1e-6);
0843   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({4, 1}), (Point{0.75, 0.}), 1e-6);
0844   CHECK_CLOSE_ABS(ma.getLowerLeftBinEdge({4, 2}), (Point{0.75, 0.5}), 1e-6);
0845 
0846   // test some upper-right bin edges
0847   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 1}), (Point{0.25, 0.5}), 1e-6);
0848   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({1, 2}), (Point{0.25, 3.}), 1e-6);
0849   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({2, 1}), (Point{0.5, 0.5}), 1e-6);
0850   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({2, 2}), (Point{0.5, 3.}), 1e-6);
0851   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({3, 1}), (Point{0.75, 0.5}), 1e-6);
0852   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({3, 2}), (Point{0.75, 3.}), 1e-6);
0853   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({4, 1}), (Point{1., 0.5}), 1e-6);
0854   CHECK_CLOSE_ABS(ma.getUpperRightBinEdge({4, 2}), (Point{1., 3.}), 1e-6);
0855 }
0856 
0857 BOOST_AUTO_TEST_CASE(neighborhood) {
0858   using bins_t = std::vector<std::size_t>;
0859 
0860   const Axis a(0.0, 1.0, 10u);
0861   const Axis b(0.0, 1.0, 10u);
0862   const Axis c(0.0, 1.0, 10u);
0863 
0864   const MultiAxis ma1(a);
0865   const MultiAxis ma2(a, b);
0866   const MultiAxis ma3(a, b, c);
0867 
0868   // 1D case
0869   BOOST_CHECK(ma1.getNeighborHoodIndices({0}, 1).collectVector() ==
0870               (bins_t{0, 1}));
0871   BOOST_CHECK(ma1.getNeighborHoodIndices({0}, 2).collectVector() ==
0872               (bins_t{0, 1, 2}));
0873   BOOST_CHECK(ma1.getNeighborHoodIndices({1}, 1).collectVector() ==
0874               (bins_t{0, 1, 2}));
0875   BOOST_CHECK(ma1.getNeighborHoodIndices({1}, 3).collectVector() ==
0876               (bins_t{0, 1, 2, 3, 4}));
0877   BOOST_CHECK(ma1.getNeighborHoodIndices({4}, 2).collectVector() ==
0878               (bins_t{2, 3, 4, 5, 6}));
0879   BOOST_CHECK(ma1.getNeighborHoodIndices({9}, 2).collectVector() ==
0880               (bins_t{7, 8, 9, 10, 11}));
0881   BOOST_CHECK(ma1.getNeighborHoodIndices({10}, 2).collectVector() ==
0882               (bins_t{8, 9, 10, 11}));
0883   BOOST_CHECK(ma1.getNeighborHoodIndices({11}, 2).collectVector() ==
0884               (bins_t{9, 10, 11}));
0885 
0886   // 2D case
0887   BOOST_CHECK(ma2.getNeighborHoodIndices({0, 0}, 1).collectVector() ==
0888               (bins_t{0, 1, 12, 13}));
0889   BOOST_CHECK(ma2.getNeighborHoodIndices({0, 1}, 1).collectVector() ==
0890               (bins_t{0, 1, 2, 12, 13, 14}));
0891   BOOST_CHECK(ma2.getNeighborHoodIndices({1, 0}, 1).collectVector() ==
0892               (bins_t{0, 1, 12, 13, 24, 25}));
0893   BOOST_CHECK(ma2.getNeighborHoodIndices({1, 1}, 1).collectVector() ==
0894               (bins_t{0, 1, 2, 12, 13, 14, 24, 25, 26}));
0895   BOOST_CHECK(ma2.getNeighborHoodIndices({5, 5}, 1).collectVector() ==
0896               (bins_t{52, 53, 54, 64, 65, 66, 76, 77, 78}));
0897   BOOST_CHECK(ma2.getNeighborHoodIndices({9, 10}, 2).collectVector() ==
0898               (bins_t{92,  93,  94,  95,  104, 105, 106, 107, 116, 117,
0899                       118, 119, 128, 129, 130, 131, 140, 141, 142, 143}));
0900 
0901   // 3D case
0902   BOOST_CHECK(ma3.getNeighborHoodIndices({0, 0, 0}, 1).collectVector() ==
0903               (bins_t{0, 1, 12, 13, 144, 145, 156, 157}));
0904   BOOST_CHECK(ma3.getNeighborHoodIndices({0, 0, 1}, 1).collectVector() ==
0905               (bins_t{0, 1, 2, 12, 13, 14, 144, 145, 146, 156, 157, 158}));
0906   BOOST_CHECK(ma3.getNeighborHoodIndices({0, 1, 0}, 1).collectVector() ==
0907               (bins_t{0, 1, 12, 13, 24, 25, 144, 145, 156, 157, 168, 169}));
0908   BOOST_CHECK(ma3.getNeighborHoodIndices({1, 0, 0}, 1).collectVector() ==
0909               (bins_t{0, 1, 12, 13, 144, 145, 156, 157, 288, 289, 300, 301}));
0910   BOOST_CHECK(ma3.getNeighborHoodIndices({0, 1, 1}, 1).collectVector() ==
0911               (bins_t{0, 1, 2, 12, 13, 14, 24, 25, 26, 144, 145, 146, 156, 157,
0912                       158, 168, 169, 170}));
0913   BOOST_CHECK(ma3.getNeighborHoodIndices({1, 1, 1}, 1).collectVector() ==
0914               (bins_t{0,   1,   2,   12,  13,  14,  24,  25,  26,
0915                       144, 145, 146, 156, 157, 158, 168, 169, 170,
0916                       288, 289, 290, 300, 301, 302, 312, 313, 314}));
0917   BOOST_CHECK(ma3.getNeighborHoodIndices({11, 10, 9}, 1).collectVector() ==
0918               (bins_t{1556, 1557, 1558, 1568, 1569, 1570, 1580, 1581, 1582,
0919                       1700, 1701, 1702, 1712, 1713, 1714, 1724, 1725, 1726}));
0920 
0921   // Neighbors array
0922   std::array<std::pair<int, int>, 1> a1;
0923   a1.at(0) = std::make_pair<int, int>(-1, 1);
0924   BOOST_CHECK(ma1.getNeighborHoodIndices({0}, a1).collectVector() ==
0925               (bins_t{0, 1}));
0926   BOOST_CHECK(ma1.getNeighborHoodIndices({2}, a1).collectVector() ==
0927               (bins_t{1, 2, 3}));
0928 
0929   a1.at(0) = std::make_pair<int, int>(2, 3);
0930   BOOST_CHECK(ma1.getNeighborHoodIndices({2}, a1).collectVector() ==
0931               (bins_t{4, 5}));
0932 
0933   a1.at(0) = std::make_pair<int, int>(-2, -1);
0934   BOOST_CHECK(ma1.getNeighborHoodIndices({2}, a1).collectVector() ==
0935               (bins_t{0, 1}));
0936 
0937   a1.at(0) = std::make_pair<int, int>(-3, -1);
0938   BOOST_CHECK(ma1.getNeighborHoodIndices({2}, a1).collectVector() ==
0939               (bins_t{0, 1}));
0940 
0941   const Axis d(AxisClosed, 0.0, 1.0, 10u);
0942 
0943   const MultiAxis ma1Cl(d);
0944 
0945   BOOST_CHECK(ma1Cl.getNeighborHoodIndices({0}, 1)
0946                   .collectVector()
0947                   .empty());  // underflow, makes no sense
0948   BOOST_CHECK(ma1Cl.getNeighborHoodIndices({11}, 1)
0949                   .collectVector()
0950                   .empty());  // overflow, makes no sense
0951   BOOST_CHECK(ma1Cl.getNeighborHoodIndices({1}, 1).collectVector() ==
0952               (bins_t{10, 1, 2}));
0953   BOOST_CHECK(ma1Cl.getNeighborHoodIndices({5}, 1).collectVector() ==
0954               (bins_t{4, 5, 6}));
0955 
0956   const Axis f(AxisClosed, 0.0, 1.0, 5u);
0957   const Axis e(AxisClosed, 0.0, 1.0, 5u);
0958 
0959   const MultiAxis ma2Cl(e, f);
0960 
0961   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({3, 3}, 1).collectVector() ==
0962               (bins_t{16, 17, 18, 23, 24, 25, 30, 31, 32}));
0963   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({1, 1}, 1).collectVector() ==
0964               (bins_t{40, 36, 37, 12, 8, 9, 19, 15, 16}));
0965   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({1, 5}, 1).collectVector() ==
0966               (bins_t{39, 40, 36, 11, 12, 8, 18, 19, 15}));
0967   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({5, 1}, 1).collectVector() ==
0968               (bins_t{33, 29, 30, 40, 36, 37, 12, 8, 9}));
0969   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({5, 5}, 1).collectVector() ==
0970               (bins_t{32, 33, 29, 39, 40, 36, 11, 12, 8}));
0971 
0972   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({3, 3}, 2).collectVector() ==
0973               (bins_t{8,  9,  10, 11, 12, 15, 16, 17, 18, 19, 22, 23, 24,
0974                       25, 26, 29, 30, 31, 32, 33, 36, 37, 38, 39, 40}));
0975   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({1, 1}, 2).collectVector() ==
0976               (bins_t{32, 33, 29, 30, 31, 39, 40, 36, 37, 38, 11, 12, 8,
0977                       9,  10, 18, 19, 15, 16, 17, 25, 26, 22, 23, 24}));
0978   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({1, 5}, 2).collectVector() ==
0979               (bins_t{31, 32, 33, 29, 30, 38, 39, 40, 36, 37, 10, 11, 12,
0980                       8,  9,  17, 18, 19, 15, 16, 24, 25, 26, 22, 23}));
0981   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({5, 1}, 2).collectVector() ==
0982               (bins_t{25, 26, 22, 23, 24, 32, 33, 29, 30, 31, 39, 40, 36,
0983                       37, 38, 11, 12, 8,  9,  10, 18, 19, 15, 16, 17}));
0984   BOOST_CHECK(ma2Cl.getNeighborHoodIndices({5, 5}, 2).collectVector() ==
0985               (bins_t{24, 25, 26, 22, 23, 31, 32, 33, 29, 30, 38, 39, 40,
0986                       36, 37, 10, 11, 12, 8,  9,  17, 18, 19, 15, 16}));
0987 
0988   std::array<std::pair<int, int>, 2> a2;
0989   a2.at(0) =
0990       std::make_pair<int, int>(-2, -1);  // only 2 bins left of requested bin
0991                                          // (not including the requested bin)
0992   a2.at(1) = std::make_pair<int, int>(
0993       -1, 2);  // one bin left of requested bin, the requested bin itself and 2
0994                // bins right of requested bin
0995   std::set<std::size_t> returnedBins;
0996 
0997   auto returnedBinsVec =
0998       ma2Cl.getNeighborHoodIndices({3, 2}, a2).collectVector();
0999   returnedBins.insert(returnedBinsVec.begin(), returnedBinsVec.end());
1000   std::set<std::size_t> expectedBins{{8, 9, 10, 11, 15, 16, 17, 18}};
1001   BOOST_CHECK(returnedBins == expectedBins);
1002 
1003   returnedBinsVec = ma2Cl.getNeighborHoodIndices({1, 5}, a2).collectVector();
1004   returnedBins.clear();
1005   returnedBins.insert(returnedBinsVec.begin(), returnedBinsVec.end());
1006   expectedBins = {{29, 30, 32, 33, 36, 37, 39, 40}};
1007   BOOST_CHECK(returnedBins == expectedBins);
1008 
1009   a2.at(0) = {-6, 7};
1010   a2.at(1) = {0, 0};
1011   returnedBinsVec = ma2Cl.getNeighborHoodIndices({1, 5}, a2).collectVector();
1012   returnedBins.clear();
1013   returnedBins.insert(returnedBinsVec.begin(), returnedBinsVec.end());
1014   expectedBins = {{12, 19, 26, 33, 40}};
1015   BOOST_CHECK(returnedBins == expectedBins);
1016 
1017   // @TODO 3D test would be nice, but should essentially not be a problem if
1018   // 2D works.
1019 
1020   // clang-format off
1021   /*
1022    *       1   2    3    4    5
1023    *   |------------------------|
1024    * 1 |  8 |  9 | 10 | 11 | 12 |
1025    *   |----|----|----|----|----|
1026    * 2 | 15 | 16 | 17 | 18 | 19 |
1027    *   |----|----|----|----|----|
1028    * 3 | 22 | 23 | 24 | 25 | 26 |
1029    *   |----|----|----|----|----|
1030    * 4 | 29 | 30 | 31 | 32 | 33 |
1031    *   |----|----|----|----|----|
1032    * 5 | 36 | 37 | 38 | 39 | 40 |
1033    *   |------------------------|
1034    */
1035   // clang-format on
1036 }
1037 
1038 BOOST_AUTO_TEST_CASE(closestPoints) {
1039   using Point1 = std::array<double, 1>;
1040   using Point2 = std::array<double, 2>;
1041   using Point3 = std::array<double, 3>;
1042   using bins_t = std::vector<std::size_t>;
1043 
1044   const Axis a(0.0, 1.0, 10u);
1045   const Axis b(0.0, 1.0, 5u);
1046   const Axis c(0.0, 1.0, 3u);
1047 
1048   const MultiAxis ma1(a);
1049   const MultiAxis ma2(a, b);
1050   const MultiAxis ma3(a, b, c);
1051 
1052   // 1D case
1053   CHECK_EQUAL_COLLECTIONS(
1054       ma1.getClosestPointsIndices(Point1{0.52}).collectVector(),
1055       (bins_t{6, 7}));
1056   CHECK_EQUAL_COLLECTIONS(
1057       ma1.getClosestPointsIndices(Point1{0.98}).collectVector(),
1058       (bins_t{10, 11}));
1059 
1060   // 2D case
1061   CHECK_EQUAL_COLLECTIONS(
1062       ma2.getClosestPointsIndices(Point2{0.52, 0.08}).collectVector(),
1063       (bins_t{43, 44, 50, 51}));
1064   CHECK_EQUAL_COLLECTIONS(
1065       ma2.getNeighborHoodIndices(ma2.getLocalBinsFromPoint(Point2{0.05, 0.08}),
1066                                  {0, 1})
1067           .collectVector(),
1068       (bins_t{8, 9, 15, 16}));
1069 
1070   // 3D case
1071   CHECK_EQUAL_COLLECTIONS(
1072       ma3.getClosestPointsIndices(Point3{0.23, 0.13, 0.61}).collectVector(),
1073       (bins_t{112, 113, 117, 118, 147, 148, 152, 153}));
1074   CHECK_EQUAL_COLLECTIONS(
1075       ma3.getClosestPointsIndices(Point3{0.52, 0.35, 0.71}).collectVector(),
1076       (bins_t{223, 224, 228, 229, 258, 259, 263, 264}));
1077 
1078   using EAxisClosed = Axis<AxisType::Equidistant, AxisBoundaryType::Closed>;
1079 
1080   using MultiAxis1Cl_t = MultiAxis<EAxisClosed>;
1081   using MultiAxis2Cl_t = MultiAxis<EAxisClosed, EAxisClosed>;
1082   // using MultiAxis3Cl_t = MultiAxis<EAxisClosed, EAxisClosed, EAxisClosed>;
1083 
1084   EAxisClosed aCl(0.0, 1.0, 10u);
1085   EAxisClosed bCl(0.0, 1.0, 5u);
1086   // EAxisClosed   cCl(0.0, 1.0, 3u);
1087 
1088   MultiAxis1Cl_t ma1Cl(std::make_tuple(aCl));
1089   MultiAxis2Cl_t ma2Cl(std::make_tuple(aCl, bCl));
1090 
1091   // 1D case
1092   CHECK_EQUAL_COLLECTIONS(
1093       ma1Cl.getClosestPointsIndices(Point1{0.52}).collectVector(),
1094       (bins_t{6, 7}));
1095   CHECK_EQUAL_COLLECTIONS(
1096       ma1Cl.getClosestPointsIndices(Point1{0.98}).collectVector(),
1097       (bins_t{10, 1}));
1098 
1099   // 2D case
1100   CHECK_EQUAL_COLLECTIONS(
1101       ma2Cl.getClosestPointsIndices(Point2{0.52, 0.08}).collectVector(),
1102       (bins_t{43, 44, 50, 51}));
1103   CHECK_EQUAL_COLLECTIONS(
1104       ma2Cl.getClosestPointsIndices(Point2{0.52, 0.68}).collectVector(),
1105       (bins_t{46, 47, 53, 54}));
1106   CHECK_EQUAL_COLLECTIONS(
1107       ma2Cl.getClosestPointsIndices(Point2{0.52, 0.88}).collectVector(),
1108       (bins_t{47, 43, 54, 50}));
1109   CHECK_EQUAL_COLLECTIONS(
1110       ma2Cl.getClosestPointsIndices(Point2{0.05, 0.08}).collectVector(),
1111       (bins_t{8, 9, 15, 16}));
1112   CHECK_EQUAL_COLLECTIONS(
1113       ma2Cl.getClosestPointsIndices(Point2{0.9, 0.95}).collectVector(),
1114       (bins_t{75, 71, 12, 8}));
1115 
1116   // @TODO: 3D checks would also be nice
1117 
1118   const Axis aOp(AxisBound, 0.0, 1.0, 10u);
1119   const Axis bOp(AxisBound, 0.0, 1.0, 5u);
1120 
1121   const MultiAxis ma1Op(aOp);
1122   const MultiAxis ma2Op(aOp, bOp);
1123 
1124   // 1D case
1125   CHECK_EQUAL_COLLECTIONS(
1126       ma1Op.getClosestPointsIndices(Point1{0.52}).collectVector(),
1127       (bins_t{6, 7}));
1128   CHECK_EQUAL_COLLECTIONS(
1129       ma1Op.getClosestPointsIndices(Point1{0.98}).collectVector(),
1130       (bins_t{10}));
1131   CHECK_EQUAL_COLLECTIONS(
1132       ma1Op.getClosestPointsIndices(Point1{0.88}).collectVector(),
1133       (bins_t{9, 10}));
1134 
1135   // 2D case
1136   CHECK_EQUAL_COLLECTIONS(
1137       ma2Op.getClosestPointsIndices(Point2{0.52, 0.08}).collectVector(),
1138       (bins_t{43, 44, 50, 51}));
1139   CHECK_EQUAL_COLLECTIONS(
1140       ma2Op.getClosestPointsIndices(Point2{0.52, 0.68}).collectVector(),
1141       (bins_t{46, 47, 53, 54}));
1142   CHECK_EQUAL_COLLECTIONS(
1143       ma2Op.getClosestPointsIndices(Point2{0.52, 0.88}).collectVector(),
1144       (bins_t{47, 54}));
1145   CHECK_EQUAL_COLLECTIONS(
1146       ma2Op.getClosestPointsIndices(Point2{0.05, 0.1}).collectVector(),
1147       (bins_t{8, 9, 15, 16}));
1148   CHECK_EQUAL_COLLECTIONS(
1149       ma2Op.getClosestPointsIndices(Point2{0.95, 0.95}).collectVector(),
1150       (bins_t{75}));
1151 
1152   // @TODO: 3D checks would also be nice
1153 
1154   // clang-format off
1155   /*
1156    *       1    2    3    4    5
1157    *    |------------------------|
1158    *  1 |  8 |  9 | 10 | 11 | 12 |
1159    *    |----|----|----|----|----|
1160    *  2 | 15 | 16 | 17 | 18 | 19 |
1161    *    |----|----|----|----|----|
1162    *  3 | 22 | 23 | 24 | 25 | 26 |
1163    *    |----|----|----|----|----|
1164    *  4 | 29 | 30 | 31 | 32 | 33 |
1165    *    |----|----|----|----|----|
1166    *  5 | 36 | 37 | 38 | 39 | 40 |
1167    *    |------------------------|
1168    *  6 | 43 | 44 | 45 | 46 | 47 |
1169    *    |------------------------|
1170    *  7 | 50 | 51 | 52 | 53 | 54 |
1171    *    |------------------------|
1172    *  8 | 57 | 58 | 59 | 60 | 61 |
1173    *    |------------------------|
1174    *  9 | 64 | 65 | 66 | 67 | 68 |
1175    *    |------------------------|
1176    * 10 | 71 | 72 | 73 | 74 | 75 |
1177    *    |------------------------|
1178    * 77   78   79   80   81   82   83
1179    */
1180   // clang-format on
1181 }
1182 
1183 BOOST_AUTO_TEST_CASE(Output) {
1184   const Axis a{AxisOpen, 0.0, 1.0, 10u};
1185   const Axis b{AxisBound, {1, 2, 3}};
1186 
1187   const MultiAxis ma(a, b);
1188 
1189   std::stringstream ss;
1190   ss << ma;
1191   BOOST_CHECK_EQUAL(ss.str(),
1192                     "Axis<Equidistant, Open>(0, 1, 10, Undefined), "
1193                     "Axis<Variable, Bound>({1, 2, 3}, Undefined)");
1194 
1195   const IMultiAxis& ima = ma;
1196 
1197   ss.str("");
1198 
1199   ss << ima;
1200 
1201   BOOST_CHECK_EQUAL(ss.str(),
1202                     "Axis<Equidistant, Open>(0, 1, 10, Undefined), "
1203                     "Axis<Variable, Bound>({1, 2, 3}, Undefined)");
1204 }
1205 
1206 BOOST_AUTO_TEST_CASE(Equality) {
1207   const Axis a{AxisOpen, 0.0, 1.0, 10u};
1208   const Axis b{AxisBound, {1, 2, 3}};
1209   const Axis c{AxisClosed, {1, 2, 5}};
1210 
1211   const MultiAxis ma_ab(a, b);
1212   const MultiAxis ma_ac(a, c);
1213 
1214   BOOST_CHECK_EQUAL(ma_ab, ma_ab);
1215   BOOST_CHECK_EQUAL(ma_ac, ma_ac);
1216   BOOST_CHECK_NE(ma_ab, ma_ac);
1217 
1218   const IMultiAxis& ima_ab = ma_ab;
1219   const IMultiAxis& ima_ac = ma_ac;
1220 
1221   BOOST_CHECK_EQUAL(ima_ab, ima_ab);
1222   BOOST_CHECK_EQUAL(ima_ac, ima_ac);
1223 }
1224 
1225 BOOST_AUTO_TEST_SUITE_END()
1226 
1227 }  // namespace ActsTests