extendmatrix 0.1.0 → 0.2.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.
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
- === 0.0.60 / 2010-05-04
1
+ === 0.2.0 / 2010-05-04
2
+ * More rubyesque implementation of some methods
3
+ * Matrix#new is not altered and previously extended #new is called #new_with_values
4
+
5
+ === 0.1.0 / 2010-05-04
2
6
 
3
7
  * First gem version
data/Manifest.txt CHANGED
@@ -5,3 +5,4 @@ README.txt
5
5
  Rakefile
6
6
  lib/extendmatrix.rb
7
7
  spec/extendmatrix_spec.rb
8
+ spec/spec.opts
data/lib/extendmatrix.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  require 'rational'
2
2
  require 'matrix'
3
-
4
3
  class Vector
5
4
  include Enumerable
6
- # fix for Vector#coerce on Ruby 1.8.x
7
- if RUBY_VERSION<="1.9.0"
5
+ # fix for Vector#coerce on Ruby 1.8.x
6
+ if RUBY_VERSION<="1.9.0"
8
7
  alias_method :old_coerce, :coerce
9
8
  def coerce(other)
10
9
  case other
@@ -14,14 +13,11 @@ class Vector
14
13
  raise TypeError, "#{self.class} can't be coerced into #{other.class}"
15
14
  end
16
15
  end
17
-
18
16
  end
19
-
17
+
20
18
  module Norm
21
- def Norm.sqnorm(obj, p)
22
- sum = 0
23
- obj.each{|x| sum += x ** p}
24
- sum
19
+ def self.sqnorm(obj, p)
20
+ obj.inject(0) {|ac,x| ac+(x**p)}
25
21
  end
26
22
  end
27
23
 
@@ -63,11 +59,12 @@ class Vector
63
59
  class << self
64
60
  #
65
61
  # Returns a concatenated Vector
62
+ #
63
+ # Vector.concat(Vector[1,2,3], Vector[4,5,6])
64
+ # => Vector[1, 2, 3, 4, 5, 6]
66
65
  #
67
66
  def concat(*args)
68
- v = []
69
- args.each{|x| v += x.to_a}
70
- Vector[*v]
67
+ Vector.elements(args.inject([]){|ac,v| ac+v.to_a}, false)
71
68
  end
72
69
  end
73
70
 
@@ -100,12 +97,17 @@ class Vector
100
97
  def min
101
98
  to_a.min
102
99
  end
103
-
100
+ #
101
+ # Returns the sum of values of the vector
102
+ #
103
+ def sum
104
+ to_a.inject(&:+)
105
+ end
104
106
  #
105
107
  # Returns the p-norm of a vector
106
108
  #
107
109
  def norm(p = 2)
108
- Norm.sqnorm(self, p) ** (Float(1)/p)
110
+ Norm.sqnorm(self, p) ** (1.quo(p))
109
111
  end
110
112
 
111
113
  #
@@ -143,7 +145,7 @@ class Vector
143
145
  #
144
146
  # Return the vector divided by a scalar
145
147
  #
146
- def /(c)
148
+ def / (c)
147
149
  map {|e| e.quo(c)}
148
150
  end
149
151
 
@@ -193,7 +195,7 @@ class Vector
193
195
  # Return the vector normalized
194
196
  #
195
197
  def normalize
196
- self / self.norm
198
+ self.quo(self.norm)
197
199
  end
198
200
 
199
201
  #
@@ -212,67 +214,58 @@ class Vector
212
214
  end
213
215
  end
214
216
 
215
- class Matrix
216
-
217
- EXTENSION_VERSION="0.1.0"
217
+ class Matrix
218
+
219
+ EXTENSION_VERSION="0.2.0"
218
220
  include Enumerable
219
- public_class_method :new
220
221
 
221
222
  attr_reader :rows, :wrap
222
223
  @wrap = nil
223
-
224
- def initialize(*argv)
225
- return initialize_old(*argv) if argv[0].is_a?(Symbol)
226
- n, m, val = argv; val = 0 if not val
227
- f = (block_given?)? lambda {|i,j| yield(i, j)} : lambda {|i,j| val}
228
- init_rows((0...n).collect {|i| (0...m).collect {|j| f.call(i,j)}}, true)
229
- end
230
-
231
224
  #
