backports 2.3.0 → 2.4.0

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.
Files changed (55) hide show
  1. data/.irbrc +1 -0
  2. data/README.rdoc +55 -3
  3. data/Rakefile +1 -0
  4. data/VERSION.yml +1 -1
  5. data/backports.gemspec +99 -118
  6. data/lib/backports/1.8.7/string.rb +1 -1
  7. data/lib/backports/1.9.1/array.rb +1 -2
  8. data/lib/backports/1.9.1/file.rb +20 -0
  9. data/lib/backports/1.9.1/float.rb +19 -0
  10. data/lib/backports/1.9.1/hash.rb +20 -3
  11. data/lib/backports/1.9.1/integer.rb +19 -0
  12. data/lib/backports/1.9.1/io.rb +18 -3
  13. data/lib/backports/1.9.1/numeric.rb +9 -0
  14. data/lib/backports/1.9.1/regexp.rb +1 -6
  15. data/lib/backports/1.9.1/stdlib/prime.rb +495 -0
  16. data/lib/backports/1.9.1/stdlib.rb +1 -0
  17. data/lib/backports/1.9.1/string.rb +2 -7
  18. data/lib/backports/1.9.2/array.rb +3 -4
  19. data/lib/backports/1.9.2/complex.rb +6 -0
  20. data/lib/backports/1.9.2/stdlib/matrix/eigenvalue_decomposition.rb +886 -0
  21. data/lib/backports/1.9.2/stdlib/matrix/lup_decomposition.rb +218 -0
  22. data/lib/backports/1.9.2/stdlib/matrix.rb +1872 -0
  23. data/lib/backports/1.9.2/stdlib/set.rb +13 -0
  24. data/lib/backports/1.9.2/stdlib.rb +1 -0
  25. data/lib/backports/1.9.3/io.rb +12 -0
  26. data/lib/backports/1.9.3.rb +5 -0
  27. data/lib/backports/1.9.rb +1 -1
  28. data/lib/backports/basic_object.rb +3 -2
  29. data/lib/backports/force/array_map.rb +1 -0
  30. data/lib/backports/force/enumerable_map.rb +3 -0
  31. data/lib/backports/force/hash_select.rb +9 -0
  32. data/lib/backports/force/string_length.rb +10 -0
  33. data/lib/backports/force/string_size.rb +1 -0
  34. data/lib/backports/tools.rb +137 -1
  35. data/test/README +13 -0
  36. metadata +25 -42
  37. data/.gitignore +0 -7
  38. data/test/_README +0 -1
  39. data/test/array_test.rb +0 -82
  40. data/test/basic_object_test.rb +0 -70
  41. data/test/binding_test.rb +0 -20
  42. data/test/enumerable_test.rb +0 -244
  43. data/test/enumerator_test.rb +0 -45
  44. data/test/hash_test.rb +0 -26
  45. data/test/kernel_test.rb +0 -31
  46. data/test/math_test.rb +0 -59
  47. data/test/method_missing_test.rb +0 -37
  48. data/test/method_test.rb +0 -73
  49. data/test/module_test.rb +0 -20
  50. data/test/object_test.rb +0 -35
  51. data/test/proc_test.rb +0 -116
  52. data/test/regexp_test.rb +0 -14
  53. data/test/string_test.rb +0 -74
  54. data/test/symbol_test.rb +0 -23
  55. data/test/test_helper.rb +0 -8
