ed-precompiled_bigdecimal 3.3.1-arm64-darwin

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.
@@ -0,0 +1,28 @@
1
+ #include <ruby/ruby.h>
2
+
3
+ #ifdef HAVE_RUBY_ATOMIC_H
4
+ # include <ruby/atomic.h>
5
+ #endif
6
+
7
+ #ifdef RUBY_ATOMIC_PTR_CAS
8
+ # define ATOMIC_PTR_CAS(var, old, new) RUBY_ATOMIC_PTR_CAS(var, old, new)
9
+ #endif
10
+
11
+ #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
12
+ /* GCC warns about unknown sanitizer, which is annoying. */
13
+ # undef NO_SANITIZE
14
+ # define NO_SANITIZE(x, y) \
15
+ _Pragma("GCC diagnostic push") \
16
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
17
+ __attribute__((__no_sanitize__(x))) y; \
18
+ _Pragma("GCC diagnostic pop") \
19
+ y
20
+ #endif
21
+
22
+ #undef strtod
23
+ #define strtod BigDecimal_strtod
24
+ #undef dtoa
25
+ #define dtoa BigDecimal_dtoa
26
+ #undef hdtoa
27
+ #define hdtoa BigDecimal_hdtoa
28
+ #include "missing/dtoa.c"
@@ -0,0 +1,104 @@
1
+ #ifndef MISSING_H
2
+ #define MISSING_H 1
3
+
4
+ #if defined(__cplusplus)
5
+ extern "C" {
6
+ #if 0
7
+ } /* satisfy cc-mode */
8
+ #endif
9
+ #endif
10
+
11
+ #ifndef RB_UNUSED_VAR
12
+ # if defined(_MSC_VER) && _MSC_VER >= 1911
13
+ # define RB_UNUSED_VAR(x) x [[maybe_unused]]
14
+
15
+ # elif defined(__has_cpp_attribute) && __has_cpp_attribute(maybe_unused)
16
+ # define RB_UNUSED_VAR(x) x [[maybe_unused]]
17
+
18
+ # elif defined(__has_c_attribute) && __has_c_attribute(maybe_unused)
19
+ # define RB_UNUSED_VAR(x) x [[maybe_unused]]
20
+
21
+ # elif defined(__GNUC__)
22
+ # define RB_UNUSED_VAR(x) x __attribute__ ((unused))
23
+
24
+ # else
25
+ # define RB_UNUSED_VAR(x) x
26
+ # endif
27
+ #endif /* RB_UNUSED_VAR */
28
+
29
+ #if defined(_MSC_VER) && _MSC_VER >= 1310
30
+ # define HAVE___ASSUME 1
31
+
32
+ #elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300
33
+ # define HAVE___ASSUME 1
34
+ #endif
35
+
36
+ #ifndef UNREACHABLE
37
+ # if __has_builtin(__builtin_unreachable)
38
+ # define UNREACHABLE __builtin_unreachable()
39
+
40
+ # elif defined(HAVE___ASSUME)
41
+ # define UNREACHABLE __assume(0)
42
+
43
+ # else
44
+ # define UNREACHABLE /* unreachable */
45
+ # endif
46
+ #endif /* UNREACHABLE */
47
+
48
+ /* bool */
49
+
50
+ #ifndef __bool_true_false_are_defined
51
+ # include <stdbool.h>
52
+ #endif
53
+
54
+ /* dtoa */
55
+ char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
56
+
57
+ /* complex */
58
+
59
+ #ifndef HAVE_RB_COMPLEX_REAL
60
+ static inline VALUE
61
+ rb_complex_real(VALUE cmp)
62
+ {
63
+ #ifdef RCOMPLEX
64
+ return RCOMPLEX(cmp)->real;
65
+ #else
66
+ return rb_funcall(cmp, rb_intern("real"), 0);
67
+ #endif
68
+ }
69
+ #endif
70
+
71
+ #ifndef HAVE_RB_COMPLEX_IMAG
72
+ static inline VALUE
73
+ rb_complex_imag(VALUE cmp)
74
+ {
75
+ # ifdef RCOMPLEX
76
+ return RCOMPLEX(cmp)->imag;
77
+ # else
78
+ return rb_funcall(cmp, rb_intern("imag"), 0);
79
+ # endif
80
+ }
81
+ #endif
82
+
83
+ /* st */
84
+
85
+ #ifndef ST2FIX
86
+ # undef RB_ST2FIX
87
+ # define RB_ST2FIX(h) LONG2FIX((long)(h))
88
+ # define ST2FIX(h) RB_ST2FIX(h)
89
+ #endif
90
+
91
+ /* warning */
92
+
93
+ #if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED)
94
+ # define rb_category_warn(category, ...) rb_warn(__VA_ARGS__)
95
+ #endif
96
+
97
+ #if defined(__cplusplus)
98
+ #if 0
99
+ { /* satisfy cc-mode */
100
+ #endif
101
+ } /* extern "C" { */
102
+ #endif
103
+
104
+ #endif /* MISSING_H */
@@ -0,0 +1,54 @@
1
+ #ifndef BIGDECIMAL_STATIC_ASSERT_H
2
+ #define BIGDECIMAL_STATIC_ASSERT_H
3
+
4
+ #include "feature.h"
5
+
6
+ #ifdef HAVE_RUBY_INTERNAL_STATIC_ASSERT_H
7
+ # include <ruby/internal/static_assert.h>
8
+ #endif
9
+
10
+ #ifdef RBIMPL_STATIC_ASSERT
11
+ # define STATIC_ASSERT RBIMPL_STATIC_ASSERT
12
+ #endif
13
+
14
+ #ifndef STATIC_ASSERT
15
+ # /* The following section is copied from CRuby's static_assert.h */
16
+
17
+ # if defined(__cplusplus) && defined(__cpp_static_assert)
18
+ # /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
19
+ # define BIGDECIMAL_STATIC_ASSERT0 static_assert
20
+
21
+ # elif defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER >= 1600
22
+ # define BIGDECIMAL_STATIC_ASSERT0 static_assert
23
+
24
+ # elif defined(__INTEL_CXX11_MODE__)
25
+ # define BIGDECIMAL_STATIC_ASSERT0 static_assert
26
+
27
+ # elif defined(__cplusplus) && __cplusplus >= 201103L
28
+ # define BIGDECIMAL_STATIC_ASSERT0 static_assert
29
+
30
+ # elif defined(__cplusplus) && __has_extension(cxx_static_assert)
31
+ # define BIGDECIMAL_STATIC_ASSERT0 __extension__ static_assert
32
+
33
+ # elif defined(__STDC_VERSION__) && __has_extension(c_static_assert)
34
+ # define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert
35
+
36
+ # elif defined(__STDC_VERSION__) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
37
+ # define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert
38
+ #endif
39
+
40
+ # if defined(__DOXYGEN__)
41
+ # define STATIC_ASSERT static_assert
42
+
43
+ # elif defined(BIGDECIMAL_STATIC_ASSERT0)
44
+ # define STATIC_ASSERT(name, expr) \
45
+ BIGDECIMAL_STATIC_ASSERT0(expr, #name ": " #expr)
46
+
47
+ # else
48
+ # define STATIC_ASSERT(name, expr) \
49
+ typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)]
50
+ # endif
51
+ #endif /* STATIC_ASSERT */
52
+
53
+
54
+ #endif /* BIGDECIMAL_STATIC_ASSERT_H */
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'bigdecimal'
4
+
5
+ # require 'bigdecimal/jacobian'
6
+ #
7
+ # Provides methods to compute the Jacobian matrix of a set of equations at a
8
+ # point x. In the methods below:
9
+ #
10
+ # f is an Object which is used to compute the Jacobian matrix of the equations.
11
+ # It must provide the following methods:
12
+ #
13
+ # f.values(x):: returns the values of all functions at x
14
+ #
15
+ # f.zero:: returns 0.0
16
+ # f.one:: returns 1.0
17
+ # f.two:: returns 2.0
18
+ # f.ten:: returns 10.0
19
+ #
20
+ # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
21
+ #
22
+ # x is the point at which to compute the Jacobian.
23
+ #
24
+ # fx is f.values(x).
25
+ #
26
+ module Jacobian
27
+ module_function
28
+
29
+ # Determines the equality of two numbers by comparing to zero, or using the epsilon value
30
+ def isEqual(a,b,zero=0.0,e=1.0e-8)
31
+ aa = a.abs
32
+ bb = b.abs
33
+ if aa == zero && bb == zero then
34
+ true
35
+ else
36
+ if ((a-b)/(aa+bb)).abs < e then
37
+ true
38
+ else
39
+ false
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+ # Computes the derivative of +f[i]+ at +x[i]+.
46
+ # +fx+ is the value of +f+ at +x+.
47
+ def dfdxi(f,fx,x,i)
48
+ nRetry = 0
49
+ n = x.size
50
+ xSave = x[i]
51
+ ok = 0
52
+ ratio = f.ten*f.ten*f.ten
53
+ dx = x[i].abs/ratio
54
+ dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
55
+ dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps)
56
+ until ok>0 do
57
+ deriv = []
58
+ nRetry += 1
59
+ if nRetry > 100
60
+ raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
61
+ end
62
+ dx = dx*f.two
63
+ x[i] += dx
64
+ fxNew = f.values(x)
65
+ for j in 0...n do
66
+ if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
67
+ ok += 1
68
+ deriv <<= (fxNew[j]-fx[j])/dx
69
+ else
70
+ deriv <<= f.zero
71
+ end
72
+ end
73
+ x[i] = xSave
74
+ end
75
+ deriv
76
+ end
77
+
78
+ # Computes the Jacobian of +f+ at +x+. +fx+ is the value of +f+ at +x+.
79
+ def jacobian(f,fx,x)
80
+ n = x.size
81
+ dfdx = Array.new(n*n)
82
+ for i in 0...n do
83
+ df = dfdxi(f,fx,x,i)
84
+ for j in 0...n do
85
+ dfdx[j*n+i] = df[j]
86
+ end
87
+ end
88
+ dfdx
89
+ end
90
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: false
2
+ require 'bigdecimal'
3
+
4
+ #
5
+ # Solves a*x = b for x, using LU decomposition.
6
+ #
7
+ module LUSolve
8
+ module_function
9
+
10
+ # Performs LU decomposition of the n by n matrix a.
11
+ def ludecomp(a,n,zero=0,one=1)
12
+ prec = BigDecimal.limit(nil)
13
+ ps = []
14
+ scales = []
15
+ for i in 0...n do # pick up largest(abs. val.) element in each row.
16
+ ps <<= i
17
+ nrmrow = zero
18
+ ixn = i*n
19
+ for j in 0...n do
20
+ biggst = a[ixn+j].abs
21
+ nrmrow = biggst if biggst>nrmrow
22
+ end
23
+ if nrmrow>zero then
24
+ scales <<= one.div(nrmrow,prec)
25
+ else
26
+ raise "Singular matrix"
27
+ end
28
+ end
29
+ n1 = n - 1
30
+ for k in 0...n1 do # Gaussian elimination with partial pivoting.
31
+ biggst = zero;
32
+ for i in k...n do
33
+ size = a[ps[i]*n+k].abs*scales[ps[i]]
34
+ if size>biggst then
35
+ biggst = size
36
+ pividx = i
37
+ end
38
+ end
39
+ raise "Singular matrix" if biggst<=zero
40
+ if pividx!=k then
41
+ j = ps[k]
42
+ ps[k] = ps[pividx]
43
+ ps[pividx] = j
44
+ end
45
+ pivot = a[ps[k]*n+k]
46
+ for i in (k+1)...n do
47
+ psin = ps[i]*n
48
+ a[psin+k] = mult = a[psin+k].div(pivot,prec)
49
+ if mult!=zero then
50
+ pskn = ps[k]*n
51
+ for j in (k+1)...n do
52
+ a[psin+j] -= mult.mult(a[pskn+j],prec)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ raise "Singular matrix" if a[ps[n1]*n+n1] == zero
58
+ ps
59
+ end
60
+
61
+ # Solves a*x = b for x, using LU decomposition.
62
+ #
63
+ # a is a matrix, b is a constant vector, x is the solution vector.
64
+ #
65
+ # ps is the pivot, a vector which indicates the permutation of rows performed
66
+ # during LU decomposition.
67
+ def lusolve(a,b,ps,zero=0.0)
68
+ prec = BigDecimal.limit(nil)
69
+ n = ps.size
70
+ x = []
71
+ for i in 0...n do
72
+ dot = zero
73
+ psin = ps[i]*n
74
+ for j in 0...i do
75
+ dot = a[psin+j].mult(x[j],prec) + dot
76
+ end
77
+ x <<= b[ps[i]] - dot
78
+ end
79
+ (n-1).downto(0) do |i|
80
+ dot = zero
81
+ psin = ps[i]*n
82
+ for j in (i+1)...n do
83
+ dot = a[psin+j].mult(x[j],prec) + dot
84
+ end
85
+ x[i] = (x[i]-dot).div(a[psin+i],prec)
86
+ end
87
+ x
88
+ end
89
+ end
@@ -0,0 +1,249 @@
1
+ # frozen_string_literal: false
2
+ require 'bigdecimal'
3
+
4
+ #
5
+ #--
6
+ # Contents:
7
+ # sqrt(x, prec)
8
+ # sin (x, prec)
9
+ # cos (x, prec)
10
+ # tan (x, prec)
11
+ # atan(x, prec)
12
+ # PI (prec)
13
+ # E (prec) == exp(1.0,prec)
14
+ #
15
+ # where:
16
+ # x ... BigDecimal number to be computed.
17
+ # prec ... Number of digits to be obtained.
18
+ #++
19
+ #
20
+ # Provides mathematical functions.
21
+ #
22
+ # Example:
23
+ #
24
+ # require "bigdecimal/math"
25
+ #
26
+ # include BigMath
27
+ #
28
+ # a = BigDecimal((PI(49)/2).to_s)
29
+ # puts sin(a,100) # => 0.9999999999...9999999986e0
30
+ #
31
+ module BigMath
32
+ module_function
33
+
34
+ # call-seq:
35
+ # sqrt(decimal, numeric) -> BigDecimal
36
+ #
37
+ # Computes the square root of +decimal+ to the specified number of digits of
38
+ # precision, +numeric+.
39
+ #
40
+ # BigMath.sqrt(BigDecimal('2'), 32).to_s
41
+ # #=> "0.14142135623730950488016887242097e1"
42
+ #
43
+ def sqrt(x, prec)
44
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :sqrt)
45
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sqrt)
46
+ x.sqrt(prec)
47
+ end
48
+
49
+
50
+ # Returns [sign, reduced_x] where reduced_x is in -pi/2..pi/2
51
+ # and satisfies sin(x) = sign * sin(reduced_x)
52
+ # If add_half_pi is true, adds pi/2 to x before reduction.
53
+ # Precision of pi is adjusted to ensure reduced_x has the required precision.
54
+ private_class_method def _sin_periodic_reduction(x, prec, add_half_pi: false) # :nodoc:
55
+ return [1, x] if -Math::PI/2 <= x && x <= Math::PI/2 && !add_half_pi
56
+
57
+ mod_prec = prec + BigDecimal.double_fig
58
+ pi_extra_prec = [x.exponent, 0].max + BigDecimal.double_fig
59
+ while true
60
+ pi = PI(mod_prec + pi_extra_prec)
61
+ half_pi = pi / 2
62
+ div, mod = (add_half_pi ? x + pi : x + half_pi).divmod(pi)
63
+ mod -= half_pi
64
+ if mod.zero? || mod_prec + mod.exponent <= 0
65
+ # mod is too small to estimate required pi precision
66
+ mod_prec = mod_prec * 3 / 2 + BigDecimal.double_fig
67
+ elsif mod_prec + mod.exponent < prec
68
+ # Estimate required precision of pi
69
+ mod_prec = prec - mod.exponent + BigDecimal.double_fig
70
+ else
71
+ return [div % 2 == 0 ? 1 : -1, mod.mult(1, prec)]
72
+ end
73
+ end
74
+ end
75
+
76
+ # call-seq:
77
+ # sin(decimal, numeric) -> BigDecimal
78
+ #
79
+ # Computes the sine of +decimal+ to the specified number of digits of
80
+ # precision, +numeric+.
81
+ #
82
+ # If +decimal+ is Infinity or NaN, returns NaN.
83
+ #
84
+ # BigMath.sin(BigMath.PI(5)/4, 32).to_s
85
+ # #=> "0.70710807985947359435812921837984e0"
86
+ #
87
+ def sin(x, prec)
88
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :sin)
89
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sin)
90
+ return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan?
91
+ n = prec + BigDecimal.double_fig
92
+ one = BigDecimal("1")
93
+ two = BigDecimal("2")
94
+ sign, x = _sin_periodic_reduction(x, n)
95
+ x1 = x
96
+ x2 = x.mult(x,n)
97
+ y = x
98
+ d = y
99
+ i = one
100
+ z = one
101
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
102
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
103
+ x1 = -x2.mult(x1,n)
104
+ i += two
105
+ z *= (i-one) * i
106
+ d = x1.div(z,m)
107
+ y += d
108
+ end
109
+ y = BigDecimal("1") if y > 1
110
+ y.mult(sign, prec)
111
+ end
112
+
113
+ # call-seq:
114
+ # cos(decimal, numeric) -> BigDecimal
115
+ #
116
+ # Computes the cosine of +decimal+ to the specified number of digits of
117
+ # precision, +numeric+.
118
+ #
119
+ # If +decimal+ is Infinity or NaN, returns NaN.
120
+ #
121
+ # BigMath.cos(BigMath.PI(16), 32).to_s
122
+ # #=> "-0.99999999999999999999999999999997e0"
123
+ #
124
+ def cos(x, prec)
125
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :cos)
126
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cos)
127
+ return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan?
128
+ sign, x = _sin_periodic_reduction(x, prec + BigDecimal.double_fig, add_half_pi: true)
129
+ sign * sin(x, prec)
130
+ end
131
+
132
+ # call-seq:
133
+ # tan(decimal, numeric) -> BigDecimal
134
+ #
135
+ # Computes the tangent of +decimal+ to the specified number of digits of
136
+ # precision, +numeric+.
137
+ #
138
+ # If +decimal+ is Infinity or NaN, returns NaN.
139
+ #
140
+ # BigMath.tan(BigDecimal("0.0"), 4).to_s
141
+ # #=> "0.0"
142
+ #
143
+ # BigMath.tan(BigMath.PI(24) / 4, 32).to_s
144
+ # #=> "0.99999999999999999999999830836025e0"
145
+ #
146
+ def tan(x, prec)
147
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :tan)
148
+ sin(x, prec + BigDecimal.double_fig).div(cos(x, prec + BigDecimal.double_fig), prec)
149
+ end
150
+
151
+ # call-seq:
152
+ # atan(decimal, numeric) -> BigDecimal
153
+ #
154
+ # Computes the arctangent of +decimal+ to the specified number of digits of
155
+ # precision, +numeric+.
156
+ #
157
+ # If +decimal+ is NaN, returns NaN.
158
+ #
159
+ # BigMath.atan(BigDecimal('-1'), 32).to_s
160
+ # #=> "-0.78539816339744830961566084581988e0"
161
+ #
162
+ def atan(x, prec)
163
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :atan)
164
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atan)
165
+ return BigDecimal::Internal.nan_computation_result if x.nan?
166
+ n = prec + BigDecimal.double_fig
167
+ pi = PI(n)
168
+ x = -x if neg = x < 0
169
+ return pi.div(neg ? -2 : 2, prec) if x.infinite?
170
+ return pi.div(neg ? -4 : 4, prec) if x.round(prec) == 1
171
+ x = BigDecimal("1").div(x, n) if inv = x > 1
172
+ x = (-1 + sqrt(1 + x.mult(x, n), n)).div(x, n) if dbl = x > 0.5
173
+ y = x
174
+ d = y
175
+ t = x
176
+ r = BigDecimal("3")
177
+ x2 = x.mult(x,n)
178
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
179
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
180
+ t = -t.mult(x2,n)
181
+ d = t.div(r,m)
182
+ y += d
183
+ r += 2
184
+ end
185
+ y *= 2 if dbl
186
+ y = pi / 2 - y if inv
187
+ y = -y if neg
188
+ y.mult(1, prec)
189
+ end
190
+
191
+ # call-seq:
192
+ # PI(numeric) -> BigDecimal
193
+ #
194
+ # Computes the value of pi to the specified number of digits of precision,
195
+ # +numeric+.
196
+ #
197
+ # BigMath.PI(32).to_s
198
+ # #=> "0.31415926535897932384626433832795e1"
199
+ #
200
+ def PI(prec)
201
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :PI)
202
+ n = prec + BigDecimal.double_fig
203
+ zero = BigDecimal("0")
204
+ one = BigDecimal("1")
205
+ two = BigDecimal("2")
206
+
207
+ m25 = BigDecimal("-0.04")
208
+ m57121 = BigDecimal("-57121")
209
+
210
+ pi = zero
211
+
212
+ d = one
213
+ k = one
214
+ t = BigDecimal("-80")
215
+ while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
216
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
217
+ t = t*m25
218
+ d = t.div(k,m)
219
+ k = k+two
220
+ pi = pi + d
221
+ end
222
+
223
+ d = one
224
+ k = one
225
+ t = BigDecimal("956")
226
+ while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
227
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
228
+ t = t.div(m57121,n)
229
+ d = t.div(k,m)
230
+ pi = pi + d
231
+ k = k+two
232
+ end
233
+ pi.mult(1, prec)
234
+ end
235
+
236
+ # call-seq:
237
+ # E(numeric) -> BigDecimal
238
+ #
239
+ # Computes e (the base of natural logarithms) to the specified number of
240
+ # digits of precision, +numeric+.
241
+ #
242
+ # BigMath.E(32).to_s
243
+ # #=> "0.27182818284590452353602874713527e1"
244
+ #
245
+ def E(prec)
246
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :E)
247
+ BigMath.exp(1, prec)
248
+ end
249
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: false
2
+ require "bigdecimal/ludcmp"
3
+ require "bigdecimal/jacobian"
4
+
5
+ #
6
+ # newton.rb
7
+ #
8
+ # Solves the nonlinear algebraic equation system f = 0 by Newton's method.
9
+ # This program is not dependent on BigDecimal.
10
+ #
11
+ # To call:
12
+ # n = nlsolve(f,x)
13
+ # where n is the number of iterations required,
14
+ # x is the initial value vector
15
+ # f is an Object which is used to compute the values of the equations to be solved.
16
+ # It must provide the following methods:
17
+ #
18
+ # f.values(x):: returns the values of all functions at x
19
+ #
20
+ # f.zero:: returns 0.0
21
+ # f.one:: returns 1.0
22
+ # f.two:: returns 2.0
23
+ # f.ten:: returns 10.0
24
+ #
25
+ # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
26
+ #
27
+ # On exit, x is the solution vector.
28
+ #
29
+ module Newton
30
+ include LUSolve
31
+ include Jacobian
32
+ module_function
33
+
34
+ def norm(fv,zero=0.0) # :nodoc:
35
+ s = zero
36
+ n = fv.size
37
+ for i in 0...n do
38
+ s += fv[i]*fv[i]
39
+ end
40
+ s
41
+ end
42
+
43
+ # See also Newton
44
+ def nlsolve(f,x)
45
+ nRetry = 0
46
+ n = x.size
47
+
48
+ f0 = f.values(x)
49
+ zero = f.zero
50
+ one = f.one
51
+ two = f.two
52
+ p5 = one/two
53
+ d = norm(f0,zero)
54
+ minfact = f.ten*f.ten*f.ten
55
+ minfact = one/minfact
56
+ e = f.eps
57
+ while d >= e do
58
+ nRetry += 1
59
+ # Not yet converged. => Compute Jacobian matrix
60
+ dfdx = jacobian(f,f0,x)
61
+ # Solve dfdx*dx = -f0 to estimate dx
62
+ dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
63
+ fact = two
64
+ xs = x.dup
65
+ begin
66
+ fact *= p5
67
+ if fact < minfact then
68
+ raise "Failed to reduce function values."
69
+ end
70
+ for i in 0...n do
71
+ x[i] = xs[i] - dx[i]*fact
72
+ end
73
+ f0 = f.values(x)
74
+ dn = norm(f0,zero)
75
+ end while(dn>=d)
76
+ d = dn
77
+ end
78
+ nRetry
79
+ end
80
+ end