multiarray 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake/packagetask'
6
6
  require 'rbconfig'
7
7
 
8
8
  PKG_NAME = 'multiarray'
9
- PKG_VERSION = '0.17.0'
9
+ PKG_VERSION = '0.18.0'
10
10
  RB_FILES = FileList[ 'lib/**/*.rb' ]
11
11
  TC_FILES = FileList[ 'test/tc_*.rb' ]
12
12
  TS_FILES = FileList[ 'test/ts_*.rb' ]
@@ -55,8 +55,7 @@ begin
55
55
  # For development just run it with "yard server --reload".
56
56
  require 'yard'
57
57
  YARD::Rake::YardocTask.new :yard do |y|
58
- y.options << '--no-private'
59
- y.files << FileList[ 'lib/**/*.rb' ]
58
+ y.files << RB_FILES
60
59
  end
61
60
  rescue LoadError
62
61
  STDERR.puts 'Please install \'yard\' if you want to generate documentation'
data/lib/multiarray.rb CHANGED
@@ -552,34 +552,6 @@ end
552
552
  # The +Numeric+ class is extended with a few methods
553
553
  class Numeric
554
554
 
555
- # Compute complex conjugate
556
- #
557
- # @return [Numeric] Returns +self+.
558
- def conj
559
- self
560
- end
561
-
562
- # Get red component
563
- #
564
- # @return [Numeric] Returns +self+.
565
- def r
566
- self
567
- end
568
-
569
- # Get green component
570
- #
571
- # @return [Numeric] Returns +self+.
572
- def g
573
- self
574
- end
575
-
576
- # Get blue component
577
- #
578
- # @return [Numeric] Returns +self+.
579
- def b
580
- self
581
- end
582
-
583
555
  # Get larger number of two numbers
584
556
  #
585
557
  # @param [Numeric] other The other number.
@@ -673,6 +673,18 @@ module Math
673
673
 
674
674
  end
675
675
 
676
+ # The +Numeric+ class is extended with a few methods
677
+ class Numeric
678
+
679
+ # Compute complex conjugate
680
+ #
681
+ # @return [Numeric] Returns +self+.
682
+ def conj
683
+ self
684
+ end
685
+
686
+ end
687
+
676
688
  module Hornetseye
677
689
 
678
690
  # Class for representing native complex values
@@ -166,7 +166,7 @@ module Hornetseye
166
166
  end
167
167
  i = INT.new i
168
168
  end
169
- i.size = @index.size if @index.size.get and i.is_a? Variable
169
+ i.size = @index.size if i.is_a?( Variable ) and @index.size.get
170
170
  @term.subst @index => i
171
171
  end
172
172
 
@@ -322,6 +322,9 @@ module Hornetseye
322
322
  value = element( index ).inject nil, :block => block,
323
323
  :var1 => var1, :var2 => var2
324
324
  value = typecode.new value unless value.is_a? Node
325
+ if initial.nil? and index.size.get == 0
326
+ raise "Array was empty and no initial value for injection was given"
327
+ end
325
328
  Inject.new( value, index, initial, block, var1, var2 ).force
326
329
  end
327
330
  end
@@ -349,16 +352,20 @@ module Hornetseye
349
352
 
350
353
  # Find minimum value of array
351
354
  #
355
+ # @param [Object] initial Only consider values less than this value.
356
+ #
352
357
  # @return [Object] Minimum value of array.
353
- def min
354
- inject { |a,b| a.minor b }
358
+ def min( initial = nil )
359
+ inject( initial ) { |a,b| a.minor b }
355
360
  end
356
361
 
357
362
  # Find maximum value of array
358
363
  #
364
+ # @param [Object] initial Only consider values greater than this value.
365
+ #
359
366
  # @return [Object] Maximum value of array.
360
- def max
361
- inject { |a,b| a.major b }
367
+ def max( initial = nil )
368
+ inject( initial ) { |a,b| a.major b }
362
369
  end
363
370
 
364
371
  # Compute sum of array
@@ -371,8 +378,8 @@ module Hornetseye
371
378
  # Find range of values of array
372
379
  #
373
380
  # @return [Object] Range of values of array.
374
- def range
375
- min .. max
381
+ def range( initial = nil )
382
+ min( initial ? initial.min : nil ) .. max( initial ? initial.max : nil )
376
383
  end
377
384
 
378
385
  # Normalise values of array