232
225
  # For invoking a method
233
226
  #
234
- def initialize_old(init_method, *argv)
227
+ def initialize_old(init_method, *argv) #:nodoc:
235
228
  self.send(init_method, *argv)
236
229
  end
237
230
 
238
231
  alias :ids :[]
239
232
  #
240
- # Return a value or a vector/matrix of values depending
241
- # if the indexes are ranges or not
242
- # m = Matrix.new(4, 3){|i, j| i * 3 + j}
243
- # m: 0 1 2
244
- # 3 4 5
245
- # 6 7 8
246
- # 9 10 11
247
- # m[1, 2] => 5
248
- # m[3,1..2] => Vector[10, 11]
249
- # m[0..1, 0..2] => Matrix[[0, 1, 2], [3, 4, 5]]
250
- #
251
- def [](i, j)
252
- case i
253
- when Range
254
- case j
255
- when Range
256
- Matrix[*i.collect{|l| self.row(l)[j].to_a}]
257
- else
258
- column(j)[i]
259
- end
260
- else
261
- case j
262
- when Range
263
- row(i)[j]
264
- else
265
- ids(i, j)
266
- end
267
- end
268
- end
269
-
270
-
271
-
233
+ # Return a value or a vector/matrix of values depending
234
+ # if the indexes are ranges or not
235
+ # m = Matrix.new_with_value(4, 3){|i, j| i * 3 + j}
236
+ # m: 0 1 2
237
+ # 3 4 5
238
+ # 6 7 8
239
+ # 9 10 11
240
+ # m[1, 2] => 5
241
+ # m[3,1..2] => Vector[10, 11]
242
+ # m[0..1, 0..2] => Matrix[[0, 1, 2], [3, 4, 5]]
243
+ #
244
+ def [](i, j)
245
+ case i
246
+ when Range
247
+ case j
248
+ when Range
249
+ Matrix[*i.collect{|l| self.row(l)[j].to_a}]
250
+ else
251
+ column(j)[i]
252
+ end
253
+ else
254
+ case j
255
+ when Range
256
+ row(i)[j]
257
+ else
258
+ ids(i, j)
259
+ end
260
+ end
261
+ end
262
+
263
+
264
+
272
265
 
273
266
  #
274
267
  # Set the values of a matrix
275
- # m = Matrix.new(3, 3){|i, j| i * 3 + j}
268
+ # m = Matrix.build(3, 3){|i, j| i * 3 + j}
276
269
  # m: 0 1 2
277
270
  # 3 4 5
278
271
  # 6 7 8
@@ -314,9 +307,9 @@ class Matrix
314
307
  end
315
308
 
316
309
  #
317
- # Return a clone matrix
310
+ # Return a duplicate matrix
318
311
  #
319
- def clone
312
+ def dup
320
313
  super
321
314
  end
322
315
 
@@ -327,6 +320,18 @@ class Matrix
327
320
 
328
321
 
329
322
  class << self
323
+ if !self.respond_to? :build
324
+ #
325
+ # Creates a matrix <tt>n</tt> x <tt>m</tt>
326
+ # If you provide a block, it will be used to set the values.
327
+ # If not, <tt>val</tt> will be used
328
+ #
329
+
330
+ def build(n,m,val=0)
331
+ f = (block_given?)? lambda {|i,j| yield(i, j)} : lambda {|i,j| val}
332
+ Matrix.rows((0...n).collect {|i| (0...m).collect {|j| f.call(i,j)}})
333
+ end
334
+ end
330
335
  #
331
336
  # Creates a matrix with the given matrices as diagonal blocks
332
337
  #
@@ -377,7 +382,7 @@ class Matrix
377
382
  def quo(v)
378
383
  map {|e| e.quo(v)}
379
384
  end
380
-
385
+ alias :old_divition :/
381
386
  #
382
387
  # quo seems always desirable
383
388
  #
