Skip to content

Commit 1690093

Browse files
committed
added generated files
1 parent ffa69e9 commit 1690093

217 files changed

Lines changed: 405845 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ext/common/bigdecimal/jacobian.rb

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#
2+
# require 'bigdecimal/jacobian'
3+
#
4+
# Provides methods to compute the Jacobian matrix of a set of equations at a
5+
# point x. In the methods below:
6+
#
7+
# f is an Object which is used to compute the Jacobian matrix of the equations.
8+
# It must provide the following methods:
9+
#
10+
# f.values(x):: returns the values of all functions at x
11+
#
12+
# f.zero:: returns 0.0
13+
# f.one:: returns 1.0
14+
# f.two:: returns 1.0
15+
# f.ten:: returns 10.0
16+
#
17+
# 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.
18+
#
19+
# x is the point at which to compute the Jacobian.
20+
#
21+
# fx is f.values(x).
22+
#
23+
module Jacobian
24+
module_function
25+
26+
# Determines the equality of two numbers by comparing to zero, or using the epsilon value
27+
def isEqual(a,b,zero=0.0,e=1.0e-8)
28+
aa = a.abs
29+
bb = b.abs
30+
if aa == zero && bb == zero then
31+
true
32+
else
33+
if ((a-b)/(aa+bb)).abs < e then
34+
true
35+
else
36+
false
37+
end
38+
end
39+
end
40+
41+
42+
# Computes the derivative of f[i] at x[i].
43+
# fx is the value of f at x.
44+
def dfdxi(f,fx,x,i)
45+
nRetry = 0
46+
n = x.size
47+
xSave = x[i]
48+
ok = 0
49+
ratio = f.ten*f.ten*f.ten
50+
dx = x[i].abs/ratio
51+
dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
52+
dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps)
53+
until ok>0 do
54+
s = f.zero
55+
deriv = []
56+
if(nRetry>100) then
57+
raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
58+
end
59+
dx = dx*f.two
60+
x[i] += dx
61+
fxNew = f.values(x)
62+
for j in 0...n do
63+
if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
64+
ok += 1
65+
deriv <<= (fxNew[j]-fx[j])/dx
66+
else
67+
deriv <<= f.zero
68+
end
69+
end
70+
x[i] = xSave
71+
end
72+
deriv
73+
end
74+
75+
# Computes the Jacobian of f at x. fx is the value of f at x.
76+
def jacobian(f,fx,x)
77+
n = x.size
78+
dfdx = Array::new(n*n)
79+
for i in 0...n do
80+
df = dfdxi(f,fx,x,i)
81+
for j in 0...n do
82+
dfdx[j*n+i] = df[j]
83+
end
84+
end
85+
dfdx
86+
end
87+
end

