Skip to content

Commit

Permalink
gd and agd
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap authored Nov 28, 2024
1 parent c38eee7 commit 7521486
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/kyosu/functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <kyosu/functions/acot.hpp>
#include <kyosu/functions/acoth.hpp>
#include <kyosu/functions/acotpi.hpp>
#include <kyosu/functions/agd.hpp>
#include <kyosu/functions/atanpi.hpp>
#include <kyosu/functions/acsc.hpp>
#include <kyosu/functions/acscpi.hpp>
Expand Down Expand Up @@ -90,6 +91,7 @@
#include <kyosu/functions/frac.hpp>
#include <kyosu/functions/from_polar.hpp>
#include <kyosu/functions/fsm.hpp>
#include <kyosu/functions/gd.hpp>
#include <kyosu/functions/hypot.hpp>
#include <kyosu/functions/horner.hpp>
#include <kyosu/functions/inc.hpp>
Expand Down
78 changes: 78 additions & 0 deletions include/kyosu/functions/agd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright: KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once
#include "eve/traits/as_logical.hpp"
#include <kyosu/details/callable.hpp>
#include <kyosu/functions/log.hpp>
#include <kyosu/functions/tan.hpp>
#include <kyosu/constants/wrapped.hpp>

namespace kyosu
{
template<typename Options>
struct agd_t : eve::elementwise_callable<agd_t, Options>
{
template<concepts::cayley_dickson Z>
KYOSU_FORCEINLINE constexpr Z operator()(Z const& z) const noexcept
{
if constexpr(concepts::complex<Z> )
return kyosu::log(kyosu::tan(z*kyosu::half(as(z))+kyosu::pio_4(as(z))));
else
return kyosu::_::cayley_extend(*this, z);
}

template<concepts::real V>
KYOSU_FORCEINLINE constexpr complex_t<V> operator()(V v) const noexcept
{ return (*this)(complex(v)); }

KYOSU_CALLABLE_OBJECT(agd_t, agd_);
};

//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var agd
//! @brief Computes the gudermanian of the argument.
//!
//! @groupheader{Header file}
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T> constexpr T agd(T z) noexcept;
//! template<eve::floating_ordered_value T> constexpr T agd(T z) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z`: Value to process.
//!
//! **Return value**
//!
//! Returns the inverse gudermanian of the argument.
//!
//! @groupheader{External references}
//! * [Wolfram MathWorld: Inverse Gudermannian](https://mathworld.wolfram.com/Gudermannian.html)
//! * [Wikipedia: Gudermannian function](https://en.wikipedia.org/wiki/Gudermannian_function)
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/agd.cpp}
//======================================================================================================================
inline constexpr auto agd = eve::functor<agd_t>;
//======================================================================================================================
//! @}
//======================================================================================================================
}
78 changes: 78 additions & 0 deletions include/kyosu/functions/gd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright: KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once
#include "eve/traits/as_logical.hpp"
#include <kyosu/details/callable.hpp>
#include <kyosu/constants/wrapped.hpp>
#include <kyosu/functions/tanh.hpp>
#include <kyosu/functions/atan.hpp>

namespace kyosu
{
template<typename Options>
struct gd_t : eve::elementwise_callable<gd_t, Options>
{
template<concepts::cayley_dickson Z>
KYOSU_FORCEINLINE constexpr Z operator()(Z const& z) const noexcept
{
if constexpr(concepts::complex<Z> )
return 2*kyosu::atan(tanh(z*kyosu::half(as(z))));
else
return kyosu::_::cayley_extend(*this, z);
}

template<concepts::real V>
KYOSU_FORCEINLINE constexpr V operator()(V v) const noexcept
{ return eve::gd(v); }

KYOSU_CALLABLE_OBJECT(gd_t, gd_);
};

//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var gd
//! @brief Computes the gudermanian of the argument.
//!
//! @groupheader{Header file}
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T> constexpr T gd(T z) noexcept;
//! template<eve::floating_ordered_value T> constexpr T gd(T z) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z`: Value to process.
//!
//! **Return value**
//!
//! Returns the gudermanian of the argument.
//!
//! @groupheader{External references}
//! * [Wolfram MathWorld: Gudermannian](https://mathworld.wolfram.com/Gudermannian.html)
//! * [Wikipedia: Gudermannian function](https://en.wikipedia.org/wiki/Gudermannian_function)
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/gd.cpp}
//======================================================================================================================
inline constexpr auto gd = eve::functor<gd_t>;
//======================================================================================================================
//! @}
//======================================================================================================================
}
25 changes: 25 additions & 0 deletions test/doc/agd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <kyosu/kyosu.hpp>
#include <eve/wide.hpp>
#include <iostream>