@@ -434,6 +439,8 @@ def cols_len
434
439
  (0...column_size).collect {|j| max_len_column(j)}
435
440
  end
436
441
 
442
+ alias :to_s_old :to_s
443
+
437
444
  #
438
445
  # Returns a string for nice printing matrix
439
446
  #
@@ -541,7 +548,7 @@ alias :column_collect! :column!
541
548
 
542
549
  #
543
550
  # Set a certain column with the values of a Vector
544
- # m = Matrix.new(3, 3){|i, j| i * 3 + j + 1}
551
+ # m = Matrix.build(3, 3){|i, j| i * 3 + j + 1}
545
552
  # m.column= 1, Vector[1, 1, 1], 1..2
546
553
  # m => 1 2 3
547
554
  # 4 1 6
@@ -569,7 +576,7 @@ def row=(args)
569
576
  end
570
577
 
571
578
  def norm(p = 2)
572
- Vector::Norm.sqnorm(self, p) ** (Float(1)/p)
579
+ Vector::Norm.sqnorm(self, p) ** (1.quo(p))
573
580
  end
574
581
 
575
582
  def norm_frobenius
@@ -587,8 +594,9 @@ end
587
594
  #
588
595
  # Returns the row/s of matrix as a Matrix
589
596
  #
597
+
590
598
  def row2matrix(r)
591
- a = self.send(:row, r).to_a
599
+ a = row(r).to_a
592
600
  if r.is_a?(Range) and r.entries.size > 1
593
601
  return Matrix[*a]
594
602
  else
@@ -597,10 +605,10 @@ def row2matrix(r)
597
605
  end
598
606
 
599
607
  #
600
- # Returns the colomn/s of matrix as a Matrix
608
+ # Returns the column/s of matrix as a Matrix
601
609
  #
602
610
  def column2matrix(c)
603
- a = self.send(:column, c).to_a
611
+ a = column(c).to_a
604
612
  if c.is_a?(Range) and c.entries.size > 1
605
613
  return Matrix[*a]
606
614
  else
@@ -608,23 +616,23 @@ def column2matrix(c)
608
616
  end
609
617
  end
610
618
 
611
- # Calculate marginal of rows
612
- def row_sum
619
+ # Returns the marginal of rows
620
+ def row_sum
613
621
  (0...row_size).collect {|i|
614
- row(i).to_a.inject(0) {|a,v| a+v}
622
+ row(i).sum
615
623
  }
616
- end
617
- # Calculate marginal of columns
618
- def column_sum
624
+ end
625
+ # Returns the of columns
626
+ def column_sum
619
627
  (0...column_size).collect {|i|
620
- column(i).to_a.inject(0) {|a,v| a+v}
628
+ column(i).sum
621
629
  }
622
- end
630
+ end
623
631
  # Calculate sum of cells
624
- def total_sum
625
- row_sum.inject(0){|a,v| a+v}
626
- end
627
-
632
+ def total_sum
633
+ row_sum.inject(&:+)
634
+ end
635
+
628
636
  module LU
629
637
  #
630
638
  # Return the Gauss vector, MC, Golub, 3.2.1 Gauss Transformation, p94
@@ -796,7 +804,7 @@ module Householder
796
804
  a = clone
797
805
  n = column_size
798
806
  m = row_size
799
- q = Matrix.new(m, n){0}
807
+ q = Matrix.build(m, n){0}
800
808
  r = Matrix.zero(n)
801
809
  for k in 0...n
802
810
  r[k,k] = a[0...m, k].norm
@@ -8,21 +8,27 @@ describe "Vector class extension:" do
8
8
  before do
9
9
  @v = Vector.[](1, 2, 3, 4)
10
10
  end
11
-
12
- it "[] method" do
13
- v = @v.clone
14
- v[1..2] = Vector[9, 9, 9, 9, 9]
15
- v.should == Vector[1, 9, 9, 4]
11
+ it "[] with range returns correct values" do
12
+ @v[1..2]==Vector[2,3]
16
13
  end