@@ -504,7 +511,11 @@ module Hornetseye
504
511
  # @return [Node] The histogram.
505
512
  def histogram( *ret_shape )
506
513
  options = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {}
507
- options = { :weight => UINT.new( 1 ), :safe => true }.merge options
514
+ options = { :weight => UINT. new( 1 ), :safe => true }.merge options
515
+ unless options[ :weight ].is_a? Node
516
+ options[ :weight ] =
517
+ Node.match( options[ :weight ] ).maxint.new options[ :weight ]
518
+ end
508
519
  if shape.first != 1 and ret_shape.size == 1
509
520
  [ self ].histogram *( ret_shape + [ options ] )
510
521
  else
@@ -638,6 +649,11 @@ module Hornetseye
638
649
  warp *( field + [ :safe => false ] )
639
650
  end
640
651
 
652
+ # Create array with shifted elements
653
+ #
654
+ # @param [Array<Integer>] offset Array with amount of shift for each dimension.
655
+ #
656
+ # @return [Node] The result of the shifting operation.
641
657
  def shift( *offset )
642
658
  if offset.size != dimension
643
659
  raise "#{offset.size} offset(s) were given but array has " +
@@ -673,6 +689,13 @@ module Hornetseye
673
689
  retval
674
690
  end
675
691
 
692
+ # Downsampling of arrays
693
+ #
694
+ # @overload downsample( *rate, options = {} )
695
+ # @param [Array<Integer>] rate The sampling rates for each dimension.
696
+ # @option options [Array<Integer>] :offset Sampling offsets for each dimension.
697
+ #
698
+ # @return [Node] The downsampled data.
676
699
  def downsample( *rate )
677
700
  options = rate.last.is_a?( Hash ) ? rate.pop : {}
678
701
  options = { :offset => rate.collect { |r| r - 1 } }.merge options
@@ -728,7 +751,11 @@ class Array
728
751
  # @return [Node] The histogram.
729
752
  def histogram( *ret_shape )
730
753
  options = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {}
731
- options = { :weight => Hornetseye::UINT.new( 1 ), :safe => true }.merge options
754
+ options = { :weight => Hornetseye::UINT. new( 1 ), :safe => true }.merge options
755
+ unless options[ :weight ].is_a? Hornetseye::Node
756
+ options[ :weight ] =
757
+ Hornetseye::Node.match( options[ :weight ] ).maxint.new options[ :weight ]
758
+ end
732
759
  weight = options[ :weight ]
733
760
  if options[ :safe ]
734
761
  if size != ret_shape.size
@@ -740,7 +767,7 @@ class Array
740
767
  source_type.check_shape *array_types
741
768
  source_type.check_shape options[ :weight ]
742
769
  for i in 0 ... size
743
- range = self[ i ].range
770
+ range = self[ i ].range 0 ... ret_shape[ i ]
744
771
  if range.begin < 0
745
772
  raise "#{i+1}th dimension of index must be in 0 ... #{ret_shape[i]} " +
746
773
  "(but was #{range.begin})"
@@ -780,12 +807,12 @@ class Array
780
807
  source_type = array_types.inject { |a,b| a.coercion b }
781
808
  source_type.check_shape *array_types
782
809
  for i in 0 ... size
783
- range = self[ i ].range
810
+ offset = table.dimension - size
811
+ range = self[ i ].range 0 ... table.shape[ i + offset ]
784
812
  if range.begin < 0
785
813
  raise "#{i+1}th index must be in 0 ... #{table.shape[i]} " +
786
814
  "(but was #{range.begin})"
787
815
  end
788
- offset = table.dimension - size
789
816
  if range.end >= table.shape[ i + offset ]
790
817
  raise "#{i+1}th index must be in 0 ... " +
791
818
  "#{table.shape[ i + offset ]} (but was #{range.end})"
@@ -146,9 +146,7 @@ module Hornetseye
146
146
 
147
147
  # This operation has no effect
148
148
  #
149
- # @return [InternalComplex] Returns +self+.
150
- #
151
- # @private
149
+ # @return [RGB] Returns +self+.
152
150
  def +@
153
151
  self
154
152
  end
@@ -175,8 +173,6 @@ module Hornetseye
175
173
  # Check whether value is equal to zero
176
174
  #
177
175
  # @return [Boolean,GCCValue] The result.
178
- #
179
- # @private
180
176
  def zero?
