Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:13

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 #pragma once
0010 
0011 // Project include(s).
0012 #include "detray/algebra/concepts.hpp"
0013 #include "detray/algebra/type_traits.hpp"
0014 
0015 // Test include(s).
0016 #include "detray/test/framework/fixture_base.hpp"
0017 #include "detray/test/framework/types.hpp"
0018 
0019 namespace detray::test {
0020 
0021 /// Test case class, contains the basic test definitions and algebra types
0022 class detray_algebra : public fixture_base<> {
0023   using base = fixture_base<>;
0024 
0025  public:
0026   /// Constructor
0027   using base::base;
0028 
0029  protected:
0030 #if !DETRAY_ALGEBRA_VC_AOS
0031   template <std::size_t ROWS, std::size_t COLS>
0032   void matrix_test_ops_any_matrix() {
0033     // Test the set_product method.
0034     {
0035       matrix<ROWS, ROWS> m1;
0036       matrix<ROWS, COLS> m2;
0037 
0038       for (std::size_t i = 0; i < ROWS; ++i) {
0039         for (std::size_t j = 0; j < ROWS; ++j) {
0040           detray::getter::element(m1, i, j) = static_cast<scalar>(i * ROWS + j);
0041         }
0042       }
0043 
0044       for (std::size_t i = 0; i < ROWS; ++i) {
0045         for (std::size_t j = 0; j < COLS; ++j) {
0046           detray::getter::element(m2, i, j) = static_cast<scalar>(i * COLS + j);
0047         }
0048       }
0049 
0050       {
0051         matrix<ROWS, COLS> r1 = m1 * m2;
0052         matrix<ROWS, COLS> r2;
0053         detray::matrix::set_product(r2, m1, m2);
0054 
0055         for (std::size_t i = 0; i < ROWS; ++i) {
0056           for (std::size_t j = 0; j < COLS; ++j) {
0057             ASSERT_NEAR(detray::getter::element(r1, i, j),
0058                         detray::getter::element(r2, i, j), this->epsilon());
0059           }
0060         }
0061       }
0062     }
0063 
0064     // Test the set_product_right_transpose method.
0065     {
0066       matrix<ROWS, ROWS> m1;
0067       matrix<COLS, ROWS> m2;
0068 
0069       for (std::size_t i = 0; i < ROWS; ++i) {
0070         for (std::size_t j = 0; j < ROWS; ++j) {
0071           detray::getter::element(m1, i, j) = static_cast<scalar>(i * ROWS + j);
0072         }
0073       }
0074 
0075       for (std::size_t i = 0; i < COLS; ++i) {
0076         for (std::size_t j = 0; j < ROWS; ++j) {
0077           detray::getter::element(m2, i, j) = static_cast<scalar>(i * COLS + j);
0078         }
0079       }
0080 
0081       {
0082         matrix<ROWS, COLS> r1 = m1 * detray::matrix::transpose(m2);
0083         matrix<ROWS, COLS> r2;
0084         detray::matrix::set_product_right_transpose(r2, m1, m2);
0085 
0086         for (std::size_t i = 0; i < ROWS; ++i) {
0087           for (std::size_t j = 0; j < COLS; ++j) {
0088             ASSERT_NEAR(detray::getter::element(r1, i, j),
0089                         detray::getter::element(r2, i, j), this->epsilon());
0090           }
0091         }
0092       }
0093     }
0094 
0095     // Test the set_product_left_transpose method.
0096     {
0097       matrix<ROWS, ROWS> m1;
0098       matrix<ROWS, COLS> m2;
0099 
0100       for (std::size_t i = 0; i < ROWS; ++i) {
0101         for (std::size_t j = 0; j < ROWS; ++j) {
0102           detray::getter::element(m1, i, j) = static_cast<scalar>(i * ROWS + j);
0103         }
0104       }
0105 
0106       for (std::size_t i = 0; i < ROWS; ++i) {
0107         for (std::size_t j = 0; j < COLS; ++j) {
0108           detray::getter::element(m2, i, j) = static_cast<scalar>(i * COLS + j);
0109         }
0110       }
0111 
0112       {
0113         matrix<ROWS, COLS> r1 = detray::matrix::transpose(m1) * m2;
0114         matrix<ROWS, COLS> r2;
0115         detray::matrix::set_product_left_transpose(r2, m1, m2);
0116 
0117         for (std::size_t i = 0; i < ROWS; ++i) {
0118           for (std::size_t j = 0; j < COLS; ++j) {
0119             ASSERT_NEAR(detray::getter::element(r1, i, j),
0120                         detray::getter::element(r2, i, j), this->epsilon());
0121           }
0122         }
0123       }
0124 
0125       // Test the transposable_product method.
0126       {
0127         // Both untransposed
0128         {
0129           matrix<ROWS, COLS> r1 = m1 * m2;
0130           matrix<ROWS, COLS> r2 =
0131               detray::matrix::transposed_product<false, false>(m1, m2);
0132 
0133           for (std::size_t i = 0; i < ROWS; ++i) {
0134             for (std::size_t j = 0; j < COLS; ++j) {
0135               ASSERT_NEAR(detray::getter::element(r1, i, j),
0136                           detray::getter::element(r2, i, j), this->epsilon());
0137             }
0138           }
0139         }
0140       }
0141     }
0142   }
0143 
0144   template <std::size_t N>
0145   void matrix_test_ops_square_matrix() {
0146     {
0147       matrix<N, N> m1;
0148       matrix<N, N> m2;
0149 
0150       for (std::size_t i = 0; i < N; ++i) {
0151         for (std::size_t j = 0; j < N; ++j) {
0152           detray::getter::element(m1, i, j) = static_cast<scalar>(i * N + j);
0153           detray::getter::element(m2, i, j) =
0154               -1.f * static_cast<scalar>(i * N + j) + 42;
0155         }
0156       }
0157 
0158       // Test the set_product method.
0159       {
0160         matrix<N, N> r1 = m1 * m2;
0161         matrix<N, N> r2;
0162         detray::matrix::set_product(r2, m1, m2);
0163 
0164         for (std::size_t i = 0; i < N; ++i) {
0165           for (std::size_t j = 0; j < N; ++j) {
0166             ASSERT_NEAR(detray::getter::element(r1, i, j),
0167                         detray::getter::element(r2, i, j), this->epsilon());
0168           }
0169         }
0170       }
0171 
0172       // Test the set_product_right_transpose method.
0173       {
0174         matrix<N, N> r1 = m1 * detray::matrix::transpose(m2);
0175         matrix<N, N> r2;
0176         detray::matrix::set_product_right_transpose(r2, m1, m2);
0177 
0178         for (std::size_t i = 0; i < N; ++i) {
0179           for (std::size_t j = 0; j < N; ++j) {
0180             ASSERT_NEAR(detray::getter::element(r1, i, j),
0181                         detray::getter::element(r2, i, j), this->epsilon());
0182           }
0183         }
0184       }
0185 
0186       // Test the set_product_left_transpose method.
0187       {
0188         matrix<N, N> r1 = detray::matrix::transpose(m1) * m2;
0189         matrix<N, N> r2;
0190         detray::matrix::set_product_left_transpose(r2, m1, m2);
0191 
0192         for (std::size_t i = 0; i < N; ++i) {
0193           for (std::size_t j = 0; j < N; ++j) {
0194             ASSERT_NEAR(detray::getter::element(r1, i, j),
0195                         detray::getter::element(r2, i, j), this->epsilon());
0196           }
0197         }
0198       }
0199 
0200       // Test the set_inplace_product_right method.
0201       {
0202         matrix<N, N> r1 = m1 * m2;
0203         matrix<N, N> r2 = m1;
0204         detray::matrix::set_inplace_product_right(r2, m2);
0205 
0206         for (std::size_t i = 0; i < N; ++i) {
0207           for (std::size_t j = 0; j < N; ++j) {
0208             ASSERT_NEAR(detray::getter::element(r1, i, j),
0209                         detray::getter::element(r2, i, j), this->epsilon());
0210           }
0211         }
0212       }
0213 
0214       // Test the set_inplace_product_left method.
0215       {
0216         matrix<N, N> r1 = m1 * m2;
0217         matrix<N, N> r2 = m2;
0218         detray::matrix::set_inplace_product_left(r2, m1);
0219 
0220         for (std::size_t i = 0; i < N; ++i) {
0221           for (std::size_t j = 0; j < N; ++j) {
0222             ASSERT_NEAR(detray::getter::element(r1, i, j),
0223                         detray::getter::element(r2, i, j), this->epsilon());
0224           }
0225         }
0226       }
0227 
0228       // Test the set_inplace_product_right_transpose method.
0229       {
0230         matrix<N, N> r1 = m1 * detray::matrix::transpose(m2);
0231         matrix<N, N> r2 = m1;
0232         detray::matrix::set_inplace_product_right_transpose(r2, m2);
0233 
0234         for (std::size_t i = 0; i < N; ++i) {
0235           for (std::size_t j = 0; j < N; ++j) {
0236             ASSERT_NEAR(detray::getter::element(r1, i, j),
0237                         detray::getter::element(r2, i, j), this->epsilon());
0238           }
0239         }
0240       }
0241 
0242       // Test the set_inplace_product_left_transpose method.
0243       {
0244         matrix<N, N> r1 = detray::matrix::transpose(m1) * m2;
0245         matrix<N, N> r2 = m2;
0246         detray::matrix::set_inplace_product_left_transpose(r2, m1);
0247 
0248         for (std::size_t i = 0; i < N; ++i) {
0249           for (std::size_t j = 0; j < N; ++j) {
0250             ASSERT_NEAR(detray::getter::element(r1, i, j),
0251                         detray::getter::element(r2, i, j), this->epsilon());
0252           }
0253         }
0254       }
0255 
0256       // Test the transposable_product method.
0257       {
0258         // Only left transposed
0259         {
0260           matrix<N, N> r1 = detray::matrix::transpose(m1) * m2;
0261           matrix<N, N> r2 =
0262               detray::matrix::transposed_product<true, false>(m1, m2);
0263 
0264           for (std::size_t i = 0; i < N; ++i) {
0265             for (std::size_t j = 0; j < N; ++j) {
0266               ASSERT_NEAR(detray::getter::element(r1, i, j),
0267                           detray::getter::element(r2, i, j), this->epsilon());
0268             }
0269           }
0270         }
0271 
0272         // Only right transposed
0273         {
0274           matrix<N, N> r1 = m1 * detray::matrix::transpose(m2);
0275           matrix<N, N> r2 =
0276               detray::matrix::transposed_product<false, true>(m1, m2);
0277 
0278           for (std::size_t i = 0; i < N; ++i) {
0279             for (std::size_t j = 0; j < N; ++j) {
0280               ASSERT_NEAR(detray::getter::element(r1, i, j),
0281                           detray::getter::element(r2, i, j), this->epsilon());
0282             }
0283           }
0284         }
0285 
0286         // Both transposed
0287         {
0288           matrix<N, N> r1 =
0289               detray::matrix::transpose(m1) * detray::matrix::transpose(m2);
0290           matrix<N, N> r2 =
0291               detray::matrix::transposed_product<true, true>(m1, m2);
0292 
0293           for (std::size_t i = 0; i < N; ++i) {
0294             for (std::size_t j = 0; j < N; ++j) {
0295               ASSERT_NEAR(detray::getter::element(r1, i, j),
0296                           detray::getter::element(r2, i, j), this->epsilon());
0297             }
0298           }
0299         }
0300       }
0301     }
0302 
0303     this->template matrix_test_ops_any_matrix<N, N>();
0304   }
0305 
0306   template <std::size_t M, std::size_t N, std::size_t O>
0307   void matrix_test_ops_inhomogeneous_multipliable_matrices() {
0308     // Test NxM and MxO matrix multiplication
0309     {
0310       matrix<N, M> m1;
0311       matrix<M, O> m2;
0312 
0313       for (std::size_t i = 0; i < N; ++i) {
0314         for (std::size_t j = 0; j < M; ++j) {
0315           detray::getter::element(m1, i, j) = static_cast<scalar>(i * N + j);
0316         }
0317       }
0318 
0319       for (std::size_t i = 0; i < M; ++i) {
0320         for (std::size_t j = 0; j < O; ++j) {
0321           detray::getter::element(m2, i, j) = static_cast<scalar>(i * M + j);
0322         }
0323       }
0324 
0325       {
0326         matrix<N, O> r1 = m1 * m2;
0327         matrix<N, O> r2 =
0328             detray::matrix::transposed_product<false, false>(m1, m2);
0329 
0330         for (std::size_t i = 0; i < N; ++i) {
0331           for (std::size_t j = 0; j < O; ++j) {
0332             ASSERT_NEAR(detray::getter::element(r1, i, j),
0333                         detray::getter::element(r2, i, j), this->epsilon());
0334           }
0335         }
0336       }
0337     }
0338 
0339     // Test NxM and (OxM)^T matrix multiplication
0340     {
0341       matrix<N, M> m1;
0342       matrix<O, M> m2;
0343 
0344       for (std::size_t i = 0; i < N; ++i) {
0345         for (std::size_t j = 0; j < M; ++j) {
0346           detray::getter::element(m1, i, j) = static_cast<scalar>(i * N + j);
0347         }
0348       }
0349 
0350       for (std::size_t i = 0; i < O; ++i) {
0351         for (std::size_t j = 0; j < M; ++j) {
0352           detray::getter::element(m2, i, j) = static_cast<scalar>(i * O + j);
0353         }
0354       }
0355 
0356       {
0357         matrix<N, O> r1 = m1 * detray::matrix::transpose(m2);
0358         matrix<N, O> r2 =
0359             detray::matrix::transposed_product<false, true>(m1, m2);
0360 
0361         for (std::size_t i = 0; i < N; ++i) {
0362           for (std::size_t j = 0; j < O; ++j) {
0363             ASSERT_NEAR(detray::getter::element(r1, i, j),
0364                         detray::getter::element(r2, i, j), this->epsilon());
0365           }
0366         }
0367       }
0368     }
0369 
0370     // Test (MxN)^T and MxO matrix multiplication
0371     {
0372       matrix<M, N> m1;
0373       matrix<M, O> m2;
0374 
0375       for (std::size_t i = 0; i < M; ++i) {
0376         for (std::size_t j = 0; j < N; ++j) {
0377           detray::getter::element(m1, i, j) = static_cast<scalar>(i * M + j);
0378         }
0379       }
0380 
0381       for (std::size_t i = 0; i < M; ++i) {
0382         for (std::size_t j = 0; j < O; ++j) {
0383           detray::getter::element(m2, i, j) = static_cast<scalar>(i * M + j);
0384         }
0385       }
0386 
0387       {
0388         matrix<N, O> r1 = detray::matrix::transpose(m1) * m2;
0389         matrix<N, O> r2 =
0390             detray::matrix::transposed_product<true, false>(m1, m2);
0391 
0392         for (std::size_t i = 0; i < N; ++i) {
0393           for (std::size_t j = 0; j < O; ++j) {
0394             ASSERT_NEAR(detray::getter::element(r1, i, j),
0395                         detray::getter::element(r2, i, j), this->epsilon());
0396           }
0397         }
0398       }
0399     }
0400 
0401     // Test (MxN)^T and (OxM)^T matrix multiplication
0402     {
0403       matrix<M, N> m1;
0404       matrix<O, M> m2;
0405 
0406       for (std::size_t i = 0; i < M; ++i) {
0407         for (std::size_t j = 0; j < N; ++j) {
0408           detray::getter::element(m1, i, j) = static_cast<scalar>(i * M + j);
0409         }
0410       }
0411 
0412       for (std::size_t i = 0; i < O; ++i) {
0413         for (std::size_t j = 0; j < M; ++j) {
0414           detray::getter::element(m2, i, j) = static_cast<scalar>(i * O + j);
0415         }
0416       }
0417 
0418       {
0419         matrix<N, O> r1 =
0420             detray::matrix::transpose(m1) * detray::matrix::transpose(m2);
0421         matrix<N, O> r2 =
0422             detray::matrix::transposed_product<true, true>(m1, m2);
0423 
0424         for (std::size_t i = 0; i < N; ++i) {
0425           for (std::size_t j = 0; j < O; ++j) {
0426             ASSERT_NEAR(detray::getter::element(r1, i, j),
0427                         detray::getter::element(r2, i, j), this->epsilon());
0428           }
0429         }
0430       }
0431     }
0432   }
0433 #endif
0434 };
0435 
0436 }  // namespace detray::test