17
-
18
- it "Vector.concat method" do
14
+ it "[]= should change only specified range" do
15
+ @v[1..2] = Vector[9, 9, 9, 9, 9]
16
+ @v.should == Vector[1, 9, 9, 4]
17
+ end
18
+
19
+ it "Vector.concat method should concat vectors" do
19
20
  Vector.concat(Vector[1], Vector[2, 3]).should == Vector[1, 2, 3]
20
21
  Vector.concat(Vector[1], Vector[2, 3], Vector[4, 5]).should == Vector[1, 2, 3, 4, 5]
21
22
  end
22
-
23
- it "collect method" do
24
- @v.collect!{|i| i * i}.should == Vector.[](1, 4, 9, 16)
25
- @v.collect!{|i| 3 * i}.should == Vector.[](3, 12, 27, 48)
23
+ it "collect method returns collected vector and doesn't change original" do
24
+ @v.collect{|i| i*i}.should== Vector.[](1,4,9,16)
25
+ @v.should==Vector[1,2,3,4]
26
+ end
27
+ it "collect! method should change vector" do
28
+ @v.collect!{|i| i * i}
29
+ @v.should == Vector.[](1, 4, 9, 16)
30
+ @v.collect!{|i| 3 * i}
31
+ @v.should == Vector.[](3, 12, 27, 48)
26
32
  end
27
33
 
28
34
  it "each method" do
@@ -31,15 +37,15 @@ describe "Vector class extension:" do
31
37
  r.should == [2, 3, 4, 5]
32
38
  end
33
39
 
34
- it "max element" do
40
+ it "max method should return max element" do
35
41
  @v.max.should == 4
36
42
  end
37
43
 
38
- it "max element" do
44
+ it "min method should return min element" do
39
45
  @v.min.should == 1
40
46
  end
41
47
 
42
- it "norm method" do
48
+ it "norm method returns correct norm" do
43
49
  v = Vector.[](3, 4)
44
50
  v.norm.should == 5
45
51
  end
@@ -66,7 +72,7 @@ describe "Vector class extension:" do
66
72
  v.norm(4).should < 4.29
67
73
  end
68
74
 
69
- it "[]= method" do
75
+ it "[]= method should change specific value" do
70
76
  @v[3] = 10
71
77
  @v.should == Vector.[](1, 2, 3, 10)
72
78
  end
@@ -74,17 +80,20 @@ describe "Vector class extension:" do
74
80
  it "norm_inf" do
75
81
  @v.norm_inf.should == 4
76
82
  end
83
+ it "sum method returns the sum of elements" do
84
+ @v.sum.should==10
85
+ end
77
86
  end
78
87
 
79
88
  describe "Matrix class extension:" do
80
89
  before do
81
90
  @m = Matrix[[1, 2, 222], [2, 33, 4]]
82
91
  end
83
- it "to_s method" do
92
+ it "to_s method should return something" do
84
93
  @m.to_s.size.should_not == 0
85
94
  end
86
95
  it "[] method" do
87
- m = Matrix.new(4, 3){|i, j| i * 3 + j}
96
+ m = Matrix.build(4, 3){|i, j| i * 3 + j}
88
97
  m[1, 2].should == 5
89
98
  m[3, 1..2].should == Vector[10, 11]
90
99
  m[0..1, 0..2].should == Matrix[[0, 1, 2], [3, 4, 5]]
@@ -100,7 +109,7 @@ describe "Matrix class extension:" do
100
109
  end
101
110
 
102
111
  it "[]= method" do
103
- m = Matrix.new(3, 3){|i, j| i * 3 + j}
112
+ m = Matrix.build(3, 3){|i, j| i * 3 + j}
104
113
  m[1, 2] = 9
105
114
  m.should == Matrix[[0, 1, 2], [3, 4, 9], [6, 7, 8]]
106
115
  m[1, 1..2] = Vector[8, 8]
@@ -110,14 +119,14 @@ describe "Matrix class extension:" do
110
119
  end
111
120
 
112
121
  it "set method" do
113
- n = Matrix.new(2, 3)
122
+ n = Matrix.build(2, 3)
114
123
  n.set(@m)
115
124
  n.should == @m
116
125
  end
117
126
 