181
177
  @r.zero?.and( @g.zero? ).and( @b.zero? )
182
178
  end
@@ -184,20 +180,23 @@ module Hornetseye
184
180
  # Check whether value is not equal to zero
185
181
  #
186
182
  # @return [Boolean,GCCValue] The result.
187
- #
188
- # @private
189
183
  def nonzero?
190
184
  @r.nonzero?.or( @g.nonzero? ).or( @b.nonzero? )
191
185
  end
192
186
 
187
+ # Swap colour channels
188
+ #
189
+ # @return [RGB] The result.
190
+ def swap_rgb
191
+ RGB.new @b, @g, @r
192
+ end
193
+
193
194
  # Test on equality
194
195
  #
195
196
  # @param [Object] other Object to compare with.
196
197
  #
197
198
  # @return [Boolean] Returns boolean indicating whether objects are
198
199
  # equal or not.
199
- #
200
- # @private
201
200
  def ==( other )
202
201
  if other.is_a? RGB
203
202
  @r.eq( other.r ).and( @g.eq( other.g ) ).and( @b.eq( other.b ) )
@@ -213,6 +212,8 @@ module Hornetseye
213
212
  # This method decomposes the RGB value into an array.
214
213
  #
215
214
  # @return [Node] An array with the three channel values as elements.
215
+ #
216
+ # @private
216
217
  def decompose( i )
217
218
  [ @r, @g, @b ][ i ]
218
219
  end
@@ -520,6 +521,7 @@ module Hornetseye
520
521
  define_unary_op :r, :scalar
521
522
  define_unary_op :g, :scalar
522
523
  define_unary_op :b, :scalar
524
+ define_unary_op :swap_rgb
523
525
 
524
526
  # Fast extraction for red channel of RGB array
525
527
  #
@@ -617,7 +619,31 @@ module Hornetseye
617
619
  end
618
620
  end
619
621
 
620
- # Histograms
622
+ # Swapping colour channels for scalar values
623
+ #
624
+ # @return [Node] Array with swapped colour channels.
625
+ def swap_rgb_with_scalar
626
+ if typecode == OBJECT or typecode < RGB_
627
+ swap_rgb_without_scalar
628
+ else
629
+ self
630
+ end
631
+ end
632
+
633
+ alias_method_chain :swap_rgb, :scalar
634
+
635
+ # Compute colour histogram of this array
636
+ #
637
+ # The array is decomposed to its colour channels and a histogram is computed.
638
+ #
639
+ # @overload histogram( *ret_shape, options = {} )
640
+ # @param [Array<Integer>] ret_shape Dimensions of resulting histogram.
641
+ # @option options [Node] :weight (Hornetseye::UINT(1)) Weights for computing the
642
+ # histogram.
643
+ # @option options [Boolean] :safe (true) Do a boundary check before creating the
644
+ # histogram.
645
+ #
646
+ # @return [Node] The histogram.
621
647
  def histogram_with_rgb( *ret_shape )
622
648
  if typecode < RGB_
623
649
  [ r, g, b ].histogram *ret_shape
@@ -628,6 +654,13 @@ module Hornetseye
628
654
 
629
655
  alias_method_chain :histogram, :rgb
630
656
 
657
+ # Perform element-wise lookup with colour values
658
+ #
659
+ # @param [Node] table The lookup table (LUT).
660
+ # @option options [Boolean] :safe (true) Do a boundary check before creating the
661
+ # element-wise lookup.
662
+ #
663
+ # @return [Node] The result of the lookup operation.
631
664
  def lut_with_rgb( table, options = {} )
632
665
  if typecode < RGB_
633
666
  [ r, g, b ].lut table, options
@@ -844,6 +877,39 @@ module Hornetseye
844
877
 
845
878
  end
846
879
 
880
+ # The +Numeric+ class is extended with a few methods
881
+ class Numeric
882
+
883
+ # Get red component
884
+ #
885
+ # @return [Numeric] Returns +self+.
886
+ def r
887
+ self
888
+ end
889
+
890
+ # Get green component
891
+ #
892
+ # @return [Numeric] Returns +self+.
893
+ def g
894
+ self
895
+ end
896
+
897
+ # Get blue component
898
+ #
899
+ # @return [Numeric] Returns +self+.
900
+ def b
901
+ self
902
+ end
903
+
904
+ # Swap colour channels
905
+ #
906
+ # @return [Numeric] Returns +self+.
907
+ def swap_rgb
908
+ self
909
+ end
910
+
911
+ end
912
+
847
913
  class Fixnum
