Skip to content

Commit 7255bf4

Browse files
committed
Implemented the zeta and gamma functions
1 parent 9102026 commit 7255bf4

3 files changed

Lines changed: 163 additions & 1 deletion

File tree

src/shaders/embedded_shaders.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const float TWO_OVER_PI = 2.0f / PI;
5353
5454
const vec2 CPI = vec2(PI,0.0f);
5555
const vec2 ONE = vec2(1.0f,0.0f);
56+
const vec2 MINUS_ONE = vec2(-1.0f,0.0f);
5657
const 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

src/shaders/plotter.frag

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const float TWO_OVER_PI = 2.0f / PI;
1515

1616
const vec2 CPI = vec2(PI,0.0f);
1717
const vec2 ONE = vec2(1.0f,0.0f);
18+
const vec2 MINUS_ONE = vec2(-1.0f,0.0f);
1819
const vec2 I = vec2(0.0f,1.0f);
1920

2021
#define END_CONSTANT_DEFINITIONS HERE
@@ -222,6 +223,82 @@ vec2 im(vec2 z){
222223
return vec2(z.y,0.0f);
223224
}
224225

226+
// Non-elementary functions
227+
228+
const int GAMMA_PRECISION = 7;
229+
230+
const float GAMMA_COEFFICIENTS[7] = float[](
231+
1.000000000190015, 76.18009172947146, -86.50532032941677,
232+
24.01409824083091, -1.231739572450155, 1.208650973866179e-3, -5.395239384953e-6
233+
);
234+
235+
const vec2 SQUARE_ROOT_TWO_PI = vec2(sqrt(PI * 2.0f),0.0f);
236+
237+
vec2 cgamma(vec2 z){
238+
vec2 sum = vec2(GAMMA_COEFFICIENTS[0],0.0);
239+
for(int i = 1; i < 7; ++i) {
240+
sum = cadd(sum, cdiv(vec2(GAMMA_COEFFICIENTS[i], 0.0), cadd(z, vec2(float(i), 0.0))));
241+
}
242+
vec2 t = cadd(z, vec2(5.5, 0.0));
243+
vec2 exp_term = cmult(cpow(t, cadd(z, vec2(0.5, 0.0))), cexp(-t));
244+
vec2 result_pos = cdiv(cmult(cmult(exp_term, SQUARE_ROOT_TWO_PI), sum),z);
245+
246+
vec2 z_neg = cneg(z);
247+
vec2 sum_neg = vec2(GAMMA_COEFFICIENTS[0],0.0);
248+
for(int i = 1; i < 7; ++i) {
249+
sum_neg = cadd(sum_neg, cdiv(vec2(GAMMA_COEFFICIENTS[i], 0.0), cadd(z_neg, vec2(float(i), 0.0))));
250+
}
251+
vec2 t_neg = cadd(z_neg,vec2(5.5,0.0));
252+
vec2 exp_term_neg = cmult(cpow(t_neg, cadd(z_neg, vec2(0.5, 0.0))), cexp(-t_neg));
253+
vec2 gamma_1_minus_z = cmult(cmult(exp_term_neg, SQUARE_ROOT_TWO_PI), sum_neg);
254+
vec2 pi_z = cmult(z,vec2(PI,0.0));
255+
vec2 result_neg = cdiv(vec2(PI,0.0),cmult(csin(pi_z),gamma_1_minus_z));
256+
257+
float is_positive = step(0.5,z.x);
258+
return mix(result_neg,result_pos,is_positive);
259+
}
260+
261+
const int ZETA_PRECISION = 10;
262+
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);
263+
264+
vec2 czeta_main_branch(vec2 s){
265+
vec2 sum = vec2(0.0, 0.0);
266+
float sign = 1.0;
267+
for(int n = 0; n < 10; ++n){
268+
vec2 n_to_neg_s = cpow(vec2(float(n+1),0.0), cmult(s, MINUS_ONE));
269+
270+
n_to_neg_s = cmult(n_to_neg_s, vec2(sign * ZETA_COEFFICIENTS[ ZETA_PRECISION - 1 - n], 0.0));
271+
sum = cadd(sum,n_to_neg_s);
272+
sign = -sign;
273+
}
274+
vec2 eta = cmult(sum,vec2(1.0/ZETA_COEFFICIENTS[ZETA_PRECISION - 1], 0.0));
275+
vec2 one_minus_s = csub(ONE,s);
276+
vec2 two_pow = cpow(vec2(2.0,0.0),one_minus_s);
277+
return cdiv(eta,csub(ONE,two_pow));
278+
}
279+
280+
vec2 czeta_negative_branch(vec2 s){
281+
vec2 one_minus_s = csub(ONE, s);
282+
vec2 term1 = cpow(vec2(2.0, 0.0), s);
283+
vec2 term2 = cpow(vec2(PI, 0.0), csub(s, ONE));
284+
vec2 term3 = csin(cmult(s, vec2(PI / 2.0, 0.0)));
285+
vec2 term4 = cgamma(one_minus_s);
286+
vec2 term5 = czeta_main_branch(one_minus_s);
287+
return cmult(term1, cmult(term2, cmult(term3, cmult(term4, term5))));
288+
289+
}
290+
291+
vec2 czeta(vec2 s){
292+
if (s.x >= 0.0) {
293+
return czeta_main_branch(s);
294+
}
295+
else {
296+
return czeta_negative_branch(s);
297+
}
298+
}
299+
300+
301+
225302
#define END_FUNCTION_DEFINITIONS HERE
226303