int main()
{
using kyosu::agd;
using kyosu::complex_t;
using kyosu::quaternion_t;

std::cout << "Real: ";
std::cout << 72.9f << " -> " << agd(72.9f) << "\n";

std::cout << "Complex: ";
std::cout << kyosu::complex_t<float>(3.5f,-2.9f) << " -> " << agd(kyosu::complex_t<float>(3.5f,-2.9f)) << "\n";

std::cout << "Quaternion: ";
std::cout << kyosu::quaternion_t<double>(1.,2.,3.,4.) << " -> " << agd(kyosu::quaternion_t<double>(1.,2.,3.,4.)) << "\n";

std::cout << "SIMD: ";
using wc_t = eve::wide<kyosu::complex_t<double>, eve::fixed<2>>;
std::cout << wc_t(kyosu::complex_t<double>(1.3,-3.7)) << " -> " << agd(wc_t(kyosu::complex_t<double>(1.3,-3.7))) << "\n";

return 0;
}
25 changes: 25 additions & 0 deletions test/doc/gd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <kyosu/kyosu.hpp>
#include <eve/wide.hpp>
#include <iostream>

int main()
{
using kyosu::gd;
using kyosu::complex_t;
using kyosu::quaternion_t;

std::cout << "Real: ";
std::cout << 72.9f << " -> " << gd(72.9f) << "\n";

std::cout << "Complex: ";
std::cout << kyosu::complex_t<float>(3.5f,-2.9f) << " -> " << gd(kyosu::complex_t<float>(3.5f,-2.9f)) << "\n";

std::cout << "Quaternion: ";
std::cout << kyosu::quaternion_t<double>(1.,2.,3.,4.) << " -> " << gd(kyosu::quaternion_t<double>(1.,2.,3.,4.)) << "\n";

std::cout << "SIMD: ";
using wc_t = eve::wide<kyosu::complex_t<double>, eve::fixed<2>>;
std::cout << wc_t(kyosu::complex_t<double>(1.3,-3.7)) << " -> " << gd(wc_t(kyosu::complex_t<double>(1.3,-3.7))) << "\n";

return 0;
}
28 changes: 28 additions & 0 deletions test/unit/function/agd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#include <kyosu/kyosu.hpp>
#include <test.hpp>

TTS_CASE_WITH ( "Check kyosu::agd over real"
, kyosu::real_types
, tts::generate(tts::randoms(-1,1))
)
<typename T>(T data)
{
TTS_RELATIVE_EQUAL(kyosu::agd(data), kyosu::complex(eve::agd(data)), tts::prec<T>());
};

TTS_CASE_WITH ( "Check kyosu::agd over real"
, kyosu::real_types
, tts::generate(tts::randoms(-1,1), tts::randoms(-1,1))
)
<typename T>(T a0, T a1)
{
kyosu::complex_t<T> data(a0, a1);
TTS_RELATIVE_EQUAL(kyosu::gd( kyosu::agd(data)), data, tts::prec<T>());
};
28 changes: 28 additions & 0 deletions test/unit/function/gd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#include <kyosu/kyosu.hpp>
#include <test.hpp>

TTS_CASE_WITH ( "Check kyosu::gd over real"
, kyosu::real_types
, tts::generate(tts::randoms(-1,1))
)
<typename T>(T data)
{
TTS_RELATIVE_EQUAL(kyosu::gd(data), eve::gd(data), tts::prec<T>());
};

TTS_CASE_WITH ( "Check kyosu::gd over real"
, kyosu::real_types
, tts::generate(tts::randoms(-1,1), tts::randoms(-1,1))
)
<typename T>(T a0, T a1)
{
kyosu::complex_t<T> data(a0, a1);
TTS_RELATIVE_EQUAL(kyosu::agd( kyosu::gd(data)), data, tts::prec<T>());
};

0 comments on commit 7521486

Please sign in to comment.