diff --git a/VectorisationWrappers/Accelerate/AccelerateTrigonometry.h b/VectorisationWrappers/Accelerate/AccelerateTrigonometry.h index 752698c..7768ab8 100644 --- a/VectorisationWrappers/Accelerate/AccelerateTrigonometry.h +++ b/VectorisationWrappers/Accelerate/AccelerateTrigonometry.h @@ -2,6 +2,72 @@ namespace Vectorised::Trigonometry { + template + static void hardClipVectorised(const T* InputBuffer, T* OutputBuffer, const int BufferSize, const T* ClipLowerLimit, const T* ClipUpperLimit) + { + if constexpr (std::is_same_v) + vDSP_vclip(InputBuffer, 1, ClipLowerLimit, ClipUpperLimit, OutputBuffer, 1, BufferSize); + else if constexpr (std::is_same_v) + vDSP_vclipD(InputBuffer, 1, ClipLowerLimit, ClipUpperLimit, OutputBuffer, 1, BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for hard clipping"); + } + + template + static void inverseSinhVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvasinhf (OutputBuffer, WorkBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvasinh (OutputBuffer, WorkBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for tanh"); + } + + template + static void inverseCoshVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvacoshf (OutputBuffer, WorkBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvacosh (OutputBuffer, WorkBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for tanh"); + } + + template + static void inverseTanhVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvatanhf (OutputBuffer, WorkBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvatanh (OutputBuffer, WorkBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for tanh"); + } + + template + static void sinhVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvsinhf (OutputBuffer, WorkBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvsinh (OutputBuffer, WorkBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for tanh"); + } + + template + static void coshVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvcoshf (OutputBuffer, WorkBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvcosh (OutputBuffer, WorkBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for tanh"); + } + template static void tanhVectorised (const T* WorkBuffer, T* OutputBuffer, const int BufferSize) { @@ -13,26 +79,79 @@ namespace Vectorised::Trigonometry static_assert (sizeof(T) == 0, "Unsupported type for tanh"); } - // Vectorised tanh function for hard clipping template - static void hardClipVectorised(const T* InputBuffer, T* OutputBuffer, const int BufferSize, const T* ClipLowerLimit, const T* ClipUpperLimit) + static void sineVectorised (const T* InputBuffer, T* OutputBuffer,const int BufferSize) { if constexpr (std::is_same_v) - vDSP_vclip(InputBuffer, 1, ClipLowerLimit, ClipUpperLimit, OutputBuffer, 1, BufferSize); - else if constexpr (std::is_same_v) - vDSP_vclipD(InputBuffer, 1, ClipLowerLimit, ClipUpperLimit, OutputBuffer, 1, BufferSize); + vvsinf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvsin (OutputBuffer, InputBuffer, &BufferSize); else - static_assert (sizeof(T) == 0, "Unsupported type for hard clipping"); + static_assert (sizeof(T) == 0, "Unsupported type for sine"); + } + + template + static void cosVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvcosf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvcos (OutputBuffer, InputBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for sine"); + } + + template + static void tanVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvtanf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvtan (OutputBuffer, InputBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for sine"); + } + + template + static void arcSinVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvasinf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvasin (OutputBuffer, InputBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for sine"); + } + + template + static void arcCosVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvacosf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvacos (OutputBuffer, InputBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for sine"); + } + + template + static void arcTanVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize) + { + if constexpr (std::is_same_v) + vvatanf (OutputBuffer, InputBuffer, &BufferSize); + else if constexpr (std::is_same_v) + vvatan (OutputBuffer, InputBuffer, &BufferSize); + else + static_assert (sizeof(T) == 0, "Unsupported type for sine"); } - // Vectorised tanh function for sine template - static void sineVectorised (T* InputBuffer, const int BufferSize) + static void arcTanXYVectorised (const T* XBuffer, const T* YBuffer, T* OutputBuffer, const int BufferSize) { if constexpr (std::is_same_v) - vvsinf (InputBuffer, InputBuffer, &BufferSize); + vvatan2f (OutputBuffer, YBuffer, XBuffer, &BufferSize); else if constexpr (std::is_same_v) - vvsin (InputBuffer, InputBuffer, &BufferSize); + vvatan2 (OutputBuffer, YBuffer, XBuffer, &BufferSize); else static_assert (sizeof(T) == 0, "Unsupported type for sine"); } diff --git a/VectorisationWrappers/Accelerate/Tests/AccelerateTrigonometryUnitTests.cpp b/VectorisationWrappers/Accelerate/Tests/AccelerateTrigonometryUnitTests.cpp index a22fa08..b630463 100644 --- a/VectorisationWrappers/Accelerate/Tests/AccelerateTrigonometryUnitTests.cpp +++ b/VectorisationWrappers/Accelerate/Tests/AccelerateTrigonometryUnitTests.cpp @@ -17,7 +17,7 @@ TEMPLATE_TEST_CASE("Accelerate Trigonometry Unit Testing", "[Accelerate Trigonom { auto sinValue = static_cast (std::sin (1.f)); - Vectorised::Trigonometry::sineVectorised (workingBuffer.data(), bufferSize); + Vectorised::Trigonometry::sineVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); for (const auto& value : workingBuffer) { @@ -25,6 +25,90 @@ TEMPLATE_TEST_CASE("Accelerate Trigonometry Unit Testing", "[Accelerate Trigonom } } + SECTION ("Cos Function Tests") + { + auto cosValue = static_cast (std::cos (1.f)); + + Vectorised::Trigonometry::cosVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (cosValue)); + } + } + + SECTION ("Tan Function Tests") + { + auto tanValue = static_cast (std::tan (1.f)); + + Vectorised::Trigonometry::tanVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (tanValue)); + } + } + + SECTION ("Arcsin Function Tests") + { + auto asinValue = static_cast (std::asin (1.f)); + + Vectorised::Trigonometry::arcSinVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (asinValue)); + } + } + + SECTION ("Arccos Function Tests") + { + auto aCosValue = static_cast (std::acos (1.f)); + + Vectorised::Trigonometry::arcCosVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (aCosValue)); + } + } + + SECTION ("ArcTan Function Tests") + { + auto aTanValue = static_cast (std::atan (1.f)); + + Vectorised::Trigonometry::arcTanVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (aTanValue)); + } + } + + SECTION ("Sinh Function Tests") + { + const auto sinhValue = static_cast (std::sinh (1.f)); + + Vectorised::Trigonometry::sinhVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (sinhValue)); + } + } + + SECTION ("Cosh Function Tests") + { + const auto coshValue = static_cast (std::cosh (1.f)); + + Vectorised::Trigonometry::coshVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (coshValue)); + } + } + SECTION ("Tanh Function Tests") { workingBuffer.assign (bufferSize, static_cast (10)); @@ -38,7 +122,46 @@ TEMPLATE_TEST_CASE("Accelerate Trigonometry Unit Testing", "[Accelerate Trigonom } } - SECTION ("Sigmud Function Tests") + SECTION ("Inverse Hyperbolic Cosine Function Tests") + { + workingBuffer.assign (bufferSize, static_cast (2)); + const auto compareValue = static_cast (std::asinh (2)); + + Vectorised::Trigonometry::inverseSinhVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (compareValue)); + } + } + + SECTION ("Inverse Hyperbolic Cosine Function Tests") + { + workingBuffer.assign (bufferSize, static_cast (2)); + const auto compareValue = static_cast (std::acosh (2)); + + Vectorised::Trigonometry::inverseCoshVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (compareValue)); + } + } + + SECTION ("Inverse Hyperbolic Tangent Function Tests") + { + workingBuffer.assign (bufferSize, static_cast (0.8)); + const auto compareValue = static_cast (std::atanh (0.8)); + + Vectorised::Trigonometry::inverseTanhVectorised (workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (compareValue)); + } + } + + SECTION ("Sigmoid Function Tests") { const auto minValue = static_cast(-1); const auto maxValue = static_cast(1); @@ -59,4 +182,16 @@ TEMPLATE_TEST_CASE("Accelerate Trigonometry Unit Testing", "[Accelerate Trigonom REQUIRE (value == Catch::Approx (maxValue)); } } + + SECTION ("Arc tangent of X Y Function Tests") + { + auto normalValue = static_cast (std::atan2 (1.f, 1.f)); + + Vectorised::Trigonometry::arcTanXYVectorised (workingBuffer.data(), workingBuffer.data(), workingBuffer.data(), bufferSize); + + for (const auto& value : workingBuffer) + { + REQUIRE (value == Catch::Approx (normalValue)); + } + } } \ No newline at end of file