HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
math.hpp
1// Copyright Take Vos 2019-2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "required.hpp"
8#include "cast.hpp"
9#include "type_traits.hpp"
10#include <complex>
11#include <cmath>
12#include <limits>
13#include <span>
14#include <tuple>
15#include <numeric>
16#include <iterator>
17#include <bit>
18
19#if TT_COMPILER == TT_CC_MSVC
20#include <intrin.h>
21#endif
22#if TT_PROCESSOR == TT_CPU_X64
23#include <immintrin.h>
24#endif
25
26namespace tt {
27
28constexpr long long pow10_table[20] {
29 1LL,
30 10LL,
31 100LL,
32 1'000LL,
33 10'000LL,
34 100'000LL,
35 1'000'000LL,
36 10'000'000LL,
37 100'000'000LL,
38 1'000'000'000LL,
39 10'000'000'000LL,
40 100'000'000'000LL,
41 1'000'000'000'000LL,
42 10'000'000'000'000LL,
43 100'000'000'000'000LL,
44 1'000'000'000'000'000LL,
45 10'000'000'000'000'000LL,
46 100'000'000'000'000'000LL,
47 1'000'000'000'000'000'000LL,
48};
49
50constexpr long long pow10ll(int x) noexcept {
51 tt_axiom(x >= 0 && x <= 18);
52 return pow10_table[x];
53}
54
58template<typename T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>,int> = 0>
59constexpr int bsr(T x) noexcept
60{
61 return static_cast<int>(sizeof(T) * 8 - std::countr_zero(x)) - 1;
62}
63
66template<typename T>
67constexpr T make_mask(T x)
68{
69 ttlet x_ = static_cast<unsigned long long>(x) + 1;
70 ttlet p2 = std::bit_ceil(x_);
71 return static_cast<T>(p2 - 1);
72}
73
74
75template<typename T>
76constexpr T median(T a, T b, T c) noexcept {
77 return std::clamp(c, std::min(a, b), std::max(a, b));
78}
79
80inline bool almost_equal(float a, float b) noexcept {
81 uint32_t a_;
82 uint32_t b_;
83
84 std::memcpy(&a_, &a, sizeof(a_));
85 std::memcpy(&b_, &b, sizeof(b_));
86
87 auto a__ = static_cast<int>(a_ & 0x7ffffff);
88 auto b__ = static_cast<int>(b_ & 0x7ffffff);
89
90 if ((a_ < 0) == (b_ < 0)) {
91 return std::abs(a__ - b__) < 10;
92 } else {
93 return std::abs(a__ + b__) < 10;
94 }
95}
96
97template<typename Iterator>
98auto mean(Iterator first, Iterator last)
99{
100 ttlet init = static_cast<typename std::iterator_traits<Iterator>::value_type>(0);
101
102 ttlet sum = std::reduce(first, last, init);
103 ttlet count = static_cast<decltype(sum)>(std::distance(first, last));
104
105 return count > 0.0 ? sum / count : sum;
106}
107
108template<typename Iterator, typename T>
109auto stddev(Iterator first, Iterator last, T mean)
110{
111 ttlet init = static_cast<typename std::iterator_traits<Iterator>::value_type>(0);
112
113 ttlet sum = std::accumulate(first, last, init, [=](ttlet &acc, ttlet &value) {
114 ttlet tmp = value - mean;
115 return acc + tmp*tmp;
116 });
117
118 ttlet count = static_cast<decltype(sum)>(std::distance(first, last));
119 return count > 0.0 ? sum / count : sum;
120}
121
122}
T accumulate(T... args)
T count(T... args)
T distance(T... args)
T max(T... args)
T memcpy(T... args)
T min(T... args)