.ext/common/bigdecimal/ludcmp.rb

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
require 'bigdecimal'
2+
3+
#
4+
# Solves a*x = b for x, using LU decomposition.
5+
#
6+
module LUSolve
7+
module_function
8+
9+
# Performs LU decomposition of the n by n matrix a.
10+
def ludecomp(a,n,zero=0,one=1)
11+
prec = BigDecimal.limit(nil)
12+
ps = []
13+
scales = []
14+
for i in 0...n do # pick up largest(abs. val.) element in each row.
15+
ps <<= i
16+
nrmrow = zero
17+
ixn = i*n
18+
for j in 0...n do
19+
biggst = a[ixn+j].abs
20+
nrmrow = biggst if biggst>nrmrow
21+
end
22+
if nrmrow>zero then
23+
scales <<= one.div(nrmrow,prec)
24+
else
25+
raise "Singular matrix"
26+
end
27+
end
28+
n1 = n - 1
29+
for k in 0...n1 do # Gaussian elimination with partial pivoting.
30+
biggst = zero;
31+
for i in k...n do
32+
size = a[ps[i]*n+k].abs*scales[ps[i]]
33+
if size>biggst then
34+
biggst = size
35+
pividx = i
36+
end
37+
end
38+
raise "Singular matrix" if biggst<=zero
39+
if pividx!=k then
40+
j = ps[k]
41+
ps[k] = ps[pividx]
42+
ps[pividx] = j
43+
end
44+
pivot = a[ps[k]*n+k]
45+
for i in (k+1)...n do
46+
psin = ps[i]*n
47+
a[psin+k] = mult = a[psin+k].div(pivot,prec)
48+
if mult!=zero then
49+
pskn = ps[k]*n
50+
for j in (k+1)...n do
51+
a[psin+j] -= mult.mult(a[pskn+j],prec)
52+
end
53+
end
54+
end
55+
end
56+
raise "Singular matrix" if a[ps[n1]*n+n1] == zero
57+
ps
58+
end
59+
60+
# Solves a*x = b for x, using LU decomposition.
61+
#
62+
# a is a matrix, b is a constant vector, x is the solution vector.
63+
#
64+
# ps is the pivot, a vector which indicates the permutation of rows performed
65+
# during LU decomposition.
66+
def lusolve(a,b,ps,zero=0.0)
67+
prec = BigDecimal.limit(nil)
68+
n = ps.size
69+
x = []
70+
for i in 0...n do
71+
dot = zero
72+
psin = ps[i]*n
73+
for j in 0...i do
74+
dot = a[psin+j].mult(x[j],prec) + dot
75+
end
76+
x <<= b[ps[i]] - dot
77+
end
78+
(n-1).downto(0) do |i|
79+
dot = zero
80+
psin = ps[i]*n
81+
for j in (i+1)...n do
82+
dot = a[psin+j].mult(x[j],prec) + dot
83+
end
84+
x[i] = (x[i]-dot).div(a[psin+i],prec)
85+
end
86+
x
87+
end
88+
end