118
127
  it "set method and wrap value" do
119
128
  @m.wrap = :torus
120
- n = Matrix.new(2, 3)
129
+ n = Matrix.build(2, 3)
121
130
  n.set(@m)
122
131
  n.wrap.should == :torus
123
132
  end
@@ -173,7 +182,7 @@ describe "Matrix class extension:" do
173
182
  end
174
183
 
175
184
  it "column= " do
176
- m = Matrix.new(3, 3){|i, j| i * 3 + j + 1}
185
+ m = Matrix.build(3, 3){|i, j| i * 3 + j + 1}
177
186
  m.column= 1, Vector[1,1,1,1,1,1]
178
187
  m.should == Matrix[[1, 1, 3],[4, 1, 6],[7, 1, 9]]
179
188
  m.column= 2, Vector[9,9], 0..1
@@ -181,7 +190,7 @@ describe "Matrix class extension:" do
181
190
  end
182
191
 
183
192
  it "row= " do
184
- m = Matrix.new(3, 3){|i, j| i * 3 + j + 1}
193
+ m = Matrix.build(3, 3){|i, j| i * 3 + j + 1}
185
194
  m.row= 1, Vector[1,1,1,1,1,1]
186
195
  m.should == Matrix[[1, 2, 3],[1, 1, 1],[7, 8, 9]]
187
196
  m.row= 2, Vector[9,9], 0..2
@@ -200,14 +209,14 @@ describe "Matrix class extension:" do
200
209
  end
201
210
 
202
211
  it "row2matrix" do
203
- m = Matrix.new(4, 3){|i, j| i * 3 + j + 1}
212
+ m = Matrix.build(4, 3){|i, j| i * 3 + j + 1}
204
213
  m.row2matrix(1..2).should == Matrix[[4, 5, 6],[7, 8, 9]]
205
214
  m.row2matrix(2).should == Matrix[[7, 8, 9]]
206
215
  m.row2matrix(0..4).should == m
207
216
  end
208
217
 
209
218
  it "column2matrix" do
210
- m = Matrix.new(4, 3){|i, j| i * 3 + j + 1}
219
+ m = Matrix.build(4, 3){|i, j| i * 3 + j + 1}
211
220
  m.column2matrix(1).should == Matrix[[2], [5], [8], [11]]
212
221
  end
213
222
 
@@ -215,7 +224,7 @@ describe "Matrix class extension:" do
215
224
  m1 = Matrix[[1]]
216
225
  m2 = Matrix[[2, 0], [0, 3]]
217
226
  m3 = Matrix[[4, 0, 0], [0, 5, 0], [0, 0, 6]]
218
- a1 = Matrix.new(6, 6){|i, j| i == j ? i + 1: 0}
227
+ a1 = Matrix.build(6, 6){|i, j| i == j ? i + 1: 0}
219
228
  Matrix.diag(m1, m2, m3).should == a1
220
229
  Matrix.diag(m2).should == m2
