6#ifndef _CPG_CALCULUS_HPP
7#define _CPG_CALCULUS_HPP
13#ifdef CPG_INCLUDE_SYCL
14 #include <cl/sycl.hpp>
19 namespace numerical_analysis
21 #ifdef CPG_INCLUDE_SYCL
23 template<
typename CharType =
char>
24 void display_device(sycl::queue& queue,
auto name, std::basic_ostream<CharType>& os)
26 os <<
"Queue '"<< name <<
"' runs on "
27 << queue.get_device().get_info<sycl::info::device::name>() <<
cpg::endl;
33 template<
typename Type>
36 return v / std::numeric_limits<Type>::epsilon();
39 template<
typename Type>
42 return v / std::numeric_limits<Type>::epsilon();
46 template<
typename Type>
49 return value + std::numeric_limits<Type>::epsilon();
53 template<
typename Type>
56 return value - std::numeric_limits<Type>::epsilon();
59 template<
typename Type>
62 template<
typename Type>
72 #pragma warning(disable: 4244)
76 template<
typename ValueType, std::size_t N,
77 typename PairType = std::pair<ValueType, ValueType>,
78 typename ReturnType = std::array<PairType, N>>
82 return ReturnType{ PairType(1.0000000000000000, -0.5773502691896257),
83 PairType(1.0000000000000000, 0.5773502691896257) };
85 else if constexpr(N == 3)
86 return ReturnType{ PairType(0.8888888888888888, 0.0000000000000000),
87 PairType(0.5555555555555556, -0.7745966692414834),
88 PairType(0.5555555555555556, 0.7745966692414834) };
90 else if constexpr(N == 4)
91 return ReturnType{ PairType(0.6521451548625461, -0.3399810435848563),
92 PairType(0.6521451548625461, 0.3399810435848563),
93 PairType(0.3478548451374538, -0.8611363115940526),
94 PairType(0.3478548451374538, 0.8611363115940526) };
96 else if constexpr(N == 5)
97 return ReturnType{ PairType(0.5688888888888889, 0.0000000000000000),
98 PairType(0.4786286704993665, -0.5384693101056831),
99 PairType(0.4786286704993665, 0.5384693101056831),
100 PairType(0.2369268850561891, -0.9061798459386640),
101 PairType(0.2369268850561891, 0.9061798459386640) };
103 else if constexpr(N == 6)
104 return ReturnType{ PairType(0.3607615730481386, 0.6612093864662645),
105 PairType(0.3607615730481386, -0.6612093864662645),
106 PairType(0.4679139345726910, -0.2386191860831969),
107 PairType(0.4679139345726910, 0.2386191860831969),
108 PairType(0.1713244923791704, -0.9324695142031521),
109 PairType(0.1713244923791704, 0.9324695142031521) };
111 else if constexpr(N == 7)
112 return ReturnType{ PairType(0.4179591836734694, 0.0000000000000000),
113 PairType(0.3818300505051189, 0.4058451513773972),
114 PairType(0.3818300505051189, -0.4058451513773972),
115 PairType(0.2797053914892766, -0.7415311855993945),
116 PairType(0.2797053914892766, 0.7415311855993945),
117 PairType(0.1294849661688697, -0.9491079123427585),
118 PairType(0.1294849661688697, 0.9491079123427585) };
120 else if constexpr(N == 8)
121 return ReturnType{ PairType(0.3626837833783620, -0.1834346424956498),
122 PairType(0.3626837833783620, 0.1834346424956498),
123 PairType(0.3137066458778873, -0.5255324099163290),
124 PairType(0.3137066458778873, 0.5255324099163290),
125 PairType(0.2223810344533745, -0.7966664774136267),
126 PairType(0.2223810344533745, 0.7966664774136267),
127 PairType(0.1012285362903763, -0.9602898564975363),
128 PairType(0.1012285362903763, 0.9602898564975363) };
130 else if constexpr(N == 9)
131 return ReturnType{ PairType(0.3302393550012598, 0.0000000000000000),
132 PairType(0.1806481606948574, -0.8360311073266358),
133 PairType(0.1806481606948574, 0.8360311073266358),
134 PairType(0.0812743883615744, -0.9681602395076261),
135 PairType(0.0812743883615744, 0.9681602395076261),
136 PairType(0.3123470770400029, -0.3242534234038089),
137 PairType(0.3123470770400029, 0.3242534234038089),
138 PairType(0.2606106964029354, -0.6133714327005904),
139 PairType(0.2606106964029354, 0.6133714327005904) };
141 else if constexpr(N == 10)
142 return ReturnType{ PairType(0.2955242247147529, -0.1488743389816312),
143 PairType(0.2955242247147529, 0.1488743389816312),
144 PairType(0.2692667193099963, -0.4333953941292472),
145 PairType(0.2692667193099963, 0.4333953941292472),
146 PairType(0.2190863625159820, -0.6794095682990244),
147 PairType(0.2190863625159820, 0.6794095682990244),
148 PairType(0.1494513491505806, -0.8650633666889845),
149 PairType(0.1494513491505806, 0.8650633666889845),
150 PairType(0.0666713443086881, -0.9739065285171717),
151 PairType(0.0666713443086881, 0.9739065285171717) };
153 else if constexpr(N == 11)
154 return ReturnType{ PairType(0.2729250867779006, 0.0000000000000000),
155 PairType(0.2628045445102467, -0.2695431559523450),
156 PairType(0.2628045445102467, 0.2695431559523450),
157 PairType(0.2331937645919905, -0.5190961292068118),
158 PairType(0.2331937645919905, 0.5190961292068118),
159 PairType(0.1862902109277343, -0.7301520055740494),
160 PairType(0.1862902109277343, 0.7301520055740494),
161 PairType(0.1255803694649046, -0.8870625997680953),
162 PairType(0.1255803694649046, 0.8870625997680953),
163 PairType(0.0556685671161737, -0.9782286581460570),
164 PairType(0.0556685671161737, 0.9782286581460570) };
166 else if constexpr(N == 12)
167 return ReturnType{ PairType(0.2491470458134028, -0.1252334085114689),
168 PairType(0.2491470458134028, 0.1252334085114689),
169 PairType(0.2334925365383548, -0.3678314989981802),
170 PairType(0.2334925365383548, 0.3678314989981802),
171 PairType(0.2031674267230659, -0.5873179542866175),
172 PairType(0.2031674267230659, 0.5873179542866175),
173 PairType(0.1600783285433462, -0.7699026741943047),
174 PairType(0.1600783285433462, 0.7699026741943047),
175 PairType(0.1069393259953184, -0.9041172563704749),
176 PairType(0.1069393259953184, 0.9041172563704749),
177 PairType(0.0471753363865118, -0.9815606342467192),
178 PairType(0.0471753363865118, 0.9815606342467192) };
180 else if constexpr(N == 13)
181 return ReturnType{ PairType(0.2325515532308739, 0.0000000000000000),
182 PairType(0.2262831802628972, -0.2304583159551348),
183 PairType(0.2262831802628972, 0.2304583159551348),
184 PairType(0.2078160475368885, -0.4484927510364469),
185 PairType(0.2078160475368885, 0.4484927510364469),
186 PairType(0.1781459807619457, -0.6423493394403402),
187 PairType(0.1781459807619457, 0.6423493394403402),
188 PairType(0.1388735102197872, -0.8015780907333099),
189 PairType(0.1388735102197872, 0.8015780907333099),
190 PairType(0.0921214998377285, -0.9175983992229779),
191 PairType(0.0921214998377285, 0.9175983992229779),
192 PairType(0.0404840047653159, -0.9841830547185881),
193 PairType(0.0404840047653159, 0.9841830547185881) };
195 else if constexpr(N == 14)
196 return ReturnType{ PairType(0.2152638534631578, -0.1080549487073437),
197 PairType(0.2152638534631578, 0.1080549487073437),
198 PairType(0.2051984637212956, -0.3191123689278897),
199 PairType(0.2051984637212956, 0.3191123689278897),
200 PairType(0.1855383974779378, -0.5152486363581541),
201 PairType(0.1855383974779378, 0.5152486363581541),
202 PairType(0.1572031671581935, -0.6872929048116855),
203 PairType(0.1572031671581935, 0.6872929048116855),
204 PairType(0.1215185706879032, -0.8272013150697650),
205 PairType(0.1215185706879032, 0.8272013150697650),
206 PairType(0.0801580871597602, -0.9284348836635735),
207 PairType(0.0801580871597602, 0.9284348836635735),
208 PairType(0.0351194603317519, -0.9862838086968123),
209 PairType(0.0351194603317519, 0.9862838086968123) };
211 else if constexpr(N == 15)
212 return ReturnType{ PairType(0.2025782419255613, 0.0000000000000000),
213 PairType(0.1984314853271116, -0.2011940939974345),
214 PairType(0.1984314853271116, 0.2011940939974345),
215 PairType(0.1861610000155622, -0.3941513470775634),
216 PairType(0.1861610000155622, 0.3941513470775634),
217 PairType(0.1662692058169939, -0.5709721726085388),
218 PairType(0.1662692058169939, 0.5709721726085388),
219 PairType(0.1395706779261543, -0.7244177313601701),
220 PairType(0.1395706779261543, 0.7244177313601701),
221 PairType(0.1071592204671719, -0.8482065834104272),
222 PairType(0.1071592204671719, 0.8482065834104272),
223 PairType(0.0703660474881081, -0.9372733924007060),
224 PairType(0.0703660474881081, 0.9372733924007060),
225 PairType(0.0307532419961173, -0.9879925180204854),
226 PairType(0.0307532419961173, 0.9879925180204854) };
228 else if constexpr(N == 16)
229 return ReturnType{ PairType(0.1894506104550685, -0.0950125098376374),
230 PairType(0.1894506104550685, 0.0950125098376374),
231 PairType(0.1826034150449236, -0.2816035507792589),
232 PairType(0.1826034150449236, 0.2816035507792589),
233 PairType(0.1691565193950025, -0.4580167776572274),
234 PairType(0.1691565193950025, 0.4580167776572274),
235 PairType(0.1495959888165767, -0.6178762444026438),
236 PairType(0.1495959888165767, 0.6178762444026438),
237 PairType(0.1246289712555339, -0.7554044083550030),
238 PairType(0.1246289712555339, 0.7554044083550030),
239 PairType(0.0951585116824928, -0.8656312023878318),
240 PairType(0.0951585116824928, 0.8656312023878318),
241 PairType(0.0622535239386479, -0.9445750230732326),
242 PairType(0.0622535239386479, 0.9445750230732326),
243 PairType(0.0271524594117541, -0.9894009349916499),
244 PairType(0.0271524594117541, 0.9894009349916499) };
246 else if constexpr(N == 17)
247 return ReturnType{ PairType(0.1794464703562065, 0.0000000000000000),
248 PairType(0.1765627053669926, -0.1784841814958479),
249 PairType(0.1765627053669926, 0.1784841814958479),
250 PairType(0.1680041021564500, -0.3512317634538763),
251 PairType(0.1680041021564500, 0.3512317634538763),
252 PairType(0.1540457610768103, -0.5126905370864769),
253 PairType(0.1540457610768103, 0.5126905370864769),
254 PairType(0.1351363684685255, -0.6576711592166907),
255 PairType(0.1351363684685255, 0.6576711592166907),
256 PairType(0.1118838471934040, -0.7815140038968014),
257 PairType(0.1118838471934040, 0.7815140038968014),
258 PairType(0.0850361483171792, -0.8802391537269859),
259 PairType(0.0850361483171792, 0.8802391537269859),
260 PairType(0.0554595293739872, -0.9506755217687678),
261 PairType(0.0554595293739872, 0.9506755217687678),
262 PairType(0.0241483028685479, -0.9905754753144174),
263 PairType(0.0241483028685479, 0.9905754753144174) };
265 else if constexpr(N == 18)
266 return ReturnType{ PairType(0.1691423829631436, -0.0847750130417353),
267 PairType(0.1691423829631436, 0.0847750130417353),
268 PairType(0.1642764837458327, -0.2518862256915055),
269 PairType(0.1642764837458327, 0.2518862256915055),
270 PairType(0.1546846751262652, -0.4117511614628426),
271 PairType(0.1546846751262652, 0.4117511614628426),
272 PairType(0.1406429146706507, -0.5597708310739475),
273 PairType(0.1406429146706507, 0.5597708310739475),
274 PairType(0.1225552067114785, -0.6916870430603532),
275 PairType(0.1225552067114785, 0.6916870430603532),
276 PairType(0.1009420441062872, -0.8037049589725231),
277 PairType(0.1009420441062872, 0.8037049589725231),
278 PairType(0.0764257302548891, -0.8926024664975557),
279 PairType(0.0764257302548891, 0.8926024664975557),
280 PairType(0.0497145488949698, -0.9558239495713977),
281 PairType(0.0497145488949698, 0.9558239495713977),
282 PairType(0.0216160135264833, -0.9915651684209309),
283 PairType(0.0216160135264833, 0.9915651684209309) };
285 else if constexpr(N == 19)
286 return ReturnType{ PairType(0.1610544498487837, 0.0000000000000000),
287 PairType(0.1589688433939543, -0.1603586456402254),
288 PairType(0.1589688433939543, 0.1603586456402254),
289 PairType(0.1527660420658597, -0.3165640999636298),
290 PairType(0.1527660420658597, 0.3165640999636298),
291 PairType(0.1426067021736066, -0.4645707413759609),
292 PairType(0.1426067021736066, 0.4645707413759609),
293 PairType(0.1287539625393362, -0.6005453046616810),
294 PairType(0.1287539625393362, 0.6005453046616810),
295 PairType(0.1115666455473340, -0.7209661773352294),
296 PairType(0.1115666455473340, 0.7209661773352294),
297 PairType(0.0914900216224500, -0.8227146565371428),
298 PairType(0.0914900216224500, 0.8227146565371428),
299 PairType(0.0690445427376412, -0.9031559036148179),
300 PairType(0.0690445427376412, 0.9031559036148179),
301 PairType(0.0448142267656996, -0.9602081521348300),
302 PairType(0.0448142267656996, 0.9602081521348300),
303 PairType(0.0194617882297265, -0.9924068438435844),
304 PairType(0.0194617882297265, 0.9924068438435844) };
306 else if constexpr(N == 20)
307 return ReturnType{ PairType(0.1527533871307258, -0.0765265211334973),
308 PairType(0.1527533871307258, 0.0765265211334973),
309 PairType(0.1491729864726037, -0.2277858511416451),
310 PairType(0.1491729864726037, 0.2277858511416451),
311 PairType(0.1420961093183820, -0.3737060887154195),
312 PairType(0.1420961093183820, 0.3737060887154195),
313 PairType(0.1316886384491766, -0.5108670019508271),
314 PairType(0.1316886384491766, 0.5108670019508271),
315 PairType(0.1181945319615184, -0.6360536807265150),
316 PairType(0.1181945319615184, 0.6360536807265150),
317 PairType(0.1019301198172404, -0.7463319064601508),
318 PairType(0.1019301198172404, 0.7463319064601508),
319 PairType(0.0832767415767048, -0.8391169718222188),
320 PairType(0.0832767415767048, 0.8391169718222188),
321 PairType(0.0626720483341091, -0.9122344282513259),
322 PairType(0.0626720483341091, 0.9122344282513259),
323 PairType(0.0406014298003869, -0.9639719272779138),
324 PairType(0.0406014298003869, 0.9639719272779138),
325 PairType(0.0176140071391521, -0.9931285991850949),
326 PairType(0.0176140071391521, 0.9931285991850949) };
328 else if constexpr(N == 21)
329 return ReturnType{ PairType(0.1460811336496904, 0.0000000000000000),
330 PairType(0.1445244039899700, -0.1455618541608951),
331 PairType(0.1445244039899700, 0.1455618541608951),
332 PairType(0.1398873947910731, -0.2880213168024011),
333 PairType(0.1398873947910731, 0.2880213168024011),
334 PairType(0.1322689386333375, -0.4243421202074388),
335 PairType(0.1322689386333375, 0.4243421202074388),
336 PairType(0.1218314160537285, -0.5516188358872198),
337 PairType(0.1218314160537285, 0.5516188358872198),
338 PairType(0.1087972991671484, -0.6671388041974123),
339 PairType(0.1087972991671484, 0.6671388041974123),
340 PairType(0.0934444234560339, -0.7684399634756779),
341 PairType(0.0934444234560339, 0.7684399634756779),
342 PairType(0.0761001136283793, -0.8533633645833173),
343 PairType(0.0761001136283793, 0.8533633645833173),
344 PairType(0.0571344254268572, -0.9200993341504008),
345 PairType(0.0571344254268572, 0.9200993341504008),
346 PairType(0.0369537897708525, -0.9672268385663063),
347 PairType(0.0369537897708525, 0.9672268385663063),
348 PairType(0.0160172282577743, -0.9937521706203895),
349 PairType(0.0160172282577743, 0.9937521706203895) };
351 else if constexpr(N == 31)
352 return ReturnType{ PairType(0.0997205447934265, 0.0000000000000000),
353 PairType(0.0992250112266723, -0.0995553121523415),
354 PairType(0.0992250112266723, 0.0995553121523415),
355 PairType(0.0977433353863287, -0.1981211993355706),
356 PairType(0.0977433353863287, 0.1981211993355706),
357 PairType(0.0952902429123195, -0.2947180699817016),
358 PairType(0.0952902429123195, 0.2947180699817016),
359 PairType(0.0918901138936415, -0.3883859016082329),
360 PairType(0.0918901138936415, 0.3883859016082329),
361 PairType(0.0875767406084779, -0.4781937820449025),
362 PairType(0.0875767406084779, 0.4781937820449025),
363 PairType(0.0823929917615893, -0.5632491614071493),
364 PairType(0.0823929917615893, 0.5632491614071493),
365 PairType(0.0763903865987766, -0.6427067229242603),
366 PairType(0.0763903865987766, 0.6427067229242603),
367 PairType(0.0696285832354104, -0.7157767845868532),
368 PairType(0.0696285832354104, 0.7157767845868532),
369 PairType(0.0621747865610284, -0.7817331484166249),
370 PairType(0.0621747865610284, 0.7817331484166249),
371 PairType(0.0541030824249169, -0.8399203201462674),
372 PairType(0.0541030824249169, 0.8399203201462674),
373 PairType(0.0454937075272011, -0.8897600299482711),
374 PairType(0.0454937075272011, 0.8897600299482711),
375 PairType(0.0364322739123855, -0.9307569978966481),
376 PairType(0.0364322739123855, 0.9307569978966481),
377 PairType(0.0270090191849794, -0.9625039250929497),
378 PairType(0.0270090191849794, 0.9625039250929497),
379 PairType(0.0173186207903106, -0.9846859096651525),
380 PairType(0.0173186207903106, 0.9846859096651525),
381 PairType(0.0074708315792488, -0.9970874818194770),
382 PairType(0.0074708315792488, 0.9970874818194770) };
384 else if constexpr(N == 41)
385 return ReturnType{ PairType(0.0756955356472984, 0.0000000000000000),
386 PairType(0.0754787470927158, -0.0756232589891630),
387 PairType(0.0754787470927158, 0.0756232589891630),
388 PairType(0.0748296231762215, -0.1508133548639922),
389 PairType(0.0748296231762215, 0.1508133548639922),
390 PairType(0.0737518820272235, -0.2251396056334228),
391 PairType(0.0737518820272235, 0.2251396056334228),
392 PairType(0.0722516968610231, -0.2981762773418249),
393 PairType(0.0722516968610231, 0.2981762773418249),
394 PairType(0.0703376606208175, -0.3695050226404815),
395 PairType(0.0703376606208175, 0.3695050226404815),
396 PairType(0.0680207367608768, -0.4387172770514071),
397 PairType(0.0680207367608768, 0.4387172770514071),
398 PairType(0.0653141964535274, -0.5054165991994061),
399 PairType(0.0653141964535274, 0.5054165991994061),
400 PairType(0.0622335425809663, -0.5692209416102159),
401 PairType(0.0622335425809663, 0.5692209416102159),
402 PairType(0.0587964209498719, -0.6297648390721963),
403 PairType(0.0587964209498719, 0.6297648390721963),
404 PairType(0.0550225192425787, -0.6867015020349513),
405 PairType(0.0550225192425787, 0.6867015020349513),
406 PairType(0.0509334542946175, -0.7397048030699261),
407 PairType(0.0509334542946175, 0.7397048030699261),
408 PairType(0.0465526483690143, -0.7884711450474093),
409 PairType(0.0465526483690143, 0.7884711450474093),
410 PairType(0.0419051951959097, -0.8327212004013613),
411 PairType(0.0419051951959097, 0.8327212004013613),
412 PairType(0.0370177167035080, -0.8722015116924414),
413 PairType(0.0370177167035080, 0.8722015116924414),
414 PairType(0.0319182117316993, -0.9066859447581012),
415 PairType(0.0319182117316993, 0.9066859447581012),
416 PairType(0.0266358992071104, -0.9359769874978539),
417 PairType(0.0266358992071104, 0.9359769874978539),
418 PairType(0.0212010633687796, -0.9599068917303463),
419 PairType(0.0212010633687796, 0.9599068917303463),
420 PairType(0.0156449384078186, -0.9783386735610834),
421 PairType(0.0156449384078186, 0.9783386735610834),
422 PairType(0.0099999387739059, -0.9911671096990163),
423 PairType(0.0099999387739059, 0.9911671096990163),
424 PairType(0.0043061403581649, -0.9983215885747715),
425 PairType(0.0043061403581649, 0.9983215885747715) };
427 else if constexpr(N == 51)
428 return ReturnType{ PairType(0.0609989248412059, 0.0000000000000000),
429 PairType(0.0608854648448563, -0.0609611001505787),
430 PairType(0.0608854648448563, 0.0609611001505787),
431 PairType(0.0605455069347378, -0.1216954210188888),
432 PairType(0.0605455069347378, 0.1216954210188888),
433 PairType(0.0599803157775033, -0.1819770269570775),
434 PairType(0.0599803157775033, 0.1819770269570775),
435 PairType(0.0591919939229615, -0.2415816664477987),
436 PairType(0.0591919939229615, 0.2415816664477987),
437 PairType(0.0581834739825921, -0.3002876063353319),
438 PairType(0.0581834739825921, 0.3002876063353319),
439 PairType(0.0569585077202587, -0.3578764566884095),
440 PairType(0.0569585077202587, 0.3578764566884095),
441 PairType(0.0555216520957387, -0.4141339832263039),
442 PairType(0.0555216520957387, 0.4141339832263039),
443 PairType(0.0538782523130456, -0.4688509042860410),
444 PairType(0.0538782523130456, 0.4688509042860410),
445 PairType(0.0520344219366971, -0.5218236693661858),
446 PairType(0.0520344219366971, 0.5218236693661858),
447 PairType(0.0499970201500574, -0.5728552163513039),
448 PairType(0.0499970201500574, 0.5728552163513039),
449 PairType(0.0477736262406231, -0.6217557046007233),
450 PairType(0.0477736262406231, 0.6217557046007233),
451 PairType(0.0453725114076501, -0.6683432211753700),
452 PairType(0.0453725114076501, 0.6683432211753700),
453 PairType(0.0428026079978801, -0.7124444575770367),
454 PairType(0.0428026079978801, 0.7124444575770367),
455 PairType(0.0400734762854965, -0.7538953544853755),
456 PairType(0.0400734762854965, 0.7538953544853755),
457 PairType(0.0371952689232603, -0.7925417120993812),
458 PairType(0.0371952689232603, 0.7925417120993812),
459 PairType(0.0341786932041883, -0.8282397638230649),
460 PairType(0.0341786932041883, 0.8282397638230649),
461 PairType(0.0310349712901600, -0.8608567111822923),
462 PairType(0.0310349712901600, 0.8608567111822923),
463 PairType(0.0277757985941625, -0.8902712180295274),
464 PairType(0.0277757985941625, 0.8902712180295274),
465 PairType(0.0244133005737814, -0.9163738623097802),
466 PairType(0.0244133005737814, 0.9163738623097802),
467 PairType(0.0209599884017032, -0.9390675440029623),
468 PairType(0.0209599884017032, 0.9390675440029623),
469 PairType(0.0174287147234011, -0.9582678486139082),
470 PairType(0.0174287147234011, 0.9582678486139082),
471 PairType(0.0138326340064778, -0.9739033680193239),
472 PairType(0.0138326340064778, 0.9739033680193239),
473 PairType(0.0101851912978217, -0.9859159917359029),
474 PairType(0.0101851912978217, 0.9859159917359029),
475 PairType(0.0065003377832526, -0.9942612604367526),
476 PairType(0.0065003377832526, 0.9942612604367526),
477 PairType(0.0027968071710899, -0.9989099908489035),
478 PairType(0.0027968071710899, 0.9989099908489035) };
480 else if constexpr(N == 61)
481 return ReturnType{ PairType(0.0510811194407862, 0.0000000000000000),
482 PairType(0.0510144870386973, -0.0510589067079743),
483 PairType(0.0510144870386973, 0.0510589067079743),
484 PairType(0.0508147636688183, -0.1019846065622741),
485 PairType(0.0508147636688183, 0.1019846065622741),
486 PairType(0.0504824703867974, -0.1526442402308153),
487 PairType(0.0504824703867974, 0.1526442402308153),
488 PairType(0.0500184741081783, -0.2029056425180585),
489 PairType(0.0500184741081783, 0.2029056425180585),
490 PairType(0.0494239853467356, -0.2526376871690535),
491 PairType(0.0494239853467356, 0.2526376871690535),
492 PairType(0.0487005550564115, -0.3017106289630307),
493 PairType(0.0487005550564115, 0.3017106289630307),
494 PairType(0.0478500705850956, -0.3499964422040668),
495 PairType(0.0478500705850956, 0.3499964422040668),
496 PairType(0.0468747507508091, -0.3973691547257566),
497 PairType(0.0468747507508091, 0.3973691547257566),
498 PairType(0.0457771400531460, -0.4437051765385316),
499 PairType(0.0457771400531460, 0.4437051765385316),
500 PairType(0.0445601020350835, -0.4888836222622521),
501 PairType(0.0445601020350835, 0.4888836222622521),
502 PairType(0.0432268118124961, -0.5327866265029253),
503 PairType(0.0432268118124961, 0.5327866265029253),
504 PairType(0.0417807477908885, -0.5752996513508306),
505 PairType(0.0417807477908885, 0.5752996513508306),
506 PairType(0.0402256825909982, -0.6163117851979217),
507 PairType(0.0402256825909982, 0.6163117851979217),
508 PairType(0.0385656732070082, -0.6557160320950709),
509 PairType(0.0385656732070082, 0.6557160320950709),
510 PairType(0.0368050504231548, -0.6934095908944912),
511 PairType(0.0368050504231548, 0.6934095908944912),
512 PairType(0.0349484075165334, -0.7292941234494651),
513 PairType(0.0349484075165334, 0.7292941234494651),
514 PairType(0.0330005882759074, -0.7632760111723123),
515 PairType(0.0330005882759074, 0.7632760111723123),
516 PairType(0.0309666743683974, -0.7952665992823597),
517 PairType(0.0309666743683974, 0.7952665992823597),
518 PairType(0.0288519720881834, -0.8251824281086599),
519 PairType(0.0288519720881834, 0.8251824281086599),
520 PairType(0.0266619985241509, -0.8529454508476635),
521 PairType(0.0266619985241509, 0.8529454508476635),
522 PairType(0.0244024671875442, -0.8784832372148811),
523 PairType(0.0244024671875442, 0.8784832372148811),
524 PairType(0.0220792731483190, -0.9017291624740011),
525 PairType(0.0220792731483190, 0.9017291624740011),
526 PairType(0.0196984777461012, -0.9226225813829553),
527 PairType(0.0196984777461012, 0.9226225813829553),
528 PairType(0.0172662929876137, -0.9411089866813611),
529 PairType(0.0172662929876137, 0.9411089866813611),
530 PairType(0.0147890658849379, -0.9571401519129841),
531 PairType(0.0147890658849379, 0.9571401519129841),
532 PairType(0.0122732635078121, -0.9706742588331829),
533 PairType(0.0122732635078121, 0.9706742588331829),
534 PairType(0.0097254618303561, -0.9816760112840370),
535 PairType(0.0097254618303561, 0.9816760112840370),
536 PairType(0.0071523549917491, -0.9901167452325170),
537 PairType(0.0071523549917491, 0.9901167452325170),
538 PairType(0.0045609240060124, -0.9959745998151203),
539 PairType(0.0045609240060124, 0.9959745998151203),
540 PairType(0.0019614533616703, -0.9992355976313635),
541 PairType(0.0019614533616703, 0.9992355976313635) };
543 static_assert(N <= 21 || N == 31 || N == 41 || N == 51 || N == 61);
547 #pragma warning(default: 4244)
550 template<std::size_t WeightCount = 21,
551 typename FunctionType = double(&)(double),
typename ValueType =
double>
555 weights_abscissae<ValueType, WeightCount>();
557 auto a = (x2 - x1) / 2.0;
558 auto b = (x2 + x1) / 2.0;
562 for(
auto&& [w, t]: wa)
564 I += w * f(a * t + b);
570 template<std::size_t WeightCount = 12,
571 typename FuncType = double(&)(double), cpt::arithmetic_c BoundType =
double>
574 constexpr BoundType tolerance
575 = std::numeric_limits<BoundType>::epsilon() * 100;
577 auto c = ( a + b ) / 2;
579 auto s1 = gaussian_quadrature<WeightCount>(f, a, b);
581 auto s2 = gaussian_quadrature<WeightCount>(f, a, c)
582 + gaussian_quadrature<WeightCount>(f, c, b);
584 auto diff = std::abs(s1 - s2);
593 if(diff <= tolerance)
598 return adaptive_gaussian_quadrature<WeightCount>(f, a, c)
599 + adaptive_gaussian_quadrature<WeightCount>(f, c, b);
603 template<
typename FuncType, cpt::tuple_flat_c TupleType>
605 requires (cpt::arithmetic_c<FuncType> ||
requires{
std::apply(func, arg); })
607 if constexpr(cpt::arithmetic_c<FuncType>)
613 template<
typename FuncType, cpt::arithmetic_c ArgType>
615 requires (cpt::arithmetic_c<FuncType> || std::invocable<FuncType, ArgType>)
617 if constexpr ( cpt::arithmetic_c<FuncType>)
619 using common_t = std::common_type_t<FuncType, ArgType>;
626 template<
typename FuncType, cpt::arithmetic_c ArgType>
627 auto evaluate(FuncType&& f, ArgType arg1, ArgType arg2)
628 requires (cpt::arithmetic_c<FuncType> || std::invocable<FuncType, ArgType, ArgType>)
630 if constexpr ( cpt::arithmetic_c<FuncType>)
632 using common_t = std::common_type_t<FuncType, ArgType>;
636 return f(arg1, arg2);
639 template<
typename FuncType, cpt::arithmetic_c ArgType>
640 auto evaluate(FuncType&& f, ArgType arg1, ArgType arg2, ArgType arg3)
641 requires (cpt::arithmetic_c<FuncType> || std::invocable<FuncType, ArgType, ArgType, ArgType>)
643 if constexpr ( cpt::arithmetic_c<FuncType>)
645 using common_t = std::common_type_t<FuncType, ArgType>;
649 return f(arg1, arg2, arg3);
652 template<
typename FuncType, cpt::arithmetic_c ArgType>
653 auto evaluate(FuncType&& f, ArgType arg1, ArgType arg2, ArgType arg3, ArgType arg4)
654 requires (cpt::arithmetic_c<FuncType> || std::invocable<FuncType, ArgType, ArgType, ArgType, ArgType>)
656 if constexpr ( cpt::arithmetic_c<FuncType>)
658 using common_t = std::common_type_t<FuncType, ArgType>;
662 return f(arg1, arg2, arg3, arg4);
665 template<
typename FuncType1,
typename FuncType2, cpt::arithmetic_c ArgType>
666 auto evaluate( std::tuple<FuncType1, FuncType2> funcs,
669 return std::tuple{
evaluate(std::get<0>(funcs), arg1),
670 evaluate(std::get<1>(funcs), arg1) };
673 template<
typename FuncType1,
typename FuncType2, cpt::arithmetic_c ArgType>
674 auto evaluate( std::tuple<FuncType1, FuncType2> funcs,
675 ArgType arg1, ArgType arg2)
677 return std::tuple{
evaluate(std::get<0>(funcs), arg1, arg2),
678 evaluate(std::get<1>(funcs), arg1, arg2) };
681 template<
typename FuncType1,
typename FuncType2, cpt::arithmetic_c ArgType>
682 auto evaluate( std::tuple<FuncType1, FuncType2> funcs,
683 ArgType arg1, ArgType arg2, ArgType arg3)
685 return std::tuple{
evaluate(std::get<0>(funcs), arg1, arg2, arg3),
686 evaluate(std::get<1>(funcs), arg1, arg2, arg3) };
689 template<
typename FuncType1,
typename FuncType2, cpt::arithmetic_c ArgType>
690 auto evaluate( std::tuple<FuncType1, FuncType2> funcs,
691 ArgType arg1, ArgType arg2, ArgType arg3, ArgType arg4)
693 return std::tuple{
evaluate(std::get<0>(funcs), arg1, arg2, arg3, arg4),
694 evaluate(std::get<1>(funcs), arg1, arg2, arg3, arg4) };
698 template<
bool UseRecursion =
true,
699 std::size_t WeightCount = 31,
typename FuncType=double(&)(double),
typename BoundType =
double>
700 BoundType
integral(FuncType&& f, std::tuple<BoundType, BoundType> bound)
701 requires (cpt::arithmetic_c<FuncType> || std::invocable<FuncType, BoundType>)
703 if constexpr(cpt::arithmetic_c<FuncType>)
704 return f * (std::get<1>(bound) - std::get<0>(bound));
705 else if constexpr(UseRecursion)
707 return adaptive_gaussian_quadrature<6>(f, std::get<0>(bound), std::get<1>(bound));
711 if constexpr(std::same_as<BoundType, float>)
712 return gaussian_quadrature<WeightCount>(f, std::get<0>(bound), std::get<1>(bound));
713 else if constexpr(std::same_as<BoundType, double>)
714 return gaussian_quadrature<WeightCount>(f, std::get<0>(bound), std::get<1>(bound));
716 return gaussian_quadrature<WeightCount>(f, std::get<0>(bound), std::get<1>(bound));
721 template<
bool UseRecursion =
true, std::size_t WeightCount = 31,
typename FuncType = double,
722 typename Lower_0 = double,
typename Upper_0 = double,
723 typename Lower_1 = double,
typename Upper_1 = double,
724 auto First=0,
auto Second=1>
725 std::common_type_t<Lower_0, Upper_0>
727 std::tuple<Lower_0, Upper_0> bound_0,
730 using bound_t = std::common_type_t<Lower_0, Upper_0>;
732 auto F0 = [&](bound_t v0)
734 auto F1 = [&](bound_t v1)
736 std::tuple<bound_t, bound_t> args{};
738 std::get<First >(args) = v0;
739 std::get<Second>(args) = v1;
744 return integral<UseRecursion, WeightCount>(F1,
evaluate(bound_1, v0));
747 return integral<UseRecursion, WeightCount>(F0, bound_0);
751 template<
bool UseRecursion =
true, std::size_t WeightCount = 31,
typename FuncType = double(&)(double),
752 typename Lower_0=
double,
typename Upper_0=
double,
753 typename Lower_1=
double,
typename Upper_1=
double,
754 typename Lower_2=
double,
typename Upper_2 =
double,
755 auto First = 0,
auto Second= 1,
auto Third = 2 >
756 std::common_type_t<Lower_0, Upper_0>
758 std::tuple<Lower_0, Upper_0> bound_0,
759 std::tuple<Lower_1, Upper_1> bound_1,
762 using bound_t = std::common_type_t<Lower_0, Upper_0>;
764 auto F0 = [&](bound_t v0)
766 auto F1 = [&](bound_t v1)
768 auto F2 = [&](bound_t v2)
770 std::tuple<bound_t, bound_t, bound_t> args{};
772 std::get<First >(args) = v0;
773 std::get<Second>(args) = v1;
774 std::get<Third>(args) = v2;
779 return integral<UseRecursion, WeightCount>(F2,
evaluate(bound_2, v0, v1));
782 return integral<UseRecursion, WeightCount>(F1,
evaluate(bound_1, v0));
785 return integral<UseRecursion, WeightCount>(F0, bound_0);
789 template<
bool UseRecursion =
true, std::size_t WeightCount = 31,
typename FuncType = double(&)(double),
790 typename Lower_0 =
double,
typename Upper_0 =
double,
791 typename Lower_1 =
double,
typename Upper_1 =
double,
792 typename Lower_2 =
double,
typename Upper_2 =
double,
793 typename Lower_3 =
double,
typename Upper_3 =
double,
794 auto First = 0,
auto Second= 1,
auto Third= 2,
auto Fourth= 3>
795 std::common_type_t<Lower_0, Upper_0>
797 std::tuple<Lower_0, Upper_0> bound_0,
798 std::tuple<Lower_1, Upper_1> bound_1,
799 std::tuple<Lower_2, Upper_2> bound_2,
802 using bound_t = std::common_type_t<Lower_0, Upper_0>;
804 auto F0 = [&](bound_t v0)
806 auto F1 = [&](bound_t v1)
808 auto F2 = [&](bound_t v2)
810 auto F3 = [&](bound_t v3)
812 std::tuple<bound_t, bound_t, bound_t, bound_t> args{};
814 std::get<First >(args) = v0;
815 std::get<Second>(args) = v1;
816 std::get<Third >(args) = v2;
817 std::get<Third >(args) = v3;
822 return integral<UseRecursion, WeightCount>(F3,
evaluate(bound_2, v0, v1, v2));
825 return integral<UseRecursion, WeightCount>(F2,
evaluate(bound_2, v0, v1));
828 return integral<UseRecursion, WeightCount>(F1,
evaluate(bound_1, v0));
831 return integral<UseRecursion, WeightCount>(F0, bound_0);
836 template<
typename Type>
struct delta
838 constexpr static double h_1 = 0.0001;
839 constexpr static double h_2 = 0.001;
840 constexpr static double h_3 = 0.001;
841 constexpr static double h_4 = 0.01;
842 constexpr static double h_5 = 0.01;
843 constexpr static double h_6 = 0.1;
844 constexpr static double h_7 = 0.1;
845 constexpr static double h_8 = 0.1;
848 template<auto Order,
typename DeltaType>
851 if constexpr(Order == 1)
853 else if constexpr(Order == 2)
855 else if constexpr(Order == 3)
857 else if constexpr(Order == 4)
859 else if constexpr(Order == 5)
861 else if constexpr(Order == 6)
863 else if constexpr(Order == 7)
865 else if constexpr(Order == 8)
869 static_assert(Order<=8,
"Order of derivative above 8 is not supported.");
873 template<
typename CountType,
typename BoundType>
876 auto& lower = std::get<0>(bound);
877 auto& upper = std::get<1>(bound);
881 lower = (upper + lower)/(BoundType)2;
886 return (upper - lower) / (
count - 1);
890 template<
typename Type>
893 Type f = std::round(arg);
894 return std::abs(f - arg) < 1.0e-5 ? f : arg;
897 template<
typename Type>
900 if constexpr(std::is_same_v<Type, float>)
902 return adjust_integer<float>( std::abs(arg) < 1.0e-5 ? 0.0f : arg );
904 else if constexpr(std::is_same_v<Type, double>)
906 return adjust_integer<double>( std::abs(arg) < 1.0e-6 ? 0.0f : arg );
908 else if constexpr(std::is_same_v<Type, long double>)
910 return adjust_integer<long double>( std::abs(arg) < 1.0e-6 ? 0.0f : arg );
914 return adjust_integer<Type>( std::abs(arg) < 1.0e-5 ? 0.0f : arg );
918 template<
typename SeqType,
typename... SeqTypes>
928 inline constexpr auto iv_x = 0;
929 inline constexpr auto iv_y = 1;
930 inline constexpr auto iv_z = 2;
1081 template<std::
size_t Order,
typename FuncType,
typename ArgType>
1087 if constexpr(cpt::arithmetic_c<func_t>)
1089 if constexpr( Order == 0)
1094 else if constexpr( Order == 0 )
1096 else if constexpr(Order == 1)
1100 auto o1h = (f(x + h) - f(x - h))/2;
1101 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1102 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1103 auto o4h = (f(x + 4 * h) - f(x - 4 * h))/2;
1105 return (672 * o1h - 168 * o2h + 32 * o3h - 3 * o4h)/(420 * h);
1107 else if constexpr(Order == 2)
1112 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1113 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1114 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1115 auto e4h = (f(x + 4 * h) + f(x - 4 * h) ) / 2 - fx;
1117 return (8064 * e1h - 1008 * e2h + 128 * e3h - 9 * e4h)/(2520 * h * h);
1119 else if constexpr(Order == 3)
1123 auto o1h = (f(x + h) - f(x - h))/2;
1124 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1125 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1126 auto o4h = (f(x + 4 * h) - f(x - 4 * h))/2;
1128 return (-488 * o1h + 338 * o2h - 72 * o3h + 7 * o4h)/(120*h*h*h);
1130 else if constexpr(Order == 4)
1135 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1136 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1137 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1138 auto e4h = (f(x + 4 * h) + f(x - 4 * h) ) / 2 - fx;
1140 return (-1952 * e1h + 676 * e2h - 96 * e3h + 7 * e4h)/(120*h*h*h*h);
1142 else if constexpr(Order == 5)
1146 auto o1h = (f(x + h) - f(x - h))/2;
1147 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1148 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1149 auto o4h = (f(x + 4 * h) - f(x - 4 * h))/2;
1151 return (29 * o1h - 26 * o2h + 9 * o3h - o4h)/(3*h*h*h*h*h);
1153 else if constexpr(Order == 6)
1158 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1159 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1160 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1161 auto e4h = (f(x + 4 * h) + f(x - 4 * h) ) / 2 - fx;
1163 return (116 * e1h - 52 * e2h + 12 * e3h - e4h)/(2*h*h*h*h*h*h);
1165 else if constexpr(Order == 7)
1169 auto o1h = (f(x + h) - f(x - h))/2;
1170 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1171 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1172 auto o4h = (f(x + 4 * h) - f(x - 4 * h))/2;
1174 return (-14 * o1h + 14 * o2h - 6 * o3h + o4h)/(h*h*h*h*h*h*h);
1176 else if constexpr(Order == 8)
1181 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1182 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1183 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1184 auto e4h = (f(x + 4 * h) + f(x - 4 * h) ) / 2 - fx;
1186 return -2*(56 *e1h - 28 * e2h + 8 * e3h - e4h)/(h*h*h*h*h*h*h*h);
1190 static_assert(Order <= 8);
1197 template<std::
size_t Order,
typename FuncType,
typename ArgType>
1203 if constexpr(cpt::arithmetic_c<func_t>)
1205 if constexpr( Order == 0)
1210 else if constexpr( Order == 0 )
1212 else if constexpr(Order == 1)
1216 auto o1h = (f(x + h) - f(x - h))/2;
1217 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1218 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1220 return (45 * o1h - 9 * o2h + o3h)/(30 * h);
1222 else if constexpr(Order == 2)
1227 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1228 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1229 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1231 return (270 * e1h - 27 * e2h + 2 * e3h)/(90 * h * h);
1233 else if constexpr(Order == 3)
1237 auto o1h = (f(x + h) - f(x - h))/2;
1238 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1239 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1241 return (-13 * o1h + 8 * o2h - o3h)/(4 * h * h * h );
1243 else if constexpr(Order == 4)
1248 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1249 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1250 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1252 return (-39 * e1h + 12 * e2h - e3h)/(3*h*h*h*h);
1254 else if constexpr(Order == 5)
1258 auto o1h = (f(x + h) - f(x - h))/2;
1259 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1260 auto o3h = (f(x + 3 * h) - f(x - 3 * h))/2;
1262 return (5 * o1h - 4 * o2h + o3h)/ (h*h*h*h*h);
1264 else if constexpr(Order == 6)
1269 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1270 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1271 auto e3h = (f(x + 3 * h) + f(x - 3 * h) ) / 2 - fx;
1273 return 2 * (15 * e1h - 6 * e2h + e3h) / (h*h*h*h*h*h);
1277 return nine_point_stencil<Order>(f, x);
1281 template<std::
size_t Order,
typename FunctionType,
typename ArgType>
1286 if constexpr(cpt::arithmetic_c<func_t>)
1288 if constexpr( Order == 0)
1293 else if constexpr( Order == 0 )
1295 else if constexpr( Order == 1 )
1299 auto o1h = (f(x + h) - f(x - h))/2;
1300 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1302 return (8 * o1h - o2h )/(6*h);
1304 else if constexpr( Order == 2 )
1309 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1310 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1312 return (16 * e1h - e2h)/(6*h*h);
1314 else if constexpr( Order == 3 )
1318 auto o1h = (f(x + h) - f(x - h))/2;
1319 auto o2h = (f(x + 2 * h) - f(x - 2 * h))/2;
1321 return (-2 * o1h + o2h )/(h*h*h);
1323 else if constexpr( Order == 4 )
1328 auto e1h = (f(x + h) + f(x - h) ) / 2 - fx;
1329 auto e2h = (f(x + 2 * h) + f(x - 2 * h) ) / 2 - fx;
1331 return -2 * (4 * e1h - e2h) / (h*h*h*h);
1335 return seven_point_stencil<Order>(f, x);
1340 template<
auto VarIndex,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1343 return [&func, args...](
auto v)
1345 std::tuple arguments{ args... };
1347 std::get<VarIndex>(arguments) = v;
1353 template<
auto VarIndex,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1356 auto wrapper = [func](
auto... arguments)
1358 return fix_variables_other_than_VarIndex_ed<VarIndex>(func, arguments...);
1364 template<auto VarIndex,
typename FuncType, cpt::arithmetic_c ArgType, std::
size_t N>
1367 auto wrapper = [func](
auto... arguments)
1369 return fix_variables_other_than_VarIndex_ed<VarIndex>(func, arguments...);
1375 template<
auto VarIndex,
auto Order,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1378 auto fixed = fix_variables_other_than_VarIndex_ed<VarIndex>(func, args...);
1379 auto arguments = std::forward_as_tuple(args...);
1380 auto v = std::get<VarIndex>(arguments);
1381 return five_point_stencil<Order>(fixed, v);
1384 template<
auto VarIndex,
auto Order,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1386 std::tuple<ArgTypes...> args)
noexcept
1388 auto fixed = fix_variables_other_than_VarIndex_ed<VarIndex>(func, args);
1389 auto v = std::get<VarIndex>(args);
1390 return five_point_stencil<Order>(fixed, v);
1393 template<
auto VarIndex,
auto Order,
typename FuncType,
1394 cpt::arithmetic_c ArgType, std::size_t N>
1396 FuncType&& func, std::array<ArgType, N> args)
noexcept
1398 auto fixed = fix_variables_other_than_VarIndex_ed<VarIndex>(func, args);
1399 auto v = std::get<VarIndex>(args);
1400 return five_point_stencil<Order>(fixed, v);
1403 template<
typename VarOdr,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1406 constexpr auto VarIndex = cpt::get_nth_value<0>( VarOdr{} );
1407 constexpr auto Order = cpt::get_nth_value<1>( VarOdr{} );
1409 auto fixed = fix_variables_other_than_VarIndex_ed<VarIndex>(func, args...);
1410 auto arguments = std::forward_as_tuple(args...);
1411 auto v = std::get<VarIndex>(arguments);
1412 return five_point_stencil<Order>(fixed, v);
1415 template<
typename VarOdr,
typename FuncType, cpt::arithmetic_c... ArgTypes>
1417 FuncType&& func, std::tuple<ArgTypes...>
const& args)
noexcept
1419 auto wrapper = [=](
auto... arguments)
1427 template<
typename VarOdr,
typename FuncType, cpt::arithmetic_c ArgType, std::
size_t N>
1429 FuncType&& func, std::array<ArgType, N>
const& args)
noexcept
1431 auto wrapper = [=](
auto... arguments)
1439 template<
typename VarOdr1,
typename VarOdr2,
typename... VarOdrs,
1440 typename FuncType, cpt::arithmetic_c... ArgTypes>
1442 FuncType&& func, ArgTypes... args)
noexcept
1444 auto right_derivatives = [&func](
auto... arguments)
1452 template<
typename VarOdr1,
typename VarOdr2,
typename... VarOdrs,
1453 typename FuncType, cpt::arithmetic_c... ArgTypes>
1455 FuncType&& func, std::tuple<ArgTypes...>
const& args)
noexcept
1457 auto wrapper = [=](
auto... arguments)
1465 template<
typename VarOdr1,
typename VarOdr2,
typename... VarOdrs,
1466 typename FuncType, cpt::arithmetic_c ArgType, std::size_t N>
1468 FuncType&& func, std::array<ArgType, N>
const& args)
noexcept
1470 auto wrapper = [=](
auto... arguments)
1478 template<
typename FuncType,
1479 typename... VariableTypes,
typename ParamType>
1481 std::tuple<VariableTypes...>
const& vars, ParamType param)
1483 auto f_of_param = [&](
auto p)
1485 constexpr auto N =
sizeof...(VariableTypes);
1489 return f( std::get<i>(vars)(p)... );
1492 return cpt::for_stallion<N>(call_func);
1495 return five_point_stencil<1>(f_of_param, param);
1498 template<
typename... CmdTypes,
typename FuncType,
1499 typename... VariableTypes,
typename... ParamTypes>
1501 FuncType && f, std::tuple<VariableTypes...>
const& vars, ParamTypes... ps)
1503 auto f_of_params = [&](
auto... params)
1505 constexpr auto N =
sizeof...(VariableTypes);
1509 return f( std::get<i>(vars)(params...)... );
1512 return cpt::for_stallion<N>(call_func);
1518 template<
typename... CmdTypes,
typename FuncType,
1519 typename... VariableTypes,
typename... ParamTypes>
1521 FuncType && f, std::tuple<VariableTypes...>
const& vars, std::tuple<ParamTypes...> ps)
1523 auto f_of_params = [&](
auto... params)
1525 constexpr auto N =
sizeof...(VariableTypes);
1529 return f( std::get<i>(vars)(params...)... );
1532 return cpt::for_stallion<N>(call_func);
1538 template<
typename... CmdTypes,
typename FuncType,
1539 typename... VariableTypes,
typename ParamType, std::size_t N>
1541 FuncType && f, std::tuple<VariableTypes...>
const& vars, std::array<ParamType, N> ps)
1543 auto f_of_params = [&](
auto... params)
1545 constexpr auto NN =
sizeof...(VariableTypes);
1549 return f( std::get<i>(vars)(params...)... );
1552 return cpt::for_stallion<NN>(call_func);
1561 template<
typename FuncType, cpt::arithmetic_c...ArgTypes>
1565 using namespace commands;
1578 return std::array{ adjust_zero<ele_t>(x),
1579 adjust_zero<ele_t>(y),
1580 adjust_zero<ele_t>(z)};
1583 template<
typename FuncType, cpt::arithmetic_c...ArgTypes>
1587 auto wrapper = [&](
auto... arguments)
1595 template<
typename FuncType, cpt::arithmetic_c ArgType, std::
size_t N>
1598 auto wrapper = [&](
auto... arguments)
1608 template<
typename FuncTypeX,
typename FuncTypeY,
1609 typename FuncTypeZ, cpt::arithmetic_c...ArgTypes>
1613 auto curl(FuncTypeX&& func_x, FuncTypeY&& func_y,
1614 FuncTypeZ&& func_z, ArgTypes... args)
noexcept
1616 using namespace commands;
1633 return std::array{ adjust_zero<ele_t>(x), adjust_zero<ele_t>(y), adjust_zero<ele_t>(z) };
1636 template<
typename FuncTypeX,
typename FuncTypeY,
1637 typename FuncTypeZ, cpt::arithmetic_c...ArgTypes>
1641 auto curl(FuncTypeX&& func_x, FuncTypeY&& func_y,
1642 FuncTypeZ&& func_z,
const std::tuple<ArgTypes...>& args)
noexcept
1644 auto wrapper = [&](
auto... arguments)
1646 return curl(func_x, func_y, func_z, arguments...);
1652 template<
typename FuncTypeX,
typename FuncTypeY,
1653 typename FuncTypeZ, cpt::arithmetic_c ArgType, std::size_t N>
1654 auto curl(FuncTypeX&& func_x, FuncTypeY&& func_y,
1655 FuncTypeZ&& func_z,
const std::array<ArgType, N>& args)
noexcept
1657 auto wrapper = [&](
auto... arguments)
1659 return curl(func_x, func_y, func_z, arguments...);
1667 template<
typename FuncTypeX,
typename FuncTypeY,
1668 typename FuncTypeZ, cpt::arithmetic_c...ArgTypes>
1673 FuncTypeZ&& func_z, ArgTypes... args)
noexcept
1675 using namespace commands;
1687 return adjust_zero<ele_t>(d);
1690 template<
typename FuncTypeX,
typename FuncTypeY,
1691 typename FuncTypeZ, cpt::arithmetic_c...ArgTypes>
1696 FuncTypeZ&& func_z,
const std::tuple<ArgTypes...>& args)
noexcept
1698 auto wrapper = [&](
auto... arguments)
1700 return divergence(func_x, func_y, func_z, arguments...);
1706 template<
typename FuncTypeX,
typename FuncTypeY,
1707 typename FuncTypeZ, cpt::arithmetic_c ArgType, std::size_t N>
1709 FuncTypeZ&& func_z,
const std::array<ArgType, N>& args)
noexcept
1711 auto wrapper = [&](
auto... arguments)
1713 return divergence(func_x, func_y, func_z, arguments...);
1719 #ifdef CPG_INCLUDE_SYCL
1723 template<
typename FuncType,
typename BoundType>
1724 auto evaluate(sycl::queue& queue, FuncType func,
1725 std::size_t N, std::array<BoundType, 2> bound)
1727 using arg_t = BoundType;
1729 using array_t = std::array<BoundType, 2>;
1731 std::vector<array_t> result(N);
1734 sycl::buffer<array_t, 1> buffer{ result.data(), sycl::range<1>{ N } };
1736 auto lower = std::get<0>(bound);
1737 auto upper = std::get<1>(bound);
1739 auto dx = (upper - lower)/(N - 1);
1743 [&](sycl::handler& cgh)
1745 sycl::accessor v{ buffer, cgh, sycl::write_only, sycl::no_init };
1750 auto coord = adjust_zero<BoundType>(lower + dx * (
int)idx);
1751 v[idx] = std::array<BoundType, 2>{ coord, adjust_zero<BoundType>( func(coord) ) };
1763 template<auto VarIndex, auto DerivativeOrder,
typename FuncType,
typename BoundType>
1765 FuncType func, std::size_t N, std::array<BoundType, 2> bound)
1767 using arg_t = BoundType;
1769 auto deriv = [func](
auto value)
1771 return five_point_stencil<DerivativeOrder>(func, value);
1774 return evaluate(queue, deriv, N, bound);
1780 template<std::
size_t Index,
typename FuncType,
typename BoundType>
1781 auto evaluate(sycl::queue& queue, FuncType func,
1782 std::size_t N, std::array<BoundType, 2> bound,
auto... args)
1784 using arg_t = BoundType;
1786 using array_t = std::array<BoundType,
sizeof...(args) + 1>;
1788 std::vector<array_t> result(N);
1791 sycl::buffer<array_t, 1> buffer{ result.data(), sycl::range<1>{ N } };
1793 auto lower = std::get<0>(bound);
1794 auto upper = std::get<1>(bound);
1796 auto dx = (upper - lower)/(N - 1);
1800 [&](sycl::handler& cgh)
1802 sycl::accessor v{ buffer, cgh, sycl::write_only, sycl::no_init };
1807 auto coord = adjust_zero<BoundType>(lower + dx * (
int)idx);
1809 if constexpr(
requires{ func(coord); })
1811 v[idx] = std::array{ (arg_t)args..., adjust_zero<BoundType>(func(coord)) };
1812 std::get<Index>(v[idx]) = coord;
1814 else if constexpr(
requires{ func(args...); })
1816 auto arguments = std::tuple{ args ... };
1817 std::get<Index>(arguments) = coord;
1819 v[idx] = std::array{ (arg_t)args..., adjust_zero<BoundType>(
std::apply(func, arguments)) };
1820 std::get<Index>(v[idx]) = coord;
1833 template<
auto VarIndex,
typename IndexType,
typename... IndexTypes,
typename FuncType,
typename BoundType>
1836 FuncType func, std::size_t N, BoundType bound,
auto... args)
1840 auto deriv = [command, func, args...](
auto value)
1842 auto arguments = std::tuple{args...};
1843 std::get<VarIndex>(arguments) = value;
1848 return evaluate<VarIndex>(queue, deriv, N, bound, args...);
1853 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
1854 typename FuncType,
typename BoundType>
1855 auto gradients(sycl::queue& queue, FuncType&& func,
1856 std::array<BoundType, 2> bound_x,
1857 std::array<BoundType, 2> bound_y,
1858 std::array<BoundType, 2> bound_z)
1859 requires requires { func( BoundType{}, BoundType{}, BoundType{}); }
1861 using vertex_t =
decltype(std::tuple{ std::array<BoundType, 3>{},
1862 gradient(func, std::tuple<BoundType, BoundType, BoundType>{}) });
1864 using vertices_t = std::vector<vertex_t>;
1866 vertices_t vertices(CountX * CountY * CountZ);
1869 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
1871 BoundType lower[3], upper[3], delta[3];
1878 lower[0] = std::get<0>(bound_x);
1879 upper[0] = std::get<1>(bound_x);
1881 lower[1] = std::get<0>(bound_y);
1882 upper[1] = std::get<1>(bound_y);
1884 lower[2] = std::get<0>(bound_z);
1885 upper[2] = std::get<1>(bound_z);
1887 auto range = sycl::range<3>{CountX, CountY, CountZ};
1889 sycl::buffer<BoundType, 1> buf_lower{ lower, 3 };
1890 sycl::buffer<BoundType, 1> buf_delta{ delta, 3 };
1893 sycl::buffer<vertex_t, 3> buf_vertices{ vertices.data(),
range};
1896 auto command_group = [&](sycl::handler& cgh)
1898 sycl::accessor acc_lower{ buf_lower, cgh, sycl::read_only };
1899 sycl::accessor acc_delta{ buf_delta, cgh, sycl::read_only };
1900 sycl::accessor acc_v{ buf_vertices, cgh, sycl::write_only, sycl::no_init};
1902 auto kernel = [=](sycl::id<3> idx)
1904 auto i = idx[0];
auto j = idx[1];
auto k = idx[2];
1906 auto x = adjust_zero<BoundType>(acc_lower[0] + acc_delta[0] * i);
1907 auto y = adjust_zero<BoundType>(acc_lower[1] + acc_delta[1] * j);
1908 auto z = adjust_zero<BoundType>(acc_lower[2] + acc_delta[2] * k);
1910 acc_v[idx] = vertex_t{std::array{x, y, z},
1911 gradient(func, std::tuple{x, y, z}) };
1914 cgh.parallel_for(
range, kernel);
1918 queue.submit(command_group);
1926 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
1927 typename FuncTypeX,
typename FuncTypeY,
typename FuncTypeZ,
1929 auto curls(sycl::queue& queue, FuncTypeX&& func_x, FuncTypeY&& func_y, FuncTypeZ&& func_z,
1930 std::array<BoundType, 2> bound_x,
1931 std::array<BoundType, 2> bound_y,
1932 std::array<BoundType, 2> bound_z)
1934 { func_x( BoundType{}, BoundType{}, BoundType{});
1935 func_y( BoundType{}, BoundType{}, BoundType{});
1936 func_z( BoundType{}, BoundType{}, BoundType{}); }
1938 using vertex_t =
decltype(std::tuple{ std::array<BoundType, 3>{},
1939 curl(func_x, func_y, func_z, std::tuple<BoundType, BoundType, BoundType>{}) });
1941 using vertices_t = std::vector<vertex_t>;
1943 vertices_t vertices(CountX * CountY * CountZ);
1946 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
1948 BoundType lower[3], upper[3], delta[3];
1955 lower[0] = std::get<0>(bound_x);
1956 upper[0] = std::get<1>(bound_x);
1958 lower[1] = std::get<0>(bound_y);
1959 upper[1] = std::get<1>(bound_y);
1961 lower[2] = std::get<0>(bound_z);
1962 upper[2] = std::get<1>(bound_z);
1964 auto range = sycl::range<3>{CountX, CountY, CountZ};
1966 sycl::buffer<BoundType, 1> buf_lower{ lower, 3 };
1967 sycl::buffer<BoundType, 1> buf_delta{ delta, 3 };
1970 sycl::buffer<vertex_t, 3> buf_vertices{ vertices.data(),
range};
1973 auto command_group = [&](sycl::handler& cgh)
1975 sycl::accessor acc_lower{ buf_lower, cgh, sycl::read_only };
1976 sycl::accessor acc_delta{ buf_delta, cgh, sycl::read_only };
1977 sycl::accessor acc_v{ buf_vertices, cgh, sycl::write_only, sycl::no_init};
1979 auto kernel = [=](sycl::id<3> idx)
1981 auto i = idx[0];
auto j = idx[1];
auto k = idx[2];
1983 auto x = adjust_zero<BoundType>(acc_lower[0] + acc_delta[0] * i);
1984 auto y = adjust_zero<BoundType>(acc_lower[1] + acc_delta[1] * j);
1985 auto z = adjust_zero<BoundType>(acc_lower[2] + acc_delta[2] * k);
1987 acc_v[idx] = vertex_t{std::array{x, y, z},
1988 curl(func_x, func_y, func_z, std::tuple{x, y, z}) };
1991 cgh.parallel_for(
range, kernel);
1995 queue.submit(command_group);
2003 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
2004 typename FuncTypeX,
typename FuncTypeY,
typename FuncTypeZ,
2006 auto divs(sycl::queue& queue, FuncTypeX&& func_x, FuncTypeY&& func_y, FuncTypeZ&& func_z,
2007 std::array<BoundType, 2> bound_x,
2008 std::array<BoundType, 2> bound_y,
2009 std::array<BoundType, 2> bound_z)
2011 { func_x( BoundType{}, BoundType{}, BoundType{});
2012 func_y( BoundType{}, BoundType{}, BoundType{});
2013 func_z( BoundType{}, BoundType{}, BoundType{}); }
2015 using vertex_t = std::array<BoundType, 4>;
2017 using vertices_t = std::vector<vertex_t>;
2019 vertices_t vertices(CountX * CountY * CountZ);
2022 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
2024 BoundType lower[3], upper[3], delta[3];
2031 lower[0] = std::get<0>(bound_x);
2032 upper[0] = std::get<1>(bound_x);
2034 lower[1] = std::get<0>(bound_y);
2035 upper[1] = std::get<1>(bound_y);
2037 lower[2] = std::get<0>(bound_z);
2038 upper[2] = std::get<1>(bound_z);
2040 auto range = sycl::range<3>{CountX, CountY, CountZ};
2042 sycl::buffer<BoundType, 1> buf_lower{ lower, 3 };
2043 sycl::buffer<BoundType, 1> buf_delta{ delta, 3 };
2046 sycl::buffer<vertex_t, 3> buf_vertices{ vertices.data(),
range};
2049 auto command_group = [&](sycl::handler& cgh)
2051 sycl::accessor acc_lower{ buf_lower, cgh, sycl::read_only };
2052 sycl::accessor acc_delta{ buf_delta, cgh, sycl::read_only };
2053 sycl::accessor acc_v{ buf_vertices, cgh, sycl::write_only, sycl::no_init};
2055 auto kernel = [=](sycl::id<3> idx)
2057 auto i = idx[0];
auto j = idx[1];
auto k = idx[2];
2059 auto x = adjust_zero<BoundType>(acc_lower[0] + acc_delta[0] * i);
2060 auto y = adjust_zero<BoundType>(acc_lower[1] + acc_delta[1] * j);
2061 auto z = adjust_zero<BoundType>(acc_lower[2] + acc_delta[2] * k);
2063 acc_v[idx] = std::array{x, y, z,
2064 divergence(func_x, func_y, func_z, std::tuple{x, y, z}) };
2067 cgh.parallel_for(
range, kernel);
2071 queue.submit(command_group);
2082 template<
typename FuncType,
typename BoundType>
2084 std::array<BoundType, 2> bound)
requires requires { func(BoundType{}); }
2086 using arg_t = BoundType;
2087 using array_t = std::array<arg_t, 2>;
2089 std::vector<array_t> result(N);
2091 auto lower = std::get<0>(bound);
2092 auto upper = std::get<1>(bound);
2094 auto dx = (upper - lower)/ (N - 1);
2096 auto process = [&func, &result, lower, dx](
auto range)
2098 for(
auto i =
range.begin(); i <
range.end(); ++i)
2100 auto coord = adjust_zero<BoundType>(lower + i * dx);
2101 result[i] = array_t{ coord, adjust_zero<BoundType>(func( coord )) };
2112 template<std::size_t VarIndex,
typename FuncType,
typename BoundType,
typename...ArgTypes>
2113 auto evaluate(FuncType&& func, std::size_t N, std::array<BoundType, 2> bound, ArgTypes... args)
2115 using arg_t = BoundType;
2116 using array_t = std::array<BoundType,
sizeof...(args) + 1>;
2118 std::vector<array_t> result(N);
2120 auto lower = std::get<0>(bound);
2121 auto upper = std::get<1>(bound);
2123 auto dx = (upper - lower)/ (N - 1);
2125 auto process = [&func, &result, lower, dx, args...](
auto range)
2127 auto arguments = std::tuple{args...};
2129 for(
auto i =
range.begin(); i <
range.end(); ++i)
2131 auto coord = adjust_zero<BoundType>(lower + i * dx);
2133 std::get<VarIndex>(arguments) = coord;
2135 result[i] = array_t{ (arg_t)args ...,
2136 adjust_zero<BoundType>(
std::apply(func, arguments)) };
2138 std::get<VarIndex>(result[i]) = coord;
2149 template<auto VarIndex, auto DerivativeOrder,
typename FuncType,
typename BoundType>
2151 FuncType&& func, std::size_t N, std::array<BoundType, 2> bound)
2152 requires requires { func(BoundType{}); }
2154 using arg_t = BoundType;
2156 auto ff = [&func](
auto value)
2158 return five_point_stencil<DerivativeOrder>(func, value);
2161 using array_t = std::array<arg_t, 2>;
2163 std::vector<array_t> result(N);
2165 auto lower = std::get<0>(bound);
2166 auto upper = std::get<1>(bound);
2168 auto dx = (upper - lower)/ (N - 1);
2170 auto process = [&ff, &result, lower, dx](
auto range)
2172 for(
auto i =
range.begin(); i <
range.end(); ++i)
2174 auto coord = adjust_zero<BoundType>(lower + i * dx);
2176 result[i] = array_t{ coord, adjust_zero<BoundType>(ff(coord))};
2187 template<
auto VarIndex,
typename IndexType,
typename... IndexTypes,
2188 typename FuncType,
typename BoundType>
2190 FuncType&& func, std::size_t N, std::array<BoundType, 2> bound,
2191 auto... args)
requires requires { func(args...); }
2195 auto ff = [&func, args...](
auto value)
2197 auto arguments = std::tuple{args...};
2198 std::get<VarIndex>(arguments) = value;
2204 using array_t =
decltype(std::array{ (arg_t)args..., arg_t{}});
2206 std::vector<array_t> result(N);
2208 auto lower = std::get<0>(bound);
2209 auto upper = std::get<1>(bound);
2211 auto dx = (upper - lower)/ (N - 1);
2213 auto process = [&ff, &result, lower, dx, args...](
auto range)
2215 for(
auto i =
range.begin(); i <
range.end(); ++i)
2217 auto coord = adjust_zero<BoundType>(lower + i * dx);
2219 result[i] = array_t{ args ..., adjust_zero<BoundType>(ff(coord))};
2221 std::get<VarIndex>(result[i]) = coord;
2232 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
2233 typename FuncType,
typename BoundType>
2235 std::array<BoundType, 2> bound_x,
2236 std::array<BoundType, 2> bound_y,
2237 std::array<BoundType, 2> bound_z)
2238 requires requires { func( BoundType{}, BoundType{}, BoundType{}); }
2240 using vertex_t =
decltype(std::tuple{ std::array<BoundType, 3>{},
2241 gradient(func, std::tuple<BoundType, BoundType, BoundType>{}) });
2243 using vertices_t = std::vector<vertex_t>;
2245 vertices_t vertices(CountX * CountY * CountZ);
2248 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
2250 BoundType lower[3], upper[3], delta[3];
2257 lower[0] = std::get<0>(bound_x);
2258 upper[0] = std::get<1>(bound_x);
2260 lower[1] = std::get<0>(bound_y);
2261 upper[1] = std::get<1>(bound_y);
2263 lower[2] = std::get<0>(bound_z);
2264 upper[2] = std::get<1>(bound_z);
2266 auto compute_gradient = [&lower, &delta, &v, &func]
2267 (tbb::blocked_range3d<std::size_t>&
range)
2269 auto& pages =
range.pages();
2270 auto& rows =
range.rows();
2271 auto& cols =
range.cols();
2273 for(
auto i = pages.begin(); i != pages.end(); ++i)
2274 for(
auto j = rows.begin(); j != rows.end(); ++j)
2275 for(
auto k = cols.begin(); k != cols.end(); ++k)
2277 auto x = adjust_zero<BoundType>(lower[0] + delta[0] * i);
2278 auto y = adjust_zero<BoundType>(lower[1] + delta[1] * j);
2279 auto z = adjust_zero<BoundType>(lower[2] + delta[2] * k);
2281 v[i][j][k] = vertex_t{std::array{x, y, z},
2282 gradient(func, std::tuple{x, y, z}) };
2288 auto range3d = tbb::blocked_range3d<std::size_t>(0, CountX, 0, CountY, 0, CountZ);
2297 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
2298 typename FuncTypeX,
typename FuncTypeY,
typename FuncTypeZ,
2300 auto curls(FuncTypeX&& func_x, FuncTypeY&& func_y, FuncTypeZ&& func_z,
2301 std::array<BoundType, 2> bound_x,
2302 std::array<BoundType, 2> bound_y,
2303 std::array<BoundType, 2> bound_z)
2305 { func_x( BoundType{}, BoundType{}, BoundType{});
2306 func_y( BoundType{}, BoundType{}, BoundType{});
2307 func_z( BoundType{}, BoundType{}, BoundType{}); }
2309 using vertex_t =
decltype(std::tuple{ std::array<BoundType, 3>{},
2310 curl(func_x, func_y, func_z, std::tuple<BoundType, BoundType, BoundType>{}) });
2312 using vertices_t = std::vector<vertex_t>;
2314 vertices_t vertices(CountX * CountY * CountZ);
2317 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
2319 BoundType lower[3], upper[3], delta[3];
2326 lower[0] = std::get<0>(bound_x);
2327 upper[0] = std::get<1>(bound_x);
2329 lower[1] = std::get<0>(bound_y);
2330 upper[1] = std::get<1>(bound_y);
2332 lower[2] = std::get<0>(bound_z);
2333 upper[2] = std::get<1>(bound_z);
2335 auto compute_gradient = [&lower, &delta, &v,
2336 &func_x, &func_y, &func_z]
2337 (tbb::blocked_range3d<std::size_t>&
range)
2339 auto& pages =
range.pages();
2340 auto& rows =
range.rows();
2341 auto& cols =
range.cols();
2343 for(
auto i = pages.begin(); i != pages.end(); ++i)
2344 for(
auto j = rows.begin(); j != rows.end(); ++j)
2345 for(
auto k = cols.begin(); k != cols.end(); ++k)
2347 auto x = adjust_zero<BoundType>(lower[0] + delta[0] * i);
2348 auto y = adjust_zero<BoundType>(lower[1] + delta[1] * j);
2349 auto z = adjust_zero<BoundType>(lower[2] + delta[2] * k);
2351 v[i][j][k] = vertex_t{std::array{x, y, z},
2352 curl(func_x, func_y, func_z, std::tuple{x, y, z}) };
2358 auto range3d = tbb::blocked_range3d<std::size_t>(0, CountX, 0, CountY, 0, CountZ);
2367 template<std::size_t CountX, std::size_t CountY, std::size_t CountZ,
2368 typename FuncTypeX,
typename FuncTypeY,
typename FuncTypeZ,
2370 auto divs(FuncTypeX&& func_x, FuncTypeY&& func_y, FuncTypeZ&& func_z,
2371 std::array<BoundType, 2> bound_x,
2372 std::array<BoundType, 2> bound_y,
2373 std::array<BoundType, 2> bound_z)
2375 { func_x( BoundType{}, BoundType{}, BoundType{});
2376 func_y( BoundType{}, BoundType{}, BoundType{});
2377 func_z( BoundType{}, BoundType{}, BoundType{}); }
2379 using vertex_t = std::array<BoundType, 4>;
2381 using vertices_t = std::vector<vertex_t>;
2383 vertices_t vertices(CountX * CountY * CountZ);
2386 cpt::cast_ref(std::index_sequence<CountX, CountY, CountZ>{}, vertices);
2388 BoundType lower[3], upper[3], delta[3];
2395 lower[0] = std::get<0>(bound_x);
2396 upper[0] = std::get<1>(bound_x);
2398 lower[1] = std::get<0>(bound_y);
2399 upper[1] = std::get<1>(bound_y);
2401 lower[2] = std::get<0>(bound_z);
2402 upper[2] = std::get<1>(bound_z);
2404 auto compute_gradient = [&lower, &delta, &v,
2405 &func_x, &func_y, &func_z]
2406 (tbb::blocked_range3d<std::size_t>&
range)
2408 auto& pages =
range.pages();
2409 auto& rows =
range.rows();
2410 auto& cols =
range.cols();
2412 for(
auto i = pages.begin(); i != pages.end(); ++i)
2413 for(
auto j = rows.begin(); j != rows.end(); ++j)
2414 for(
auto k = cols.begin(); k != cols.end(); ++k)
2416 auto x = adjust_zero<BoundType>(lower[0] + delta[0] * i);
2417 auto y = adjust_zero<BoundType>(lower[1] + delta[1] * j);
2418 auto z = adjust_zero<BoundType>(lower[2] + delta[2] * k);
2420 v[i][j][k] = std::array{x, y, z,
2421 divergence(func_x, func_y, func_z, std::tuple{x, y, z}) };
2427 auto range3d = tbb::blocked_range3d<std::size_t>(0, CountX, 0, CountY, 0, CountZ);
2435 template<
typename FuncType, cpt::arithmetic_c BoundType>
2438 if constexpr( std::same_as<BoundType, float> ||
2439 std::same_as<BoundType, double> ||
2440 std::same_as<BoundType, long double> )
2446 return (b - a) * ( f(a) + 3 * f( (2*a + b)/3 )
2447 + 3 * f( (a + 2*b)/3 ) + f(b) ) / 8;
2451 static_assert( std::same_as<BoundType, float> ||
2452 std::same_as<BoundType, double> ||
2453 std::same_as<BoundType, long double>);
2464 template<
typename FuncType, cpt::arithmetic_c BoundType>
2467 constexpr auto tolerance =
2468 std::numeric_limits<BoundType>::epsilon();
2470 auto c = ( a + b ) / 2;
2475 auto diff = std::abs(s1 - s2);
2484 if(diff <= tolerance)
bool parallel_for(CallbackType &&callback, PolicyType &&policy, BeginType begin_index, EndType end_index)
std::common_type_t< S, T > common_t
auto curls(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, std::array< BoundType, 2 > bound_x, std::array< BoundType, 2 > bound_y, std::array< BoundType, 2 > bound_z)
auto divs(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, std::array< BoundType, 2 > bound_x, std::array< BoundType, 2 > bound_y, std::array< BoundType, 2 > bound_z)
auto smart_apply(FuncType &&func, TupleType arg)
auto differentiate(cpt::sequence< VarIndex, DerivativeOrder >, FuncType &&func, std::size_t N, std::array< BoundType, 2 > bound)
auto nine_point_stencil(FuncType &&f, ArgType x) noexcept
constexpr ReturnType weights_abscissae() noexcept
auto parametric_derivative(cpt::type_container< CmdTypes... > cmd, FuncType &&f, std::tuple< VariableTypes... > const &vars, ParamTypes... ps)
constexpr Type negative_zero
auto seven_point_stencil(FuncType &&f, ArgType x) noexcept
BoundType compute_delta(CountType count, std::array< BoundType, 2 > &bound) noexcept
constexpr auto create_command(SeqType, SeqTypes...) noexcept
Type adjust_zero(auto arg) noexcept
BoundType integral(FuncType &&f, std::tuple< BoundType, BoundType > bound)
constexpr Type negative_approach(Type value)
ValueType gaussian_quadrature(FunctionType &&f, ValueType x1, ValueType x2)
auto fix_variables_other_than_VarIndex_ed(FuncType &&func, ArgTypes... args) noexcept
auto gradients(FuncType &&func, std::array< BoundType, 2 > bound_x, std::array< BoundType, 2 > bound_y, std::array< BoundType, 2 > bound_z)
BoundType adaptive_gaussian_quadrature(FuncType &&f, BoundType a, BoundType b)
auto gradient(FuncType &&function, ArgTypes... args) noexcept
BoundType simpson_rule(FuncType &&f, BoundType a, BoundType b) noexcept
auto divergence(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, ArgTypes... args) noexcept
constexpr Type positive_approach(Type value)
auto curl(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, const std::array< ArgType, N > &args) noexcept
BoundType adaptive_simpson_quadrature(FuncType &&f, BoundType a, BoundType b)
constexpr Type positive_infinity(Type v)
constexpr Type negative_infinity(Type v)
auto partial_derivative(cpt::sequence< VarIndex, Order >, FuncType &&func, ArgTypes... args) noexcept
auto curl(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, ArgTypes... args) noexcept
ArgType five_point_stencil(FunctionType &&f, ArgType x) noexcept
auto evaluate(FuncType &&f, ArgType arg1)
auto directional_derivative(FuncType &&f, std::tuple< VariableTypes... > const &vars, ParamType param)
auto divergence(FuncTypeX &&func_x, FuncTypeY &&func_y, FuncTypeZ &&func_z, const std::array< ArgType, N > &args) noexcept
Type adjust_integer(auto arg) noexcept
constexpr Type positive_zero
auto gradient(FuncType &&function, const std::array< ArgType, N > &args) noexcept
constexpr auto get_delta(delta< DeltaType > del) noexcept
auto & cast_ref(std::unique_ptr< T[], Deleter > &uptr) noexcept
std::integer_sequence< std::common_type_t< std::remove_cvref_t< decltype(Indices)>... >, Indices... > sequence
Includes subnamespace conversion.
constexpr decltype(auto) apply(F &&f, T(&&c_array)[N])
typename st_common_type_solver< Types... >::type common_type_t
remove_cv_ref_t< Type > remove_cvref_t
constexpr bool is_invocable_v