Files
pip/libs/main/math/pimathcomplex.h
2026-03-12 14:46:57 +03:00

190 lines
7.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \~\file pimathcomplex.h
//! \~\ingroup Math
//! \~\brief
//! \~english Complex numbers
//! \~russian Комплексные числа
/*
PIP - Platform Independent Primitives
PIP math complex
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIMATHCOMPLEX_H
#define PIMATHCOMPLEX_H
#include "pibytearray.h"
#include "pimathbase.h"
#include "pivector2d.h"
#include <complex>
#define PIP_MATH_COMPLEX
using std::complex;
//! \~\ingroup Math
//! \~english Type trait that reports whether \a T is a specialization of \c std::complex.
//! \~russian Признак типа, определяющий, является ли \a T специализацией \c std::complex.
template<typename T>
struct is_complex: std::false_type {};
//! \~\ingroup Math
//! \~english Specialization for complex types.
//! \~russian Специализация для комплексных типов.
template<typename T>
struct is_complex<std::complex<T>>: std::true_type {};
//! \~english Complex integer type.
//! \~russian Комплексный тип на целых числах.
typedef complex<int> complexi;
//! \~english Complex short integer type.
//! \~russian Комплексный тип на \c short.
typedef complex<short> complexs;
//! \~english Complex single-precision type.
//! \~russian Комплексный тип одинарной точности.
typedef complex<float> complexf;
//! \~english Complex extended-precision type.
//! \~russian Комплексный тип расширенной точности.
typedef complex<ldouble> complexld;
#ifndef QPIEVALUATOR_COMPLEX
//! \~english Complex double-precision type.
//! \~russian Комплексный тип двойной точности.
typedef complex<double> complexd;
//! \~english Imaginary unit in double precision.
//! \~russian Мнимая единица двойной точности.
const complexd complexd_i(0., 1.);
//! \~english Zero value in double precision.
//! \~russian Нулевое значение двойной точности.
const complexd complexd_0(0.);
//! \~english Unity value in double precision.
//! \~russian Единичное значение двойной точности.
const complexd complexd_1(1.);
#endif
//! \~english Imaginary unit in extended precision.
//! \~russian Мнимая единица расширенной точности.
const complexld complexld_i(0., 1.);
//! \~english Zero value in extended precision.
//! \~russian Нулевое значение расширенной точности.
const complexld complexld_0(0.);
//! \~english Unity value in extended precision.
//! \~russian Единичное значение расширенной точности.
const complexld complexld_1(1.);
//! \~english Returns sign for real and imaginary parts independently.
//! \~russian Возвращает знак действительной и мнимой частей по отдельности.
inline complexd sign(const complexd & x) {
return complexd(sign(x.real()), sign(x.imag()));
}
//! \~\brief
//! \~english Round, floor, and ceil functions for complex numbers.
//! \~russian Округление, округление вниз и округление вверх комплексных чисел.
inline complexd round(const complexd & c) {
return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));
}
//! \~\brief
//! \~english Floor a complex number.
//! \~russian Округление комплексного числа вниз.
inline complexd floor(const complexd & c) {
return complexd(floor(c.real()), floor(c.imag()));
}
//! \~\brief
//! \~english Ceil a complex number.
//! \~russian Округление комплексного числа вверх.
inline complexd ceil(const complexd & c) {
return complexd(ceil(c.real()), ceil(c.imag()));
}
#define acosc acos
#define asinc asin
#define atanc atan
#ifdef CC_GCC
# if CC_GCC_VERSION <= 0x025F
inline complexd tan(const complexd & c) {
return sin(c) / cos(c);
}
inline complexd tanh(const complexd & c) {
return sinh(c) / cosh(c);
}
inline complexd log2(const complexd & c) {
return log(c) / M_LN2;
}
inline complexd log10(const complexd & c) {
return log(c) / M_LN10;
}
# endif
#endif
//! \relatesalso PICout
//! \~english Writes a complex number as `(real; imag)`.
//! \~russian Записывает комплексное число в виде `(real; imag)`.
template<typename T>
inline PICout operator<<(PICout s, const complex<T> & v) {
s.space();
s.saveAndSetControls(0);
s << "(" << v.real() << "; " << v.imag() << ")";
s.restoreControls();
return s;
}
//! \~english Returns magnitudes of all complex elements in the vector.
//! \~russian Возвращает модули всех комплексных элементов вектора.
inline PIVector<double> abs(const PIVector<complexd> & v) {
PIVector<double> result;
result.resize(v.size());
for (uint i = 0; i < v.size(); i++)
result[i] = abs(v[i]);
return result;
}
//! \~english Returns element-wise magnitudes of a complex matrix.
//! \~russian Возвращает матрицу модулей для комплексной матрицы.
inline PIVector2D<double> abs(const PIVector2D<complexd> & v) {
PIVector2D<double> result(v.rows(), v.cols());
for (uint i = 0; i < v.rows(); i++)
for (uint j = 0; j < v.cols(); j++)
result[i][j] = abs(v.element(i, j));
return result;
}
//! \~english Checks whether a floating-point value is close to zero.
//! \~russian Проверяет, находится ли вещественное значение вблизи нуля.
template<typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
inline bool PIMathFloatNullCompare(const T v) {
static_assert(std::is_floating_point<T>::value, "Type must be floating point");
return (piAbs(v) < T(1E-200));
}
//! \~english Checks whether a complex value with floating-point components is close to zero.
//! \~russian Проверяет, находится ли комплексное значение с вещественными компонентами вблизи нуля.
template<typename T,
typename std::enable_if<std::is_floating_point<decltype(T::real)>::value && std::is_floating_point<decltype(T::imag)>::value,
int>::type = 0>
inline bool PIMathFloatNullCompare(const T v) {
static_assert(std::is_floating_point<decltype(v.real)>::value, "Type must be floating point");
static_assert(std::is_floating_point<decltype(v.imag)>::value, "Type must be floating point");
return (abs(v) < float(1E-200));
}
#endif // PIMATHCOMPLEX_H