Loading...
Searching...
No Matches
ElementFunctions.h
Go to the documentation of this file.
#ifndef ELEMENT_FUNCTIONS_H
#define ELEMENT_FUNCTIONS_H
#include <cmath>
#include <complex>
#include <limits>
namespace casacore {
namespace arrays_internal {
inline bool near(unsigned val1, unsigned val2, double tol) {
if (tol <= 0) {
return (val1 == val2);
}
if (val1 == val2) {
return true;
} else if (val1 > val2) {
return (double(val1-val2) <= tol*std::max(val1,val2));
} else {
return (double(val2-val1) <= tol*std::max(val1,val2));
}
}
inline bool near(int val1, int val2, double tol) {
if (tol <=0) {
return (val1 == val2);
}
if (val1 == val2) {
return true;
}
if ((0<val1) != (0<val2)) {
return false;
}
const int aval1 = std::abs(val1);
const int aval2 = std::abs(val2);
return (double(aval1-aval2) <= tol*double(std::max(aval1,aval2)));
}
inline bool near(float val1, float val2, double tol) {
if (tol <=0) {
return (val1 == val2);
}
if (val1 == val2) {
return true;
}
if (val1 == 0) {
return (std::abs(val2) <= (1+tol)*std::numeric_limits<float>::min());
}
else if (val2 == 0) {
return (std::abs(val1) <= (1+tol)*std::numeric_limits<float>::min());
}
if ((0<val1) != (0<val2)) {
return false;
}
return (std::abs(val1-val2) <= tol*std::max(std::abs(val1), std::abs(val2)));
}
inline bool near(double val1, double val2, double tol) {
if (tol <=0) {
return (val1 == val2);
}
if (val1 == val2) {
return true;
}
if (val1 == 0) {
return (std::abs(val2) <= (1+tol)*std::numeric_limits<double>::min());
}
else if (val2 == 0) {
return (std::abs(val1) <= (1+tol)*std::numeric_limits<double>::min());
}
if ((0<val1) != (0<val2)) {
return false;
}
return (std::abs(val1-val2) <= tol*std::max(std::abs(val1),std::abs(val2)));
}
inline bool near(float val1, double val2, double tol) {
return near(double(val1), val2, tol);
}
inline bool near(double val1, float val2, double tol) {
return near(val1, double(val2), tol);
}
inline bool near(const std::complex<float> &val1, const std::complex<float> &val2, double tol=1.0e-5)
{
if (tol <= 0) return val1 == val2;
if (val1 == val2) return true;
if (near(val1.real(), val2.real(), tol) &&
near(val1.imag(), val2.imag(), tol)) return true;
float aval1(std::abs(val1)), aval2(std::abs(val2));
if (aval1 == 0) return aval2 <= (1+tol)*std::numeric_limits<float>::min();
else if (aval2 == 0) return aval1 <= (1+tol)*std::numeric_limits<float>::min();
std::complex<double> dval(val1);
dval -= std::complex<double>(val2);
return std::abs(dval) <= tol * (aval1 < aval2 ? aval2 : aval1);
}
inline bool near(const std::complex<double> &val1, const std::complex<double> &val2, double tol=1.0e-13)
{
if (tol <= 0) return val1 == val2;
if (val1 == val2) return true;
if (std::abs(val1) == 0) return std::abs(val2) <= (1+tol)*std::numeric_limits<double>::min();
else if (std::abs(val2) == 0) return std::abs(val1) <= (1+tol)*std::numeric_limits<double>::min();
double aval1(std::abs(val1)), aval2(std::abs(val2));
return std::abs(val1-val2) <= tol * (aval1 < aval2 ? aval2 : aval1);
}
inline bool nearAbs(const std::complex<float> &val1, const std::complex<float> &val2, double tol=1.0e-5)
{
return std::abs(val2 - val1) <= tol;
}
inline bool nearAbs(const std::complex<double> &val1, const std::complex<double> &val2, double tol=1.0e-13)
{
return std::abs(val2 - val1) <= tol;
}
inline bool nearAbs(unsigned val1, unsigned val2, double tol) {
if (val1 == val2) {
return true;
} else if (val1 > val2) {
return (tol >= double(val1 - val2));
} else {
return (tol >= double(val2 - val1));
}
}
inline bool nearAbs(int val1, int val2, double tol) {
return (tol >= double(std::abs(val2 - val1)));
}
inline bool nearAbs(float val1, float val2, double tol) {
return (tol >= double(std::abs(val2 - val1)));
}
inline bool nearAbs(double val1, double val2, double tol) {
return (tol >= std::abs(val2 - val1));
}
// Define a function to compare all elements of two sequences.
// It returns true if all elements compare true.
// An example compare operator is <src>std::equal_to</src>.
// <group>
template<typename InputIterator1, typename InputIterator2, typename CompareOperator>
inline bool compareAll (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, CompareOperator op)
{
for (; first1!=last1; ++first1, ++first2) {
if (!op(*first1, *first2)) return false;
}
return true;
}
// For use with a constant left value.
// This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
// (see ArrayMath.h).
template<typename InputIterator1, typename T, typename CompareOperator>
inline bool compareAllLeft (InputIterator1 first1, InputIterator1 last1,
T left, CompareOperator op)
{
for (; first1!=last1; ++first1) {
if (!op(left, *first1)) return false;
}
return true;
}
// For use with a constant right value.
// This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
// (see ArrayMath.h).
template<typename InputIterator1, typename T, typename CompareOperator>
inline bool compareAllRight (InputIterator1 first1, InputIterator1 last1,
T right, CompareOperator op)
{
for (; first1!=last1; ++first1) {
if (!op(*first1, right)) return false;
}
return true;
}
// </group>
// Define a function to compare all elements of two sequences.
// It returns true if any element compares true.
// An example compare operator is <src>std::equal_to</src>.
// <group>
template<typename InputIterator1, typename InputIterator2, typename CompareOperator>
inline bool compareAny (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, CompareOperator op)
{
for (; first1!=last1; ++first1, ++first2) {
if (op(*first1, *first2)) return true;
}
return false;
}
// For use with a constant left value.
// This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
// (see ArrayMath.h).
template<typename InputIterator1, typename T, typename CompareOperator>
inline bool compareAnyLeft (InputIterator1 first1, InputIterator1 last1,
T left, CompareOperator op)
{
for (; first1!=last1; ++first1) {
if (op(left, *first1)) return true;
}
return false;
}
// For use with a constant right value.
// This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
// (see ArrayMath.h).
template<typename InputIterator1, typename T, typename CompareOperator>
inline bool compareAnyRight (InputIterator1 first1, InputIterator1 last1,
T right, CompareOperator op)
{
for (; first1!=last1; ++first1) {
if (op(*first1, right)) return true;
}
return false;
}
// </group>
// Functor to add squared diff of right and base value to left.
// It can be used to calculate the variance.
// Note: it is specialized for complex values to handle real and imag separately.
template<typename T, typename Accum=T>
struct SumSqrDiff
{
explicit SumSqrDiff(T base) : itsBase(base) {}
Accum operator() (Accum left, T right) const
{ return left + (right-itsBase)*(right-itsBase); }
private:
Accum itsBase; // store as Accum, so subtraction results in Accum
};
// Specialize for complex values.
// Variance has to be taken for the absolute value of a complex value. thus
// sum(abs((a[i] - mean)**2
// where the sqrt used in abs and the **2 cancel each other, thus can be left out.
// See also https://en.wikipedia.org/wiki/Complex_random_variable#Variance
// Note that although the sum is real, a complex value is used to have equal template types.
template<typename T>
struct SumSqrDiff<std::complex<T>>
{
explicit SumSqrDiff(std::complex<T> base) : itsBase(base) {}
std::complex<T> operator() (std::complex<T> left, std::complex<T> right) const
{ return left + ((right.real() - itsBase.real()) * (right.real() - itsBase.real()) +
(right.imag() - itsBase.imag()) * (right.imag() - itsBase.imag())); }
private:
std::complex<T> itsBase;
};
template<typename T>
bool isnan(const std::complex<T> &val)
{
return std::isnan(val.real()) || std::isnan(val.imag());
}
template<typename T>
bool isinf(const std::complex<T> &val)
{
return std::isinf(val.real()) || std::isinf(val.imag());
}
template<typename T>
bool isfinite(const std::complex<T> &val)
{
return std::isfinite(val.real()) || std::isfinite(val.imag());
}
inline int floormod (int x, int y)
{
int r = x%y;
if (r != 0 && (x<0) != (y<0)) r+=y;
return r;
}
inline long long floormod (long long x, long long y)
{
long long r = x%y;
if (r != 0 && (x<0) != (y<0)) r+=y;
return r;
}
inline float floormod (float x, float y)
{
float r = std::fmod(x,y);
if (r != 0 && (x<0) != (y<0)) r+=y;
return r;
}
inline double floormod (double x, double y)
{
double r = std::fmod(x,y);
if (r != 0 && (x<0) != (y<0)) r+=y;
return r;
}
template<class T, class F> inline void convertScalar (T& out, F in)
{ out = static_cast<T>(in); }
inline void convertScalar (std::complex<float>& out, std::complex<double> in)
{ out = std::complex<float>(in.real(), in.imag()); }
} }
#endif
casacore::arrays_internal
Definition ElementFunctions.h:9
casacore::arrays_internal::compareAnyLeft
bool compareAnyLeft(InputIterator1 first1, InputIterator1 last1, T left, CompareOperator op)
For use with a constant left value.
Definition ElementFunctions.h:197
casacore::arrays_internal::near
bool near(unsigned val1, unsigned val2, double tol)
Definition ElementFunctions.h:11
casacore::arrays_internal::compareAll
bool compareAll(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, CompareOperator op)
Define a function to compare all elements of two sequences.
Definition ElementFunctions.h:146
casacore::arrays_internal::isfinite
bool isfinite(const std::complex< T > &val)
Definition ElementFunctions.h:262
casacore::arrays_internal::compareAnyRight
bool compareAnyRight(InputIterator1 first1, InputIterator1 last1, T right, CompareOperator op)
For use with a constant right value.
Definition ElementFunctions.h:209
casacore::arrays_internal::convertScalar
void convertScalar(T &out, F in)
Definition ElementFunctions.h:292
casacore::arrays_internal::floormod
int floormod(int x, int y)
Definition ElementFunctions.h:267
casacore::arrays_internal::compareAllLeft
bool compareAllLeft(InputIterator1 first1, InputIterator1 last1, T left, CompareOperator op)
For use with a constant left value.
Definition ElementFunctions.h:158
casacore::arrays_internal::nearAbs
bool nearAbs(const std::complex< float > &val1, const std::complex< float > &val2, double tol=1.0e-5)
Definition ElementFunctions.h:109
casacore::arrays_internal::compareAllRight
bool compareAllRight(InputIterator1 first1, InputIterator1 last1, T right, CompareOperator op)
For use with a constant right value.
Definition ElementFunctions.h:170
casacore::arrays_internal::isinf
bool isinf(const std::complex< T > &val)
Definition ElementFunctions.h:256
casacore::arrays_internal::isnan
bool isnan(const std::complex< T > &val)
Definition ElementFunctions.h:250
casacore::arrays_internal::compareAny
bool compareAny(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, CompareOperator op)
Define a function to compare all elements of two sequences.
Definition ElementFunctions.h:185
casacore
this file contains all the compiler specific defines
Definition mainpage.dox:28
std
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition Complex.h:350
casacore::arrays_internal::SumSqrDiff< std::complex< T > >::itsBase
std::complex< T > itsBase
Definition ElementFunctions.h:246
casacore::arrays_internal::SumSqrDiff< std::complex< T > >::SumSqrDiff
SumSqrDiff(std::complex< T > base)
Definition ElementFunctions.h:241
casacore::arrays_internal::SumSqrDiff::SumSqrDiff
SumSqrDiff(T base)
Definition ElementFunctions.h:225
casacore::arrays_internal::SumSqrDiff::operator()
Accum operator()(Accum left, T right) const
Definition ElementFunctions.h:226
casacore::arrays_internal::SumSqrDiff::itsBase
Accum itsBase
Definition ElementFunctions.h:229