227304

src/types/types.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ enum Operator {
6565
ASECH,
6666
ACOTH,
6767
CONJ,
68+
ZETA,
69+
GAMMA,
70+
FACTORIAL,
6871
RE,
6972
IM,
7073
DERIVATIVE,
@@ -155,6 +158,10 @@ inline std::vector<FullOperator> full_operators = {
155158
{ {Arity::UNARY, Associativity::RIGHT, Operator::ASECH, "asech", 5}, 0, "casech", "ASECH"},
156159
{ {Arity::UNARY, Associativity::RIGHT, Operator::ACOTH, "acoth", 5}, 0, "cacoth", "ACOTH"},
157160

161+
// NON ELEMANTARY
162+
{ {Arity::UNARY, Associativity::RIGHT, Operator::GAMMA, "gamma", 5}, 0, "cgamma", "GAMMA"},
163+
{ {Arity::UNARY, Associativity::RIGHT, Operator::ZETA, "zeta", 5}, 0, "czeta", "ZETA"},
164+
158165
//CONSTANTS
159166
{ {Arity::NULLARY, Associativity::NONE, Operator::CONSTANT, "CONSTANT", 0, glm::vec2(0.0f)}, 0, "", "CONSTANT"},
160167
{ {Arity::NULLARY, Associativity::NONE, Operator::CONSTANT, "i", 0, glm::vec2(0,1)}, 0, ""},
@@ -167,13 +174,14 @@ inline std::vector<FullOperator> full_operators = {
167174
{ {Arity::NULLARY, Associativity::NONE, Operator::VARIABLEX, "x", 0}, 0, "vec2(z.x,0.0f)", "VARIABLEX"},
168175
{ {Arity::NULLARY, Associativity::NONE, Operator::VARIABLEY, "y", 0}, 0, "vec2(z.y,0.0f)", "VARIABLEY"},
169176
{ {Arity::NULLARY, Associativity::NONE, Operator::VARIABLET, "t", 0}, 0, "vec2(time,0.0f)", "VARIABLET"},
170-
177+
171178
//PARSER STUFF
172179
{ {Arity::NULLARY, Associativity::NONE, Operator::VARIABLEPLACEHOLDER, "uplaceholder", 0}, 0},
173180
{ {Arity::NULLARY, Associativity::NONE, Operator::SECONDVARIABLEPLACEHOLDER, "vplaceholder", 0}, 0},
174181
{ {Arity::PAREN, Associativity::NONE, Operator::LPAREN, "(", 0}, 0, "" },
175182
{ {Arity::PAREN, Associativity::NONE, Operator::RPAREN, ")", 0}, 0, "" },
176183

184+
177185
//HIGHER ORDER
178186
{ {Arity::UNARY, Associativity::RIGHT, Operator::DERIVATIVE, "derivative", 0,glm::vec2(0.0f),true}, 0, ""},
179187

0 commit comments

Comments
 (0)