File indexing completed on 2026-05-27 07:24:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/test/cpu/algebra_fixture.hpp"
0011
0012
0013 #include "detray/algebra/utils/approximately_equal.hpp"
0014 #include "detray/algebra/utils/casts.hpp"
0015 #include "detray/algebra/utils/print.hpp"
0016
0017
0018 #include <gtest/gtest.h>
0019
0020 namespace detray::test {
0021
0022
0023 TEST_F(detray_algebra, vector2D) {
0024
0025 point2 vA{0.f, 1.f};
0026 ASSERT_EQ(vA[0], 0.f);
0027 ASSERT_EQ(vA[1], 1.f);
0028
0029
0030 std::cout << vA << std::endl;
0031
0032
0033 ASSERT_TRUE(detray::algebra::approx_equal(vA, vA));
0034 ASSERT_TRUE(detray::algebra::approx_equal(vA, vA, this->epsilon()));
0035
0036 scalar rel_err{1.f + 10.f * this->epsilon()};
0037 point2 vA_err = rel_err * vA;
0038 ASSERT_TRUE(
0039 detray::algebra::approx_equal(vA, vA_err, 11.f * this->epsilon()));
0040 ASSERT_FALSE(
0041 detray::algebra::approx_equal(vA, vA_err, 9.f * this->epsilon()));
0042
0043 rel_err = 1.f + 17.f * this->epsilon();
0044 vA_err = rel_err * vA;
0045 ASSERT_TRUE(
0046 detray::algebra::approx_equal(vA, vA_err, 18.f * this->epsilon()));
0047 ASSERT_FALSE(
0048 detray::algebra::approx_equal(vA, vA_err, 16.f * this->epsilon()));
0049
0050 const auto vA_cast_f = detray::algebra::cast_to<float>(vA);
0051
0052 for (index i = 0; i < 2; ++i) {
0053 auto elem_i = vA_cast_f[i];
0054
0055 static_assert(std::same_as<decltype(elem_i), float>);
0056 ASSERT_FLOAT_EQ(elem_i, static_cast<float>(vA[i]));
0057 }
0058
0059 const auto vA_cast_d = detray::algebra::cast_to<double>(vA);
0060
0061 for (index i = 0; i < 2; ++i) {
0062 auto elem_i = vA_cast_d[i];
0063
0064 static_assert(std::same_as<decltype(elem_i), double>);
0065 ASSERT_DOUBLE_EQ(elem_i, static_cast<double>(vA[i]));
0066 }
0067
0068 const auto vA_cast_i = detray::algebra::cast_to<int>(vA);
0069
0070 for (index i = 0; i < 2; ++i) {
0071 auto elem_i = vA_cast_i[i];
0072
0073 static_assert(std::same_as<decltype(elem_i), int>);
0074 ASSERT_EQ(elem_i, static_cast<int>(vA[i]));
0075 }
0076
0077
0078 point2 vB = vA;
0079 ASSERT_EQ(vB[0], 0.f);
0080 ASSERT_EQ(vB[1], 1.f);
0081
0082
0083 point2 vC = vA + vB;
0084 ASSERT_EQ(vC[0], 0.f);
0085 ASSERT_EQ(vC[1], 2.f);
0086
0087
0088 point2 vC2 = vC * 2.f;
0089 ASSERT_EQ(vC2[0], 0.f);
0090 ASSERT_EQ(vC2[1], 4.f);
0091
0092
0093 vector2 vD{1.f, 1.f};
0094 scalar phi = detray::vector::phi(vD);
0095 ASSERT_NEAR(phi, constant<scalar>::pi_4, this->epsilon());
0096
0097 scalar perp = detray::vector::perp(vD);
0098 ASSERT_NEAR(perp, std::sqrt(2.), this->epsilon());
0099
0100 scalar norm = detray::vector::norm(vD);
0101 ASSERT_NEAR(norm, std::sqrt(2.), this->epsilon());
0102
0103 vector2 vDnorm = detray::vector::normalize(vD);
0104 ASSERT_NEAR(vDnorm[0], 1. / std::sqrt(2.), this->epsilon());
0105 ASSERT_NEAR(vDnorm[1], 1. / std::sqrt(2.), this->epsilon());
0106
0107
0108 point2 vE{100.f, 462809.f};
0109
0110 ASSERT_TRUE(detray::algebra::approx_equal(vE, vE));
0111 ASSERT_TRUE(detray::algebra::approx_equal(vE, vE, this->epsilon()));
0112
0113 rel_err = 1.f + 10.f * this->epsilon();
0114 point2 vE_err = rel_err * vE;
0115 ASSERT_TRUE(
0116 detray::algebra::approx_equal(vE, vE_err, 11.f * this->epsilon()));
0117 ASSERT_FALSE(
0118 detray::algebra::approx_equal(vE, vE_err, 9.f * this->epsilon()));
0119
0120 point2 vE_abs_err{100.00001f, 462809.05f};
0121 ASSERT_TRUE(detray::algebra::approx_equal(vE, vE_abs_err, 0.00001f));
0122 ASSERT_FALSE(detray::algebra::approx_equal(vE, vE_abs_err, this->epsilon()));
0123
0124 rel_err = 1.f + 17.f * this->epsilon();
0125 vE_err = rel_err * vE;
0126 ASSERT_TRUE(
0127 detray::algebra::approx_equal(vE, vE_err, 18.f * this->epsilon()));
0128 ASSERT_FALSE(
0129 detray::algebra::approx_equal(vE, vE_err, 16.f * this->epsilon()));
0130 }
0131
0132
0133 TEST_F(detray_algebra, vector3D) {
0134
0135 static_assert(detray::concepts::scalar<scalar>);
0136 static_assert(!detray::concepts::vector<scalar>);
0137
0138 static_assert(!detray::concepts::scalar<vector3>);
0139 static_assert(detray::concepts::vector<vector3>);
0140 static_assert(detray::concepts::vector3D<vector3>);
0141 static_assert(!detray::concepts::vector2D<vector3>);
0142
0143 static_assert(!detray::concepts::scalar<vector2>);
0144 static_assert(detray::concepts::vector<vector2>);
0145 static_assert(detray::concepts::vector2D<vector2>);
0146 static_assert(!detray::concepts::vector3D<vector2>);
0147
0148
0149 vector3 vA{0.f, 1.f, 2.f};
0150 ASSERT_EQ(vA[0], 0.f);
0151 ASSERT_EQ(vA[1], 1.f);
0152 ASSERT_EQ(vA[2], 2.f);
0153
0154
0155 std::cout << vA << std::endl;
0156
0157
0158 const auto vA_cast_f = detray::algebra::cast_to<float>(vA);
0159
0160 for (index i = 0; i < 3; ++i) {
0161 auto elem_i = vA_cast_f[i];
0162
0163 static_assert(std::same_as<decltype(elem_i), float>);
0164 ASSERT_FLOAT_EQ(elem_i, static_cast<float>(vA[i]));
0165 }
0166
0167 const auto vA_cast_d = detray::algebra::cast_to<double>(vA);
0168
0169 for (index i = 0; i < 3; ++i) {
0170 auto elem_i = vA_cast_d[i];
0171
0172 static_assert(std::same_as<decltype(elem_i), double>);
0173 ASSERT_DOUBLE_EQ(elem_i, static_cast<double>(vA[i]));
0174 }
0175
0176 const auto vA_cast_i = detray::algebra::cast_to<int>(vA);
0177
0178 for (index i = 0; i < 3; ++i) {
0179 auto elem_i = vA_cast_i[i];
0180
0181 static_assert(std::same_as<decltype(elem_i), int>);
0182 ASSERT_EQ(elem_i, static_cast<int>(vA[i]));
0183 }
0184
0185
0186 vector3 vB = vA;
0187 ASSERT_EQ(vB[0], 0.f);
0188 ASSERT_EQ(vB[1], 1.f);
0189 ASSERT_EQ(vB[2], 2.f);
0190
0191
0192 vector3 vC = vA + vB;
0193 ASSERT_EQ(vC[0], 0.f);
0194 ASSERT_EQ(vC[1], 2.f);
0195 ASSERT_EQ(vC[2], 4.f);
0196
0197
0198 vector3 vC2 = vC * 2.0f;
0199 ASSERT_EQ(vC2[0], 0.f);
0200 ASSERT_EQ(vC2[1], 4.f);
0201 ASSERT_EQ(vC2[2], 8.f);
0202
0203
0204 vector3 vD{1.f, 1.f, 1.f};
0205 scalar phi = detray::vector::phi(vD);
0206 ASSERT_NEAR(phi, constant<scalar>::pi_4, this->epsilon());
0207
0208 scalar theta = detray::vector::theta(vD);
0209 ASSERT_NEAR(theta, std::atan2(std::sqrt(2.), 1.), this->epsilon());
0210
0211 scalar eta = detray::vector::eta(vD);
0212 ASSERT_NEAR(eta, 0.65847891569137573, this->tolerance());
0213
0214 scalar perp = detray::vector::perp(vD);
0215 ASSERT_NEAR(perp, std::sqrt(2.), this->epsilon());
0216
0217 scalar norm = detray::vector::norm(vD);
0218 ASSERT_NEAR(norm, std::sqrt(3.), this->epsilon());
0219 }
0220
0221
0222 TEST_F(detray_algebra, element_getter) {
0223 vector3 v3{1.f, 1.f, 1.f};
0224
0225
0226 vector3 v3n = detray::vector::normalize(v3);
0227 ASSERT_NEAR(v3n[0], 1. / std::sqrt(3.), this->epsilon());
0228 ASSERT_NEAR(v3n[1], 1. / std::sqrt(3.), this->epsilon());
0229 ASSERT_NEAR(v3n[2], 1. / std::sqrt(3.), this->epsilon());
0230
0231
0232 vector3 z = detray::vector::normalize(vector3{3.f, 2.f, 1.f});
0233 vector3 x = detray::vector::normalize(vector3{2.f, -3.f, 0.f});
0234 vector3 y = detray::vector::cross(z, detray::vector::normalize(x));
0235
0236
0237 ASSERT_NEAR(detray::vector::dot(x, y), 0.f, this->epsilon());
0238 ASSERT_NEAR(detray::vector::dot(y, z), 0.f, this->epsilon());
0239 ASSERT_NEAR(detray::vector::dot(z, x), 0.f, this->epsilon());
0240 }
0241
0242
0243
0244
0245 TEST_F(detray_algebra, dot_product_with_ops) {
0246 vector3 v1{1.f, 2.f, 3.f};
0247 vector3 v2{3.f, 4.f, 5.f};
0248
0249 ASSERT_NEAR(detray::vector::dot(v1 + v2, v2), 76.f, this->epsilon());
0250 ASSERT_NEAR(detray::vector::dot(v1, v2 - v1), 12.f, this->epsilon());
0251 ASSERT_NEAR(detray::vector::dot(v1 + v2, v1 - v2), -36.f, this->epsilon());
0252 ASSERT_NEAR(detray::vector::dot(v1 + v2, 2 * v2), 152.f, this->epsilon());
0253 }
0254
0255
0256
0257
0258 TEST_F(detray_algebra, cross_product_add_sub) {
0259 vector3 v1{1.f, 2.f, 3.f};
0260 vector3 v2{3.f, 4.f, 5.f};
0261 vector3 v3{-6.f, 7.f, -9.f};
0262
0263 vector3 v = detray::vector::cross(v1 + v2, v3);
0264 vector3 ans{-110.f, -12.f, 64.f};
0265
0266 ASSERT_NEAR(v[0], ans[0], this->epsilon());
0267 ASSERT_NEAR(v[1], ans[1], this->epsilon());
0268 ASSERT_NEAR(v[2], ans[2], this->epsilon());
0269
0270 v = detray::vector::cross(v3 - 2 * v1, 3 * (v1 + v2));
0271 ans = {342.f, 12.f, -180.f};
0272
0273 ASSERT_NEAR(v[0], ans[0], this->epsilon());
0274 ASSERT_NEAR(v[1], ans[1], this->epsilon());
0275 ASSERT_NEAR(v[2], ans[2], this->epsilon());
0276 }
0277
0278 }