extendmatrix 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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