@@ -0,0 +1,218 @@
1
+ class Matrix
2
+ # Adapted from JAMA: http://math.nist.gov/javanumerics/jama/
3
+
4
+ #
5
+ # For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
6
+ # unit lower triangular matrix L, an n-by-n upper triangular matrix U,
7
+ # and a m-by-m permutation matrix P so that L*U = P*A.
8
+ # If m < n, then L is m-by-m and U is m-by-n.
9
+ #
10
+ # The LUP decomposition with pivoting always exists, even if the matrix is
11
+ # singular, so the constructor will never fail. The primary use of the
12
+ # LU decomposition is in the solution of square systems of simultaneous
13
+ # linear equations. This will fail if singular? returns true.
14
+ #
15
+
16
+ class LUPDecomposition
17
+ # Returns the lower triangular factor +L+
18
+
19
+ include Matrix::ConversionHelper
20
+
21
+ def l
22
+ Matrix.build(@row_size, @col_size) do |i, j|
23
+ if (i > j)
24
+ @lu[i][j]
25
+ elsif (i == j)
26
+ 1
27
+ else
28
+ 0
29
+ end
30
+ end
31
+ end
32
+
33
+ # Returns the upper triangular factor +U+
34
+
35
+ def u
36
+ Matrix.build(@col_size, @col_size) do |i, j|
37
+ if (i <= j)
38
+ @lu[i][j]
39
+ else
40
+ 0
41
+ end
42
+ end
43
+ end
44
+
45
+ # Returns the permutation matrix +P+
46
+
47
+ def p
48
+ rows = Array.new(@row_size){Array.new(@col_size, 0)}
49
+ @pivots.each_with_index{|p, i| rows[i][p] = 1}
50
+ Matrix.send :new, rows, @col_size
51
+ end
52
+
53
+ # Returns +L+, +U+, +P+ in an array
54
+
55
+ def to_ary
56
+ [l, u, p]
57
+ end
58
+ alias_method :to_a, :to_ary
59
+
60
+ # Returns the pivoting indices
61
+
62
+ attr_reader :pivots
63
+
64
+ # Returns +true+ if +U+, and hence +A+, is singular.
65
+
66
+ def singular? ()
67
+ @col_size.times do |j|
68
+ if (@lu[j][j] == 0)
69
+ return true
70
+ end
71
+ end
72
+ false
73
+ end
74
+
75
+ # Returns the determinant of +A+, calculated efficiently
76
+ # from the factorization.
77
+
78
+ def det
79
+ if (@row_size != @col_size)
80
+ Matrix.Raise Matrix::ErrDimensionMismatch unless square?
81
+ end
82
+ d = @pivot_sign
83
+ @col_size.times do |j|
84
+ d *= @lu[j][j]
85
+ end
86
+ d
87
+ end
88
+ alias_method :determinant, :det
89
+
90
+ # Returns +m+ so that <tt>A*m = b</tt>,
91
+ # or equivalently so that <tt>L*U*m = P*b</tt>
92
+ # +b+ can be a Matrix or a Vector
93
+
94
+ def solve b
95
+ if (singular?)
96
+ Matrix.Raise Matrix::ErrNotRegular, "Matrix is singular."
97
+ end
98
+ if b.is_a? Matrix
99
+ if (b.row_size != @row_size)
100
+ Matrix.Raise Matrix::ErrDimensionMismatch
101
+ end
102
+
103
+ # Copy right hand side with pivoting
104
+ nx = b.column_size
105
+ m = @pivots.map{|row| b.row(row).to_a}
106
+
107
+ # Solve L*Y = P*b
108
+ @col_size.times do |k|
109
+ (k+1).upto(@col_size-1) do |i|
110
+ nx.times do |j|
111
+ m[i][j] -= m[k][j]*@lu[i][k]
112
+ end
113
+ end
114
+ end
115
+ # Solve U*m = Y
116
+ (@col_size-1).downto(0) do |k|
117
+ nx.times do |j|
118
+ m[k][j] = m[k][j].quo(@lu[k][k])
119
+ end
120
+ k.times do |i|
121
+ nx.times do |j|
122
+ m[i][j] -= m[k][j]*@lu[i][k]
123
+ end
124
+ end
125
+ end
126
+ Matrix.send :new, m, nx
127
+ else # same algorithm, specialized for simpler case of a vector
128
+ b = convert_to_array(b)
129
+ if (b.size != @row_size)
130
+ Matrix.Raise Matrix::ErrDimensionMismatch
131
+ end
132
+
133
+ # Copy right hand side with pivoting
134
+ m = b.values_at(*@pivots)
135
+
136
+ # Solve L*Y = P*b
137
+ @col_size.times do |k|
138
+ (k+1).upto(@col_size-1) do |i|
139
+ m[i] -= m[k]*@lu[i][k]
140
+ end
141
+ end
142
+ # Solve U*m = Y
143
+ (@col_size-1).downto(0) do |k|
144
+ m[k] = m[k].quo(@lu[k][k])
145
+ k.times do |i|
146
+ m[i] -= m[k]*@lu[i][k]
147
+ end
148
+ end
149
+ Vector.elements(m, false)
150
+ end
151
+ end
152
+
153
+ def initialize a
154
+ raise TypeError, "Expected Matrix but got #{a.class}" unless a.is_a?(Matrix)
155
+ # Use a "left-looking", dot-product, Crout/Doolittle algorithm.
156
+ @lu = a.to_a
157
+ @row_size = a.row_size
158
+ @col_size = a.column_size
159
+ @pivots = Array.new(@row_size)
160
+ @row_size.times do |i|
161
+ @pivots[i] = i
162
+ end
163
+ @pivot_sign = 1
164
+ lu_col_j = Array.new(@row_size)
165
+
166
+ # Outer loop.
167
+
168
+ @col_size.times do |j|
169
+
170
+ # Make a copy of the j-th column to localize references.
171
+
172
+ @row_size.times do |i|
173
+ lu_col_j[i] = @lu[i][j]
174
+ end
175
+
176
+ # Apply previous transformations.
177
+
178
+ @row_size.times do |i|
179
+ lu_row_i = @lu[i]
180
+
181
+ # Most of the time is spent in the following dot product.
182
+
183
+ kmax = [i, j].min
184
+ s = 0
185
+ kmax.times do |k|
186
+ s += lu_row_i[k]*lu_col_j[k]
187
+ end
188
+
189
+ lu_row_i[j] = lu_col_j[i] -= s
190
+ end
191
+
192
+ # Find pivot and exchange if necessary.
193
+
194
+ p = j
195
+ (j+1).upto(@row_size-1) do |i|
196
+ if (lu_col_j[i].abs > lu_col_j[p].abs)
197
+ p = i
198
+ end
199
+ end
200
+ if (p != j)
201
+ @col_size.times do |k|
202
+ t = @lu[p][k]; @lu[p][k] = @lu[j][k]; @lu[j][k] = t
203
+ end
204
+ k = @pivots[p]; @pivots[p] = @pivots[j]; @pivots[j] = k
205
+ @pivot_sign = -@pivot_sign
206
+ end
207
+
208
+ # Compute multipliers.
209
+
210
+ if (j < @row_size && @lu[j][j] != 0)
211
+ (j+1).upto(@row_size-1) do |i|
212
+ @lu[i][j] = @lu[i][j].quo(@lu[j][j])
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end