bigdecimal 3.1.8 → 4.1.2

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.
@@ -8,14 +8,6 @@ extern "C" {
8
8
  #endif
9
9
  #endif
10
10
 
11
- #ifdef HAVE_STDLIB_H
12
- # include <stdlib.h>
13
- #endif
14
-
15
- #ifdef HAVE_MATH_H
16
- # include <math.h>
17
- #endif
18
-
19
11
  #ifndef RB_UNUSED_VAR
20
12
  # if defined(_MSC_VER) && _MSC_VER >= 1911
21
13
  # define RB_UNUSED_VAR(x) x [[maybe_unused]]
@@ -55,102 +47,18 @@ extern "C" {
55
47
 
56
48
  /* bool */
57
49
 
58
- #if defined(__bool_true_false_are_defined)
59
- # /* Take that. */
60
-
61
- #elif defined(HAVE_STDBOOL_H)
50
+ #ifndef __bool_true_false_are_defined
62
51
  # include <stdbool.h>
63
-
64
- #else
65
- typedef unsigned char _Bool;
66
- # define bool _Bool
67
- # define true ((_Bool)+1)
68
- # define false ((_Bool)-1)
69
- # define __bool_true_false_are_defined
70
- #endif
71
-
72
- /* abs */
73
-
74
- #ifndef HAVE_LABS
75
- static inline long
76
- labs(long const x)
77
- {
78
- if (x < 0) return -x;
79
- return x;
80
- }
81
- #endif
82
-
83
- #ifndef HAVE_LLABS
84
- static inline LONG_LONG
85
- llabs(LONG_LONG const x)
86
- {
87
- if (x < 0) return -x;
88
- return x;
89
- }
90
- #endif
91
-
92
- #ifdef vabs
93
- # undef vabs
94
- #endif
95
- #if SIZEOF_VALUE <= SIZEOF_INT
96
- # define vabs abs
97
- #elif SIZEOF_VALUE <= SIZEOF_LONG
98
- # define vabs labs
99
- #elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
100
- # define vabs llabs
101
- #endif
102
-
103
- /* finite */
104
-
105
- #ifndef HAVE_FINITE
106
- static int
107
- finite(double)
108
- {
109
- return !isnan(n) && !isinf(n);
110
- }
111
- #endif
112
-
113
- #ifndef isfinite
114
- # ifndef HAVE_ISFINITE
115
- # define HAVE_ISFINITE 1
116
- # define isfinite(x) finite(x)
117
- # endif
118
52
  #endif
119
53
 
120
54
  /* dtoa */
121
55
  char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
122
56
 
123
- /* rational */
124
-
125
- #ifndef HAVE_RB_RATIONAL_NUM
126
- static inline VALUE
127
- rb_rational_num(VALUE rat)
128
- {
129
- #ifdef RRATIONAL
130
- return RRATIONAL(rat)->num;
131
- #else
132
- return rb_funcall(rat, rb_intern("numerator"), 0);
133
- #endif
134
- }
135
- #endif
136
-
137
- #ifndef HAVE_RB_RATIONAL_DEN
138
- static inline VALUE
139
- rb_rational_den(VALUE rat)
140
- {
141
- #ifdef RRATIONAL
142
- return RRATIONAL(rat)->den;
143
- #else
144
- return rb_funcall(rat, rb_intern("denominator"), 0);
145
- #endif
146
- }
147
- #endif
148
-
149
57
  /* complex */
150
58
 
151
59
  #ifndef HAVE_RB_COMPLEX_REAL
152
60
  static inline VALUE
153
- rb_complex_real(VALUE cmp)
61
+ rb_complex_real_fallback(VALUE cmp)
154
62
  {
155
63
  #ifdef RCOMPLEX
156
64
  return RCOMPLEX(cmp)->real;
@@ -158,11 +66,12 @@ rb_complex_real(VALUE cmp)
158
66
  return rb_funcall(cmp, rb_intern("real"), 0);
159
67
  #endif
160
68
  }
69
+ #define rb_complex_real rb_complex_real_fallback
161
70
  #endif
162
71
 
163
72
  #ifndef HAVE_RB_COMPLEX_IMAG
164
73
  static inline VALUE
165
- rb_complex_imag(VALUE cmp)
74
+ rb_complex_imag_fallback(VALUE cmp)
166
75
  {
167
76
  # ifdef RCOMPLEX
168
77
  return RCOMPLEX(cmp)->imag;
@@ -170,6 +79,7 @@ rb_complex_imag(VALUE cmp)
170
79
  return rb_funcall(cmp, rb_intern("imag"), 0);
171
80
  # endif
172
81
  }
82
+ #define rb_complex_imag rb_complex_imag_fallback
173
83
  #endif
174
84
 
175
85
  /* st */
@@ -0,0 +1,191 @@
1
+ // NTT (Number Theoretic Transform) implementation for BigDecimal multiplication
2
+
3
+ #define NTT_PRIMITIVE_ROOT 17
4
+ #define NTT_PRIME_BASE1 24
5
+ #define NTT_PRIME_BASE2 26
6
+ #define NTT_PRIME_BASE3 29
7
+ #define NTT_PRIME_SHIFT 27
8
+ #define NTT_PRIME1 (((uint32_t)NTT_PRIME_BASE1 << NTT_PRIME_SHIFT) | 1)
9
+ #define NTT_PRIME2 (((uint32_t)NTT_PRIME_BASE2 << NTT_PRIME_SHIFT) | 1)
10
+ #define NTT_PRIME3 (((uint32_t)NTT_PRIME_BASE3 << NTT_PRIME_SHIFT) | 1)
11
+ #define MAX_NTT32_BITS 27
12
+ #define NTT_DECDIG_BASE 1000000000
13
+
14
+ // Calculates base**ex % mod
15
+ static uint32_t
16
+ mod_pow(uint32_t base, uint32_t ex, uint32_t mod) {
17
+ uint32_t res = 1;
18
+ uint32_t bit = 1;
19
+ while (true) {
20
+ if (ex & bit) {
21
+ ex ^= bit;
22
+ res = ((uint64_t)res * base) % mod;
23
+ }
24
+ if (!ex) break;
25
+ base = ((uint64_t)base * base) % mod;
26
+ bit <<= 1;
27
+ }
28
+ return res;
29
+ }
30
+
31
+ // Recursively performs butterfly operations of NTT
32
+ static void
33
+ ntt_recursive(int size_bits, uint32_t *input, uint32_t *output, uint32_t *tmp, int depth, uint32_t r, uint32_t prime) {
34
+ if (depth > 0) {
35
+ ntt_recursive(size_bits, input, tmp, output, depth - 1, ((uint64_t)r * r) % prime, prime);
36
+ } else {
37
+ tmp = input;
38
+ }
39
+ uint32_t size_half = (uint32_t)1 << (size_bits - 1);
40
+ uint32_t stride = (uint32_t)1 << (size_bits - depth - 1);
41
+ uint32_t n = size_half / stride;
42
+ uint32_t rn = 1, rm = prime - 1;
43
+ for (uint32_t i = 0; i < n; i++) {
44
+ uint32_t *aptr = tmp + i * 2 * stride;
45
+ uint32_t *bptr = aptr + stride;
46
+ uint32_t *out1 = output + stride * i;
47
+ uint32_t *out2 = out1 + size_half;
48
+ for (uint32_t k = 0; k < stride; k++) {
49
+ uint32_t a = aptr[k], b = bptr[k];
50
+ out1[k] = (a + (uint64_t)rn * b) % prime;
51
+ out2[k] = (a + (uint64_t)rm * b) % prime;
52
+ }
53
+ rn = ((uint64_t)rn * r) % prime;
54
+ rm = ((uint64_t)rm * r) % prime;
55
+ }
56
+ }
57
+
58
+ /* Perform NTT on input array.
59
+ * base, shift: Represent the prime number as (base << shift | 1)
60
+ * r_base: Primitive root of unity modulo prime
61
+ * size_bits: log2 of the size of the input array. Should be less or equal to shift
62
+ * input: input array of size (1 << size_bits)
63
+ */
64
+ static void
65
+ ntt(int size_bits, uint32_t *input, uint32_t *output, uint32_t *tmp, int r_base, int base, int shift, int dir) {
66
+ uint32_t size = (uint32_t)1 << size_bits;
67
+ uint32_t prime = ((uint32_t)base << shift) | 1;
68
+
69
+ // rmax**(1 << shift) % prime == 1
70
+ // r**size % prime == 1
71
+ uint32_t rmax = mod_pow((uint32_t)r_base, (uint32_t)base, prime);
72
+ uint32_t r = mod_pow(rmax, (uint32_t)1 << (shift - size_bits), prime);
73
+
74
+ if (dir < 0) r = mod_pow(r, prime - 2, prime);
75
+ ntt_recursive(size_bits, input, output, tmp, size_bits - 1, r, prime);
76
+ if (dir < 0) {
77
+ uint32_t n_inv = mod_pow((uint32_t)size, prime - 2, prime);
78
+ for (uint32_t i = 0; i < size; i++) {
79
+ output[i] = ((uint64_t)output[i] * n_inv) % prime;
80
+ }
81
+ }
82
+ }
83
+
84
+ /* Calculate c that satisfies: c % PRIME1 == mod1 && c % PRIME2 == mod2 && c % PRIME3 == mod3
85
+ * c = (mod1 * 35002755423056150739595925972 + mod2 * 14584479687667766215746868453 + mod3 * 37919651490985126265126719818) % (PRIME1 * PRIME2 * PRIME3)
86
+ * Assume c <= 999999999**2*(1<<27)
87
+ */
88
+ static inline void
89
+ mod_restore_prime_24_26_29_shift_27(uint32_t mod1, uint32_t mod2, uint32_t mod3, uint32_t *digits) {
90
+ // Use mixed radix notation to eliminate modulo by PRIME1 * PRIME2 * PRIME3
91
+ // [DIG0, DIG1, DIG2] = DIG0 + DIG1 * PRIME1 + DIG2 * PRIME1 * PRIME2
92
+ // DIG0: 0...PRIME1, DIG1: 0...PRIME2, DIG2: 0...PRIME3
93
+ // 35002755423056150739595925972 = [1, 3489660916, 3113851359]
94
+ // 14584479687667766215746868453 = [0, 13, 1297437912]
95
+ // 37919651490985126265126719818 = [0, 0, 3373338954]
96
+ uint64_t c0 = mod1;
97
+ uint64_t c1 = (uint64_t)mod2 * 13 + (uint64_t)mod1 * 3489660916;
98
+ uint64_t c2 = (uint64_t)mod3 * 3373338954 % NTT_PRIME3 + (uint64_t)mod2 * 1297437912 % NTT_PRIME3 + (uint64_t)mod1 * 3113851359 % NTT_PRIME3;
99
+ c2 += c1 / NTT_PRIME2;
100
+ c1 %= NTT_PRIME2;
101
+ c2 %= NTT_PRIME3;
102
+ // Base conversion. c fits in 3 digits.
103
+ c1 += c2 % NTT_DECDIG_BASE * NTT_PRIME2;
104
+ c0 += c1 % NTT_DECDIG_BASE * NTT_PRIME1;
105
+ c1 /= NTT_DECDIG_BASE;
106
+ digits[0] = c0 % NTT_DECDIG_BASE;
107
+ c0 /= NTT_DECDIG_BASE;
108
+ c1 += c2 / NTT_DECDIG_BASE % NTT_DECDIG_BASE * NTT_PRIME2;
109
+ c0 += c1 % NTT_DECDIG_BASE * NTT_PRIME1;
110
+ c1 /= NTT_DECDIG_BASE;
111
+ digits[1] = c0 % NTT_DECDIG_BASE;
112
+ digits[2] = (uint32_t)(c0 / NTT_DECDIG_BASE + c1 % NTT_DECDIG_BASE * NTT_PRIME1);
113
+ }
114
+
115
+ /*
116
+ * NTT multiplication
117
+ * Uses three NTTs with mod (24 << 27 | 1), (26 << 27 | 1), and (29 << 27 | 1)
118
+ */
119
+ static void
120
+ ntt_multiply(size_t a_size, size_t b_size, uint32_t *a, uint32_t *b, uint32_t *c) {
121
+ if (a_size < b_size) {
122
+ ntt_multiply(b_size, a_size, b, a, c);
123
+ return;
124
+ }
125
+
126
+ int ntt_size_bits = (int)bit_length(b_size - 1) + 1;
127
+ if (ntt_size_bits > MAX_NTT32_BITS) {
128
+ rb_raise(rb_eArgError, "Multiply size too large");
129
+ }
130
+
131
+ // To calculate large_a * small_b faster, split into several batches.
132
+ uint32_t ntt_size = (uint32_t)1 << ntt_size_bits;
133
+ uint32_t batch_size = ntt_size - (uint32_t)b_size;
134
+ uint32_t batch_count = (uint32_t)((a_size + batch_size - 1) / batch_size);
135
+
136
+ uint32_t *mem = ruby_xcalloc(ntt_size * 9, sizeof(uint32_t));
137
+ uint32_t *ntt1 = mem;
138
+ uint32_t *ntt2 = mem + ntt_size;
139
+ uint32_t *ntt3 = mem + ntt_size * 2;
140
+ uint32_t *tmp1 = mem + ntt_size * 3;
141
+ uint32_t *tmp2 = mem + ntt_size * 4;
142
+ uint32_t *tmp3 = mem + ntt_size * 5;
143
+ uint32_t *conv1 = mem + ntt_size * 6;
144
+ uint32_t *conv2 = mem + ntt_size * 7;
145
+ uint32_t *conv3 = mem + ntt_size * 8;
146
+
147
+ // Calculate NTT for b in three primes. Result is reused for each batch of a.
148
+ memcpy(tmp1, b, b_size * sizeof(uint32_t));
149
+ memset(tmp1 + b_size, 0, (ntt_size - b_size) * sizeof(uint32_t));
150
+ ntt(ntt_size_bits, tmp1, ntt1, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, +1);
151
+ ntt(ntt_size_bits, tmp1, ntt2, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, +1);
152
+ ntt(ntt_size_bits, tmp1, ntt3, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, +1);
153
+
154
+ memset(c, 0, (a_size + b_size) * sizeof(uint32_t));
155
+ for (uint32_t idx = 0; idx < batch_count; idx++) {
156
+ uint32_t len = idx == batch_count - 1 ? (uint32_t)a_size - idx * batch_size : batch_size;
157
+ memcpy(tmp1, a + idx * batch_size, len * sizeof(uint32_t));
158
+ memset(tmp1 + len, 0, (ntt_size - len) * sizeof(uint32_t));
159
+ // Calculate convolution for this batch in three primes
160
+ ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, +1);
161
+ for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt1[i]) % NTT_PRIME1;
162
+ ntt(ntt_size_bits, tmp2, conv1, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, -1);
163
+ ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, +1);
164
+ for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt2[i]) % NTT_PRIME2;
165
+ ntt(ntt_size_bits, tmp2, conv2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, -1);
166
+ ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, +1);
167
+ for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt3[i]) % NTT_PRIME3;
168
+ ntt(ntt_size_bits, tmp2, conv3, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, -1);
169
+
170
+ // Restore the original convolution value from three convolutions calculated in three primes.
171
+ // Each convolution value is maximum 999999999**2*(1<<27)/2
172
+ for (uint32_t i = 0; i < ntt_size; i++) {
173
+ uint32_t dig[3];
174
+ mod_restore_prime_24_26_29_shift_27(conv1[i], conv2[i], conv3[i], dig);
175
+ // Maximum values of dig[0], dig[1], and dig[2] are 999999999, 999999999 and 67108863 respectively
176
+ // Maximum overlapped sum (considering overlaps between 2 batches) is less than 4134217722
177
+ // so this sum doesn't overflow uint32_t.
178
+ for (int j = 0; j < 3; j++) {
179
+ // Index check: if dig[j] is non-zero, assign index is within valid range.
180
+ if (dig[j]) c[idx * batch_size + i + 1 - (uint32_t)j] += dig[j];
181
+ }
182
+ }
183
+ }
184
+ uint32_t carry = 0;
185
+ for (int32_t i = (int32_t)(a_size + b_size - 1); i >= 0; i--) {
186
+ uint32_t v = c[i] + carry;
187
+ c[i] = v % NTT_DECDIG_BASE;
188
+ carry = v / NTT_DECDIG_BASE;
189
+ }
190
+ ruby_xfree(mem);
191
+ }
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'bigdecimal'
4
4
 
5
+ warn "'bigdecimal/jacobian' is deprecated and will be removed in a future release."
6
+
5
7
  # require 'bigdecimal/jacobian'
6
8
  #
7
9
  # Provides methods to compute the Jacobian matrix of a set of equations at a
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: false
2
2
  require 'bigdecimal'
3
3
 
4
+ warn "'bigdecimal/ludcmp' is deprecated and will be removed in a future release."
5
+
4
6
  #
5
7
  # Solves a*x = b for x, using LU decomposition.
6
8
  #