//  ************************************************************************************************
//
//  libheinz:  C++ base library of Heinz Maier-Leibnitz Zentrum
//
//! @file      heinz/Complex.h
//! @brief     Defines complex_t, and a few elementary functions
//!
//! @homepage  https://jugit.fz-juelich.de/mlz/libheinz
//! @license   Public Domain (BSD Zero Clause License, see LICENSE)
//! @copyright Forschungszentrum Jülich GmbH 2021
//! @authors   Scientific Computing Group at MLZ
//
//  ************************************************************************************************

#ifndef LIBHEINZ_COMPLEX_H
#define LIBHEINZ_COMPLEX_H

#include <cmath>
#include <complex>
#include <concepts>

using complex_t = std::complex<double>;

template <typename T>
concept DoubleOrComplex = std::same_as<T, double> || std::same_as<T, complex_t>;

#ifndef I
constexpr complex_t I = complex_t(0.0, 1.0);
#endif

//! Returns product I*z, where I is the imaginary unit.
inline complex_t mul_I(complex_t z)
{
    return complex_t(-z.imag(), z.real());
}

//! Returns exp(I*z), where I is the imaginary unit.
inline complex_t exp_I(complex_t z)
{
    return std::exp(complex_t(-z.imag(), z.real()));
}

inline bool isfinite(complex_t z)
{
    return std::isfinite(z.real()) && std::isfinite(z.imag());
}

#endif // LIBHEINZ_COMPLEX_H