848
914
 
849
915
  if method_defined? :rpower
@@ -341,6 +341,8 @@ class TC_MultiArray < Test::Unit::TestCase
341
341
  assert_equal M[ [ 1, 4 ], [ 5, 6 ] ], M[ [ C( 1, 2, 3 ), 4 ], [ 5, 6 ] ].r
342
342
  assert_equal M[ [ 2, 4 ], [ 5, 6 ] ], M[ [ C( 1, 2, 3 ), 4 ], [ 5, 6 ] ].g
343
343
  assert_equal M[ [ 3, 4 ], [ 5, 6 ] ], M[ [ C( 1, 2, 3 ), 4 ], [ 5, 6 ] ].b
344
+ assert_equal M[ [ C( 3, 2, 1 ), 4 ], [ 5, 6 ] ],
345
+ M[ [ C( 1, 2, 3 ), 4 ], [ 5, 6 ] ].swap_rgb
344
346
  assert_equal M[ [ 1, 4 ], [ 5, 6 ] ],
345
347
  M[ [ C( 1, 2, 3 ), 4 ], [ 5, 6 ] ].collect { |x| x.r }
346
348
  assert_equal M[ [ 2, 4 ], [ 5, 6 ] ],
@@ -431,17 +433,17 @@ class TC_MultiArray < Test::Unit::TestCase
431
433
  end
432
434
 
433
435
  def test_histogram
434
- assert_equal S( I, 5 )[ 0, 1, 1, 2, 0 ],
435
- M[ [ 1, 2 ], [ 3, 3 ] ].histogram( 5, :weight => I.new( 1 ) )
436
- assert_equal M( I, 2, 2 )[ [ 1, 0 ], [ 1, 1 ] ],
436
+ assert_equal [ 0, 1, 1, 2, 0 ],
437
+ M[ [ 1, 2 ], [ 3, 3 ] ].histogram( 5, :weight => 1 ).to_a
438
+ assert_equal [ [ 1, 0 ], [ 1, 1 ] ],
437
439
  M[ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ] ].
438
- histogram( 2, 2, :weight => I.new( 1 ) )
439
- assert_equal M( I, 2, 2 )[ [ 1, 0 ], [ 1, 1 ] ],
440
+ histogram( 2, 2, :weight => 1 ).to_a
441
+ assert_equal [ [ 1, 0 ], [ 1, 1 ] ],
440
442
  [ S[ 0, 0, 1 ], S[ 0, 1, 1 ] ].
441
- histogram( 2, 2, :weight => I.new( 1 ) )
442
- assert_equal M( I, 2, 2, 1 )[ [ [ 0, 1 ], [ 1, 0 ] ] ],
443
+ histogram( 2, 2, :weight => 1 ).to_a
444
+ assert_equal [ [ [ 0, 1 ], [ 1, 0 ] ] ],
443
445
  S[ C( 1, 0, 0 ), C( 0, 1, 0 ) ].
444
- histogram( 2, 2, 1, :weight => I.new( 1 ) )
446
+ histogram( 2, 2, 1, :weight => 1 ).to_a
445
447
  assert_raise( RuntimeError ) { S[ 1, 2, 3 ].histogram 4, 4 }
446
448
  assert_raise( RuntimeError ) { M[ [ -1, 0 ] ].histogram 3, 2 }
447
449
  assert_raise( RuntimeError ) { M[ [ 0, -1 ] ].histogram 3, 2 }
data/test/tc_sequence.rb CHANGED
@@ -240,6 +240,7 @@ class TC_Sequence < Test::Unit::TestCase
240
240
  assert_equal [ 1, 4, 5 ], t[ C( 1, 2, 3 ), 4, 5 ].collect { |x| x.r }.to_a
241
241
  assert_equal [ 2, 4, 5 ], t[ C( 1, 2, 3 ), 4, 5 ].collect { |x| x.g }.to_a
242
242
  assert_equal [ 3, 4, 5 ], t[ C( 1, 2, 3 ), 4, 5 ].collect { |x| x.b }.to_a
243
+ assert_equal t[ C( 3, 2, 1 ), 4, 5 ], t[ C( 1, 2, 3 ), 4, 5 ].swap_rgb
243
244
  s = t[ 0, 0, 0 ]