.ext/common/bigdecimal/math.rb

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
require 'bigdecimal'
2+
3+
#
4+
#--
5+
# Contents:
6+
# sqrt(x, prec)
7+
# sin (x, prec)
8+
# cos (x, prec)
9+
# atan(x, prec) Note: |x|<1, x=0.9999 may not converge.
10+
# log (x, prec)
11+
# PI (prec)
12+
# E (prec) == exp(1.0,prec)
13+
#
14+
# where:
15+
# x ... BigDecimal number to be computed.
16+
# |x| must be small enough to get convergence.
17+
# prec ... Number of digits to be obtained.
18+
#++
19+
#
20+
# Provides mathematical functions.
21+
#
22+
# Example:
23+
#
24+
# require "bigdecimal"
25+
# require "bigdecimal/math"
26+
#
27+
# include BigMath
28+
#
29+
# a = BigDecimal((PI(100)/2).to_s)
30+
# puts sin(a,100) # -> 0.10000000000000000000......E1
31+
#
32+
module BigMath
33+
module_function
34+
35+
# Computes the square root of x to the specified number of digits of
36+
# precision.
37+
#
38+
# BigDecimal.new('2').sqrt(16).to_s
39+
# -> "0.14142135623730950488016887242096975E1"
40+
#
41+
def sqrt(x,prec)
42+
x.sqrt(prec)
43+
end
44+
45+
# Computes the sine of x to the specified number of digits of precision.
46+
#
47+
# If x is infinite or NaN, returns NaN.
48+
def sin(x, prec)
49+
raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
50+
return BigDecimal("NaN") if x.infinite? || x.nan?
51+
n = prec + BigDecimal.double_fig
52+
one = BigDecimal("1")
53+
two = BigDecimal("2")
54+
x = -x if neg = x < 0
55+
if x > (twopi = two * BigMath.PI(prec))
56+
if x > 30
57+
x %= twopi
58+
else
59+
x -= twopi while x > twopi
60+
end
61+
end
62+
x1 = x
63+
x2 = x.mult(x,n)
64+
sign = 1
65+
y = x
66+
d = y
67+
i = one
68+
z = one
69+
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
70+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
71+
sign = -sign
72+
x1 = x2.mult(x1,n)
73+
i += two
74+
z *= (i-one) * i
75+
d = sign * x1.div(z,m)
76+
y += d
77+
end
78+
neg ? -y : y
79+
end
80+
81+
# Computes the cosine of x to the specified number of digits of precision.
82+
#
83+
# If x is infinite or NaN, returns NaN.
84+
def cos(x, prec)
85+
raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
86+
return BigDecimal("NaN") if x.infinite? || x.nan?
87+
n = prec + BigDecimal.double_fig
88+
one = BigDecimal("1")
89+
two = BigDecimal("2")
90+
x = -x if x < 0
91+
if x > (twopi = two * BigMath.PI(prec))
92+
if x > 30
93+
x %= twopi
94+
else
95+
x -= twopi while x > twopi
96+
end
97+
end
98+
x1 = one
99+
x2 = x.mult(x,n)
100+
sign = 1
101+
y = one
102+
d = y
103+
i = BigDecimal("0")
104+
z = one
105+
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
106+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
107+
sign = -sign
108+
x1 = x2.mult(x1,n)
109+
i += two
110+
z *= (i-one) * i
111+
d = sign * x1.div(z,m)
112+
y += d
113+
end
114+
y
115+
end
116+
117+
# Computes the arctangent of x to the specified number of digits of precision.
118+
#
119+
# If x is NaN, returns NaN.
120+
def atan(x, prec)
121+
raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
122+
return BigDecimal("NaN") if x.nan?
123+
pi = PI(prec)
124+
x = -x if neg = x < 0
125+
return pi.div(neg ? -2 : 2, prec) if x.infinite?
126+
return pi / (neg ? -4 : 4) if x.round(prec) == 1
127+
x = BigDecimal("1").div(x, prec) if inv = x > 1
128+
x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
129+
n = prec + BigDecimal.double_fig
130+
y = x
131+
d = y
132+
t = x
133+
r = BigDecimal("3")
134+
x2 = x.mult(x,n)
135+
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
136+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
137+
t = -t.mult(x2,n)
138+
d = t.div(r,m)
139+
y += d
140+
r += 2
141+
end
142+
y *= 2 if dbl
143+
y = pi / 2 - y if inv
144+
y = -y if neg
145+
y
146+
end
147+
148+
# Computes the value of pi to the specified number of digits of precision.
149+
def PI(prec)
150+
raise ArgumentError, "Zero or negative argument for PI" if prec <= 0
151+
n = prec + BigDecimal.double_fig
152+
zero = BigDecimal("0")
153+
one = BigDecimal("1")
154+
two = BigDecimal("2")
155+
156+
m25 = BigDecimal("-0.04")
157+
m57121 = BigDecimal("-57121")
158+
159+
pi = zero
160+
161+
d = one
162+
k = one
163+
w = one
164+
t = BigDecimal("-80")
165+
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
166+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
167+
t = t*m25
168+
d = t.div(k,m)
169+
k = k+two
170+
pi = pi + d
171+
end
172+
173+
d = one
174+
k = one
175+
w = one
176+
t = BigDecimal("956")
177+
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
178+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
179+
t = t.div(m57121,n)
180+
d = t.div(k,m)
181+
pi = pi + d
182+
k = k+two
183+
end
184+
pi
185+
end
186+
187+
# Computes e (the base of natural logarithms) to the specified number of
188+
# digits of precision.
189+
def E(prec)
190+
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
191+
n = prec + BigDecimal.double_fig
192+
one = BigDecimal("1")
193+
y = one
194+
d = y
195+
z = one
196+
i = 0
197+
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
198+
m = BigDecimal.double_fig if m < BigDecimal.double_fig
199+
i += 1
200+
z *= i
201+
d = one.div(z,m)
202+
y += d
203+
end
204+
y
205+
end
206+
end

0 commit comments

Comments
 (0)