From 9c450cc0e0b2e7060fa0a74a5196906bc28d0625 Mon Sep 17 00:00:00 2001 From: John Richardson Date: Wed, 22 Nov 2017 12:00:41 +0000 Subject: COMPMID-695: Update Phase and Validation Wrapping Simplify Phase reference implementation so that its results are more inline with the CL implementation (note: NEON uses a fast arctan approximation). Modify validate_wrap function to limit use to Integer types only. Change-Id: Ie4222568a8ef2587cab8e6d478745c5d0ded3d57 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/110192 Tested-by: BSG Visual Compute Jenkins server to access repositories on http://mpd-gerrit.cambridge.arm.com Reviewed-by: Anthony Barbier Reviewed-by: Gian Marco Iodice --- tests/validation/CPP/Phase.cpp | 49 +++++++++++------------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) (limited to 'tests/validation/CPP/Phase.cpp') diff --git a/tests/validation/CPP/Phase.cpp b/tests/validation/CPP/Phase.cpp index 4311ef091e..7827cd2989 100644 --- a/tests/validation/CPP/Phase.cpp +++ b/tests/validation/CPP/Phase.cpp @@ -34,50 +34,25 @@ namespace reference template SimpleTensor phase(const SimpleTensor &gx, const SimpleTensor &gy, PhaseType phase_type) { - const float pi = std::atan(1) * 4; - const float rad_to_deg = 180.0f / pi; - const float scale_factor = 128.f / 180.f; - const float epsilon = 1e-9f; // used to avoid division by zero - - const float ninety = scale_factor * 90.f; - const float one_eighty = scale_factor * 180.f; - const float two_seventy = scale_factor * 270.f; - - // unsigned: map to [0-255) - // signed: map to [0-180) degrees - const float scale = (phase_type == PhaseType::UNSIGNED) ? rad_to_deg : rad_to_deg * scale_factor; - + const float PI = std::atan(1) * 4; SimpleTensor phase(gx.shape(), DataType::U8); - for(int i = 0; i < gx.num_elements(); ++i) + if(phase_type == PhaseType::UNSIGNED) // unsigned: map to [0-255) { - bool quad_two = std::signbit(gx[i]) && !std::signbit(gy[i]); - bool quad_three = std::signbit(gx[i]) && std::signbit(gy[i]); - bool quad_four = !std::signbit(gx[i]) && std::signbit(gy[i]); - - float x = gy[i] / (gx[i] + epsilon); - double arctan = std::atan(x); - - const bool is_negative = std::signbit(arctan); - - // Radians to degrees conversion with applied scale factor - arctan = arctan * scale; - - if(phase_type == PhaseType::UNSIGNED) + for(int i = 0; i < gx.num_elements(); ++i) { - arctan = is_negative ? arctan + 180.f : arctan; + float angle_deg = (std::atan2(float(gy[i]), float(gx[i])) / PI) * 180.0f; + phase[i] = (angle_deg < 0.0f) ? 180.f + angle_deg : angle_deg; } - else + } + else // signed: map to [0-180) degrees + { + for(int i = 0; i < gx.num_elements(); ++i) { - arctan = is_negative ? arctan + ninety : arctan; - - // Choose correct quandrant - arctan = quad_two ? ninety + arctan : arctan; - arctan = quad_three ? one_eighty + arctan : arctan; - arctan = quad_four ? two_seventy + arctan : arctan; + float angle_pi = std::atan2(gy[i], gx[i]) / PI; + angle_pi = (angle_pi < 0.0f) ? 2 + angle_pi : angle_pi; + phase[i] = lround(angle_pi * 128) & 0xFFu; } - - phase[i] = saturate_cast(arctan + 0.5f); } return phase; -- cgit v1.2.1