modular_forms 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 749de4a6eccae53fa56728d33efae75d5f9c0d4376d2031760202dddb0815666
4
- data.tar.gz: 0c4d325ea237d6c6478c2fae75f862e0b1f8e116d1b822b5a35eac5481ea88c4
3
+ metadata.gz: 1e77e70af5b9ca9fa2bcc7543c8eaa45ac1603bf168d0fd2c9fa73aa639836de
4
+ data.tar.gz: 2df87ac5d2f7c6c950fb5312226422dc146a180e250ca3ce2e31abbb100a18d2
5
5
  SHA512:
6
- metadata.gz: 7f9b7939543427e63283e38d4c3c4bd796823962809c65348ef0023c6a66a94cde414bddf5cfffe2f2ed0c88e342f90da8aa60774de78cf932d09d36a89f8d18
7
- data.tar.gz: cc6ea4af26b7e9502d607e6128f522a383e03f4da9c1cf2b328158fb94f6b85a226cb3c2f9837fc00fbc2a1f0a1370d58b88df7c7a930f1e3968d03235829949
6
+ metadata.gz: 90ec48ab7fad347c8ab257bdc65f71d21f34c2dfc50822695d178f6babc624358477d448bb947fc681e6767ece07a8b1cb8c168fe0f6ca364a2a33a03d288b59
7
+ data.tar.gz: ee4e8a42d6b2953c8de928d6582d487447364847e455f7ae74a2a5e3a1d96d597fdc95cb8e7bcdba4121cf9decca5c1ee0e960528fa5173ece1dba0f5a474235
data/README.md CHANGED
@@ -14,37 +14,42 @@ A creative toolkit for exploring modular forms and elliptic curves through [Soni
14
14
  ## ⚙️ Project Status
15
15
 
16
16
  This is a pre-alpha release of `modular_forms`. At this stage, only a subset of core mathematical definitions and operations is implemented.
17
- Future updates might include a DSL, depending on how the library is used and the interest from the community.
18
17
 
19
- Contributions are welcome! Feel free to fork and submit a pull request.
18
+ Future updates might include a DSL, depending on how the library is used and the interest from the community. A key challenge lies in creating musical mappings that stay true to the underlying mathematics while also sounding intentional, expressive, and naturally fitting within a musical structure.
20
19
 
21
20
  ## 🧊 Features
22
21
 
23
22
  - **Accessible to both musicians and coders**: No math expertise required. Create musical patterns, rhythms, timbres, and harmonies by experimenting with mathematical ideas and turning them into sound and effects intuitively.
24
23
  - **Interactive Educational Resource**: Use **Sonic Pi** to discover introductory number theory in a hands-on, immersive way, gaining insights into abstract concepts through math in action.
25
24
 
26
- ### Purpose and Scope
25
+ ## 💡 Purpose and Scope
27
26
 
28
- Given the vastness of the field, this tool intentionally focuses on a limited subset of definitions, without covering all aspects of each. Below is a list of the implemented modules:
27
+ ### Overview
29
28
 
30
- - [Eisenstein Series](#eisenstein-series)
31
- - [Eta Functions and Eta Quotients](#eta-functions-and-eta-quotients)
32
- - [Theta functions](#theta-functions)
33
- - [Ramanujan Tau Function](#ramanujan-tau-function)
34
- - [J-Function](#j-function)
35
- - [Hecke Operators](#hecke-operators)
36
- - [SL(2,Z) Group](#sl2z-group)
37
- - [Dirichlet Characters](#dirichlet-characters)
38
- - [Elliptic Curves over Rationals](#elliptic-curves-over-rationals)
39
- - [Elliptic Curves over Finite Fields](#elliptic-curves-over-finite-fields)
40
- - [Newforms Invariants](#newforms-invariants)
41
- - [L-functions](#l-functions)
29
+ Given the vastness of the field, this tool intentionally focuses on a limited subset of definitions, without covering all aspects of each.
30
+
31
+ - 🧩 List of implemented modules:
32
+ - [Eisenstein Series](#eisenstein-series)
33
+ - [Eta Functions and Eta Quotients](#eta-functions-and-eta-quotients)
34
+ - [Theta Functions](#theta-functions)
35
+ - [Ramanujan Tau Function](#ramanujan-tau-function)
36
+ - [J-Function](#j-function)
37
+ - [Hecke Operators](#hecke-operators)
38
+ - [SL(2,Z) Group](#sl2z-group)
39
+ - [Dirichlet Characters](#dirichlet-characters)
40
+ - [Elliptic Curves over Rationals](#elliptic-curves-over-rationals)
41
+ - [Elliptic Curves over Finite Fields](#elliptic-curves-over-finite-fields)
42
+ - [Newform Invariants](#newform-invariants)
43
+ - [L-functions](#l-functions)
44
+ - [p-adic Fields](#p-adic-fields)
45
+ - [Number Fields](#number-fields)
42
46
 
43
47
  ### Not Optimized for Computational Efficiency
44
48
 
45
- This library is designed for creative exploration rather than maximum computational efficiency. It is not intended to replace advanced mathematical software. Instead, it draws inspiration from tools like **SageMath**, **Pari/GP**, and the **LMFDB database**.
49
+ This library is designed for creative exploration rather than maximum computational efficiency. It is **not intended** to replace specialized mathematical software optimized for heavy or large-scale computations. Instead, it draws inspiration from tools like **SageMath**, **Pari/GP**, and the **LMFDB database**.
46
50
 
47
51
  ### Goal
52
+
48
53
  The goal is simple: to provide an accessible and creative starting point for those who wish to explore, learn, and uncover new ideas, regardless of their mathematical background.
49
54
 
50
55
  ## 💎 Installation
@@ -60,31 +65,20 @@ If you are **use Ruby**, then import via
60
65
  require 'modular_forms'
61
66
  ```
62
67
 
63
- If you are **using Sonic Pi**, replace `<PATH>` with the directory path to the `modular_forms.rb` file inside the gem installation on your system:
68
+ If you are **using Sonic Pi**, replace `<PATH>` with the directory path to the `modular_forms.rb` file inside the gem installation on your system. You can find the full path by running:
64
69
 
65
- ```rb
66
- require "<PATH>/modular_forms.rb"
70
+ ```bash
71
+ gem which modular_forms
67
72
  ```
68
73
 
69
- ## 🧰 How to use?
70
-
71
- ### 🎶 Play an Eisenstein Series as Music for Warm-Up
72
-
73
- Here is a simple example of how to use **modular_forms** to generate a basic musical pattern:
74
+ Then require the file like this:
74
75
 
75
76
  ```rb
76
77
  require "<PATH>/modular_forms.rb"
77
-
78
- # Generate an Eisenstein series of weight k = 4
79
- eisenstein_melody = ModularForms.eisenstein_serie(4)
80
-
81
- # Play the melody in a loop with a mathematical transformation
82
- 120.times do
83
- play eisenstein_melody.next % 12 * 7
84
- sleep 0.5
85
- end
86
78
  ```
87
79
 
80
+ ## 🧰 How to use?
81
+
88
82
  ### 🎶 Explore Fermat’s Last Theorem in Sonic Pi
89
83
 
90
84
  The Taniyama–Shimura Conjecture (now the Modularity Theorem), proven for semistable cases by Andrew Wiles, connects elliptic curves over the rationals to modular forms. This profound result was crucial in proving **Fermat’s Last Theorem**.
@@ -122,6 +116,55 @@ live_loop :modularity_music do
122
116
  end
123
117
  ```
124
118
 
119
+ ### 🎶 Merging Machine and Organism - Warp Up
120
+
121
+ Unlike the structured Fermat example, this finite loop explores more abstract territory, using multiple concepts to create a sonic landscape that, while grounded in mathematical principles, goes beyond conventional musical forms.
122
+
123
+ ```rb
124
+ require "<PATH>/modular_forms.rb"
125
+
126
+ p = 3
127
+ eisenstein_melody = ModularForms.eisenstein_series(8)
128
+ e8 = eisenstein_melody.take(58)
129
+ hecke_op = ModularForms.hecke_operator_prime_non_cusp(e8, p, 8, 20)
130
+
131
+ ellc = ModularForms.elliptic_curve_q([2, 5])
132
+ disc = ModularForms.discriminant_q(ellc)
133
+
134
+ j_func = ModularForms.j_function(40)
135
+ newform_ac = ModularForms.analytic_conductor(15, 2)
136
+ pol = ModularForms.def_pol_2deg(41)
137
+
138
+ x = 7
139
+ dirichlet_char_group = []
140
+ (1..x).each do |i|
141
+ dirichlet_char_group << ModularForms.conrey_p_pminus1(x, i)
142
+ end
143
+
144
+ (disc * -1).times do
145
+ synth :zawa,
146
+ note: ModularForms.zeta_coeffs_deg2(dirichlet_char_group, 30)
147
+ .tick(:zeta) + 72, amp: rrand(0.3, 0.6)
148
+
149
+ synth :subpulse, note: ModularForms.padic_valuation(eisenstein_melody.next, p) % 7 + 70,
150
+ release: 0.25 if (spread (disc % 6), 7).tick(:d)
151
+
152
+ synth :chiplead, note: hecke_op.tick(:tp) % 7 + 50,
153
+ release: newform_ac, attack: newform_ac
154
+
155
+ synth :fm, note: ModularForms.gauss_sum_triv(5, j_func.tick(:j)) + 51,
156
+ release: 0.25, attack: 0.012,
157
+ pan: ModularForms.analytic_conductor(j_func.look % 15, 4) * rrand_i(-1, 1) if
158
+ spread(ModularForms.gamma1_index(p), 11).tick(:g)
159
+
160
+ sample 90, release: 0.125 if pol.tick == 'x'
161
+ sample :ambi_drone, beat_stretch: 0.7 if pol.look == '*'
162
+ sample :bass_drop_c, release: 0.125 if pol.look == '6'
163
+
164
+ sleep ModularForms.padic_norm(p, p)
165
+ end
166
+ ```
167
+
125
168
  ## 🧩 Implemented Modular Forms, Elliptic Curves, and Related Definitions
126
169
 
127
170
  ### Eisenstein Series
@@ -138,7 +181,7 @@ end
138
181
  7. `ModularForms.eta_product(eta1, eta2, prec = nil)`
139
182
  8. `ModularForms.eta_quotient(num_eta, den_eta, prec)`
140
183
 
141
- ### Theta functions
184
+ ### Theta Functions
142
185
 
143
186
  9. `ModularForms.jacobi_theta_function(jacobi_index = 3, square_coefs = false)`
144
187
  10. `ModularForms.jacobi_theta_function_pow(jacobi_index, power, prec)`
@@ -198,10 +241,36 @@ end
198
241
  43. `ModularForms.cardinality_fp(curve)`
199
242
  44. `ModularForms.quadratic_twist_fp(curve)`
200
243
 
201
- ### Newforms Invariants
244
+ ### Newform Invariants
202
245
 
203
246
  45. `ModularForms.analytic_conductor(level_n, weight_k)`
204
247
 
205
248
  ### L-functions
206
249
 
207
250
  46. `ModularForms.a_p(p, cardinality)`
251
+
252
+ ### p-adic Fields
253
+
254
+ 47. `ModularForms.padic_valuation(num_b10, p)`
255
+ 48. `ModularForms.padic_norm(num_b10, p)`
256
+ 49. `ModularForms.padic_expansion(num_b10, p, prec = 11, reverse_trim = false)`
257
+ 50. `ModularForms.def_pol_2deg(p = 2, c = 0, num = 1)`
258
+
259
+ ### Number Fields
260
+
261
+ 51. `ModularForms.zeta_coeffs_deg2(dirichlet_char_group, n)`
262
+
263
+ ## 🧪 Testing
264
+
265
+ Install dependencies first:
266
+
267
+ ```bash
268
+ bundle install
269
+ ```
270
+
271
+ This project features a comprehensive Minitest suite covering core functionality across modules. While not all edge cases are tested, the main mathematical functions are well validated to ensure correctness and stability.
272
+
273
+ Run tests with:
274
+ ```bash
275
+ rake test
276
+ ```
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModularForms
4
+ module Core
5
+ # ModularForms::Core::NumberFields
6
+ #
7
+ # This module provides methods and objects related to number fields,
8
+ # such as zeta_coefficients and utility helpers.
9
+ module NumberFields
10
+ def self.fill_arr_with_interval(length, num, interval)
11
+ arr = Array.new(length, 0)
12
+ (interval - 1).step(length - 1, interval) do |i|
13
+ arr[i] = num
14
+ end
15
+ arr
16
+ end
17
+
18
+ def self.zeta_coeffs_deg2(dirichlet_char_group, num_coeffs)
19
+ ded_zeta_to_dir_serie = []
20
+ dirichlet_char_group.each_with_index do |i, j|
21
+ a = 1
22
+ while a <= num_coeffs
23
+ ded_zeta_to_dir_serie << fill_arr_with_interval(num_coeffs, i, j + a)
24
+ a += dirichlet_char_group.length
25
+ end
26
+ end
27
+ ded_zeta_to_dir_serie.transpose.map { |component| component.sum } # rubocop:disable Style/SymbolProc
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prime'
4
+ require_relative './padic_pol/padic_pol'
5
+
6
+ module ModularForms
7
+ module Core
8
+ # ModularForms::Core::PAdicFields
9
+ #
10
+ # This module provides concepts and functionality related to p-adic fields.
11
+ module PAdicFields
12
+ def self.padic_valuation(num_b10, p)
13
+ raise "#{p} is not a prime number" unless Prime.prime?(p)
14
+
15
+ index = 0
16
+ return index if num_b10 < 1
17
+
18
+ index += 1 while num_b10 % (p**index) == 0 # rubocop:disable Style/NumericPredicate
19
+ index - 1
20
+ end
21
+
22
+ def self.padic_norm(num_b10, p)
23
+ return 0 if num_b10 == 0 # rubocop:disable Style/NumericPredicate
24
+
25
+ power = padic_valuation(num_b10, p)
26
+ 1.0 / p**power
27
+ end
28
+
29
+ def self.padic_expansion(num_b10, p, prec = 11, reverse_trim = false) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Style/OptionalBooleanParameter
30
+ inverse_limit_arr = []
31
+ (1...prec).each do |index|
32
+ power = p**index
33
+ inverse_limits = ((num_b10 % power) + power) % power
34
+ inverse_limit_arr << inverse_limits
35
+ end
36
+ p_adic_expansion_array = [inverse_limit_arr[0]]
37
+
38
+ (0...(prec - 2)).each do |index|
39
+ a1 = inverse_limit_arr[index + 1]
40
+ a0 = inverse_limit_arr[index]
41
+ power = p**(index + 1)
42
+ digits = (a1 - a0) / power
43
+ p_adic_expansion_array << digits
44
+ end
45
+
46
+ if reverse_trim
47
+ reversed = p_adic_expansion_array.reverse
48
+ first_nonzero_index = reversed.index { |digit| digit != 0 } || 0
49
+ reversed[first_nonzero_index..-1] # rubocop:disable Style/SlicingWithRange
50
+ else
51
+ p_adic_expansion_array
52
+ end
53
+ end
54
+
55
+ def self.def_pol_2deg(p = 2, c = 0, num = 1)
56
+ raise ArgumentError, "Residue field characteristic #{p} must be a prime number" unless Prime.prime?(p)
57
+
58
+ unless (0..3).include?(c)
59
+ raise ArgumentError,
60
+ "The specified discriminant exponent (#{c}) is invalid. Must be in range (0..3)."
61
+ end
62
+ raise ArgumentError, "Invalid value: #{num}. Must be in range (1..4)." unless (1..4).include?(num)
63
+
64
+ PAdicPol.get_defining_polynomial(PAdicPol::DEF_POL_HASH_2DEG, p, c, num)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModularForms
4
+ module Core
5
+ module PAdicFields
6
+ module PAdicPol # rubocop:disable Metrics/ModuleLength
7
+ DATA_POL_2DEG = { '2.2.0.1' => [1, 1, 1],
8
+ '2.2.2.1' => [2, 2, 1],
9
+ '2.2.2.2' => [6, 2, 1],
10
+ '2.2.3.1' => [2, 4, 1],
11
+ '2.2.3.2' => [10, 4, 1],
12
+ '2.2.3.3' => [2, 0, 1],
13
+ '2.2.3.4' => [10, 0, 1],
14
+ '3.2.0.1' => [2, 2, 1],
15
+ '3.2.1.1' => [6, 0, 1],
16
+ '3.2.1.2' => [3, 0, 1],
17
+ '5.2.0.1' => [2, 4, 1],
18
+ '5.2.1.1' => [5, 0, 1],
19
+ '5.2.1.2' => [10, 0, 1],
20
+ '7.2.0.1' => [3, 6, 1],
21
+ '7.2.1.1' => [21, 0, 1],
22
+ '7.2.1.2' => [7, 0, 1],
23
+ '11.2.0.1' => [2, 7, 1],
24
+ '11.2.1.1' => [22, 0, 1],
25
+ '11.2.1.2' => [11, 0, 1],
26
+ '13.2.0.1' => [2, 12, 1],
27
+ '13.2.1.1' => [13, 0, 1],
28
+ '13.2.1.2' => [26, 0, 1],
29
+ '17.2.0.1' => [3, 16, 1],
30
+ '17.2.1.1' => [17, 0, 1],
31
+ '17.2.1.2' => [51, 0, 1],
32
+ '19.2.0.1' => [2, 18, 1],
33
+ '19.2.1.1' => [38, 0, 1],
34
+ '19.2.1.2' => [19, 0, 1],
35
+ '23.2.0.1' => [5, 21, 1],
36
+ '23.2.1.1' => [115, 0, 1],
37
+ '23.2.1.2' => [23, 0, 1],
38
+ '29.2.0.1' => [2, 24, 1],
39
+ '29.2.1.1' => [29, 0, 1],
40
+ '29.2.1.2' => [58, 0, 1],
41
+ '31.2.0.1' => [3, 29, 1],
42
+ '31.2.1.1' => [93, 0, 1],
43
+ '31.2.1.2' => [31, 0, 1],
44
+ '37.2.0.1' => [2, 33, 1],
45
+ '37.2.1.1' => [37, 0, 1],
46
+ '37.2.1.2' => [74, 0, 1],
47
+ '41.2.0.1' => [6, 38, 1],
48
+ '41.2.1.1' => [41, 0, 1],
49
+ '41.2.1.2' => [123, 0, 1],
50
+ '43.2.0.1' => [3, 42, 1],
51
+ '43.2.1.1' => [86, 0, 1],
52
+ '43.2.1.2' => [43, 0, 1],
53
+ '47.2.0.1' => [5, 45, 1],
54
+ '47.2.1.1' => [235, 0, 1],
55
+ '47.2.1.2' => [47, 0, 1],
56
+ '53.2.0.1' => [2, 49, 1],
57
+ '53.2.1.1' => [53, 0, 1],
58
+ '53.2.1.2' => [106, 0, 1],
59
+ '59.2.0.1' => [2, 58, 1],
60
+ '59.2.1.1' => [118, 0, 1],
61
+ '59.2.1.2' => [59, 0, 1],
62
+ '61.2.0.1' => [2, 60, 1],
63
+ '61.2.1.1' => [61, 0, 1],
64
+ '61.2.1.2' => [122, 0, 1],
65
+ '67.2.0.1' => [2, 63, 1],
66
+ '67.2.1.1' => [134, 0, 1],
67
+ '67.2.1.2' => [67, 0, 1],
68
+ '71.2.0.1' => [7, 69, 1],
69
+ '71.2.1.1' => [497, 0, 1],
70
+ '71.2.1.2' => [71, 0, 1],
71
+ '73.2.0.1' => [5, 70, 1],
72
+ '73.2.1.1' => [73, 0, 1],
73
+ '73.2.1.2' => [365, 0, 1],
74
+ '79.2.0.1' => [3, 78, 1],
75
+ '79.2.1.1' => [237, 0, 1],
76
+ '79.2.1.2' => [79, 0, 1],
77
+ '83.2.0.1' => [2, 82, 1],
78
+ '83.2.1.1' => [166, 0, 1],
79
+ '83.2.1.2' => [83, 0, 1],
80
+ '89.2.0.1' => [3, 82, 1],
81
+ '89.2.1.1' => [89, 0, 1],
82
+ '89.2.1.2' => [267, 0, 1],
83
+ '97.2.0.1' => [5, 96, 1],
84
+ '97.2.1.1' => [97, 0, 1],
85
+ '97.2.1.2' => [485, 0, 1],
86
+ '101.2.0.1' => [2, 97, 1],
87
+ '101.2.1.1' => [101, 0, 1],
88
+ '101.2.1.2' => [202, 0, 1],
89
+ '103.2.0.1' => [5, 102, 1],
90
+ '103.2.1.1' => [309, 0, 1],
91
+ '103.2.1.2' => [103, 0, 1],
92
+ '107.2.0.1' => [2, 103, 1],
93
+ '107.2.1.1' => [214, 0, 1],
94
+ '107.2.1.2' => [107, 0, 1],
95
+ '109.2.0.1' => [6, 108, 1],
96
+ '109.2.1.1' => [109, 0, 1],
97
+ '109.2.1.2' => [218, 0, 1],
98
+ '113.2.0.1' => [3, 101, 1],
99
+ '113.2.1.1' => [113, 0, 1],
100
+ '113.2.1.2' => [339, 0, 1],
101
+ '127.2.0.1' => [3, 126, 1],
102
+ '127.2.1.1' => [381, 0, 1],
103
+ '127.2.1.2' => [127, 0, 1],
104
+ '131.2.0.1' => [2, 127, 1],
105
+ '131.2.1.1' => [262, 0, 1],
106
+ '131.2.1.2' => [131, 0, 1],
107
+ '137.2.0.1' => [3, 131, 1],
108
+ '137.2.1.1' => [137, 0, 1],
109
+ '137.2.1.2' => [411, 0, 1],
110
+ '139.2.0.1' => [2, 138, 1],
111
+ '139.2.1.1' => [278, 0, 1],
112
+ '139.2.1.2' => [139, 0, 1],
113
+ '149.2.0.1' => [2, 145, 1],
114
+ '149.2.1.1' => [149, 0, 1],
115
+ '149.2.1.2' => [298, 0, 1],
116
+ '151.2.0.1' => [6, 149, 1],
117
+ '151.2.1.1' => [453, 0, 1],
118
+ '151.2.1.2' => [151, 0, 1],
119
+ '157.2.0.1' => [5, 152, 1],
120
+ '157.2.1.1' => [157, 0, 1],
121
+ '157.2.1.2' => [314, 0, 1],
122
+ '163.2.0.1' => [2, 159, 1],
123
+ '163.2.1.1' => [326, 0, 1],
124
+ '163.2.1.2' => [163, 0, 1],
125
+ '167.2.0.1' => [5, 166, 1],
126
+ '167.2.1.1' => [835, 0, 1],
127
+ '167.2.1.2' => [167, 0, 1],
128
+ '173.2.0.1' => [2, 169, 1],
129
+ '173.2.1.1' => [173, 0, 1],
130
+ '173.2.1.2' => [346, 0, 1],
131
+ '179.2.0.1' => [2, 172, 1],
132
+ '179.2.1.1' => [358, 0, 1],
133
+ '179.2.1.2' => [179, 0, 1],
134
+ '181.2.0.1' => [2, 177, 1],
135
+ '181.2.1.1' => [181, 0, 1],
136
+ '181.2.1.2' => [362, 0, 1],
137
+ '191.2.0.1' => [19, 190, 1],
138
+ '191.2.1.1' => [1337, 0, 1],
139
+ '191.2.1.2' => [191, 0, 1],
140
+ '193.2.0.1' => [5, 192, 1],
141
+ '193.2.1.1' => [193, 0, 1],
142
+ '193.2.1.2' => [965, 0, 1],
143
+ '197.2.0.1' => [2, 192, 1],
144
+ '197.2.1.1' => [197, 0, 1],
145
+ '197.2.1.2' => [394, 0, 1],
146
+ '199.2.0.1' => [3, 193, 1],
147
+ '199.2.1.1' => [597, 0, 1],
148
+ '199.2.1.2' => [199, 0, 1] }.freeze
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './data_pol_2deg'
4
+
5
+ module ModularForms
6
+ module Core
7
+ module PAdicFields
8
+ # ModularForms::Core::PAdicPol
9
+ #
10
+ # Provides a constructor for a hash of defining polynomials of finite extensions of p-adic fields.
11
+ module PAdicPol
12
+ def self.build_padic_label_hash(data_padic)
13
+ padic_coefs_by_label = {}
14
+ data_padic.each do |label, coefs|
15
+ p, _y, z, w = label.split('.').map(&:to_i)
16
+
17
+ padic_coefs_by_label[p] ||= {}
18
+ padic_coefs_by_label[p][z] ||= {}
19
+ padic_coefs_by_label[p][z][w] = coefs
20
+ end
21
+ padic_coefs_by_label
22
+ end
23
+
24
+ def self.gen_quadratic_pol_string(coefs)
25
+ c, b, = coefs
26
+ terms = []
27
+ terms << 'x**2'
28
+
29
+ if (b != 0) && (b == 1)
30
+ terms << '+ x'
31
+ elsif b > 1
32
+ terms << "+ #{b}*x"
33
+ end
34
+
35
+ terms << "+ #{c}"
36
+
37
+ terms.join(' ')
38
+ end
39
+
40
+ def self.get_defining_polynomial(hash, p, z, w)
41
+ gen_quadratic_pol_string(hash.dig(p, z, w))
42
+ end
43
+
44
+ DEF_POL_HASH_2DEG = build_padic_label_hash(DATA_POL_2DEG)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -12,3 +12,5 @@ require_relative 'core/elliptic_curves_fp'
12
12
  require_relative 'core/dirichlet_characters'
13
13
  require_relative 'core/newform_invariants'
14
14
  require_relative 'core/l_functions'
15
+ require_relative 'core/padic_fields'
16
+ require_relative 'core/number_fields'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ModularForms
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.4'
5
5
  end
data/lib/modular_forms.rb CHANGED
@@ -196,4 +196,24 @@ module ModularForms # rubocop:disable Metrics/ModuleLength
196
196
  def a_p(p, cardinality)
197
197
  Core::LFunctions.a_p(p, cardinality)
198
198
  end
199
+
200
+ def padic_valuation(num_b10, p)
201
+ Core::PAdicFields.padic_valuation(num_b10, p)
202
+ end
203
+
204
+ def padic_norm(num_b10, p)
205
+ Core::PAdicFields.padic_norm(num_b10, p)
206
+ end
207
+
208
+ def padic_expansion(num_b10, p, prec = 11, reverse_trim = false) # rubocop:disable Style/OptionalBooleanParameter
209
+ Core::PAdicFields.padic_expansion(num_b10, p, prec, reverse_trim)
210
+ end
211
+
212
+ def def_pol_2deg(p = 2, c = 0, num = 1)
213
+ Core::PAdicFields.def_pol_2deg(p, c, num)
214
+ end
215
+
216
+ def zeta_coeffs_deg2(dirichlet_char_group, n)
217
+ Core::NumberFields.zeta_coeffs_deg2(dirichlet_char_group, n)
218
+ end
199
219
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modular_forms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edgar Armando Delgado Vega
@@ -33,7 +33,11 @@ files:
33
33
  - lib/modular_forms/core/klein_j_invariant.rb
34
34
  - lib/modular_forms/core/l_functions.rb
35
35
  - lib/modular_forms/core/newform_invariants.rb
36
+ - lib/modular_forms/core/number_fields.rb
36
37
  - lib/modular_forms/core/numeric_helpers/numeric_helpers.rb
38
+ - lib/modular_forms/core/padic_fields.rb
39
+ - lib/modular_forms/core/padic_pol/data_pol_2deg.rb
40
+ - lib/modular_forms/core/padic_pol/padic_pol.rb
37
41
  - lib/modular_forms/core/ramanujan_tau_function.rb
38
42
  - lib/modular_forms/core/sl2z_groups.rb
39
43
  - lib/modular_forms/core/theta_functions.rb