Stratax 0.4.0rc1
Loading...
Searching...
No Matches
Math.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <cmath>
18#include <type_traits>
19#include <cstddef>
20
25
26namespace stratax::core::math_detail {
27
34template<Array A, DType Result, typename Op>
35auto unary_op(const A& arr, Op op)
36{
37 using result_type =
39
40 result_type result(arr.shape());
41
42 for (std::size_t i = 0; i < arr.size(); ++i)
43 {
44 result[i] = static_cast<Result>(op(arr[i]));
45 }
46
47 return result;
48}
49
51template<typename T>
53{
55 using type = std::remove_cvref_t<T>;
56};
57
59template<Integral T>
60struct MathResult<T>
61{
64};
65
67template<typename T>
70
77template<Array A, typename Op>
78auto standard_math_op(const A& arr, Op op)
79{
80 using result_value_type =
82
83 return unary_op<A, result_value_type>(arr, op);
84}
85
87template<typename L, typename R>
89{
93 std::remove_cvref_t<L>,
94 std::remove_cvref_t<R>>;
95
97 using type = std::conditional_t<
101};
102
104template<typename L, typename R>
106 typename PowResult<L, R>::type;
107
109template<typename T>
111{
113 using type = std::remove_cvref_t<T>;
114};
115
117template<typename T>
118requires (
120 DTypeKind::Complex
121)
128
130template<typename T>
132 typename AbsResult<std::remove_cvref_t<T>>::type;
133
134} // namespace stratax::core::math_detail
135
136namespace stratax::core {
137
139template<Array A>
141auto sqrt(const A& arr)
142{
143 return math_detail::standard_math_op(
144 arr, [](const auto& value)
145 {
146 return std::sqrt(value);
147 });
148}
149
151template<Array A>
153auto cbrt(const A& arr)
154{
155 return math_detail::standard_math_op(
156 arr, [](const auto& value)
157 {
158 return std::cbrt(value);
159 });
160}
161
163template<Array A>
165auto exp(const A& arr)
166{
167 return math_detail::standard_math_op(
168 arr, [](const auto& value)
169 {
170 return std::exp(value);
171 });
172}
173
175template<Array A>
177auto exp2(const A& arr)
178{
179 return math_detail::standard_math_op(
180 arr, [](const auto& value)
181 {
182 return std::exp2(value);
183 });
184}
185
187template<Array A>
189auto expm1(const A& arr)
190{
191 return math_detail::standard_math_op(
192 arr, [](const auto& value)
193 {
194 return std::expm1(value);
195 });
196}
197
199template<Array A>
201auto log(const A& arr)
202{
203 return math_detail::standard_math_op(
204 arr, [](const auto& value)
205 {
206 return std::log(value);
207 });
208}
209
211template<Array A>
213auto log2(const A& arr)
214{
215 return math_detail::standard_math_op(
216 arr, [](const auto& value)
217 {
218 return std::log2(value);
219 });
220}
221
223template<Array A>
225auto log10(const A& arr)
226{
227 return math_detail::standard_math_op(
228 arr, [](const auto& value)
229 {
230 return std::log10(value);
231 });
232}
233
235template<Array A>
237auto log1p(const A& arr)
238{
239 return math_detail::standard_math_op(
240 arr, [](const auto& value)
241 {
242 return std::log1p(value);
243 });
244}
245
247template<Array A>
249auto logb(const A& arr)
250{
251 return math_detail::standard_math_op(
252 arr, [](const auto& value)
253 {
254 return std::logb(value);
255 });
256}
257
259template<Array A>
261auto sin(const A& arr)
262{
263 return math_detail::standard_math_op(
264 arr, [](const auto& value)
265 {
266 return std::sin(value);
267 });
268}
269
271template<Array A>
273auto cos(const A& arr)
274{
275 return math_detail::standard_math_op(
276 arr, [](const auto& value)
277 {
278 return std::cos(value);
279 });
280}
281
283template<Array A>
285auto tan(const A& arr)
286{
287 return math_detail::standard_math_op(
288 arr, [](const auto& value)
289 {
290 return std::tan(value);
291 });
292}
293
295template<Array A>
297auto asin(const A& arr)
298{
299 return math_detail::standard_math_op(
300 arr, [](const auto& value)
301 {
302 return std::asin(value);
303 });
304}
305
307template<Array A>
309auto acos(const A& arr)
310{
311 return math_detail::standard_math_op(
312 arr, [](const auto& value)
313 {
314 return std::acos(value);
315 });
316}
317
319template<Array A>
321auto atan(const A& arr)
322{
323 return math_detail::standard_math_op(
324 arr, [](const auto& value)
325 {
326 return std::atan(value);
327 });
328}
329
331template<Array A>
333auto sinh(const A& arr)
334{
335 return math_detail::standard_math_op(
336 arr, [](const auto& value)
337 {
338 return std::sinh(value);
339 });
340}
341
343template<Array A>
345auto cosh(const A& arr)
346{
347 return math_detail::standard_math_op(
348 arr, [](const auto& value)
349 {
350 return std::cosh(value);
351 });
352}
353
355template<Array A>
357auto tanh(const A& arr)
358{
359 return math_detail::standard_math_op(
360 arr, [](const auto& value)
361 {
362 return std::tanh(value);
363 });
364}
365
367template<Array A>
369auto asinh(const A& arr)
370{
371 return math_detail::standard_math_op(
372 arr, [](const auto& value)
373 {
374 return std::asinh(value);
375 });
376}
377
379template<Array A>
381auto acosh(const A& arr)
382{
383 return math_detail::standard_math_op(
384 arr, [](const auto& value)
385 {
386 return std::acosh(value);
387 });
388}
389
391template<Array A>
393auto atanh(const A& arr)
394{
395 return math_detail::standard_math_op(
396 arr, [](const auto& value)
397 {
398 return std::atanh(value);
399 });
400}
401
403template<Array A>
405auto erf(const A& arr)
406{
407 return math_detail::standard_math_op(
408 arr, [](const auto& value)
409 {
410 return std::erf(value);
411 });
412}
413
415template<Array A>
417auto erfc(const A& arr)
418{
419 return math_detail::standard_math_op(
420 arr, [](const auto& value)
421 {
422 return std::erfc(value);
423 });
424}
425
427template<Array A>
429auto tgamma(const A& arr)
430{
431 return math_detail::standard_math_op(
432 arr, [](const auto& value)
433 {
434 return std::tgamma(value);
435 });
436}
437
439template<Array A>
441auto lgamma(const A& arr)
442{
443 return math_detail::standard_math_op(
444 arr, [](const auto& value)
445 {
446 return std::lgamma(value);
447 });
448}
449
457template<Array A>
459auto abs(const A& arr)
460{
461 using result_value_type =
463
464 return math_detail::unary_op<A, result_value_type>(
465 arr,
466 [](const auto& value)
467 {
468 using std::abs;
469 return abs(value);
470 });
471}
472
474template<Array A>
476auto floor(const A& arr)
477{
478 using result_value_type = typename A::value_type;
479
480 return math_detail::unary_op<A, result_value_type>(
481 arr,
482 [](const auto& value)
483 {
484 return std::floor(value);
485 });
486}
487
489template<Array A>
491auto ceil(const A& arr)
492{
493 using result_value_type = typename A::value_type;
494
495 return math_detail::unary_op<A, result_value_type>(
496 arr,
497 [](const auto& value)
498 {
499 return std::ceil(value);
500 });
501}
502
504template<Array A>
506auto trunc(const A& arr)
507{
508 using result_value_type = typename A::value_type;
509
510 return math_detail::unary_op<A, result_value_type>(
511 arr,
512 [](const auto& value)
513 {
514 return std::trunc(value);
515 });
516}
517
519template<Array A>
521auto round(const A& arr)
522{
523 using result_value_type = typename A::value_type;
524
525 return math_detail::unary_op<A, result_value_type>(
526 arr,
527 [](const auto& value)
528 {
529 return std::round(value);
530 });
531}
532
534template<Array A>
536auto nearbyint(const A& arr)
537{
538 using result_value_type = typename A::value_type;
539
540 return math_detail::unary_op<A, result_value_type>(
541 arr,
542 [](const auto& value)
543 {
544 return std::nearbyint(value);
545 });
546}
547
549template<Array A>
551auto rint(const A& arr)
552{
553 using result_value_type = typename A::value_type;
554
555 return math_detail::unary_op<A, result_value_type>(
556 arr,
557 [](const auto& value)
558 {
559 return std::rint(value);
560 });
561}
562
569template<Array L, Array R>
570auto pow(const L& lhs, const R& rhs)
571{
572 using result_type =
574 typename L::value_type,
575 typename R::value_type>;
576
577 return broadcasted_op<result_type>(
578 lhs,
579 rhs,
580 [](const auto& a, const auto& b)
581 {
582 return std::pow(a, b);
583 });
584}
585
592template<Array L, Array R>
593auto atan2(const L& lhs, const R& rhs)
594{
595 using result_type =
597 typename L::value_type,
598 typename R::value_type>;
599
600 return broadcasted_op<result_type>(
601 lhs,
602 rhs,
603 [](const auto& a, const auto& b)
604 {
605 return std::atan2(a, b);
606 });
607}
608
610template<Array L, Array R>
611auto hypot(const L& lhs, const R& rhs)
612{
613 using result_type =
615 typename L::value_type,
616 typename R::value_type>;
617
618 return broadcasted_op<result_type>(
619 lhs,
620 rhs,
621 [](const auto& a, const auto& b)
622 {
623 return std::hypot(a, b);
624 });
625}
626
628template<Array L, Array R>
629auto fmod(const L& lhs, const R& rhs)
630{
631 using result_type =
633 typename L::value_type,
634 typename R::value_type>;
635
636 return broadcasted_op<result_type>(
637 lhs,
638 rhs,
639 [](const auto& a, const auto& b)
640 {
641 return std::fmod(a, b);
642 });
643}
644
646template<Array L, Array R>
647auto remainder(const L& lhs, const R& rhs)
648{
649 using result_type =
651 typename L::value_type,
652 typename R::value_type>;
653
654 return broadcasted_op<result_type>(
655 lhs,
656 rhs,
657 [](const auto& a, const auto& b)
658 {
659 return std::remainder(a, b);
660 });
661}
662
664template<Array L, Array R>
665auto copysign(const L& lhs, const R& rhs)
666{
667 using result_type =
669 typename L::value_type,
670 typename R::value_type>;
671
672 return broadcasted_op<result_type>(
673 lhs,
674 rhs,
675 [](const auto& a, const auto& b)
676 {
677 return std::copysign(a, b);
678 });
679}
680
682template<Array L, Array R>
683auto fmax(const L& lhs, const R& rhs)
684{
685 using result_type =
687 typename L::value_type,
688 typename R::value_type>;
689
690 return broadcasted_op<result_type>(
691 lhs,
692 rhs,
693 [](const auto& a, const auto& b)
694 {
695 return std::fmax(a, b);
696 });
697}
698
700template<Array L, Array R>
701auto fmin(const L& lhs, const R& rhs)
702{
703 using result_type =
705 typename L::value_type,
706 typename R::value_type>;
707
708 return broadcasted_op<result_type>(
709 lhs,
710 rhs,
711 [](const auto& a, const auto& b)
712 {
713 return std::fmin(a, b);
714 });
715}
716
718template<Array L, Array R>
719requires (
722)
723auto fdim(const L& lhs, const R& rhs)
724{
725 using result_type =
727 typename L::value_type,
728 typename R::value_type>;
729
730 return broadcasted_op<result_type>(
731 lhs,
732 rhs,
733 [](const auto& a, const auto& b)
734 {
735 return std::fdim(a, b);
736 });
737}
738
740template<Array L, Array R>
741requires (
744)
745auto nextafter(const L& lhs, const R& rhs)
746{
747 using result_type =
749 typename L::value_type,
750 typename R::value_type>;
751
752 return broadcasted_op<result_type>(
753 lhs,
754 rhs,
755 [](const auto& a, const auto& b)
756 {
757 return std::nextafter(a, b);
758 });
759}
760
761} // namespace stratax::core
Result-container rebinding and promotion for owning arrays.
typename RebindArray< std::remove_cvref_t< A >, std::remove_cvref_t< T > >::type rebind_array_t
Convenience alias for rebinding an array to a new value type.
Trailing-axis shape compatibility and element projection.
Dtype and array interface concepts.
typename ComplexComponent< std::remove_cvref_t< T > >::type complex_component_t
Underlying real dtype of a complex dtype.
auto trunc(const A &arr)
Rounds each element toward zero.
Definition Math.hpp:506
auto hypot(const L &lhs, const R &rhs)
Computes element-wise hypotenuses after broadcasting.
Definition Math.hpp:611
auto pow(const L &lhs, const R &rhs)
Raises each broadcasted left element to its corresponding right power.
Definition Math.hpp:570
auto remainder(const L &lhs, const R &rhs)
Computes element-wise IEEE remainders after broadcasting.
Definition Math.hpp:647
auto asin(const A &arr)
Computes the element-wise inverse sine.
Definition Math.hpp:297
auto log10(const A &arr)
Computes the element-wise base-10 logarithm.
Definition Math.hpp:225
auto rint(const A &arr)
Rounds each element using the current floating-point rounding mode.
Definition Math.hpp:551
auto acos(const A &arr)
Computes the element-wise inverse cosine.
Definition Math.hpp:309
auto cosh(const A &arr)
Computes the element-wise hyperbolic cosine.
Definition Math.hpp:345
auto sin(const A &arr)
Computes the element-wise sine in radians.
Definition Math.hpp:261
auto erfc(const A &arr)
Computes the element-wise complementary error function.
Definition Math.hpp:417
typename AbsResult< std::remove_cvref_t< T > >::type abs_result_t
Absolute-value result dtype, using the real component for complex inputs.
Definition Math.hpp:132
auto cbrt(const A &arr)
Computes the element-wise real cube root.
Definition Math.hpp:153
auto sinh(const A &arr)
Computes the element-wise hyperbolic sine.
Definition Math.hpp:333
auto fmin(const L &lhs, const R &rhs)
Selects the element-wise floating-point minimum after broadcasting.
Definition Math.hpp:701
auto fdim(const L &lhs, const R &rhs)
Computes the positive difference of each broadcasted element pair.
Definition Math.hpp:723
auto round(const A &arr)
Rounds each element to the nearest integer value, with halfway cases away from zero.
Definition Math.hpp:521
auto sqrt(const A &arr)
Computes the element-wise principal square root.
Definition Math.hpp:141
auto abs(const A &arr)
Computes the absolute value or complex magnitude of each element.
Definition Math.hpp:459
auto copysign(const L &lhs, const R &rhs)
Copies each broadcasted right sign onto the corresponding left magnitude.
Definition Math.hpp:665
auto atanh(const A &arr)
Computes the element-wise inverse hyperbolic tangent.
Definition Math.hpp:393
auto log(const A &arr)
Computes the element-wise natural logarithm.
Definition Math.hpp:201
auto standard_math_op(const A &arr, Op op)
Applies a unary math callable using the standard result dtype.
Definition Math.hpp:78
auto cos(const A &arr)
Computes the element-wise cosine in radians.
Definition Math.hpp:273
auto log1p(const A &arr)
Computes the natural logarithm of one plus each element.
Definition Math.hpp:237
auto erf(const A &arr)
Computes the element-wise error function.
Definition Math.hpp:405
auto atan(const A &arr)
Computes the element-wise inverse tangent.
Definition Math.hpp:321
typename PowResult< L, R >::type pow_result_t
Binary math result dtype: promoted dtype, with integral results changed to float64.
Definition Math.hpp:106
auto nearbyint(const A &arr)
Rounds each element using the current rounding mode without raising inexact.
Definition Math.hpp:536
auto lgamma(const A &arr)
Computes the logarithm of the absolute gamma function element-wise.
Definition Math.hpp:441
auto exp2(const A &arr)
Computes 2 raised to each element.
Definition Math.hpp:177
auto expm1(const A &arr)
Computes e raised to each element minus one.
Definition Math.hpp:189
auto fmod(const L &lhs, const R &rhs)
Computes element-wise floating-point remainders after broadcasting.
Definition Math.hpp:629
auto tan(const A &arr)
Computes the element-wise tangent in radians.
Definition Math.hpp:285
auto fmax(const L &lhs, const R &rhs)
Selects the element-wise floating-point maximum after broadcasting.
Definition Math.hpp:683
auto atan2(const L &lhs, const R &rhs)
Computes the two-argument arctangent of each broadcasted element pair.
Definition Math.hpp:593
auto tanh(const A &arr)
Computes the element-wise hyperbolic tangent.
Definition Math.hpp:357
auto unary_op(const A &arr, Op op)
Applies a unary callable to every element of an array.
Definition Math.hpp:35
auto exp(const A &arr)
Computes e raised to each element.
Definition Math.hpp:165
auto tgamma(const A &arr)
Computes the element-wise gamma function.
Definition Math.hpp:429
auto logb(const A &arr)
Extracts the unbiased floating-point exponent of each element.
Definition Math.hpp:249
typename MathResult< std::remove_cvref_t< T > >::type math_result_t
Unary math result dtype: float64 for integers, otherwise the input dtype.
Definition Math.hpp:69
auto acosh(const A &arr)
Computes the element-wise inverse hyperbolic cosine.
Definition Math.hpp:381
auto nextafter(const L &lhs, const R &rhs)
Finds the next representable value from each left element toward its broadcasted right element.
Definition Math.hpp:745
auto floor(const A &arr)
Rounds each element downward.
Definition Math.hpp:476
auto log2(const A &arr)
Computes the element-wise base-2 logarithm.
Definition Math.hpp:213
auto ceil(const A &arr)
Rounds each element upward.
Definition Math.hpp:491
auto asinh(const A &arr)
Computes the element-wise inverse hyperbolic sine.
Definition Math.hpp:369
typename Promote< std::remove_cvref_t< L >, std::remove_cvref_t< R > >::type promote_t
Convenience alias for the promoted dtype of two types.
Supported scalar dtype aliases.
double float64
Native double dtype.
Definition Types.hpp:47
Supported integer dtype, excluding bool.
Definition Concepts.hpp:62
Supported integer, floating-point, or complex dtype, excluding bool.
Definition Concepts.hpp:67
Supported integer or standard floating-point type, excluding bool and complex.
Definition Concepts.hpp:160
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.
Definition Math.hpp:126
Preserves the dtype of a real absolute-value operation.
Definition Math.hpp:111
std::remove_cvref_t< T > type
Absolute-value result dtype.
Definition Math.hpp:113
dtype::float64 type
Floating-point result dtype used for integral input.
Definition Math.hpp:63
Maps a non-integral input dtype to the same result dtype.
Definition Math.hpp:53
std::remove_cvref_t< T > type
Result dtype for a standard unary math operation.
Definition Math.hpp:55
Determines the common result dtype for a binary math operation.
Definition Math.hpp:89
promote_t< std::remove_cvref_t< L >, std::remove_cvref_t< R > > promoted_type
Dtype obtained from the ordinary Stratax promotion rules.
Definition Math.hpp:94
std::conditional_t< Integral< promoted_type >, dtype::float64, promoted_type > type
Promoted dtype, with integral-only results changed to float64.
Definition Math.hpp:100