Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
math.ipp
Go to the documentation of this file.
1#pragma once
2
3#include "Math/math.h"
4
5namespace ph::math
6{
7
8template<typename T, std::size_t N>
9inline T summation(const std::array<T, N>& values, const T initialValue)
10{
11 return summation(TSpanView<T, N>{values}, initialValue);
12}
13
14template<typename T>
15inline T summation(const std::vector<T>& values, const T initialValue)
16{
17 return summation(TSpanView<T>{values}, initialValue);
18}
19
20template<typename T, std::size_t EXTENT>
21inline T summation(TSpanView<T, EXTENT> values, const T initialValue)
22{
23 return std::accumulate(values.begin(), values.end(), initialValue);
24}
25
26template<typename T, std::size_t N>
27inline T product(const std::array<T, N>& values, const T initialValue)
28{
29 return product(TSpanView<T, N>{values}, initialValue);
30}
31
32template<typename T>
33inline T product(const std::vector<T>& values, const T initialValue)
34{
35 return product(TSpanView<T>{values}, initialValue);
36}
37
38template<typename T, std::size_t EXTENT>
39inline T product(TSpanView<T, EXTENT> values, const T initialValue)
40{
41 T result = initialValue;
42 for(auto&& value : values)
43 {
44 result *= value;
45 }
46 return result;
47}
48
49template<typename T, std::size_t N>
50inline T length(const std::array<T, N>& vec)
51{
52 return length(TSpanView<T, N>{vec});
53}
54
55template<typename T>
56inline T length(const std::vector<T>& vec)
57{
58 return length(TSpanView<T>{vec});
59}
60
61template<typename T, std::size_t EXTENT>
63{
64 return std::sqrt(length_squared(vec));
65}
66
67template<typename T, std::size_t N>
68inline T length_squared(const std::array<T, N>& vec)
69{
71}
72
73template<typename T>
74inline T length_squared(const std::vector<T>& vec)
75{
76 return length_squared(TSpanView<T>{vec});
77}
78
79template<typename T, std::size_t EXTENT>
81{
82 T result(0);
83 for(const T val : vec)
84 {
85 result += val * val;
86 }
87 return result;
88}
89
90template<typename T, std::size_t N>
91inline T p_norm(const std::array<T, N>& vec)
92{
93 return p_norm(TSpanView<T, N>{vec});
94}
95
96template<typename T>
97inline T p_norm(const std::vector<T>& vec)
98{
99 return p_norm(TSpanView<T>{vec});
100}
101
102template<std::size_t P, typename T, std::size_t EXTENT>
104{
105 static_assert(P >= 1);
106
107 if constexpr(P == 1)
108 {
109 T result(0);
110 for(const T val : vec)
111 {
112 result += std::abs(val);
113 }
114 return result;
115 }
116 else if constexpr(P == 2)
117 {
118 return length<T, EXTENT>(vec);
119 }
120 else
121 {
122 float64 result(0);
123 for(const T val : vec)
124 {
125 if constexpr(P % 2 == 0)
126 {
127 result += std::pow(val, P);
128 }
129 else
130 {
131 static_assert(P % 2 == 1);
132
133 result += std::pow(std::abs(val), P);
134 }
135
136 }
137 return static_cast<T>(std::pow(result, 1.0 / P));
138 }
139}
140
141template<typename T, std::size_t N>
142inline void normalize(std::array<T, N>& vec)
143{
144 return normalize(TSpan<T, N>{vec});
145}
146
147template<typename T>
148inline void normalize(std::vector<T>& vec)
149{
150 return normalize(TSpan<T>{vec});
151}
152
153template<typename T, std::size_t EXTENT>
155{
156 if constexpr(std::is_floating_point_v<T>)
157 {
158 const T rcpLen = static_cast<T>(1) / length<T, EXTENT>(vec);
159 for(T& val : vec)
160 {
161 val *= rcpLen;
162 }
163 }
164 else
165 {
166 static_assert(std::is_integral_v<T>);
167
168 std::fill(vec.begin(), vec.end(), static_cast<T>(0));
169
170 // The only way that normalizing an integer vector will not result in
171 // a 0-vector is that only a single component has finite value, while
172 // all other components are zero. We detect these cases and directly
173 // returns the result.
174
175 constexpr auto EMPTY_IDX = static_cast<std::size_t>(-1);
176
177 auto nonZeroIdx = EMPTY_IDX;
178 for(std::size_t i = 0; i < EXTENT; ++i)
179 {
180 if(vec[i] != static_cast<T>(0))
181 {
182 // Found the first non-zero component, record the index
183 if(nonZeroIdx == EMPTY_IDX)
184 {
185 nonZeroIdx = i;
186 }
187 // This is not the first non-zero component, the result must be 0-vector
188 else
189 {
190 return;
191 }
192 }
193 }
194
195 // Only a single component is != 0
196 if(nonZeroIdx != EMPTY_IDX)
197 {
198 PH_ASSERT_NE(vec[nonZeroIdx], static_cast<T>(0));
199
200 vec[nonZeroIdx] = static_cast<T>(sign(vec[nonZeroIdx]));
201 }
202 }
203}
204
205template<typename T, std::size_t N>
206inline T dot_product(const std::array<T, N>& vecA, const std::array<T, N>& vecB)
207{
208 return dot_product(TSpanView<T, N>{vecA}, TSpanView<T, N>{vecB});
209}
210
211template<typename T>
212inline T dot_product(const std::vector<T>& vecA, const std::vector<T>& vecB)
213{
214 return dot_product(TSpanView<T>{vecA}, TSpanView<T>{vecB});
215}
216
217template<typename T, std::size_t EXTENT>
219{
220 PH_ASSERT_EQ(vecA.size(), vecB.size());
221
222 T result(0);
223 for(std::size_t i = 0; i < vecA.size(); ++i)
224 {
225 result += vecA[i] * vecB[i];
226 }
227 return result;
228}
229
230}// end namespace ph::math
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
T dot_product(const std::array< T, N > &vecA, const std::array< T, N > &vecB)
Treating input values as vectors and calculates their dot product.
Definition math.ipp:206
T length_squared(const std::array< T, N > &vec)
Treating input values as a vector and calculates its squared length.
Definition math.ipp:68
T summation(const std::array< T, N > &values, T initialValue=0)
Sum all values within a container together.
Definition math.ipp:9
void normalize(std::array< T, N > &vec)
Treating input values as a vector and normalize it. Notice that normalizing a integer typed vector wi...
Definition math.ipp:142
T p_norm(const std::array< T, N > &vec)
Treating input values as a vector and calculates its p-norm.
Definition math.ipp:91
T length(const std::array< T, N > &vec)
Treating input values as a vector and calculates its length.
Definition math.ipp:50
T product(const std::array< T, N > &values, T initialValue=1)
Multiplies all values within a container together.
Definition math.ipp:27
int sign(const T value)
Extract the sign of value.
Definition math.h:154
std::span< const T, EXTENT > TSpanView
Same as TSpan, except that the objects are const-qualified. Note that for pointer types,...
Definition TSpan.h:19
std::span< T, EXTENT > TSpan
A contiguous sequence of objects of type T. Effectively the same as std::span.
Definition TSpan.h:12