Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
AndrewVSutherland
GitHub Repository: AndrewVSutherland/lmfdb
Path: blob/main/scripts/classical_modular_forms/utils.psql
1448 views
1
CREATE OR REPLACE FUNCTION to_base26(IN n integer) RETURNS varchar AS $$
2
DECLARE
3
s varchar;
4
m integer;
5
BEGIN
6
m := n;
7
IF m < 0 THEN
8
s := 'NULL';
9
ELSIF m = 0 THEN
10
s := 'a';
11
ELSE
12
s := '';
13
WHILE m != 0 LOOP
14
s := chr(m%26+97) || s;
15
m := m/26;
16
END LOOP;
17
END IF;
18
19
RETURN s;
20
END;
21
$$ LANGUAGE plpgsql;
22
23
CREATE OR REPLACE FUNCTION from_base26(IN s varchar) RETURNS integer AS $$
24
DECLARE
25
k integer[];
26
m integer := 0;
27
p integer := 1;
28
BEGIN
29
k := array(SELECT ascii(unnest(regexp_split_to_array(reverse(s),''))) - 97);
30
FOR l in 1 .. array_length(k,1) LOOP
31
m := m + p*k[l];
32
p := p*26;
33
END LOOP;
34
return m;
35
END;
36
$$ LANGUAGE plpgsql;
37
38
CREATE OR REPLACE FUNCTION from_newform_label_to_hecke_orbit_code(IN s varchar) RETURNS bigint AS $$
39
DECLARE
40
v text[];
41
BEGIN
42
v := string_to_array(s, '.');
43
return v[1]::bigint + (v[2]::bigint::bit(64)<<24)::bigint + (from_base26(v[3])::bit(64)<<36)::bigint + (from_base26(v[4])::bit(64)<<52)::bigint;
44
END;
45
$$ LANGUAGE plpgsql;
46
47
//we could have only one function, but then we would pay heavily for the if statement
48
CREATE OR REPLACE FUNCTION from_newspace_label_to_hecke_orbit_code(IN s varchar) RETURNS bigint AS $$
49
DECLARE
50
v text[];
51
BEGIN
52
v := string_to_array(s, '.');
53
return v[1]::bigint + (v[2]::bigint::bit(64)<<24)::bigint + (from_base26(v[3])::bit(64)<<36)::bigint;
54
END;
55
$$ LANGUAGE plpgsql;
56
57
58
CREATE OR REPLACE FUNCTION prod_factorization(IN fact ANYARRAY, IN dummy ANYELEMENT = NULL) RETURNS ANYELEMENT AS $$
59
DECLARE
60
prod dummy%TYPE := 1;
61
BEGIN
62
IF array_length(fact, 1) != 0 THEN
63
FOR l in 1 .. array_length(fact, 1) LOOP
64
prod := prod * (fact[l][1]^fact[l][2]);
65
END LOOP;
66
END IF;
67
return prod;
68
END;
69
$$ LANGUAGE plpgsql;
70
71
CREATE OR REPLACE FUNCTION prod(IN list ANYARRAY, IN dummy ANYELEMENT = NULL) RETURNS ANYELEMENT AS $$
72
DECLARE
73
prod dummy%TYPE := 1;
74
BEGIN
75
IF array_length(list, 1) != 0 THEN
76
prod := list[1];
77
FOR i in 2 .. array_length(list, 1) LOOP
78
prod := prod * list[i];
79
END LOOP;
80
END IF;
81
return prod;
82
END;
83
$$ LANGUAGE plpgsql;
84
85
CREATE OR REPLACE FUNCTION prod2(IN list ANYARRAY, IN dummy ANYELEMENT = NULL) RETURNS ANYELEMENT AS $$
86
DECLARE
87
prod dummy%TYPE := 1;
88
BEGIN
89
IF array_length(list, 1) != 0 THEN
90
FOR i in 1 .. array_length(list, 1) LOOP
91
prod := prod * list[i][2];
92
END LOOP;
93
END IF;
94
return prod;
95
END;
96
$$ LANGUAGE plpgsql;
97
98
99
CREATE OR REPLACE FUNCTION check_cc_prod(IN am double precision[], IN an double precision[], IN amn double precision[]) RETURNS bool AS $$
100
BEGIN
101
return @((am[1][1]*an[1][1] - am[1][2]*an[1][2]) - amn[1][1]) < 1e-13 AND @((am[1][1]*an[1][2] + am[1][2]*an[1][1]) - amn[1][2]) < 1e-13;
102
END;
103
$$ LANGUAGE plpgsql;
104
105
CREATE OR REPLACE FUNCTION traces(IN ans double precision[]) returns double precision[] AS $$
106
DECLARE
107
res double precision[];
108
x double precision[];
109
BEGIN
110
res := array_fill(0, ARRAY[array_length(ans, 2)]);
111
FOREACH x SLICE 2 IN ARRAY ans LOOP
112
FOR i in 1 .. array_length(x, 1) LOOP
113
res[i] := res[i] + x[i][1];
114
END LOOP;
115
END LOOP;
116
return res;
117
END;
118
$$ LANGUAGE plpgsql;
119
120
121
122
CREATE OR REPLACE FUNCTION compare_traces(IN an_int anyarray, IN an_cc double precision[], IN normalization double precision) returns bool AS $$
123
BEGIN
124
FOR i in 1 .. array_length(an_int, 1) LOOP
125
IF @((an_int[i] * (i^normalization)::numeric)::double precision - an_cc[i]) > 1e-11 THEN
126
raise notice 'i: %', i;
127
raise notice 'i^normalization: %', i^normalization;
128
raise notice 'normalization: %', normalization;
129
raise notice 'an_int[i] : %', (an_int[i] * (i^normalization)::numeric;
130
raise notice 'a_cc[i] : %', an_cc[i];
131
raise notice 'diff : %', @((an_int[i] * (i^normalization)::numeric)::double precision - an_cc[i]);
132
return false;
133
END IF;
134
END LOOP;
135
return true;
136
END;
137
$$ LANGUAGE plpgsql;
138
139
140
141
CREATE OR REPLACE FUNCTION unnest_2d_1d(ANYARRAY, OUT a ANYARRAY)
142
RETURNS SETOF ANYARRAY AS
143
$func$
144
BEGIN
145
FOREACH a SLICE 1 IN ARRAY $1 LOOP
146
RETURN NEXT;
147
END LOOP;
148
END
149
$func$ LANGUAGE plpgsql IMMUTABLE;
150
151
CREATE OR REPLACE FUNCTION unnest_2d_1d_2(IN m ANYARRAY, OUT a ANYARRAY)
152
RETURNS SETOF ANYARRAY AS
153
$func$
154
BEGIN
155
FOREACH a SLICE 2 IN ARRAY m LOOP
156
RETURN NEXT;
157
END LOOP;
158
END
159
$func$ LANGUAGE plpgsql IMMUTABLE;
160
161
162
CREATE OR REPLACE FUNCTION array_max(anyarray)
163
RETURNS anyelement LANGUAGE SQL IMMUTABLE AS $$
164
SELECT max(x) FROM unnest($1) as x;
165
$$;
166
167
CREATE OR REPLACE FUNCTION array_min(anyarray)
168
RETURNS anyelement LANGUAGE SQL IMMUTABLE AS $$
169
SELECT min(x) FROM unnest($1) as x;
170
$$;
171
172
CREATE OR REPLACE FUNCTION jsonb_arr2numeric_arr(_js jsonb) RETURNS numeric[] LANGUAGE SQL IMMUTABLE AS
173
'SELECT ARRAY(SELECT jsonb_array_elements_text(_js))::numeric[]';
174
175
176
CREATE OR REPLACE FUNCTION join6dot(IN a text[]) RETURNS text LANGUAGE SQL IMMUTABLE AS $$
177
SELECT a[1] || '.' || a[2] || '.' || a[3] || '.' || a[4] || '.' || a[5] || '.' || a[6];
178
$$;
179
180