1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2024-07-16 10:11:21 +03:00
102 changed files with 3618 additions and 2171 deletions
@@ -297,6 +297,21 @@ It is possible to alternate error processing by using redirectError().
*/
CV_EXPORTS CV_NORETURN void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
/*! @brief Signals an error and terminate application.
By default the function prints information about the error to stderr, then it terminates application
with std::terminate. The function is designed for invariants check in functions and methods with
noexcept attribute.
@param _code - error code (Error::Code)
@param _err - error description
@param _func - function name. Available only when the compiler supports getting it
@param _file - source file name where the error has occurred
@param _line - line number in the source file where the error has occurred
@see CV_AssertTerminate
*/
CV_EXPORTS CV_NORETURN void terminate(int _code, const String& _err, const char* _func, const char* _file, int _line) CV_NOEXCEPT;
#ifdef CV_STATIC_ANALYSIS
// In practice, some macro are not processed correctly (noreturn is not detected).
@@ -338,8 +353,11 @@ for example:
The macros CV_Assert (and CV_DbgAssert(expr)) evaluate the specified expression. If it is 0, the macros
raise an error (see cv::error). The macro CV_Assert checks the condition in both Debug and Release
configurations while CV_DbgAssert is only retained in the Debug configuration.
CV_AssertTerminate is analog of CV_Assert for invariants check in functions with noexcept attribute.
It does not throw exception, but terminates the application.
*/
#define CV_Assert( expr ) do { if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0)
#define CV_AssertTerminate( expr ) do { if(!!(expr)) ; else cv::terminate( #expr, CV_Func, __FILE__, __LINE__ ); } while(0)
#endif // CV_STATIC_ANALYSIS
@@ -481,6 +481,7 @@ Cv64suf;
#define CV_OUT
#define CV_PROP
#define CV_PROP_RW
#define CV_ND // Indicates that input data should be parsed into Mat without channels
#define CV_WRAP
#define CV_WRAP_AS(synonym)
#define CV_WRAP_MAPPABLE(mappable)
@@ -64,7 +64,7 @@
namespace {
inline unsigned int trailingZeros32(unsigned int value) {
#if defined(_MSC_VER)
#if (_MSC_VER < 1700) || defined(_M_ARM) || defined(_M_ARM64)
#if (_MSC_VER < 1700) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
unsigned long index = 0;
_BitScanForward(&index, value);
return (unsigned int)index;
@@ -1305,6 +1305,7 @@ namespace CV__SIMD_NAMESPACE {
typedef struct v_float64 { int dummy; } v_float64;
#endif
#include "intrin_math.hpp"
#include "simd_utils.impl.hpp"
#ifndef CV_DOXYGEN
@@ -263,7 +263,8 @@ Most of these operations return only one value.
### Other math
- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude
- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude, @ref v_exp,
@ref v_erf
- Absolute values: @ref v_abs, @ref v_absdiff, @ref v_absdiffs
### Conversions
@@ -363,6 +364,8 @@ Floating point:
|reverse | x | x |
|extract_n | x | x |
|broadcast_element | x | |
|exp | x | x |
|log | x | x |
@{ */
@@ -721,11 +724,56 @@ template<typename _Tp, int n> inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a)
Only for floating point types.*/
OPENCV_HAL_IMPL_MATH_FUNC(v_sqrt, std::sqrt, _Tp)
/**
* @brief Exponential \f$ e^x \f$ of elements
*
* Only for floating point types. Core implementation steps:
* 1. Decompose Input: Convert the input to \f$ 2^{x \cdot \log_2e} \f$ and split its exponential into integer and fractional parts:
* \f$ x \cdot \log_2e = n + f \f$, where \f$ n \f$ is the integer part and \f$ f \f$ is the fractional part.
* 2. Compute \f$ 2^n \f$: Calculated by shifting the bits.
* 3. Adjust Fractional Part: Compute \f$ f \cdot \ln2 \f$ to convert the fractional part to base \f$ e \f$.
* \f$ C1 \f$ and \f$ C2 \f$ are used to adjust the fractional part.
* 4. Polynomial Approximation for \f$ e^{f \cdot \ln2} \f$: The closer the fractional part is to 0, the more accurate the result.
* - For float16 and float32, use a Taylor Series with 6 terms.
* - For float64, use Pade Polynomials Approximation with 4 terms.
* 5. Combine Results: Multiply the two parts together to get the final result:
* \f$ e^x = 2^n \cdot e^{f \cdot \ln2} \f$.
*
* @note The precision of the calculation depends on the implementation and the data type of the input vector.
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp)
#define OPENCV_HAL_MATH_HAVE_EXP 1
/**
* @brief Natural logarithm \f$ \log(x) \f$ of elements
*
* Only for floating point types. Core implementation steps:
* 1. Decompose Input: Use binary representation to decompose the input into mantissa part \f$ m \f$ and exponent part \f$ e \f$. Such that \f$ \log(x) = \log(m \cdot 2^e) = \log(m) + e \cdot \ln(2) \f$.
* 2. Adjust Mantissa and Exponent Parts: If the mantissa is less than \f$ \sqrt{0.5} \f$, adjust the exponent and mantissa to ensure the mantissa is in the range \f$ (\sqrt{0.5}, \sqrt{2}) \f$ for better approximation.
* 3. Polynomial Approximation for \f$ \log(m) \f$: The closer the \f$ m \f$ is to 1, the more accurate the result.
* - For float16 and float32, use a Taylor Series with 9 terms.
* - For float64, use Pade Polynomials Approximation with 6 terms.
* 4. Combine Results: Add the two parts together to get the final result.
*
* @note The precision of the calculation depends on the implementation and the data type of the input.
*
* @note Similar to the behavior of std::log(), \f$ \ln(0) = -\infty \f$.
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp)
#define OPENCV_HAL_MATH_HAVE_LOG 1
/**
* @brief Error function.
*
* @note Support FP32 precision for now.
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_erf, std::erf, _Tp)
//! @cond IGNORED
OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp)
#define OPENCV_HAL_MATH_HAVE_SIN 1
OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp)
OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp)
OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp)
#define OPENCV_HAL_MATH_HAVE_COS 1
//! @endcond
/** @brief Absolute value of elements
@@ -0,0 +1,467 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
// This header is not standalone. Don't include directly, use "intrin.hpp" instead.
#ifdef OPENCV_HAL_INTRIN_HPP // defined in intrin.hpp
namespace CV__SIMD_NAMESPACE {
/* Universal Intrinsics implementation of sin, cos, exp and log
Inspired by Intel Approximate Math library, and based on the
corresponding algorithms of the cephes math library
*/
/* Copyright (C) 2010,2011 RJVB - extensions */
/* Copyright (C) 2011 Julien Pommier
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
(this is the zlib license)
*/
#ifndef OPENCV_HAL_MATH_HAVE_EXP
//! @name Exponential
//! @{
#if defined(CV_SIMD_FP16) && CV_SIMD_FP16
// Implementation is the same as float32 vector.
inline v_float16 v_exp(const v_float16 &x) {
const v_float16 _vexp_lo_f16 = vx_setall_f16(hfloat(-10.7421875f));
const v_float16 _vexp_hi_f16 = vx_setall_f16(hfloat(11.f));
const v_float16 _vexp_half_fp16 = vx_setall_f16(hfloat(0.5f));
const v_float16 _vexp_one_fp16 = vx_setall_f16(hfloat(1.f));
const v_float16 _vexp_LOG2EF_f16 = vx_setall_f16(hfloat(1.44269504088896341f));
const v_float16 _vexp_C1_f16 = vx_setall_f16(hfloat(-6.93359375E-1f));
const v_float16 _vexp_C2_f16 = vx_setall_f16(hfloat(2.12194440E-4f));
const v_float16 _vexp_p0_f16 = vx_setall_f16(hfloat(1.9875691500E-4f));
const v_float16 _vexp_p1_f16 = vx_setall_f16(hfloat(1.3981999507E-3f));
const v_float16 _vexp_p2_f16 = vx_setall_f16(hfloat(8.3334519073E-3f));
const v_float16 _vexp_p3_f16 = vx_setall_f16(hfloat(4.1665795894E-2f));
const v_float16 _vexp_p4_f16 = vx_setall_f16(hfloat(1.6666665459E-1f));
const v_float16 _vexp_p5_f16 = vx_setall_f16(hfloat(5.0000001201E-1f));
const v_int16 _vexp_bias_s16 = vx_setall_s16(0xf);
v_float16 _vexp_, _vexp_x, _vexp_y, _vexp_xx;
v_int16 _vexp_mm;
// compute exponential of x
_vexp_x = v_max(x, _vexp_lo_f16);
_vexp_x = v_min(_vexp_x, _vexp_hi_f16);
_vexp_ = v_fma(_vexp_x, _vexp_LOG2EF_f16, _vexp_half_fp16);
_vexp_mm = v_floor(_vexp_);
_vexp_ = v_cvt_f16(_vexp_mm);
_vexp_mm = v_add(_vexp_mm, _vexp_bias_s16);
_vexp_mm = v_shl(_vexp_mm, 10);
_vexp_x = v_fma(_vexp_, _vexp_C1_f16, _vexp_x);
_vexp_x = v_fma(_vexp_, _vexp_C2_f16, _vexp_x);
_vexp_xx = v_mul(_vexp_x, _vexp_x);
_vexp_y = v_fma(_vexp_x, _vexp_p0_f16, _vexp_p1_f16);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p2_f16);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p3_f16);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p4_f16);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p5_f16);
_vexp_y = v_fma(_vexp_y, _vexp_xx, _vexp_x);
_vexp_y = v_add(_vexp_y, _vexp_one_fp16);
_vexp_y = v_mul(_vexp_y, v_reinterpret_as_f16(_vexp_mm));
// exp(NAN) -> NAN
v_float16 mask_not_nan = v_not_nan(x);
return v_select(mask_not_nan, _vexp_y, v_reinterpret_as_f16(vx_setall_s16(0x7e00)));
}
#endif
inline v_float32 v_exp(const v_float32 &x) {
const v_float32 _vexp_lo_f32 = vx_setall_f32(-88.3762626647949f);
const v_float32 _vexp_hi_f32 = vx_setall_f32(89.f);
const v_float32 _vexp_half_fp32 = vx_setall_f32(0.5f);
const v_float32 _vexp_one_fp32 = vx_setall_f32(1.f);
const v_float32 _vexp_LOG2EF_f32 = vx_setall_f32(1.44269504088896341f);
const v_float32 _vexp_C1_f32 = vx_setall_f32(-6.93359375E-1f);
const v_float32 _vexp_C2_f32 = vx_setall_f32(2.12194440E-4f);
const v_float32 _vexp_p0_f32 = vx_setall_f32(1.9875691500E-4f);
const v_float32 _vexp_p1_f32 = vx_setall_f32(1.3981999507E-3f);
const v_float32 _vexp_p2_f32 = vx_setall_f32(8.3334519073E-3f);
const v_float32 _vexp_p3_f32 = vx_setall_f32(4.1665795894E-2f);
const v_float32 _vexp_p4_f32 = vx_setall_f32(1.6666665459E-1f);
const v_float32 _vexp_p5_f32 = vx_setall_f32(5.0000001201E-1f);
const v_int32 _vexp_bias_s32 = vx_setall_s32(0x7f);
v_float32 _vexp_, _vexp_x, _vexp_y, _vexp_xx;
v_int32 _vexp_mm;
// compute exponential of x
_vexp_x = v_max(x, _vexp_lo_f32);
_vexp_x = v_min(_vexp_x, _vexp_hi_f32);
_vexp_ = v_fma(_vexp_x, _vexp_LOG2EF_f32, _vexp_half_fp32);
_vexp_mm = v_floor(_vexp_);
_vexp_ = v_cvt_f32(_vexp_mm);
_vexp_mm = v_add(_vexp_mm, _vexp_bias_s32);
_vexp_mm = v_shl(_vexp_mm, 23);
_vexp_x = v_fma(_vexp_, _vexp_C1_f32, _vexp_x);
_vexp_x = v_fma(_vexp_, _vexp_C2_f32, _vexp_x);
_vexp_xx = v_mul(_vexp_x, _vexp_x);
_vexp_y = v_fma(_vexp_x, _vexp_p0_f32, _vexp_p1_f32);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p2_f32);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p3_f32);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p4_f32);
_vexp_y = v_fma(_vexp_y, _vexp_x, _vexp_p5_f32);
_vexp_y = v_fma(_vexp_y, _vexp_xx, _vexp_x);
_vexp_y = v_add(_vexp_y, _vexp_one_fp32);
_vexp_y = v_mul(_vexp_y, v_reinterpret_as_f32(_vexp_mm));
// exp(NAN) -> NAN
v_float32 mask_not_nan = v_not_nan(x);
return v_select(mask_not_nan, _vexp_y, v_reinterpret_as_f32(vx_setall_s32(0x7fc00000)));
}
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
inline v_float64 v_exp(const v_float64 &x) {
const v_float64 _vexp_lo_f64 = vx_setall_f64(-709.43613930310391424428);
const v_float64 _vexp_hi_f64 = vx_setall_f64(710.);
const v_float64 _vexp_half_f64 = vx_setall_f64(0.5);
const v_float64 _vexp_one_f64 = vx_setall_f64(1.0);
const v_float64 _vexp_two_f64 = vx_setall_f64(2.0);
const v_float64 _vexp_LOG2EF_f64 = vx_setall_f64(1.44269504088896340736);
const v_float64 _vexp_C1_f64 = vx_setall_f64(-6.93145751953125E-1);
const v_float64 _vexp_C2_f64 = vx_setall_f64(-1.42860682030941723212E-6);
const v_float64 _vexp_p0_f64 = vx_setall_f64(1.26177193074810590878E-4);
const v_float64 _vexp_p1_f64 = vx_setall_f64(3.02994407707441961300E-2);
const v_float64 _vexp_p2_f64 = vx_setall_f64(9.99999999999999999910E-1);
const v_float64 _vexp_q0_f64 = vx_setall_f64(3.00198505138664455042E-6);
const v_float64 _vexp_q1_f64 = vx_setall_f64(2.52448340349684104192E-3);
const v_float64 _vexp_q2_f64 = vx_setall_f64(2.27265548208155028766E-1);
const v_float64 _vexp_q3_f64 = vx_setall_f64(2.00000000000000000009E0);
const v_int64 _vexp_bias_s64 = vx_setall_s64(0x3ff);
v_float64 _vexp_, _vexp_x, _vexp_y, _vexp_z, _vexp_xx;
v_int64 _vexp_mm;
// compute exponential of x
_vexp_x = v_max(x, _vexp_lo_f64);
_vexp_x = v_min(_vexp_x, _vexp_hi_f64);
_vexp_ = v_fma(_vexp_x, _vexp_LOG2EF_f64, _vexp_half_f64);
_vexp_mm = v_expand_low(v_floor(_vexp_));
_vexp_ = v_cvt_f64(_vexp_mm);
_vexp_mm = v_add(_vexp_mm, _vexp_bias_s64);
_vexp_mm = v_shl(_vexp_mm, 52);
_vexp_x = v_fma(_vexp_, _vexp_C1_f64, _vexp_x);
_vexp_x = v_fma(_vexp_, _vexp_C2_f64, _vexp_x);
_vexp_xx = v_mul(_vexp_x, _vexp_x);
_vexp_y = v_fma(_vexp_xx, _vexp_p0_f64, _vexp_p1_f64);
_vexp_y = v_fma(_vexp_y, _vexp_xx, _vexp_p2_f64);
_vexp_y = v_mul(_vexp_y, _vexp_x);
_vexp_z = v_fma(_vexp_xx, _vexp_q0_f64, _vexp_q1_f64);
_vexp_z = v_fma(_vexp_xx, _vexp_z, _vexp_q2_f64);
_vexp_z = v_fma(_vexp_xx, _vexp_z, _vexp_q3_f64);
_vexp_z = v_div(_vexp_y, v_sub(_vexp_z, _vexp_y));
_vexp_z = v_fma(_vexp_two_f64, _vexp_z, _vexp_one_f64);
_vexp_z = v_mul(_vexp_z, v_reinterpret_as_f64(_vexp_mm));
// exp(NAN) -> NAN
v_float64 mask_not_nan = v_not_nan(x);
return v_select(mask_not_nan, _vexp_z, v_reinterpret_as_f64(vx_setall_s64(0x7FF8000000000000)));
}
#endif
#define OPENCV_HAL_MATH_HAVE_EXP 1
//! @}
#endif
#ifndef OPENCV_HAL_MATH_HAVE_LOG
//! @name Natural Logarithm
//! @{
#if defined(CV_SIMD_FP16) && CV_SIMD_FP16
inline v_float16 v_log(const v_float16 &x) {
const v_float16 _vlog_one_fp16 = vx_setall_f16(hfloat(1.0f));
const v_float16 _vlog_SQRTHF_fp16 = vx_setall_f16(hfloat(0.707106781186547524f));
const v_float16 _vlog_q1_fp16 = vx_setall_f16(hfloat(-2.12194440E-4f));
const v_float16 _vlog_q2_fp16 = vx_setall_f16(hfloat(0.693359375f));
const v_float16 _vlog_p0_fp16 = vx_setall_f16(hfloat(7.0376836292E-2f));
const v_float16 _vlog_p1_fp16 = vx_setall_f16(hfloat(-1.1514610310E-1f));
const v_float16 _vlog_p2_fp16 = vx_setall_f16(hfloat(1.1676998740E-1f));
const v_float16 _vlog_p3_fp16 = vx_setall_f16(hfloat(-1.2420140846E-1f));
const v_float16 _vlog_p4_fp16 = vx_setall_f16(hfloat(1.4249322787E-1f));
const v_float16 _vlog_p5_fp16 = vx_setall_f16(hfloat(-1.6668057665E-1f));
const v_float16 _vlog_p6_fp16 = vx_setall_f16(hfloat(2.0000714765E-1f));
const v_float16 _vlog_p7_fp16 = vx_setall_f16(hfloat(-2.4999993993E-1f));
const v_float16 _vlog_p8_fp16 = vx_setall_f16(hfloat(3.3333331174E-1f));
const v_int16 _vlog_inv_mant_mask_s16 = vx_setall_s16(~0x7c00);
v_float16 _vlog_x, _vlog_e, _vlog_y, _vlog_z, _vlog_tmp;
v_int16 _vlog_ux, _vlog_emm0;
_vlog_ux = v_reinterpret_as_s16(x);
_vlog_emm0 = v_shr(_vlog_ux, 10);
_vlog_ux = v_and(_vlog_ux, _vlog_inv_mant_mask_s16);
_vlog_ux = v_or(_vlog_ux, v_reinterpret_as_s16(vx_setall_f16(hfloat(0.5f))));
_vlog_x = v_reinterpret_as_f16(_vlog_ux);
_vlog_emm0 = v_sub(_vlog_emm0, vx_setall_s16(0xf));
_vlog_e = v_cvt_f16(_vlog_emm0);
_vlog_e = v_add(_vlog_e, _vlog_one_fp16);
v_float16 _vlog_mask = v_lt(_vlog_x, _vlog_SQRTHF_fp16);
_vlog_tmp = v_and(_vlog_x, _vlog_mask);
_vlog_x = v_sub(_vlog_x, _vlog_one_fp16);
_vlog_e = v_sub(_vlog_e, v_and(_vlog_one_fp16, _vlog_mask));
_vlog_x = v_add(_vlog_x, _vlog_tmp);
_vlog_z = v_mul(_vlog_x, _vlog_x);
_vlog_y = v_fma(_vlog_p0_fp16, _vlog_x, _vlog_p1_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p2_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p3_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p4_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p5_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p6_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p7_fp16);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p8_fp16);
_vlog_y = v_mul(_vlog_y, _vlog_x);
_vlog_y = v_mul(_vlog_y, _vlog_z);
_vlog_y = v_fma(_vlog_e, _vlog_q1_fp16, _vlog_y);
_vlog_y = v_sub(_vlog_y, v_mul(_vlog_z, vx_setall_f16(hfloat(0.5f))));
_vlog_x = v_add(_vlog_x, _vlog_y);
_vlog_x = v_fma(_vlog_e, _vlog_q2_fp16, _vlog_x);
// log(0) -> -INF
v_float16 mask_zero = v_eq(x, vx_setzero_f16());
_vlog_x = v_select(mask_zero, v_reinterpret_as_f16(vx_setall_s16(0xfc00)), _vlog_x);
// log(NEG), log(NAN) -> NAN
v_float16 mask_not_nan = v_ge(x, vx_setzero_f16());
_vlog_x = v_select(mask_not_nan, _vlog_x, v_reinterpret_as_f16(vx_setall_s16(0x7e00)));
// log(INF) -> INF
v_float16 mask_inf = v_eq(x, v_reinterpret_as_f16(vx_setall_s16(0x7c00)));
_vlog_x = v_select(mask_inf, x, _vlog_x);
return _vlog_x;
}
#endif
inline v_float32 v_log(const v_float32 &x) {
const v_float32 _vlog_one_fp32 = vx_setall_f32(1.0f);
const v_float32 _vlog_SQRTHF_fp32 = vx_setall_f32(0.707106781186547524f);
const v_float32 _vlog_q1_fp32 = vx_setall_f32(-2.12194440E-4f);
const v_float32 _vlog_q2_fp32 = vx_setall_f32(0.693359375f);
const v_float32 _vlog_p0_fp32 = vx_setall_f32(7.0376836292E-2f);
const v_float32 _vlog_p1_fp32 = vx_setall_f32(-1.1514610310E-1f);
const v_float32 _vlog_p2_fp32 = vx_setall_f32(1.1676998740E-1f);
const v_float32 _vlog_p3_fp32 = vx_setall_f32(-1.2420140846E-1f);
const v_float32 _vlog_p4_fp32 = vx_setall_f32(1.4249322787E-1f);
const v_float32 _vlog_p5_fp32 = vx_setall_f32(-1.6668057665E-1f);
const v_float32 _vlog_p6_fp32 = vx_setall_f32(2.0000714765E-1f);
const v_float32 _vlog_p7_fp32 = vx_setall_f32(-2.4999993993E-1f);
const v_float32 _vlog_p8_fp32 = vx_setall_f32(3.3333331174E-1f);
const v_int32 _vlog_inv_mant_mask_s32 = vx_setall_s32(~0x7f800000);
v_float32 _vlog_x, _vlog_e, _vlog_y, _vlog_z, _vlog_tmp;
v_int32 _vlog_ux, _vlog_emm0;
_vlog_ux = v_reinterpret_as_s32(x);
_vlog_emm0 = v_shr(_vlog_ux, 23);
_vlog_ux = v_and(_vlog_ux, _vlog_inv_mant_mask_s32);
_vlog_ux = v_or(_vlog_ux, v_reinterpret_as_s32(vx_setall_f32(0.5f)));
_vlog_x = v_reinterpret_as_f32(_vlog_ux);
_vlog_emm0 = v_sub(_vlog_emm0, vx_setall_s32(0x7f));
_vlog_e = v_cvt_f32(_vlog_emm0);
_vlog_e = v_add(_vlog_e, _vlog_one_fp32);
v_float32 _vlog_mask = v_lt(_vlog_x, _vlog_SQRTHF_fp32);
_vlog_tmp = v_and(_vlog_x, _vlog_mask);
_vlog_x = v_sub(_vlog_x, _vlog_one_fp32);
_vlog_e = v_sub(_vlog_e, v_and(_vlog_one_fp32, _vlog_mask));
_vlog_x = v_add(_vlog_x, _vlog_tmp);
_vlog_z = v_mul(_vlog_x, _vlog_x);
_vlog_y = v_fma(_vlog_p0_fp32, _vlog_x, _vlog_p1_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p2_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p3_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p4_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p5_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p6_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p7_fp32);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p8_fp32);
_vlog_y = v_mul(_vlog_y, _vlog_x);
_vlog_y = v_mul(_vlog_y, _vlog_z);
_vlog_y = v_fma(_vlog_e, _vlog_q1_fp32, _vlog_y);
_vlog_y = v_sub(_vlog_y, v_mul(_vlog_z, vx_setall_f32(0.5)));
_vlog_x = v_add(_vlog_x, _vlog_y);
_vlog_x = v_fma(_vlog_e, _vlog_q2_fp32, _vlog_x);
// log(0) -> -INF
v_float32 mask_zero = v_eq(x, vx_setzero_f32());
_vlog_x = v_select(mask_zero, v_reinterpret_as_f32(vx_setall_s32(0xff800000)), _vlog_x);
// log(NEG), log(NAN) -> NAN
v_float32 mask_not_nan = v_ge(x, vx_setzero_f32());
_vlog_x = v_select(mask_not_nan, _vlog_x, v_reinterpret_as_f32(vx_setall_s32(0x7fc00000)));
// log(INF) -> INF
v_float32 mask_inf = v_eq(x, v_reinterpret_as_f32(vx_setall_s32(0x7f800000)));
_vlog_x = v_select(mask_inf, x, _vlog_x);
return _vlog_x;
}
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
inline v_float64 v_log(const v_float64 &x) {
const v_float64 _vlog_one_fp64 = vx_setall_f64(1.0);
const v_float64 _vlog_SQRTHF_fp64 = vx_setall_f64(0.7071067811865475244);
const v_float64 _vlog_p0_fp64 = vx_setall_f64(1.01875663804580931796E-4);
const v_float64 _vlog_p1_fp64 = vx_setall_f64(4.97494994976747001425E-1);
const v_float64 _vlog_p2_fp64 = vx_setall_f64(4.70579119878881725854);
const v_float64 _vlog_p3_fp64 = vx_setall_f64(1.44989225341610930846E1);
const v_float64 _vlog_p4_fp64 = vx_setall_f64(1.79368678507819816313E1);
const v_float64 _vlog_p5_fp64 = vx_setall_f64(7.70838733755885391666);
const v_float64 _vlog_q0_fp64 = vx_setall_f64(1.12873587189167450590E1);
const v_float64 _vlog_q1_fp64 = vx_setall_f64(4.52279145837532221105E1);
const v_float64 _vlog_q2_fp64 = vx_setall_f64(8.29875266912776603211E1);
const v_float64 _vlog_q3_fp64 = vx_setall_f64(7.11544750618563894466E1);
const v_float64 _vlog_q4_fp64 = vx_setall_f64(2.31251620126765340583E1);
const v_float64 _vlog_C0_fp64 = vx_setall_f64(2.121944400546905827679e-4);
const v_float64 _vlog_C1_fp64 = vx_setall_f64(0.693359375);
const v_int64 _vlog_inv_mant_mask_s64 = vx_setall_s64(~0x7ff0000000000000);
v_float64 _vlog_x, _vlog_e, _vlog_y, _vlog_z, _vlog_tmp, _vlog_xx;
v_int64 _vlog_ux, _vlog_emm0;
_vlog_ux = v_reinterpret_as_s64(x);
_vlog_emm0 = v_shr(_vlog_ux, 52);
_vlog_ux = v_and(_vlog_ux, _vlog_inv_mant_mask_s64);
_vlog_ux = v_or(_vlog_ux, v_reinterpret_as_s64(vx_setall_f64(0.5)));
_vlog_x = v_reinterpret_as_f64(_vlog_ux);
_vlog_emm0 = v_sub(_vlog_emm0, vx_setall_s64(0x3ff));
_vlog_e = v_cvt_f64(_vlog_emm0);
_vlog_e = v_add(_vlog_e, _vlog_one_fp64);
v_float64 _vlog_mask = v_lt(_vlog_x, _vlog_SQRTHF_fp64);
_vlog_tmp = v_and(_vlog_x, _vlog_mask);
_vlog_x = v_sub(_vlog_x, _vlog_one_fp64);
_vlog_e = v_sub(_vlog_e, v_and(_vlog_one_fp64, _vlog_mask));
_vlog_x = v_add(_vlog_x, _vlog_tmp);
_vlog_xx = v_mul(_vlog_x, _vlog_x);
_vlog_y = v_fma(_vlog_p0_fp64, _vlog_x, _vlog_p1_fp64);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p2_fp64);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p3_fp64);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p4_fp64);
_vlog_y = v_fma(_vlog_y, _vlog_x, _vlog_p5_fp64);
_vlog_y = v_mul(_vlog_y, _vlog_x);
_vlog_y = v_mul(_vlog_y, _vlog_xx);
_vlog_z = v_add(_vlog_x, _vlog_q0_fp64);
_vlog_z = v_fma(_vlog_z, _vlog_x, _vlog_q1_fp64);
_vlog_z = v_fma(_vlog_z, _vlog_x, _vlog_q2_fp64);
_vlog_z = v_fma(_vlog_z, _vlog_x, _vlog_q3_fp64);
_vlog_z = v_fma(_vlog_z, _vlog_x, _vlog_q4_fp64);
_vlog_z = v_div(_vlog_y, _vlog_z);
_vlog_z = v_sub(_vlog_z, v_mul(_vlog_e, _vlog_C0_fp64));
_vlog_z = v_sub(_vlog_z, v_mul(_vlog_xx, vx_setall_f64(0.5)));
_vlog_z = v_add(_vlog_z, _vlog_x);
_vlog_z = v_fma(_vlog_e, _vlog_C1_fp64, _vlog_z);
// log(0) -> -INF
v_float64 mask_zero = v_eq(x, vx_setzero_f64());
_vlog_z = v_select(mask_zero, v_reinterpret_as_f64(vx_setall_s64(0xfff0000000000000)), _vlog_z);
// log(NEG), log(NAN) -> NAN
v_float64 mask_not_nan = v_ge(x, vx_setzero_f64());
_vlog_z = v_select(mask_not_nan, _vlog_z, v_reinterpret_as_f64(vx_setall_s64(0x7ff8000000000000)));
// log(INF) -> INF
v_float64 mask_inf = v_eq(x, v_reinterpret_as_f64(vx_setall_s64(0x7ff0000000000000)));
_vlog_z = v_select(mask_inf, x, _vlog_z);
return _vlog_z;
}
#endif
#define OPENCV_HAL_MATH_HAVE_LOG 1
//! @}
#endif
/* This implementation is derived from the approximation approach of Error Function (Erf) from PyTorch
https://github.com/pytorch/pytorch/blob/9c50ecc84b9a6e699a7f058891b889aafbf976c7/aten/src/ATen/cpu/vec/vec512/vec512_float.h#L189-L220
*/
#ifndef OPENCV_HAL_MATH_HAVE_ERF
//! @name Error Function
//! @{
inline v_float32 v_erf(const v_float32 &v) {
const v_float32 coef0 = vx_setall_f32(0.3275911f),
coef1 = vx_setall_f32(1.061405429f),
coef2 = vx_setall_f32(-1.453152027f),
coef3 = vx_setall_f32(1.421413741f),
coef4 = vx_setall_f32(-0.284496736f),
coef5 = vx_setall_f32(0.254829592f),
ones = vx_setall_f32(1.0f),
neg_zeros = vx_setall_f32(-0.f);
v_float32 t = v_abs(v);
// sign(v)
v_float32 sign_mask = v_and(neg_zeros, v);
t = v_div(ones, v_fma(coef0, t, ones));
v_float32 r = v_fma(coef1, t, coef2);
r = v_fma(r, t, coef3);
r = v_fma(r, t, coef4);
r = v_fma(r, t, coef5);
// - v * v
v_float32 pow_2 = v_mul(v, v);
v_float32 neg_pow_2 = v_xor(neg_zeros, pow_2);
// - exp(- v * v)
v_float32 exp = v_exp(neg_pow_2);
v_float32 neg_exp = v_xor(neg_zeros, exp);
v_float32 res = v_mul(t, neg_exp);
res = v_fma(r, res, ones);
return v_xor(sign_mask, res);
}
#define OPENCV_HAL_MATH_HAVE_ERF 1
//! @}
#endif // OPENCV_HAL_MATH_HAVE_ERF
}
#endif // OPENCV_HAL_INTRIN_HPP
+1 -1
View File
@@ -2136,7 +2136,7 @@ public:
/** @overload */
template<typename _Tp, typename Functor> void forEach(const Functor& operation) const;
Mat(Mat&& m);
Mat(Mat&& m) CV_NOEXCEPT;
Mat& operator = (Mat&& m);
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+1 -1
View File
@@ -57,7 +57,7 @@ This section describes OpenGL interoperability.
To enable OpenGL support, configure OpenCV using CMake with WITH_OPENGL=ON . Currently OpenGL is
supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not
supported). For GTK backend gtkglext-1.0 library is required.
supported). For GTK-2.0 backend gtkglext-1.0 library is required.
To use OpenGL functionality you should first create OpenGL context (window or frame buffer). You can
do this with namedWindow function or with other OpenGL toolkit (GLUT, for example).
@@ -544,6 +544,18 @@ bool isAligned(const void* p1, const void* p2, const void* p3, const void* p4)
return isAligned<N>(((size_t)p1)|((size_t)p2)|((size_t)p3)|((size_t)p4));
}
/*! @brief Flags that allow to midify some functions behavior. Used as set of flags.
*/
enum AlgorithmHint {
ALGO_HINT_DEFAULT = 0, //!< Default algorithm behaviour defined during OpenCV build
ALGO_HINT_ACCURATE = 1, //!< Use generic portable implementation
ALGO_HINT_APPROX = 2, //!< Allow alternative approximations to get faster implementation. Behaviour and result depends on a platform
};
/*! @brief Returns AlgorithmHint defined during OpenCV compilation. Defines #ALGO_HINT_DEFAULT behavior.
*/
CV_EXPORTS_W AlgorithmHint getDefaultAlgorithmHint();
/** @brief Enables or disables the optimized code.
The function can be used to dynamically turn on and off optimized dispatched code (code that uses SSE4.2, AVX/AVX2,