221
230
  a2 = Matrix[[2, 0, 0, 0],
@@ -226,7 +235,7 @@ describe "Matrix class extension:" do
226
235
  end
227
236
 
228
237
  it "equal_in_delta" do
229
- m = Matrix.new(4, 3){|i, j| i * 3 + j +1}
238
+ m = Matrix.build(4, 3){|i, j| i * 3 + j +1}
230
239
  Matrix.equal_in_delta?(m, m).should == true
231
240
  mm = m.clone
232
241
  mm[0,0] += 2
@@ -235,8 +244,8 @@ describe "Matrix class extension:" do
235
244
  end
236
245
 
237
246
  it "diag_in_delta" do
238
- Matrix.diag_in_delta?(Matrix.I(5), Matrix.new(4, 4){|i, j| i + j}).should == false
239
- m = Matrix.new(5, 5){|i, j| i == j ? 1 + 0.001 * (i+1) : i + j}
247
+ Matrix.diag_in_delta?(Matrix.I(5), Matrix.build(4, 4){|i, j| i + j}).should == false
248
+ m = Matrix.build(5, 5){|i, j| i == j ? 1 + 0.001 * (i+1) : i + j}
240
249
  Matrix.diag_in_delta?(Matrix.I(5), m, 0.01).should == true
241
250
  end
242
251
 
@@ -269,7 +278,7 @@ describe "Matrix class extension:" do
269
278
  end
270
279
 
271
280
  it "houseQR " do
272
- m = Matrix.new(4, 3){|i, j| i * 3 + j +1}
281
+ m = Matrix.build(4, 3){|i, j| i * 3 + j +1}
273
282
  Matrix.equal_in_delta?(m, m.houseQ * m.houseR).should == true
274
283
  q = Matrix[[0.0776, 0.8330, 0.5329, 0.1264],
275
284
  [0.3104, 0.4512, -0.8048, 0.2286],
@@ -279,7 +288,7 @@ describe "Matrix class extension:" do
279
288
  end
280
289
 
281
290
  it "houseR " do
282
- m = Matrix.new(4, 3){|i, j| i * 3 + j +1}
291
+ m = Matrix.build(4, 3){|i, j| i * 3 + j +1}
283
292
  r = Matrix[[12.88409, 14.59162, 16.29916],
284
293
  [ 0, 1.04131, 2.082630],
285
294
  [ 0, 0, 0],
@@ -289,7 +298,7 @@ describe "Matrix class extension:" do
289
298
 
290
299
  it "bidiagonalization" do
291
300
  # MC, Golub, p252, Example 5.4.2
292
- m = Matrix.new(4, 3){|i, j| i * 3 + j +1}
301
+ m = Matrix.build(4, 3){|i, j| i * 3 + j +1}
293
302
  bidiag = Matrix[[12.884, 21.876, 0 ],
294
303
  [0, 2.246, -0.613],
295
304
  [0, 0, 0 ],
@@ -309,7 +318,7 @@ describe "Matrix class extension:" do
309
318
  end
310
319
 
311
320
  it "givens " do
312
- m = Matrix.new(4, 3){|i, j| i * 3 + j +1}
321
+ m = Matrix.build(4, 3){|i, j| i * 3 + j +1}
313
322
  Matrix.equal_in_delta?(m, m.givensQ * m.givensR, 0.001).should == true
314
323
  end
315
324
 
@@ -337,7 +346,7 @@ describe "Matrix class extension:" do
337
346
  end
338
347
 
339
348
  it "realSchur" do
340
- m = Matrix.new(3, 3){1} + Matrix.diagonal(2, 2, 2)
349
+ m = Matrix.build(3, 3){1} + Matrix.diagonal(2, 2, 2)
341
350
  e = Matrix[[5, 0, 0],[0, 2, 0],[0, 0, 2]]
342
351
  Matrix.diag_in_delta?(m.realSchur, e, 1.0e-5).should == true
343
352
  end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cosmin Bonchis
@@ -92,6 +92,7 @@ files:
92
92
  - Rakefile
93
93
  - lib/extendmatrix.rb
94
94
  - spec/extendmatrix_spec.rb
95
+ - spec/spec.opts
95
96
  has_rdoc: true
96
97
  homepage: http://github.com/clbustos/extendmatrix
97
98
  licenses: []
metadata.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- ��׮�2Hq=6���)c�f��WJۭ� �m��OUguS+ xJ�޾�,T&52,��@F�1�mkp����}��zk�i��CN.'b9]�Ve[g�0�������q�v�D��t^gK�؟\��mA�Y6`[s�����k�V��f\�\�RmP��l��0�e����F2g�h�+���P#�W�/%U:�%s�R� �@��D�dƁ�
2
- ��w���ՖdzM�*�e�&Pl02SA/I;s@����|
1
+ �`@�\M8�V��$�=h �g��Uce� ��bLi8p/��F�nfѦ�5���xm��bDUہ������o`�����}�w`Cx��Dvb�����\����y]hd)�c��]���.��#�Om !s��(y~���Y��! ����B��k��~�kSC��
2
+ !⥥7��AM�?�}Z|�=��a�Hϓk�j�f�L�J�0 ,y0M�I�gA�N"�2դy�TOBk�eIO��3