//! \~\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 . */ #ifndef PIMATHCOMPLEX_H #define PIMATHCOMPLEX_H #include "pibytearray.h" #include "pimathbase.h" #include "pivector2d.h" #include #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 struct is_complex: std::false_type {}; //! \~\ingroup Math //! \~english Specialization for complex types. //! \~russian Специализация для комплексных типов. template struct is_complex>: std::true_type {}; //! \~english Complex integer type. //! \~russian Комплексный тип на целых числах. typedef complex complexi; //! \~english Complex short integer type. //! \~russian Комплексный тип на \c short. typedef complex complexs; //! \~english Complex single-precision type. //! \~russian Комплексный тип одинарной точности. typedef complex complexf; //! \~english Complex extended-precision type. //! \~russian Комплексный тип расширенной точности. typedef complex complexld; #ifndef QPIEVALUATOR_COMPLEX //! \~english Complex double-precision type. //! \~russian Комплексный тип двойной точности. typedef complex 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(c.real()), piRound(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 inline PICout operator<<(PICout s, const complex & 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 abs(const PIVector & v) { PIVector 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 abs(const PIVector2D & v) { PIVector2D 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::value, int>::type = 0> inline bool PIMathFloatNullCompare(const T v) { static_assert(std::is_floating_point::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::value && std::is_floating_point::value, int>::type = 0> inline bool PIMathFloatNullCompare(const T v) { static_assert(std::is_floating_point::value, "Type must be floating point"); static_assert(std::is_floating_point::value, "Type must be floating point"); return (abs(v) < float(1E-200)); } #endif // PIMATHCOMPLEX_H