@@ -53,6 +53,7 @@ const float TWO_OVER_PI = 2.0f / PI;
5353
5454const vec2 CPI = vec2(PI,0.0f);
5555const vec2 ONE = vec2(1.0f,0.0f);
56+ const vec2 MINUS_ONE = vec2(-1.0f,0.0f);
5657const vec2 I = vec2(0.0f,1.0f);
5758
5859#define END_CONSTANT_DEFINITIONS HERE
@@ -260,6 +261,82 @@ vec2 im(vec2 z){
260261 return vec2(z.y,0.0f);
261262}
262263
264+ // Non-elementary functions
265+
266+ const int GAMMA_PRECISION = 7;
267+
268+ const float GAMMA_COEFFICIENTS[7] = float[](
269+ 1.000000000190015, 76.18009172947146, -86.50532032941677,
270+ 24.01409824083091, -1.231739572450155, 1.208650973866179e-3, -5.395239384953e-6
271+ );
272+
273+ const vec2 SQUARE_ROOT_TWO_PI = vec2(sqrt(PI * 2.0f),0.0f);
274+
275+ vec2 cgamma(vec2 z){
276+ vec2 sum = vec2(GAMMA_COEFFICIENTS[0],0.0);
277+ for(int i = 1; i < 7; ++i) {
278+ sum = cadd(sum, cdiv(vec2(GAMMA_COEFFICIENTS[i], 0.0), cadd(z, vec2(float(i), 0.0))));
279+ }
280+ vec2 t = cadd(z, vec2(5.5, 0.0));
281+ vec2 exp_term = cmult(cpow(t, cadd(z, vec2(0.5, 0.0))), cexp(-t));
282+ vec2 result_pos = cdiv(cmult(cmult(exp_term, SQUARE_ROOT_TWO_PI), sum),z);
283+
284+ vec2 z_neg = cneg(z);
285+ vec2 sum_neg = vec2(GAMMA_COEFFICIENTS[0],0.0);
286+ for(int i = 1; i < 7; ++i) {
287+ sum_neg = cadd(sum_neg, cdiv(vec2(GAMMA_COEFFICIENTS[i], 0.0), cadd(z_neg, vec2(float(i), 0.0))));
288+ }
289+ vec2 t_neg = cadd(z_neg,vec2(5.5,0.0));
290+ vec2 exp_term_neg = cmult(cpow(t_neg, cadd(z_neg, vec2(0.5, 0.0))), cexp(-t_neg));
291+ vec2 gamma_1_minus_z = cmult(cmult(exp_term_neg, SQUARE_ROOT_TWO_PI), sum_neg);
292+ vec2 pi_z = cmult(z,vec2(PI,0.0));
293+ vec2 result_neg = cdiv(vec2(PI,0.0),cmult(csin(pi_z),gamma_1_minus_z));
294+
295+ float is_positive = step(0.5,z.x);
296+ return mix(result_neg,result_pos,is_positive);
297+ }
298+
299+ const int ZETA_PRECISION = 10;
300+ const float ZETA_COEFFICIENTS [10] = float[](1.0, 513.0, 23041.0, 263169.0, 1153025.0, 2306049.0, 2191361.0, 950273.0, 171537.0, 9217.0);
301+
302+ vec2 czeta_main_branch(vec2 s){
303+ vec2 sum = vec2(0.0, 0.0);
304+ float sign = 1.0;
305+ for(int n = 0; n < 10; ++n){
306+ vec2 n_to_neg_s = cpow(vec2(float(n+1),0.0), cmult(s, MINUS_ONE));
307+
308+ n_to_neg_s = cmult(n_to_neg_s, vec2(sign * ZETA_COEFFICIENTS[ ZETA_PRECISION - 1 - n], 0.0));
309+ sum = cadd(sum,n_to_neg_s);
310+ sign = -sign;
311+ }
312+ vec2 eta = cmult(sum,vec2(1.0/ZETA_COEFFICIENTS[ZETA_PRECISION - 1], 0.0));
313+ vec2 one_minus_s = csub(ONE,s);
314+ vec2 two_pow = cpow(vec2(2.0,0.0),one_minus_s);
315+ return cdiv(eta,csub(ONE,two_pow));
316+ }
317+
318+ vec2 czeta_negative_branch(vec2 s){
319+ vec2 one_minus_s = csub(ONE, s);
320+ vec2 term1 = cpow(vec2(2.0, 0.0), s);
321+ vec2 term2 = cpow(vec2(PI, 0.0), csub(s, ONE));
322+ vec2 term3 = csin(cmult(s, vec2(PI / 2.0, 0.0)));
323+ vec2 term4 = cgamma(one_minus_s);
324+ vec2 term5 = czeta_main_branch(one_minus_s);
325+ return cmult(term1, cmult(term2, cmult(term3, cmult(term4, term5))));
326+
327+ }
328+
329+ vec2 czeta(vec2 s){
330+ if (s.x >= 0.0) {
331+ return czeta_main_branch(s);
332+ }
333+ else {
334+ return czeta_negative_branch(s);
335+ }
336+ }
337+
338+
339+
263340#define END_FUNCTION_DEFINITIONS HERE
264341
265342
0 commit comments