mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
sprout/complex.hpp 追加
This commit is contained in:
parent
231910c863
commit
60d4f2f2c4
7 changed files with 647 additions and 15 deletions
593
sprout/complex.hpp
Normal file
593
sprout/complex.hpp
Normal file
|
@ -0,0 +1,593 @@
|
|||
#ifndef SPROUT_COMPLEX_HPP
|
||||
#define SPROUT_COMPLEX_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T pi_div_two() {
|
||||
return 1.5707963267948966192313216916397514L;
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
class complex;
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T norm(sprout::complex<T> const& x);
|
||||
//
|
||||
// complex
|
||||
//
|
||||
template<typename T>
|
||||
class complex {
|
||||
public:
|
||||
typedef T value_type;
|
||||
private:
|
||||
T re_;
|
||||
T im_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR complex(T const& re = T(), T const& im = T())
|
||||
: re_(re)
|
||||
, im_(im)
|
||||
{}
|
||||
SPROUT_CONSTEXPR complex(complex const&) = default;
|
||||
template<typename X>
|
||||
SPROUT_CONSTEXPR complex(complex<X> const& other)
|
||||
: re_(other.real())
|
||||
, im_(other.imag())
|
||||
{}
|
||||
SPROUT_CONSTEXPR T real() const {
|
||||
return re_;
|
||||
}
|
||||
void real(T re) {
|
||||
re_ = re;
|
||||
}
|
||||
SPROUT_CONSTEXPR T imag() const{
|
||||
return im_;
|
||||
}
|
||||
void imag(T im) {
|
||||
im_ = im;
|
||||
}
|
||||
complex<T>& operator=(T const& rhs) {
|
||||
re_ = rhs;
|
||||
im_ = T();
|
||||
return *this;
|
||||
}
|
||||
complex<T>& operator+=(T const& rhs) {
|
||||
re_ += rhs;
|
||||
return *this;
|
||||
}
|
||||
complex<T>& operator-=(T const& rhs) {
|
||||
re_ -= rhs;
|
||||
return *this;
|
||||
}
|
||||
complex<T>& operator*=(T const& rhs) {
|
||||
re_ *= rhs;
|
||||
im_ *= rhs;
|
||||
return *this;
|
||||
}
|
||||
complex<T>& operator/=(T const& rhs) {
|
||||
re_ /= rhs;
|
||||
im_ /= rhs;
|
||||
return *this;
|
||||
}
|
||||
complex& operator=(complex const&) = default;
|
||||
template<typename X>
|
||||
complex<T>& operator=(complex<X> const& rhs) {
|
||||
re_ = rhs.real();
|
||||
im_ = rhs.imag();
|
||||
return *this;
|
||||
}
|
||||
template<typename X>
|
||||
complex<T>& operator+=(complex<X> const& rhs) {
|
||||
re_ += rhs.real();
|
||||
im_ += rhs.imag();
|
||||
return *this;
|
||||
}
|
||||
template<typename X>
|
||||
complex<T>& operator-=(complex<X> const& rhs) {
|
||||
re_ -= rhs.real();
|
||||
im_ -= rhs.imag();
|
||||
return *this;
|
||||
}
|
||||
template<typename X>
|
||||
complex<T>& operator*=(complex<X> const& rhs) {
|
||||
return *this = complex<T>(
|
||||
re_ * rhs.real() - im_ * rhs.imag(),
|
||||
re_ * rhs.imag() + im_ * rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename X>
|
||||
complex<T>& operator/=(complex<X> const& rhs) {
|
||||
T n = sprout::norm(rhs);
|
||||
return *this = complex<T>(
|
||||
(re_ * rhs.real() + im_ * rhs.imag()) / n,
|
||||
(im_ * rhs.real() - re_ * rhs.imag()) / n
|
||||
);
|
||||
}
|
||||
};
|
||||
// 26.4.6, operators:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() + rhs.real(),
|
||||
lhs.imag() + rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() + rhs,
|
||||
lhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator+(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs + rhs.real(),
|
||||
rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() - rhs.real(),
|
||||
lhs.imag() - rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() - rhs,
|
||||
lhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator-(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs - rhs.real(),
|
||||
-rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator*(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() * rhs.real() - lhs.imag() * rhs.imag(),
|
||||
lhs.real() * rhs.imag() + lhs.imag() * rhs.imag()
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator*(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() * rhs,
|
||||
lhs.imag() * rhs
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator*(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs * rhs.real(),
|
||||
lhs * rhs.imag()
|
||||
);
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> divides_impl(
|
||||
sprout::complex<T> const& lhs,
|
||||
sprout::complex<T> const& rhs,
|
||||
T const& n
|
||||
)
|
||||
{
|
||||
return sprout::complex<T>(
|
||||
(lhs.real() * rhs.real() + lhs.imag() * rhs.imag()) / n,
|
||||
(lhs.imag() * rhs.real() - lhs.real() * rhs.imag()) / n
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> divides_impl(
|
||||
T const& lhs,
|
||||
sprout::complex<T> const& rhs,
|
||||
T const& n
|
||||
)
|
||||
{
|
||||
return sprout::complex<T>(
|
||||
lhs * rhs.real() / n,
|
||||
-lhs * rhs.imag() / n
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator/(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs));
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator/(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return sprout::complex<T>(
|
||||
lhs.real() / rhs,
|
||||
lhs.imag() / rhs
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator/(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs));
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& x) {
|
||||
return x;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& x) {
|
||||
return sprout::complex<T>(-x.real(), -x.imag());
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator==(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator==(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return lhs.real() == rhs && lhs.imag() == T();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator==(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return lhs == rhs.real() && T() == rhs.imag();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator!=(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator!=(sprout::complex<T> const& lhs, T const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR bool operator!=(T const& lhs, sprout::complex<T> const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename T, typename Char, typename Traits>
|
||||
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& lhs, sprout::complex<T>& rhs) {
|
||||
T re, im;
|
||||
Char ch;
|
||||
lhs >> ch;
|
||||
if (ch == '(') {
|
||||
lhs >> re >> ch;
|
||||
if (ch == ',') {
|
||||
lhs >> im >> ch;
|
||||
if (ch == ')') {
|
||||
rhs = sprout::complex<T>(re, im);
|
||||
} else {
|
||||
lhs.setstate(std::ios_base::failbit);
|
||||
}
|
||||
} else if (ch == ')') {
|
||||
rhs = re;
|
||||
} else {
|
||||
lhs.setstate(std::ios_base::failbit);
|
||||
}
|
||||
} else {
|
||||
lhs.putback(ch);
|
||||
lhs >> re;
|
||||
rhs = re;
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
template<typename T, typename Char, typename Traits>
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& lhs, sprout::complex<T> const& rhs) {
|
||||
return lhs << '(' << rhs.real() << ',' << rhs.imag() << ')';
|
||||
}
|
||||
// 26.4.7, values:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T real(sprout::complex<T> const& x) {
|
||||
return x.real();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T imag(sprout::complex<T> const& x) {
|
||||
return x.imag();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T abs(sprout::complex<T> const& x) {
|
||||
using std::sqrt;
|
||||
return sqrt(sprout::norm(x));
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T arg(sprout::complex<T> const& x) {
|
||||
using std::atan2;
|
||||
return atan2(x.imag(), x.real());
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR T norm(sprout::complex<T> const& x) {
|
||||
return x.real() * x.real() + x.imag() * x.imag();
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> conj(sprout::complex<T> const& x) {
|
||||
return sprout::complex<T>(x.real(), -x.imag());
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> proj_impl(sprout::complex<T> const& x, T const& den) {
|
||||
return sprout::complex<T>(
|
||||
T(2) * x.real() / den,
|
||||
T(2) * x.imag() / den
|
||||
);
|
||||
}
|
||||
} // detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> proj(sprout::complex<T> const& x) {
|
||||
return sprout::detail::proj_impl(
|
||||
x,
|
||||
sprout::norm(x) + T(1)
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> polar(T const& rho, T const& theta = 0) {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
return sprout::complex<T>(rho * cos(theta), rho * sin(theta));
|
||||
}
|
||||
// 26.4.8, transcendentals:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> acos(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> asin(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atan(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> acosh(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> asinh(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atanh(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> cos(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> cosh(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> exp(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> log(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> log10(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, T const& y);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, sprout::complex<T> const& y);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(T const& x, sprout::complex<T> const& y);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sin(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sinh(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sqrt(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> tan(sprout::complex<T> const& x);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> tanh(sprout::complex<T> const& x);
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> acos_impl(sprout::complex<T> const& t) {
|
||||
return sprout::complex<T>(sprout::detail::pi_div_two<T>() - t.real(), -t.imag());
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> acos(sprout::complex<T> const& x) {
|
||||
return sprout::detail::acos_impl(sprout::asin(x));
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> asin_impl(sprout::complex<T> const& t) {
|
||||
return sprout::complex<T>(t.imag(), -t.real());
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> asin(sprout::complex<T> const& x) {
|
||||
return sprout::detail::asin_impl(sprout::asinh(sprout::complex<T>(-x.imag(), x.real())));
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atan_impl_1(
|
||||
sprout::complex<T> const& x,
|
||||
T const& r2,
|
||||
T const& z,
|
||||
T const& num,
|
||||
T const& den
|
||||
)
|
||||
{
|
||||
using std::atan2;
|
||||
using std::log;
|
||||
return sprout::complex<T>(
|
||||
T(0.5) * atan2(T(2) * x.real(), z),
|
||||
T(0.25) * log((r2 + num * num) / (r2 + den * den))
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atan_impl(
|
||||
sprout::complex<T> const& x,
|
||||
T const& r2
|
||||
)
|
||||
{
|
||||
return sprout::detail::atan_impl_1(
|
||||
x,
|
||||
r2,
|
||||
T(1) - r2 - x.imag() * x.imag(),
|
||||
x.imag() + T(1),
|
||||
x.imag() - T(1)
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atan(sprout::complex<T> const& x) {
|
||||
return sprout::detail::atan_impl(x, x.real() * x.real());
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> acosh(sprout::complex<T> const& x) {
|
||||
return T(2) * sprout::log(sprout::sqrt(T(0.5) * (x + T(1))) + sprout::sqrt(T(0.5) * (x - T(1))));
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> asinh(sprout::complex<T> const& x) {
|
||||
return sprout::log(
|
||||
sprout::sqrt(
|
||||
sprout::complex<T>(
|
||||
(x.real() - x.imag()) * (x.real() + x.imag()) + T(1),
|
||||
T(2) * x.real() * x.imag()
|
||||
)
|
||||
)
|
||||
+ x
|
||||
);
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atanh_impl_1(
|
||||
sprout::complex<T> const& x,
|
||||
T const& i2,
|
||||
T const& z,
|
||||
T const& num,
|
||||
T const& den
|
||||
)
|
||||
{
|
||||
using std::atan2;
|
||||
using std::log;
|
||||
return sprout::complex<T>(
|
||||
T(0.25) * (log(i2 + num * num) - log(i2 + den * den)),
|
||||
T(0.5) * atan2(T(2) * x.imag(), z)
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atanh_impl(
|
||||
sprout::complex<T> const& x,
|
||||
T const& i2
|
||||
)
|
||||
{
|
||||
return sprout::detail::atanh_impl_1(
|
||||
x,
|
||||
i2,
|
||||
T(1) - i2 - x.real() * x.real(),
|
||||
T(1) + x.imag(),
|
||||
T(1) - x.imag()
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> atanh(sprout::complex<T> const& x) {
|
||||
return sprout::detail::atanh_impl(x, x.imag() * x.imag());
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> cos(sprout::complex<T> const& x) {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
using std::cosh;
|
||||
using std::sinh;
|
||||
return sprout::complex<T>(
|
||||
cos(x.real()) * cosh(x.imag()),
|
||||
-(sin(x.real()) * sinh(x.imag()))
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> cosh(sprout::complex<T> const& x) {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
using std::cosh;
|
||||
using std::sinh;
|
||||
return sprout::complex<T>(
|
||||
cosh(x.real()) * cos(x.imag()),
|
||||
sinh(x.real()) * sin(x.imag())
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> exp(sprout::complex<T> const& x) {
|
||||
using std::exp;
|
||||
return sprout::polar(exp(x.real()), x.imag());
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> log(sprout::complex<T> const& x) {
|
||||
return sprout::complex<T>(sprout::log(sprout::abs(x)), sprout::arg(x));
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> log10(sprout::complex<T> const& x) {
|
||||
using std::log;
|
||||
return sprout::log(x) / log(T(10));
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow_impl(sprout::complex<T> const& t, T const& y) {
|
||||
using std::exp;
|
||||
return sprout::polar(exp(y * t.real()), y * t.imag());
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, T const& y) {
|
||||
using std::pow;
|
||||
return x == T() ? T()
|
||||
: x.imag() == T() && x.real() > T() ? pow(x.real(), y)
|
||||
: sprout::detail::pow_impl(sprout::log(x), y)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, sprout::complex<T> const& y) {
|
||||
return x == T() ? T()
|
||||
: sprout::exp(y * sprout::log(x))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> pow(T const& x, sprout::complex<T> const& y) {
|
||||
using std::log;
|
||||
return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * log(x))
|
||||
: sprout::pow(sprout::complex<T>(x), y)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sin(sprout::complex<T> const& x) {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
using std::cosh;
|
||||
using std::sinh;
|
||||
return sprout::complex<T>(
|
||||
sin(x.real()) * cosh(x.imag()),
|
||||
cos(x.real()) * sinh(x.imag())
|
||||
);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sinh(sprout::complex<T> const& x) {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
using std::cosh;
|
||||
using std::sinh;
|
||||
return sprout::complex<T>(
|
||||
sinh(x.real()) * cos(x.imag()),
|
||||
cosh(x.real()) * sin(x.imag())
|
||||
);
|
||||
}
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_1(sprout::complex<T> const& x, T const& t) {
|
||||
return sprout::complex<T>(t, x.imag() < T() ? -t : t);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_2_1(sprout::complex<T> const& x, T const& t, T const& u) {
|
||||
using std::abs;
|
||||
return x.real() > T() ? sprout::complex<T>(u, x.imag() / t)
|
||||
: sprout::complex<T>(abs(x.imag()) / t, x.imag() < T() ? -u : u)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_2(sprout::complex<T> const& x, T const& t) {
|
||||
return sqrt_impl_2(x, t, t / 2);
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> sqrt(sprout::complex<T> const& x) {
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
return x.real() == T() ? sprout::detail::sqrt_impl_1(x, sqrt(abs(x.imag()) / 2))
|
||||
: sprout::detail::sqrt_impl_2(x, sqrt(2 * (sprout::abs(x) + abs(x.real()))))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> tan(sprout::complex<T> const& x) {
|
||||
return sprout::sin(x) / sprout::cos(x);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR sprout::complex<T> tanh(sprout::complex<T> const& x) {
|
||||
return sprout::sinh(x) / sprout::cosh(x);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_COMPLEX_HPP
|
|
@ -901,7 +901,27 @@ namespace sprout {
|
|||
sprout::make_array<typename std::decay<T>::type>(
|
||||
sprout::forward<T>(t),
|
||||
sprout::forward<Types>(args)...,
|
||||
T()
|
||||
typename std::decay<T>::type()
|
||||
),
|
||||
typename sprout::index_range<0, 1 + sizeof...(Types)>::type()
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// make_string_as
|
||||
//
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR inline sprout::basic_string<typename std::decay<T>::type, 0>
|
||||
make_string_as() {
|
||||
return sprout::basic_string<typename std::decay<T>::type, 0>{};
|
||||
}
|
||||
template<typename T, typename... Types>
|
||||
SPROUT_CONSTEXPR inline sprout::basic_string<typename std::decay<T>::type, sizeof...(Types)>
|
||||
make_string_as(Types&&... args) {
|
||||
return sprout::detail::make_string_impl(
|
||||
sprout::make_array<typename std::decay<T>::type>(
|
||||
sprout::forward<Types>(args)...,
|
||||
typename std::decay<T>::type()
|
||||
),
|
||||
typename sprout::index_range<0, 1 + sizeof...(Types)>::type()
|
||||
);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/type/tuple.hpp>
|
||||
#include <sprout/type/type_tuple.hpp>
|
||||
#include <sprout/type/integral_array.hpp>
|
||||
#include <sprout/type/string.hpp>
|
||||
#include <sprout/type/rebind_types.hpp>
|
||||
#include <sprout/type/algorithm.hpp>
|
||||
#include <sprout/type/operation.hpp>
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/next_prior.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <sprout/type/tuple.hpp>
|
||||
#include <sprout/type/iterator/next.hpp>
|
||||
#include <sprout/type/iterator/prev.hpp>
|
||||
#include <sprout/type/operation/push_back.hpp>
|
||||
#include <sprout/type/operation/push_front.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace types {
|
||||
|
@ -49,6 +53,7 @@ namespace sprout {
|
|||
struct next<boost::mpl::string_iterator<Sequence, I, J> >
|
||||
: public boost::mpl::next<boost::mpl::string_iterator<Sequence, I, J> >
|
||||
{};
|
||||
|
||||
//
|
||||
// prev
|
||||
//
|
||||
|
@ -56,6 +61,22 @@ namespace sprout {
|
|||
struct prev<boost::mpl::string_iterator<Sequence, I, J> >
|
||||
: public boost::mpl::prior<boost::mpl::string_iterator<Sequence, I, J> >
|
||||
{};
|
||||
|
||||
//
|
||||
// push_back
|
||||
//
|
||||
template<int... Values, typename T>
|
||||
struct push_back<boost::mpl::string<Values...>, T>
|
||||
: public boost::mpl::push_back<boost::mpl::string<Values...>, T>
|
||||
{};
|
||||
|
||||
//
|
||||
// push_front
|
||||
//
|
||||
template<int... Values, typename T>
|
||||
struct push_front<boost::mpl::string<Values...>, T>
|
||||
: public boost::mpl::push_back<boost::mpl::string<Values...>, T>
|
||||
{};
|
||||
} // namespace types
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ namespace sprout {
|
|||
//
|
||||
// to_string
|
||||
//
|
||||
template<typename StringClass>
|
||||
template<typename Proxy>
|
||||
struct to_string {
|
||||
private:
|
||||
typedef decltype(StringClass()()) string_type;
|
||||
typedef decltype(Proxy()()) string_type;
|
||||
typedef sprout::fixed_container_traits<string_type> traits_type;
|
||||
private:
|
||||
template<typename IndexTuple>
|
||||
|
@ -31,12 +31,12 @@ namespace sprout {
|
|||
public:
|
||||
typedef sprout::types::basic_string<
|
||||
typename traits_type::value_type,
|
||||
(*sprout::next(sprout::begin(StringClass()()), Indexes))...
|
||||
(*sprout::next(sprout::begin(Proxy()()), Indexes))...
|
||||
> type;
|
||||
};
|
||||
public:
|
||||
typedef typename impl<
|
||||
typename sprout::index_range<0, sprout::size(StringClass()())>::type
|
||||
typename sprout::index_range<0, sprout::size(Proxy()())>::type
|
||||
>::type type;
|
||||
};
|
||||
namespace detail {
|
||||
|
@ -63,7 +63,7 @@ namespace sprout {
|
|||
// SPROUT_TYPES_STRING_TYPEDEF
|
||||
//
|
||||
# define SPROUT_TYPES_STRING_TYPEDEF(SOURCE, TYPE) \
|
||||
struct SPROUT_PP_CAT(SPROUT_TYPES_STRING_TYPEDEF_IMPL_, __LINE__) { \
|
||||
struct SPROUT_PP_CAT(SPROUT_TYPES_STRING_TYPEDEF_PROXY_, __LINE__) { \
|
||||
private: \
|
||||
typedef typename std::remove_reference<decltype(SOURCE)>::type src_type; \
|
||||
typedef sprout::types::detail::string_typedef_impl<src_type, std::is_array<src_type>::value> impl_type; \
|
||||
|
@ -74,7 +74,7 @@ namespace sprout {
|
|||
return impl_type()(SOURCE); \
|
||||
} \
|
||||
}; \
|
||||
typedef typename sprout::types::to_string<SPROUT_PP_CAT(SPROUT_TYPES_STRING_TYPEDEF_IMPL_, __LINE__)>::type TYPE
|
||||
typedef typename sprout::types::to_string<SPROUT_PP_CAT(SPROUT_TYPES_STRING_TYPEDEF_PROXY_, __LINE__)>::type TYPE
|
||||
} // namespace types
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -42,14 +42,9 @@ namespace sprout {
|
|||
typename Sequence::value_type,
|
||||
sprout::types::detail::str_length<Sequence>::value
|
||||
> to_string_constant_impl(sprout::index_tuple<Indexes...>) {
|
||||
typedef sprout::basic_string<
|
||||
typename Sequence::value_type,
|
||||
sprout::types::detail::str_length<Sequence>::value
|
||||
> type;
|
||||
return type{
|
||||
{sprout::types::tuple_element<Indexes, Sequence>::type::value...},
|
||||
sprout::types::detail::str_length<Sequence>::value
|
||||
};
|
||||
return sprout::make_string_as<typename Sequence::value_type>(
|
||||
sprout::types::tuple_element<Indexes, Sequence>::type::value...
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
template<typename Sequence>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef SPROUT_WEED_HPP
|
||||
#define SPROUT_WEED_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/weed/expr.hpp>
|
||||
#include <sprout/weed/operator.hpp>
|
||||
#include <sprout/weed/attr_cnv.hpp>
|
||||
|
|
Loading…
Reference in a new issue