7#include <stratax/core/ArrayTraits.hpp>
8#include <stratax/core/dtypes/Concepts.hpp>
9#include <stratax/core/dtypes/Types.hpp>
10#include <stratax/ops/Broadcasting.hpp>
12namespace stratax::core::math_detail {
20template<Array A, DType Result,
typename Op>
21auto unary_op(
const A& arr, Op op)
24 stratax::core::rebind_array_t<A, Result>;
26 result_type result(arr.shape());
28 for (std::size_t i = 0; i < arr.size(); ++i)
30 result[i] =
static_cast<Result
>(op(arr[i]));
41 using type = std::remove_cvref_t<T>;
49 using type = dtype::float64;
62template<Array A,
typename Op>
63auto standard_math_op(
const A& arr, Op op)
65 using result_value_type =
66 math_result_t<typename A::value_type>;
68 return unary_op<A, result_value_type>(arr, op);
72template<
typename L,
typename R>
78 std::remove_cvref_t<L>,
79 std::remove_cvref_t<R>>;
82 using type = std::conditional_t<
88template<
typename L,
typename R>
97 using type = std::remove_cvref_t<T>;
110 complex_component_t<std::remove_cvref_t<T>>;
119namespace stratax::core {
124auto sqrt(
const A& arr)
126 return math_detail::standard_math_op(
127 arr, [](
const auto& value)
129 return std::sqrt(value);
136auto cbrt(
const A& arr)
138 return math_detail::standard_math_op(
139 arr, [](
const auto& value)
141 return std::cbrt(value);
148auto exp(
const A& arr)
150 return math_detail::standard_math_op(
151 arr, [](
const auto& value)
153 return std::exp(value);
160auto exp2(
const A& arr)
162 return math_detail::standard_math_op(
163 arr, [](
const auto& value)
165 return std::exp2(value);
172auto expm1(
const A& arr)
174 return math_detail::standard_math_op(
175 arr, [](
const auto& value)
177 return std::expm1(value);
184auto log(
const A& arr)
186 return math_detail::standard_math_op(
187 arr, [](
const auto& value)
189 return std::log(value);
196auto log2(
const A& arr)
198 return math_detail::standard_math_op(
199 arr, [](
const auto& value)
201 return std::log2(value);
208auto log10(
const A& arr)
210 return math_detail::standard_math_op(
211 arr, [](
const auto& value)
213 return std::log10(value);
220auto log1p(
const A& arr)
222 return math_detail::standard_math_op(
223 arr, [](
const auto& value)
225 return std::log1p(value);
232auto logb(
const A& arr)
234 return math_detail::standard_math_op(
235 arr, [](
const auto& value)
237 return std::logb(value);
244auto sin(
const A& arr)
246 return math_detail::standard_math_op(
247 arr, [](
const auto& value)
249 return std::sin(value);
256auto cos(
const A& arr)
258 return math_detail::standard_math_op(
259 arr, [](
const auto& value)
261 return std::cos(value);
268auto tan(
const A& arr)
270 return math_detail::standard_math_op(
271 arr, [](
const auto& value)
273 return std::tan(value);
280auto asin(
const A& arr)
282 return math_detail::standard_math_op(
283 arr, [](
const auto& value)
285 return std::asin(value);
292auto acos(
const A& arr)
294 return math_detail::standard_math_op(
295 arr, [](
const auto& value)
297 return std::acos(value);
304auto atan(
const A& arr)
306 return math_detail::standard_math_op(
307 arr, [](
const auto& value)
309 return std::atan(value);
316auto sinh(
const A& arr)
318 return math_detail::standard_math_op(
319 arr, [](
const auto& value)
321 return std::sinh(value);
328auto cosh(
const A& arr)
330 return math_detail::standard_math_op(
331 arr, [](
const auto& value)
333 return std::cosh(value);
340auto tanh(
const A& arr)
342 return math_detail::standard_math_op(
343 arr, [](
const auto& value)
345 return std::tanh(value);
352auto asinh(
const A& arr)
354 return math_detail::standard_math_op(
355 arr, [](
const auto& value)
357 return std::asinh(value);
364auto acosh(
const A& arr)
366 return math_detail::standard_math_op(
367 arr, [](
const auto& value)
369 return std::acosh(value);
376auto atanh(
const A& arr)
378 return math_detail::standard_math_op(
379 arr, [](
const auto& value)
381 return std::atanh(value);
388auto erf(
const A& arr)
390 return math_detail::standard_math_op(
391 arr, [](
const auto& value)
393 return std::erf(value);
400auto erfc(
const A& arr)
402 return math_detail::standard_math_op(
403 arr, [](
const auto& value)
405 return std::erfc(value);
412auto tgamma(
const A& arr)
414 return math_detail::standard_math_op(
415 arr, [](
const auto& value)
417 return std::tgamma(value);
424auto lgamma(
const A& arr)
426 return math_detail::standard_math_op(
427 arr, [](
const auto& value)
429 return std::lgamma(value);
440auto abs(
const A& arr)
442 using result_value_type =
443 math_detail::abs_result_t<typename A::value_type>;
445 return math_detail::unary_op<A, result_value_type>(
447 [](
const auto& value)
457auto floor(
const A& arr)
459 using result_value_type =
typename A::value_type;
461 return math_detail::unary_op<A, result_value_type>(
463 [](
const auto& value)
465 return std::floor(value);
472auto ceil(
const A& arr)
474 using result_value_type =
typename A::value_type;
476 return math_detail::unary_op<A, result_value_type>(
478 [](
const auto& value)
480 return std::ceil(value);
487auto trunc(
const A& arr)
489 using result_value_type =
typename A::value_type;
491 return math_detail::unary_op<A, result_value_type>(
493 [](
const auto& value)
495 return std::trunc(value);
502auto round(
const A& arr)
504 using result_value_type =
typename A::value_type;
506 return math_detail::unary_op<A, result_value_type>(
508 [](
const auto& value)
510 return std::round(value);
517auto nearbyint(
const A& arr)
519 using result_value_type =
typename A::value_type;
521 return math_detail::unary_op<A, result_value_type>(
523 [](
const auto& value)
525 return std::nearbyint(value);
532auto rint(
const A& arr)
534 using result_value_type =
typename A::value_type;
536 return math_detail::unary_op<A, result_value_type>(
538 [](
const auto& value)
540 return std::rint(value);
550template<Array L, Array R>
551auto pow(
const L& lhs,
const R& rhs)
554 math_detail::pow_result_t<
555 typename L::value_type,
556 typename R::value_type>;
558 return broadcasted_op<result_type>(
561 [](
const auto& a,
const auto& b)
563 return std::pow(a, b);
573template<Array L, Array R>
574auto atan2(
const L& lhs,
const R& rhs)
577 math_detail::pow_result_t<
578 typename L::value_type,
579 typename R::value_type>;
581 return broadcasted_op<result_type>(
584 [](
const auto& a,
const auto& b)
586 return std::atan2(a, b);
591template<Array L, Array R>
592auto hypot(
const L& lhs,
const R& rhs)
595 math_detail::pow_result_t<
596 typename L::value_type,
597 typename R::value_type>;
599 return broadcasted_op<result_type>(
602 [](
const auto& a,
const auto& b)
604 return std::hypot(a, b);
609template<Array L, Array R>
610auto fmod(
const L& lhs,
const R& rhs)
613 math_detail::pow_result_t<
614 typename L::value_type,
615 typename R::value_type>;
617 return broadcasted_op<result_type>(
620 [](
const auto& a,
const auto& b)
622 return std::fmod(a, b);
627template<Array L, Array R>
628auto remainder(
const L& lhs,
const R& rhs)
631 math_detail::pow_result_t<
632 typename L::value_type,
633 typename R::value_type>;
635 return broadcasted_op<result_type>(
638 [](
const auto& a,
const auto& b)
640 return std::remainder(a, b);
645template<Array L, Array R>
646auto copysign(
const L& lhs,
const R& rhs)
649 math_detail::pow_result_t<
650 typename L::value_type,
651 typename R::value_type>;
653 return broadcasted_op<result_type>(
656 [](
const auto& a,
const auto& b)
658 return std::copysign(a, b);
663template<Array L, Array R>
664auto fmax(
const L& lhs,
const R& rhs)
667 math_detail::pow_result_t<
668 typename L::value_type,
669 typename R::value_type>;
671 return broadcasted_op<result_type>(
674 [](
const auto& a,
const auto& b)
676 return std::fmax(a, b);
681template<Array L, Array R>
682auto fmin(
const L& lhs,
const R& rhs)
685 math_detail::pow_result_t<
686 typename L::value_type,
687 typename R::value_type>;
689 return broadcasted_op<result_type>(
692 [](
const auto& a,
const auto& b)
694 return std::fmin(a, b);
699template<Array L, Array R>
704auto fdim(
const L& lhs,
const R& rhs)
707 math_detail::pow_result_t<
708 typename L::value_type,
709 typename R::value_type>;
711 return broadcasted_op<result_type>(
714 [](
const auto& a,
const auto& b)
716 return std::fdim(a, b);
721template<Array L, Array R>
726auto nextafter(
const L& lhs,
const R& rhs)
729 math_detail::pow_result_t<
730 typename L::value_type,
731 typename R::value_type>;
733 return broadcasted_op<result_type>(
736 [](
const auto& a,
const auto& b)
738 return std::nextafter(a, b);
Provides compile-time metadata for a supported Stratax dtype.
complex_component_t< std::remove_cvref_t< T > > type
Real magnitude dtype corresponding to the complex input.
Preserves the dtype of a real absolute-value operation.
std::remove_cvref_t< T > type
Absolute-value result dtype.
dtype::float64 type
Floating-point result dtype used for integral input.
Maps a non-integral input dtype to the same result dtype.
std::remove_cvref_t< T > type
Result dtype for a standard unary math operation.
Determines the common result dtype for a binary math operation.
promote_t< std::remove_cvref_t< L >, std::remove_cvref_t< R > > promoted_type
Dtype obtained from the ordinary Stratax promotion rules.
std::conditional_t< Integral< promoted_type >, dtype::float64, promoted_type > type
Promoted dtype, with integral-only results changed to float64.