244
245
  assert_equal 1, s.r = 1
245
246
  assert_equal S[ 1, 2, 3 ], s.g = S[ 1, 2, 3 ]
@@ -289,6 +290,8 @@ class TC_Sequence < Test::Unit::TestCase
289
290
  assert_equal C( 4, 6, 9 ), S[ C( 1, 2, 3 ), C( 2, 3, 5 ) ].
290
291
  inject( 1 ) { |a,b| a + b }
291
292
  assert_equal X( -5, 10 ), S( X, 2 )[ X( 1, 2 ), X( 3, 4 ) ].inject { |a,b| a * b }
293
+ assert_raise( RuntimeError ) { S[].inject { |a,b| a + b } }
294
+ assert_equal 0, S[].inject( 0 ) { |a,b| a + b }
292
295
  end
293
296
 
294
297
  def test_collect
@@ -312,15 +315,15 @@ class TC_Sequence < Test::Unit::TestCase
312
315
  end
313
316
 
314
317
  def test_min
315
- [ S( O, 3 ), S( I, 3 ) ].each do |t|
316
- assert_equal 2, t[ 4, 2, 3 ].min
318
+ [ O, I ].each do |t|
319
+ assert_equal 2, S( t, 3 )[ 4, 2, 3 ].min
317
320
  end
318
321
  assert_equal C( 1, 2, 1 ), S[ C( 1, 2, 3 ), C( 3, 2, 1 ) ].min
319
322
  end
320
323
 
321
324
  def test_max
322
- [ S( O, 3 ), S( I, 3 ) ].each do |t|
323
- assert_equal 4, t[ 4, 2, 3 ].max
325
+ [ O, I ].each do |t|
326
+ assert_equal 4, S( t, 3 )[ 4, 2, 3 ].max
324
327
  end
325
328
  assert_equal C( 3, 2, 3 ), S[ C( 1, 2, 3 ), C( 3, 2, 1 ) ].max
326
329
  end
@@ -360,12 +363,12 @@ class TC_Sequence < Test::Unit::TestCase
360
363
 
361
364
  def test_histogram
362
365
  [ O, I ].each do |t|
363
- assert_equal S( t, 5 )[ 0, 1, 2, 1, 1 ],
364
- S( t, 5 )[ 1, 2, 2, 3, 4 ].histogram( 5, :weight => t.new( 1 ) )
366
+ assert_equal [ 0, 1, 2, 1, 1 ],
367
+ S( t, 5 )[ 1, 2, 2, 3, 4 ].histogram( 5, :weight => 1 ).to_a
365
368
  assert_equal S( t, 5 )[ 0, 1, 2, 3, 0 ],
366
369
  S( t, 3 )[ 1, 3, 2 ].histogram( 5, :weight => S( t, 3 )[ 1, 3, 2 ] )
367
- assert_equal S( t, 4 )[ 0, 1, 1, 0 ],
368
- S( t, 2 )[ 1.0, 2.0 ].histogram( 4, :weight => t.new( 1 ) )
370
+ assert_equal [ 0, 1, 1, 0 ],
371
+ S( t, 2 )[ 1.0, 2.0 ].histogram( 4, :weight => 1 ).to_a
369
372
  end
370
373
  assert_raise( RuntimeError ) { S[ -1, 0, 1 ].histogram 3 }
371
374
  assert_raise( RuntimeError ) { S[ 1, 2, 3 ].histogram 3 }
@@ -550,7 +553,8 @@ class TC_Sequence < Test::Unit::TestCase
550
553
  end
551
554
 
552
555
  def test_conj
553
- assert_equal S[ 1.5, 2.5 ], S[ 1.5, 2.5 ].conj
556
+ assert_equal S( O, 2 )[ 1.5, 2.5 ], S( O, 2 )[ 1.5, 2.5 ].conj
557
+ assert_equal S( F, 2 )[ 1.5, 2.5 ], S( F, 2 )[ 1.5, 2.5 ].conj
554
558
  assert_equal S[ X( 1.5, -2.5 ) ], S[ X( 1.5, 2.5 ) ].conj
555
559
  end
556
560
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 17
7
+ - 18
8
8
  - 0
9
- version: 0.17.0
9
+ version: 0.18.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jan Wedekind
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-02 00:00:00 +01:00
17
+ date: 2011-01-11 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency