complex.cpp (5362B)
1 /** 2 * KFR (https://www.kfrlib.com) 3 * Copyright (C) 2016-2023 Dan Cazarin 4 * See LICENSE.txt for details 5 */ 6 7 #include <kfr/simd/complex.hpp> 8 #include <kfr/simd/read_write.hpp> 9 10 namespace kfr 11 { 12 inline namespace CMT_ARCH_NAME 13 { 14 15 TEST(complex_convertible) 16 { 17 static_assert(std::is_convertible<float, complex<float>>::value, ""); 18 static_assert(std::is_convertible<float, complex<double>>::value, ""); 19 static_assert(std::is_convertible<short, complex<double>>::value, ""); 20 21 static_assert(std::is_convertible<complex<float>, vec<complex<float>, 4>>::value, ""); 22 static_assert(!std::is_convertible<vec<complex<float>, 1>, vec<complex<float>, 4>>::value, ""); 23 24 static_assert(std::is_convertible<vec<complex<float>, 2>, vec<complex<double>, 2>>::value, ""); 25 static_assert(std::is_convertible<vec<vec<float, 4>, 2>, vec<vec<double, 4>, 2>>::value, ""); 26 27 CHECK(static_cast<complex<float>>(10.f) == complex<float>{ 10.f, 0.f }); 28 CHECK(static_cast<complex<double>>(10.f) == complex<double>{ 10., 0. }); 29 CHECK(static_cast<complex<double>>(static_cast<short>(10)) == complex<double>{ 10., 0. }); 30 31 CHECK(static_cast<vec<complex<float>, 2>>(complex<float>{ 1.f, 2.f }) == 32 vec<complex<float>, 2>{ c32{ 1.f, 2.f }, c32{ 1.f, 2.f } }); 33 34 CHECK(static_cast<vec<complex<float>, 4>>(complex<float>{ 1.f, 2.f }) == 35 vec<complex<float>, 4>{ c32{ 1.f, 2.f }, c32{ 1.f, 2.f }, c32{ 1.f, 2.f }, c32{ 1.f, 2.f } }); 36 37 CHECK(static_cast<vec<complex<double>, 2>>(vec<complex<float>, 2>{ c32{ 1.f, 2.f }, c32{ 1.f, 2.f } }) == 38 vec<complex<double>, 2>{ c64{ 1., 2. }, c64{ 1., 2. } }); 39 } 40 41 TEST(complex_static_tests) 42 { 43 static_assert(is_numeric<vec<complex<float>, 4>>, ""); 44 static_assert(is_numeric_args<vec<complex<float>, 4>>, ""); 45 46 static_assert(sizeof(vec<c32, 4>) == sizeof(vec<f32, 8>), ""); 47 static_assert(vec<f32, 4>::size() == 4, ""); 48 static_assert(vec<c32, 4>::size() == 4, ""); 49 static_assert(vec<f32, 4>::scalar_size() == 4, ""); 50 static_assert(vec<c32, 4>::scalar_size() == 8, ""); 51 testo::assert_is_same<subtype<complex<i32>>, i32>(); 52 testo::assert_is_same<vec<c32, 4>::value_type, c32>(); 53 testo::assert_is_same<vec<c32, 4>::scalar_type, f32>(); 54 testo::assert_is_same<vec<f32, 4>::value_type, f32>(); 55 testo::assert_is_same<vec<f32, 4>::scalar_type, f32>(); 56 testo::assert_is_same<vec<c32, 1>, decltype(make_vector(c32{ 0, 0 }))>(); 57 testo::assert_is_same<vec<c32, 2>, decltype(make_vector(c32{ 0, 0 }, 4))>(); 58 testo::assert_is_same<ftype<complex<i32>>, complex<f32>>(); 59 testo::assert_is_same<ftype<complex<i64>>, complex<f64>>(); 60 testo::assert_is_same<ftype<vec<complex<i32>, 4>>, vec<complex<f32>, 4>>(); 61 testo::assert_is_same<ftype<vec<complex<i64>, 8>>, vec<complex<f64>, 8>>(); 62 63 testo::assert_is_same<std::common_type_t<complex<int>, double>, complex<double>>(); 64 } 65 66 TEST(complex_shuffle) 67 { 68 const vec<c32, 2> a{ c32{ 0, 1 }, c32{ 2, 3 } }; 69 CHECK(reverse(a) == make_vector(c32{ 2, 3 }, c32{ 0, 1 })); 70 } 71 72 TEST(complex_read_write) 73 { 74 c32 buffer[8] = { c32{ 1, 2 }, c32{ 3, 4 }, c32{ 5, 6 }, c32{ 7, 8 }, 75 c32{ 9, 10 }, c32{ 11, 12 }, c32{ 13, 14 }, c32{ 15, 16 } }; 76 77 CHECK(read<4>(buffer) == make_vector(c32{ 1, 2 }, c32{ 3, 4 }, c32{ 5, 6 }, c32{ 7, 8 })); 78 CHECK(read<3>(buffer + 1) == make_vector(c32{ 3, 4 }, c32{ 5, 6 }, c32{ 7, 8 })); 79 write(buffer + 2, make_vector(c32{ 10, 11 }, c32{ 12, 13 })); 80 CHECK(read<4>(buffer) == make_vector(c32{ 1, 2 }, c32{ 3, 4 }, c32{ 10, 11 }, c32{ 12, 13 })); 81 } 82 83 TEST(complex_cast) 84 { 85 const vec<f32, 4> v1 = bitcast<f32>(make_vector(c32{ 0, 1 }, c32{ 2, 3 })); 86 CHECK(v1.flatten()[0] == 0.f); 87 CHECK(v1.flatten()[1] == 1.f); 88 CHECK(v1.flatten()[2] == 2.f); 89 CHECK(v1.flatten()[3] == 3.f); 90 91 const vec<c32, 1> v2 = bitcast<c32>(make_vector(1.f, 2.f)); 92 CHECK(v2.flatten()[0] == 1.f); 93 CHECK(v2.flatten()[1] == 2.f); 94 95 const vec<c32, 2> v3 = make_vector(1.f, 2.f); 96 CHECK(v3.flatten()[0] == 1.f); 97 CHECK(v3.flatten()[1] == 0.f); 98 CHECK(v3.flatten()[2] == 2.f); 99 CHECK(v3.flatten()[3] == 0.f); 100 101 const vec<c32, 2> v4 = make_vector(1, 2); 102 CHECK(v4.flatten()[0] == 1.f); 103 CHECK(v4.flatten()[1] == 0.f); 104 CHECK(v4.flatten()[2] == 2.f); 105 CHECK(v4.flatten()[3] == 0.f); 106 107 CHECK(zerovector<c32, 4>() == make_vector(c32{ 0, 0 }, c32{ 0, 0 }, c32{ 0, 0 }, c32{ 0, 0 })); 108 CHECK(enumerate<c32, 4>() == make_vector(c32{ 0, 0 }, c32{ 1, 0 }, c32{ 2, 0 }, c32{ 3, 0 })); 109 } 110 111 TEST(complex_vector) 112 { 113 const vec<c32, 1> c32x1{ c32{ 0, 1 } }; 114 CHECK(c32x1.flatten()[0] == 0.0f); 115 CHECK(c32x1.flatten()[1] == 1.0f); 116 117 const vec<c32, 2> c32x2{ c32{ 0, 1 }, c32{ 2, 3 } }; 118 CHECK(c32x2.flatten()[0] == 0.0f); 119 CHECK(c32x2.flatten()[1] == 1.0f); 120 CHECK(c32x2.flatten()[2] == 2.0f); 121 CHECK(c32x2.flatten()[3] == 3.0f); 122 123 const vec<c32, 3> c32x3{ c32{ 0, 1 }, c32{ 2, 3 }, c32{ 4, 5 } }; 124 CHECK(c32x3.flatten()[0] == 0.0f); 125 CHECK(c32x3.flatten()[1] == 1.0f); 126 CHECK(c32x3.flatten()[2] == 2.0f); 127 CHECK(c32x3.flatten()[3] == 3.0f); 128 CHECK(c32x3.flatten()[4] == 4.0f); 129 CHECK(c32x3.flatten()[5] == 5.0f); 130 131 const vec<c32, 1> c32s = 2; 132 CHECK(c32s.flatten()[0] == 2.f); 133 CHECK(c32s.flatten()[1] == 0.f); 134 } 135 136 } // namespace CMT_ARCH_NAME 137 } // namespace kfr