You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.2 KiB
C++
117 lines
4.2 KiB
C++
/*------------------------------------------------------------------------------
|
|
* Copyright (c) 2023 by Bai Bing (seread@163.com)
|
|
* See COPYING file for copying and redistribution conditions.
|
|
*
|
|
* Alians IT Studio.
|
|
*----------------------------------------------------------------------------*/
|
|
#pragma once
|
|
|
|
#include <cmath>
|
|
#include <complex>
|
|
#include <string>
|
|
|
|
#include "core/DataTypeInfo.h"
|
|
#include "core/TypeTraits.h"
|
|
|
|
namespace ais
|
|
{
|
|
namespace utils
|
|
{
|
|
//============================================================================
|
|
/// tests that 2 integer values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_integral<dtype>::value, int> = 0>
|
|
bool essentially_equal(dtype value1, dtype value2) noexcept
|
|
{
|
|
return value1 == value2;
|
|
}
|
|
|
|
//============================================================================
|
|
/// tests that 2 floating point values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
/// @param inEpsilon
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
bool essentially_equal(dtype value1, dtype value2, dtype inEpsilon) noexcept
|
|
{
|
|
// const auto absValue1 = std::abs(value1);
|
|
// const auto absValue2 = std::abs(value2);
|
|
// return std::abs(value1 - value2) <=
|
|
// ((absValue1 > absValue2 ? absValue2 : absValue1) * std::abs(inEpsilon));
|
|
|
|
return (std::fabs(value1 - value2) <= std::abs(inEpsilon));
|
|
}
|
|
|
|
//============================================================================
|
|
/// tests that 2 complex values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_integral<dtype>::value, int> = 0>
|
|
bool essentially_equal(const std::complex<dtype> &value1, const std::complex<dtype> &value2) noexcept
|
|
{
|
|
return value1 == value2;
|
|
}
|
|
|
|
//============================================================================
|
|
/// tests that 2 complex values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
/// @param inEpsilon
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
bool essentially_equal(const std::complex<dtype> &value1,
|
|
const std::complex<dtype> &value2,
|
|
const std::complex<dtype> &inEpsilon) noexcept
|
|
{
|
|
const auto absValue1 = std::abs(value1);
|
|
const auto absValue2 = std::abs(value2);
|
|
return std::abs(value1 - value2) <=
|
|
((absValue1 > absValue2 ? absValue2 : absValue1) * std::abs(inEpsilon));
|
|
}
|
|
|
|
//============================================================================
|
|
/// tests that 2 floating point values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
bool essentially_equal(dtype value1, dtype value2) noexcept
|
|
{
|
|
return essentially_equal(value1, value2, DataTypeInfo<dtype>::epsilon());
|
|
}
|
|
|
|
//============================================================================
|
|
/// tests that 2 floating point values are "essentially equal"
|
|
///
|
|
/// @param value1
|
|
/// @param value2
|
|
///
|
|
/// @return bool
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
bool essentially_equal(const std::complex<dtype> &value1, const std::complex<dtype> &value2) noexcept
|
|
{
|
|
return essentially_equal(value1, value2, DataTypeInfo<std::complex<dtype>>::epsilon());
|
|
}
|
|
} // namespace utils
|
|
} // namespace ais
|