Class: Hornetseye::Node
- Inherits:
-
Object
- Object
- Hornetseye::Node
- Defined in:
- lib/multiarray/node.rb,
lib/multiarray/rgb.rb,
lib/multiarray/complex.rb,
lib/multiarray/operations.rb
Overview
Base class for representing native datatypes and operations (terms)
Direct Known Subclasses
Argument, Components, Diagonal, Element, ElementWise_, Histogram, Inject, Integral, Lambda, Lookup, Lut, Mask, Pointer_, Random, Store, Unmask
Class Method Summary (collapse)
-
+ (Boolean) ===(other)
Category operator.
-
+ (Class) bool
Get corresponding boolean-based datatype.
-
+ (Class) coercion_bool(other)
Get boolean-based datatype for binary operation.
-
+ (Class) coercion_byte(other)
Get byte-based datatype for binary operation.
-
+ (Class) coercion_maxint(other)
Get maximum integer based datatype for binary operation.
-
+ (Class) cond(a, b)
Get byte-based datatype for ternary operation.
-
+ (Array<Integer>) dimension
Get dimension of this term.
-
+ (Class) float_scalar
Get corresponding type based on floating-point scalars.
-
+ (Class) floating(other)
Get floating point based datatype for binary operation.
-
+ (Object) indgen(offset = 0, increment = 1)
Generate index array of this type.
-
+ (Boolean) rgb?
Check whether this object is an RGB value.
-
+ (Class) scalar
Get corresponding scalar type.
- + (Object) shape
-
+ (Class) to_type(dest)
Convert to different element type.
-
+ (Class) typecode
Element-type of this term.
Instance Method Summary (collapse)
-
- (Node) <=>(other)
Element-wise comparison of values.
-
- (Object, Node) [](*indices)
Retrieve value of array element(s).
-
- (Object, Node) []=(*indices, value)
Assign value to array element(s).
- - (Object) allocate
-
- (Object) b=(value)
Assignment for blue channel values of RGB array.
-
- (Node) b_with_decompose
Fast extraction for blue channel of RGB array.
-
- (Class) basetype
Base-type of this term.
-
- (Node) between?(a, b)
Check values against boundaries.
-
- (Object) check_shape(*args)
Check arguments for compatible shape.
-
- (Node) clip(range = 0 .. 0xFF)
Clip values to specified range.
-
- (Node) collect(&action)
(also: #map)
Perform element-wise operation on array.
-
- (Node) components(options = {})
Perform connected component labeling.
-
- (Node) conditional(a, b)
Element-wise conditional selection of values.
-
- (Node) convolve(filter)
Convolution with other array of same dimension.
-
- (Node) decompose(i)
Decompose composite elements.
-
- (Node) dilate(n = 3)
Dilation.
-
- (Array<Integer>) dimension
Get dimension of this term.
-
- (Node) downsample(*rate, options = {})
Downsampling of arrays.
-
- (Node) dup
Duplicate object.
- - (Object) each(&action)
-
- (Boolean) empty?
Check whether this object is an empty array.
-
- (Boolean) eq_with_multiarray(other)
Equality operator.
-
- (Node) erode(n = 3)
Erosion.
-
- (Node) fill!(value = typecode.default)
Fill array with a value.
-
- (Node) flip(*dimensions)
Mirror the array.
-
- (Node) fmod_with_float(other)
Modulo operation for floating point numbers.
-
- (Object) g=(value)
Assignment for green channel values of RGB array.
-
- (Node) g_with_decompose
Fast extraction for green channel of RGB array.
-
- (Node) gauss_blur(sigma, max_error = 1.0 / 0x100)
Gaussian blur.
-
- (Node) gauss_gradient(sigma, direction, max_error = 1.0 / 0x100)
Gauss gradient.
-
- (Integer) height
Get height of two-dimensional array.
-
- (Node) histogram(*ret_shape, options = {})
Compute histogram of this array.
-
- (Node) histogram(*ret_shape, options = {})
Compute colour histogram of this array.
-
- (Object) if(&action)
Conditional operation.
-
- (Object) if_else(action1, action2)
Conditional operation.
-
- (Object) imag=(value)
Assignment for imaginary values of complex array.
-
- (Node) imag_with_decompose
Fast extraction of imaginary values of complex array.
-
- (Object) inject(*args, &action)
Perform cummulative operation on array.
-
- (String) inspect(indent = nil, lines = nil)
Display information about this object.
-
- (Node) integral
Compute integral image.
-
- (Node) lut(table, options = {})
Perform element-wise lookup.
-
- (Node) lut_with_rgb(table, options = {})
Perform element-wise lookup with colour values.
-
- (Node) mask(m)
Select values from array using a mask.
- - (Boolean) matched?
-
- (Object) max(initial = nil)
Find maximum value of array.
-
- (Object) mean
Compute average of array.
-
- (Node) memorise
Duplicate array expression if it is not in row-major format.
-
- (Malloc, ...) memory
Get memory object.
-
- (Object) min(initial = nil)
Find minimum value of array.
-
- (Node) normalise(range = 0 .. 0xFF)
Normalise values of array.
-
- (Object) prod
Compute product of array.
-
- (Object) r=(value)
Assignment for red channel values of RGB array.
-
- (Node) r_with_decompose
Fast extraction for red channel of RGB array.
-
- (Object) range(initial = nil)
Find range of values of array.
-
- (Object) real=(value)
Assignment for real values of complex array.
-
- (Node) real_with_decompose
Fast extraction for real values of complex array.
-
- (Node) reshape(*ret_shape)
Get array with same elements but different shape.
-
- (Boolean) rgb?
Check whether this object is an RGB value.
-
- (Node) roll(n = 1)
Cycle indices of array.
-
- (Array<Integer>) shape
Get shape of this term.
-
- (Node) shift(*offset)
Create array with shifted elements.
-
- (Integer) size
Get size (number of elements) of this value.
-
- (Node) sobel(direction)
Sobel operator.
-
- (Node) stretch(from = 0 .. 0xFF, to = 0 .. 0xFF)
Stretch values from one range to another.
-
- (Object) sum
Compute sum of array.
-
- (Node) swap_rgb_with_scalar
Swapping colour channels for scalar values.
-
- (Array<Object>) to_a
Convert to Ruby array of objects.
-
- (Node) to_type(dest)
Convert array elements to different element type.
-
- (Node) to_type_with_identity(dest)
Skip type conversion if it has no effect.
-
- (Node) to_type_with_rgb(dest)
Convert RGB array to scalar array.
-
- (Node) transpose(*order)
Lazy transpose of array.
-
- (Class) typecode
Element-type of this term.
-
- (Node) unmask(m, options = {})
Distribute values in a new array using a mask.
-
- (Node) unroll(n = 1)
Reverse-cycle indices of array.
-
- (Node) warp(*field, options = {})
Warp an array.
-
- (Integer) width
Get width of two-dimensional array.
Class Method Details
+ (Boolean) ===(other)
Category operator
233 234 235 |
# File 'lib/multiarray/node.rb', line 233 def ===( other ) ( other == self ) or ( other.is_a? self ) or ( other.class == self ) end |
+ (Class) bool
Get corresponding boolean-based datatype
127 128 129 |
# File 'lib/multiarray/node.rb', line 127 def bool BOOL end |
+ (Class) coercion_bool(other)
Get boolean-based datatype for binary operation
148 149 150 |
# File 'lib/multiarray/node.rb', line 148 def coercion_bool( other ) other.coercion( self ).bool end |
+ (Class) coercion_byte(other)
Get byte-based datatype for binary operation
198 199 200 |
# File 'lib/multiarray/node.rb', line 198 def coercion_byte( other ) coercion( other ).byte end |
+ (Class) coercion_maxint(other)
Get maximum integer based datatype for binary operation
164 165 166 |
# File 'lib/multiarray/node.rb', line 164 def coercion_maxint( other ) coercion( other ).maxint end |
+ (Class) cond(a, b)
Get byte-based datatype for ternary operation
208 209 210 |
# File 'lib/multiarray/node.rb', line 208 def cond(a, b) a.coercion b end |
+ (Array<Integer>) dimension
Get dimension of this term
104 105 106 |
# File 'lib/multiarray/node.rb', line 104 def dimension 0 end |
+ (Class) float_scalar
Get corresponding type based on floating-point scalars
141 142 143 |
# File 'lib/multiarray/node.rb', line 141 def float_scalar float.scalar end |
+ (Class) floating(other)
Get floating point based datatype for binary operation
180 181 182 |
# File 'lib/multiarray/node.rb', line 180 def floating( other ) other.coercion( self ).float end |
+ (Object) indgen(offset = 0, increment = 1)
Generate index array of this type
97 98 99 |
# File 'lib/multiarray/node.rb', line 97 def indgen( offset = 0, increment = 1 ) offset end |
+ (Boolean) rgb?
Check whether this object is an RGB value
120 121 122 |
# File 'lib/multiarray/node.rb', line 120 def rgb? false end |
+ (Class) scalar
Get corresponding scalar type
134 135 136 |
# File 'lib/multiarray/node.rb', line 134 def scalar self end |
+ (Object) shape
87 88 89 |
# File 'lib/multiarray/node.rb', line 87 def shape [] end |
+ (Class) to_type(dest)
Convert to different element type
217 218 219 |
# File 'lib/multiarray/node.rb', line 217 def to_type( dest ) dest end |
+ (Class) typecode
Element-type of this term
65 66 67 |
# File 'lib/multiarray/node.rb', line 65 def typecode self end |
Instance Method Details
- (Node) <=>(other)
Element-wise comparison of values
261 262 263 264 265 |
# File 'lib/multiarray/operations.rb', line 261 def <=>(other) Hornetseye::lazy do (self < other).conditional -1, (self > other).conditional(1, 0) end.force end |
- (Object, Node) [](*indices)
Retrieve value of array element(s)
549 550 551 552 553 554 555 556 557 558 559 560 |
# File 'lib/multiarray/node.rb', line 549 def []( *indices ) if indices.empty? force else if indices.last.is_a? Range view = slice indices.last.min, indices.last.size else view = element indices.last end view[ *indices[ 0 ... -1 ] ] end end |
- (Object, Node) []=(*indices, value)
Assign value to array element(s)
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
# File 'lib/multiarray/node.rb', line 595 def []=( *indices ) value = indices.pop value = typecode.new value unless value.matched? if indices.empty? check_shape value unless compilable? and value.compilable? and dimension > 0 Store.new(self, value).demand else GCCFunction.run Store.new(self, value) end value else if indices.last.is_a? Range view = slice indices.last.min, indices.last.size else view = element indices.last end view[*indices[0 ... -1]] = value end end |
- (Object) allocate
287 288 289 |
# File 'lib/multiarray/node.rb', line 287 def allocate Hornetseye::MultiArray(typecode, dimension).new *shape end |
- (Object) b=(value)
Assignment for blue channel values of RGB array
612 613 614 615 616 617 618 619 620 621 622 |
# File 'lib/multiarray/rgb.rb', line 612 def b=(value) if typecode < RGB_ decompose( 2 )[] = value elsif typecode == OBJECT self[] = Hornetseye::lazy do r * RGB.new( 1, 0, 0 ) + g * RGB.new( 0, 1, 0 ) + value * RGB.new( 0, 0, 1 ) end else raise "Cannot assign blue channel to elements of type #{typecode.inspect}" end end |
- (Node) b_with_decompose
Fast extraction for blue channel of RGB array
595 596 597 598 599 600 601 602 603 |
# File 'lib/multiarray/rgb.rb', line 595 def b_with_decompose if typecode == OBJECT or is_a?(Variable) or Thread.current[:lazy] b_without_decompose elsif typecode < RGB_ decompose 2 else self end end |
- (Class) basetype
Base-type of this term
301 302 303 |
# File 'lib/multiarray/node.rb', line 301 def basetype self.class.basetype end |
- (Node) between?(a, b)
Check values against boundaries
468 469 470 |
# File 'lib/multiarray/operations.rb', line 468 def between?( a, b ) Hornetseye::lazy { ( self >= a ).and self <= b }.force end |
- (Object) check_shape(*args)
Check arguments for compatible shape
The method will throw an exception if one of the arguments has an incompatible shape.
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/multiarray/node.rb', line 570 def check_shape(*args) _shape = shape args.each do |arg| _arg_shape = arg.shape if _shape.size < _arg_shape.size raise "#{arg.inspect} has #{arg.dimension} dimension(s) " + "but should not have more than #{dimension}" end if ( _shape + _arg_shape ).all? { |s| s.is_a? Integer } if _shape.last( _arg_shape.size ) != _arg_shape raise "#{arg.inspect} has shape #{arg.shape.inspect} " + "(does not match last value(s) of #{shape.inspect})" end end end end |
- (Node) clip(range = 0 .. 0xFF)
Clip values to specified range
503 504 505 506 507 508 509 |
# File 'lib/multiarray/operations.rb', line 503 def clip( range = 0 .. 0xFF ) if range.exclude_end? raise "Clipping does not support ranges with end value " + "excluded (such as #{range})" end collect { |x| x.major( range.begin ).minor range.end } end |
- (Node) collect(&action) Also known as: map
Perform element-wise operation on array
324 325 326 327 328 329 |
# File 'lib/multiarray/operations.rb', line 324 def collect(&action) var = Variable.new typecode block = action.call var conversion = proc { |t| t.to_type action.call(Variable.new(t.typecode)).typecode } Hornetseye::ElementWise( action, block.to_s, conversion ).new( self ).force end |
- (Node) components(options = {})
Perform connected component labeling
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
# File 'lib/multiarray/operations.rb', line 781 def components( = {} ) if shape.any? { |x| x <= 1 } raise "Every dimension must be greater than 1 (shape was #{shape})" end = { :target => UINT, :default => typecode.default }.merge target = [ :target ] default = [ :default ] default = typecode.new default unless default.matched? left = Hornetseye::MultiArray(target, dimension).new *shape labels = Sequence.new target, size; labels[0] = 0 rank = Sequence.uint size; rank[0] = 0 n = Hornetseye::Pointer( INT ).new; n.store INT.new( 0 ) block = Components.new left, self, default, target.new(0), labels, rank, n if block.compilable? Hornetseye::GCCFunction.run block else block.demand end labels = labels[0 .. n.demand.get] left.lut labels.lut(labels.histogram(labels.size, :weight => target.new(1)). minor(1).integral - 1) end |
- (Node) conditional(a, b)
Element-wise conditional selection of values
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/multiarray/operations.rb', line 212 def conditional(a, b) a = Node.match(a, b.matched? ? b : nil).new a unless a.matched? b = Node.match(b, a.matched? ? a : nil).new b unless b.matched? if dimension == 0 and variables.empty? and a.dimension == 0 and a.variables.empty? and b.dimension == 0 and b.variables.empty? target = typecode.cond a.typecode, b.typecode target.new simplify.get.conditional(proc { a.simplify.get }, proc { b.simplify.get }) else Hornetseye::ElementWise(proc { |x,y,z| x.conditional y, z }, :conditional, proc { |t,u,v| t.cond u, v }). new(self, a, b).force end end |
- (Node) convolve(filter)
Convolution with other array of same dimension
616 617 618 619 620 621 |
# File 'lib/multiarray/operations.rb', line 616 def convolve( filter ) filter = Node.match( filter, typecode ).new filter unless filter.matched? array = self (dimension - filter.dimension).times { array = array.roll } array.table(filter) { |a,b| a * b }.diagonal { |s,x| s + x } end |
- (Node) decompose(i)
Decompose composite elements
This method decomposes composite elements into array.
703 704 705 |
# File 'lib/multiarray/node.rb', line 703 def decompose( i ) self end |
- (Node) dilate(n = 3)
Dilation
The dilation operation works on boolean as well as scalar values.
642 643 644 645 |
# File 'lib/multiarray/operations.rb', line 642 def dilate( n = 3 ) filter = Hornetseye::lazy( *( [ n ] * dimension ) ) { 0 } table( filter ) { |a,b| a }.diagonal { |m,x| m.major x } end |
- (Array<Integer>) dimension
Get dimension of this term
386 387 388 |
# File 'lib/multiarray/node.rb', line 386 def dimension shape.size end |
- (Node) downsample(*rate, options = {})
Downsampling of arrays
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
# File 'lib/multiarray/operations.rb', line 921 def downsample( *rate ) = rate.last.is_a?( Hash ) ? rate.pop : {} = { :offset => rate.collect { |r| r - 1 } }.merge offset = [ :offset ] if rate.size != dimension raise "#{rate.size} sampling rate(s) given but array has " + "#{dimension} dimension(s)" end if offset.size != dimension raise "#{offset.size} sampling offset(s) given but array has " + "#{dimension} dimension(s)" end ret_shape = ( 0 ... dimension ).collect do |i| ( shape[i] + rate[i] - 1 - offset[i] ).div rate[i] end field = ( 0 ... dimension ).collect do |i| Hornetseye::lazy( *ret_shape ) { |*args| args[i] * rate[i] + offset[i] } end warp *( field + [ :safe => false ] ) end |
- (Node) dup
Duplicate object
507 508 509 510 511 |
# File 'lib/multiarray/node.rb', line 507 def dup retval = Hornetseye::MultiArray(typecode, dimension).new *shape retval[] = self retval end |
- (Object) each(&action)
390 391 392 393 394 395 396 |
# File 'lib/multiarray/operations.rb', line 390 def each( &action ) if dimension > 0 shape.last.times { |i| element( INT.new( i ) ).each &action } else action.call demand.get end end |
- (Boolean) empty?
Check whether this object is an empty array
372 373 374 |
# File 'lib/multiarray/node.rb', line 372 def empty? size == 0 end |
- (Boolean) eq_with_multiarray(other)
Equality operator
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/multiarray/operations.rb', line 401 def eq_with_multiarray(other) if other.matched? if variables.empty? if other.typecode == typecode and other.shape == shape Hornetseye::finalise { eq(other).inject true, :and } else false end else eq_without_multiarray other end else false end end |
- (Node) erode(n = 3)
Erosion
The erosion operation works on boolean as well as scalar values.
630 631 632 633 |
# File 'lib/multiarray/operations.rb', line 630 def erode( n = 3 ) filter = Hornetseye::lazy( *( [ n ] * dimension ) ) { 0 } table( filter ) { |a,b| a }.diagonal { |m,x| m.minor x } end |
- (Node) fill!(value = typecode.default)
Fill array with a value
539 540 541 542 |
# File 'lib/multiarray/operations.rb', line 539 def fill!( value = typecode.default ) self[] = value self end |
- (Node) flip(*dimensions)
Mirror the array
863 864 865 866 867 868 869 870 871 872 |
# File 'lib/multiarray/operations.rb', line 863 def flip( *dimensions ) field = ( 0 ... dimension ).collect do |i| if dimensions.member? i Hornetseye::lazy( *shape ) { |*args| shape[i] - 1 - args[i] } else Hornetseye::lazy( *shape ) { |*args| args[i] } end end warp *( field + [ :safe => false ] ) end |
- (Node) fmod_with_float(other)
Modulo operation for floating point numbers
This operation takes account of the problem that '%' does not work with floating-point numbers in C.
122 123 124 125 126 127 128 129 |
# File 'lib/multiarray/operations.rb', line 122 def fmod_with_float( other ) other = Node.match( other, typecode ).new other unless other.matched? if typecode < FLOAT_ or other.typecode < FLOAT_ fmod other else fmod_without_float other end end |
- (Object) g=(value)
Assignment for green channel values of RGB array
580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/multiarray/rgb.rb', line 580 def g=(value) if typecode < RGB_ decompose( 1 )[] = value elsif typecode == OBJECT self[] = Hornetseye::lazy do r * RGB.new( 1, 0, 0 ) + value * RGB.new( 0, 1, 0 ) + b * RGB.new( 0, 0, 1 ) end else raise "Cannot assign green channel to elements of type #{typecode.inspect}" end end |
- (Node) g_with_decompose
Fast extraction for green channel of RGB array
563 564 565 566 567 568 569 570 571 |
# File 'lib/multiarray/rgb.rb', line 563 def g_with_decompose if typecode == OBJECT or is_a?(Variable) or Thread.current[:lazy] g_without_decompose elsif typecode < RGB_ decompose 1 else self end end |
- (Node) gauss_blur(sigma, max_error = 1.0 / 0x100)
Gaussian blur
666 667 668 669 670 671 672 673 |
# File 'lib/multiarray/operations.rb', line 666 def gauss_blur( sigma, max_error = 1.0 / 0x100 ) filter_type = DFLOAT.align typecode filter = Sequence[ *Array.gauss_blur_filter( sigma, max_error / dimension ) ]. to_type filter_type ( dimension - 1 ).downto( 0 ).inject self do |retval,i| retval.convolve filter end end |
- (Node) gauss_gradient(sigma, direction, max_error = 1.0 / 0x100)
Gauss gradient
682 683 684 685 686 687 688 689 690 691 692 693 694 |
# File 'lib/multiarray/operations.rb', line 682 def gauss_gradient( sigma, direction, max_error = 1.0 / 0x100 ) filter_type = DFLOAT.align typecode gradient = Sequence[ *Array.gauss_gradient_filter( sigma, max_error / dimension ) ]. to_type filter_type blur = Sequence[ *Array.gauss_blur_filter( sigma, max_error / dimension ) ]. to_type filter_type ( dimension - 1 ).downto( 0 ).inject self do |retval,i| filter = i == direction ? gradient : blur retval.convolve filter end.force end |
- (Integer) height
Get height of two-dimensional array
315 316 317 |
# File 'lib/multiarray/node.rb', line 315 def height shape[1] end |
- (Node) histogram(*ret_shape, options = {})
Compute histogram of this array
705 706 707 708 709 710 711 712 713 714 715 716 717 |
# File 'lib/multiarray/operations.rb', line 705 def histogram( *ret_shape ) = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {} = { :weight => UINT.new( 1 ), :safe => true }.merge unless [:weight].matched? [:weight] = Node.match([:weight]).maxint.new [:weight] end if ( shape.first != 1 or dimension == 1 ) and ret_shape.size == 1 [ self ].histogram *( ret_shape + [ ] ) else ( 0 ... shape.first ).collect { |i| unroll[i] }. histogram *( ret_shape + [ ] ) end end |
- (Node) histogram(*ret_shape, options = {})
Compute colour histogram of this array
The array is decomposed to its colour channels and a histogram is computed.
649 650 651 652 653 654 655 |
# File 'lib/multiarray/rgb.rb', line 649 def histogram_with_rgb( *ret_shape ) if typecode < RGB_ [ r, g, b ].histogram *ret_shape else histogram_without_rgb *ret_shape end end |
- (Object) if(&action)
Conditional operation
242 243 244 |
# File 'lib/multiarray/operations.rb', line 242 def if( &action ) simplify.get.if &action end |
- (Object) if_else(action1, action2)
Conditional operation
252 253 254 |
# File 'lib/multiarray/operations.rb', line 252 def if_else( action1, action2 ) simplify.get.if_else action1, action2 end |
- (Object) imag=(value)
Assignment for imaginary values of complex array
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
# File 'lib/multiarray/complex.rb', line 1039 def imag=(value) if typecode < COMPLEX_ decompose( 1 )[] = value elsif typecode == OBJECT self[] = Hornetseye::lazy do real + value * Complex::I end else raise "Cannot assign imaginary values to elements of type #{typecode.inspect}" end end |
- (Node) imag_with_decompose
Fast extraction of imaginary values of complex array
1022 1023 1024 1025 1026 1027 1028 1029 1030 |
# File 'lib/multiarray/complex.rb', line 1022 def imag_with_decompose if typecode == OBJECT or is_a?(Variable) or Thread.current[:lazy] imag_without_decompose elsif typecode < COMPLEX_ decompose 1 else Hornetseye::lazy( *shape ) { typecode.new( 0 ) } end end |
- (Object) inject(initial = nil, options = {}, &action) - (Object) inject(initial = nil, symbol)
Perform cummulative operation on array
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/multiarray/operations.rb', line 351 def inject(*args, &action) = args.last.is_a?(Hash) ? args.pop : {} unless action or [:block] unless [1, 2].member? args.size raise "Inject expected 1 or 2 arguments but got #{args.size}" end initial, symbol = args[-2], args[-1] action = proc { |a,b| a.send symbol, b } else raise "Inject expected 0 or 1 arguments but got #{args.size}" if args.size > 1 initial = args.empty? ? nil : args.first end unless initial.nil? initial = Node.match( initial ).new initial unless initial.matched? initial_typecode = initial.typecode else initial_typecode = typecode end var1 = [ :var1 ] || Variable.new( initial_typecode ) var2 = [ :var2 ] || Variable.new( typecode ) block = [ :block ] || action.call( var1, var2 ) if dimension == 0 if initial block.subst(var1 => initial, var2 => self).simplify else demand end else index = Variable.new Hornetseye::INDEX( nil ) value = element( index ).inject nil, :block => block, :var1 => var1, :var2 => var2 value = typecode.new value unless value.matched? if initial.nil? and index.size.get == 0 raise "Array was empty and no initial value for injection was given" end Inject.new( value, index, initial, block, var1, var2 ).force end end |
- (String) inspect(indent = nil, lines = nil)
Display information about this object
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/multiarray/node.rb', line 424 def inspect( indent = nil, lines = nil ) if variables.empty? if dimension == 0 and not indent "#{typecode.inspect}(#{force.inspect})" else if indent prepend = '' else prepend = "#{Hornetseye::MultiArray(typecode, dimension).inspect}:\n" indent = 0 lines = 0 end if empty? retval = '[]' else retval = '[ ' for i in 0 ... shape.last x = element i if x.dimension > 0 if i > 0 retval += ",\n " lines += 1 if lines >= 10 retval += '...' if indent == 0 break end retval += ' ' * indent end str = x.inspect indent + 1, lines lines += str.count "\n" retval += str if lines >= 10 retval += '...' if indent == 0 break end else retval += ', ' if i > 0 str = x.force.inspect if retval.size + str.size >= 74 - '...'.size - '[ ]'.size * indent.succ retval += '...' break else retval += str end end end retval += ' ]' unless lines >= 10 end prepend + retval end else to_s end end |
- (Node) integral
Compute integral image
764 765 766 767 768 769 770 771 772 773 |
# File 'lib/multiarray/operations.rb', line 764 def integral left = allocate block = Integral.new left, self if block.compilable? GCCFunction.run block else block.demand end left end |
- (Node) lut(table, options = {})
Perform element-wise lookup
726 727 728 729 730 731 732 |
# File 'lib/multiarray/operations.rb', line 726 def lut( table, = {} ) if ( shape.first != 1 or dimension == 1 ) and table.dimension == 1 [ self ].lut table, else ( 0 ... shape.first ).collect { |i| unroll[i] }.lut table, end end |
- (Node) lut_with_rgb(table, options = {})
Perform element-wise lookup with colour values
666 667 668 669 670 671 672 |
# File 'lib/multiarray/rgb.rb', line 666 def lut_with_rgb( table, = {} ) if typecode < RGB_ [ r, g, b ].lut table, else lut_without_rgb table, end end |
- (Node) mask(m)
Select values from array using a mask
810 811 812 813 814 815 816 817 818 819 820 821 822 823 |
# File 'lib/multiarray/operations.rb', line 810 def mask( m ) check_shape m left = MultiArray.new typecode, *( shape.first( dimension - m.dimension ) + [ m.size ] ) index = Hornetseye::Pointer( INT ).new index.store INT.new( 0 ) block = Mask.new left, self, m, index if block.compilable? GCCFunction.run block else block.demand end left[0 ... index[]].roll end |
- (Boolean) matched?
283 284 285 |
# File 'lib/multiarray/node.rb', line 283 def matched? true end |
- (Object) max(initial = nil)
Find maximum value of array
433 434 435 |
# File 'lib/multiarray/operations.rb', line 433 def max( initial = nil ) inject initial, :major end |
- (Object) mean
Compute average of array
454 455 456 |
# File 'lib/multiarray/operations.rb', line 454 def mean sum / size end |
- (Node) memorise
Duplicate array expression if it is not in row-major format
329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/multiarray/node.rb', line 329 def memorise if memory contiguous_strides = (0 ... dimension).collect do |i| shape[0 ... i].inject 1, :* end if strides == contiguous_strides self else dup end else dup end end |
- (Malloc, ...) memory
Get memory object
347 348 349 |
# File 'lib/multiarray/node.rb', line 347 def memory nil end |
- (Object) min(initial = nil)
Find minimum value of array
424 425 426 |
# File 'lib/multiarray/operations.rb', line 424 def min( initial = nil ) inject initial, :minor end |
- (Node) normalise(range = 0 .. 0xFF)
Normalise values of array
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/multiarray/operations.rb', line 477 def normalise( range = 0 .. 0xFF ) if range.exclude_end? raise "Normalisation does not support ranges with end value " + "excluded (such as #{range})" end lower, upper = min, max if lower.is_a? RGB or upper.is_a? RGB current = [ lower.r, lower.g, lower.b ].min .. [ upper.r, upper.g, upper.b ].max else current = min .. max end if current.last != current.first factor = ( range.last - range.first ).to_f / ( current.last - current.first ) collect { |x| x * factor + ( range.first - current.first * factor ) } else self + ( range.first - current.first ) end end |
- (Object) prod
Compute product of array
447 448 449 |
# File 'lib/multiarray/operations.rb', line 447 def prod Hornetseye::lazy { to_type typecode.maxint }.inject :* end |
- (Object) r=(value)
Assignment for red channel values of RGB array
548 549 550 551 552 553 554 555 556 557 558 |
# File 'lib/multiarray/rgb.rb', line 548 def r=(value) if typecode < RGB_ decompose( 0 )[] = value elsif typecode == OBJECT self[] = Hornetseye::lazy do value * RGB.new( 1, 0, 0 ) + g * RGB.new( 0, 1, 0 ) + b * RGB.new( 0, 0, 1 ) end else raise "Cannot assign red channel to elements of type #{typecode.inspect}" end end |
- (Node) r_with_decompose
Fast extraction for red channel of RGB array
531 532 533 534 535 536 537 538 539 |
# File 'lib/multiarray/rgb.rb', line 531 def r_with_decompose if typecode == OBJECT or is_a?(Variable) or Thread.current[:lazy] r_without_decompose elsif typecode < RGB_ decompose 0 else self end end |
- (Object) range(initial = nil)
Find range of values of array
461 462 463 |
# File 'lib/multiarray/operations.rb', line 461 def range( initial = nil ) min( initial ? initial.min : nil ) .. max( initial ? initial.max : nil ) end |
- (Object) real=(value)
Assignment for real values of complex array
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 |
# File 'lib/multiarray/complex.rb', line 1007 def real=(value) if typecode < COMPLEX_ decompose( 0 )[] = value elsif typecode == OBJECT self[] = Hornetseye::lazy do value + imag * Complex::I end else self[] = value end end |
- (Node) real_with_decompose
Fast extraction for real values of complex array
990 991 992 993 994 995 996 997 998 |
# File 'lib/multiarray/complex.rb', line 990 def real_with_decompose if typecode == OBJECT or is_a?(Variable) or Thread.current[:lazy] real_without_decompose elsif typecode < COMPLEX_ decompose 0 else self end end |
- (Node) reshape(*ret_shape)
Get array with same elements but different shape
The method returns an array with the same elements but with a different shape. The desired shape must have the same number of elements.
197 198 199 200 201 202 203 204 |
# File 'lib/multiarray/operations.rb', line 197 def reshape(*ret_shape) target_size = ret_shape.inject 1, :* if target_size != size raise "Target is of size #{target_size} but should be of size #{size}" end Hornetseye::MultiArray(typecode, ret_shape.size). new *(ret_shape + [:memory => memorise.memory]) end |
- (Boolean) rgb?
Check whether this object is an RGB value
393 394 395 |
# File 'lib/multiarray/node.rb', line 393 def rgb? typecode.rgb? end |
- (Node) roll(n = 1)
Cycle indices of array
294 295 296 297 298 299 300 301 302 |
# File 'lib/multiarray/operations.rb', line 294 def roll( n = 1 ) if n < 0 unroll -n else order = ( 0 ... dimension ).to_a n.times { order = order[ 1 .. -1 ] + [ order.first ] } transpose *order end end |
- (Array<Integer>) shape
Get shape of this term
379 380 381 |
# File 'lib/multiarray/node.rb', line 379 def shape self.class.shape end |
- (Node) shift(*offset)
Create array with shifted elements
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 |
# File 'lib/multiarray/operations.rb', line 879 def shift( *offset ) if offset.size != dimension raise "#{offset.size} offset(s) were given but array has " + "#{dimension} dimension(s)" end retval = Hornetseye::MultiArray(typecode, dimension).new *shape target, source, open, close = [], [], [], [] ( shape.size - 1 ).step( 0, -1 ) do |i| callcc do |pass| delta = offset[i] % shape[i] source[i] = 0 ... shape[i] - delta target[i] = delta ... shape[i] callcc do |c| open[i] = c pass.call end source[i] = shape[i] - delta ... shape[i] target[i] = 0 ... delta callcc do |c| open[i] = c pass.call end close[i].call end end retval[ *target ] = self[ *source ] for i in 0 ... shape.size callcc do |c| close[i] = c open[i].call end end retval end |
- (Integer) size
Get size (number of elements) of this value
322 323 324 |
# File 'lib/multiarray/node.rb', line 322 def size shape.inject 1, :* end |
- (Node) sobel(direction)
Sobel operator
652 653 654 655 656 657 658 |
# File 'lib/multiarray/operations.rb', line 652 def sobel( direction ) ( dimension - 1 ).downto( 0 ).inject self do |retval,i| filter = i == direction ? Hornetseye::Sequence(SINT)[1, 0, -1] : Hornetseye::Sequence(SINT)[1, 2, 1] Hornetseye::lazy { retval.convolve filter } end.force end |
- (Node) stretch(from = 0 .. 0xFF, to = 0 .. 0xFF)
Stretch values from one range to another
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
# File 'lib/multiarray/operations.rb', line 517 def stretch(from = 0 .. 0xFF, to = 0 .. 0xFF) if from.exclude_end? raise "Stretching does not support ranges with end value " + "excluded (such as #{from})" end if to.exclude_end? raise "Stretching does not support ranges with end value " + "excluded (such as #{to})" end if from.last != from.first factor = (to.last - to.first).to_f / (from.last - from.first) collect { |x| ((x - from.first) * factor).major(to.first).minor to.last } else (self <= from.first).conditional to.first, to.last end end |
- (Object) sum
Compute sum of array
440 441 442 |
# File 'lib/multiarray/operations.rb', line 440 def sum Hornetseye::lazy { to_type typecode.maxint }.inject :+ end |
- (Node) swap_rgb_with_scalar
Swapping colour channels for scalar values
627 628 629 630 631 632 633 |
# File 'lib/multiarray/rgb.rb', line 627 def swap_rgb_with_scalar if typecode == OBJECT or typecode < RGB_ swap_rgb_without_scalar else self end end |
- (Array<Object>) to_a
Convert to Ruby array of objects
Perform pending computations and convert native array to Ruby array of objects.
412 413 414 415 416 417 418 419 |
# File 'lib/multiarray/node.rb', line 412 def to_a if dimension == 0 force else n = shape.last ( 0 ... n ).collect { |i| element( i ).to_a } end end |
- (Node) to_type(dest)
Convert array elements to different element type
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/multiarray/operations.rb', line 138 def to_type(dest) if dimension == 0 and variables.empty? target = typecode.to_type dest target.new(simplify.get).simplify else key = "to_#{dest.to_s.downcase}" Hornetseye::ElementWise( proc { |x| x.to_type dest }, key, proc { |t| t.to_type dest } ).new(self).force end end |
- (Node) to_type_with_identity(dest)
Skip type conversion if it has no effect
This operation is a special case handling type conversions to the same type.
179 180 181 182 183 184 185 |
# File 'lib/multiarray/operations.rb', line 179 def to_type_with_identity( dest ) if dest == typecode self else to_type_without_identity dest end end |
- (Node) to_type_with_rgb(dest)
Convert RGB array to scalar array
This operation is a special case handling colour to greyscale conversion.
156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/multiarray/operations.rb', line 156 def to_type_with_rgb(dest) if typecode < RGB_ if dest < FLOAT_ lazy { r * 0.299 + g * 0.587 + b * 0.114 }.to_type dest elsif dest < INT_ lazy { (r * 0.299 + g * 0.587 + b * 0.114).round }.to_type dest else to_type_without_rgb dest end else to_type_without_rgb dest end end |
- (Node) transpose(*order)
Lazy transpose of array
Lazily compute transpose by swapping indices according to the specified order.
275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/multiarray/operations.rb', line 275 def transpose(*order) if (0 ... dimension).to_a != order.sort raise 'Each array index must be specified exactly once!' end term = self variables = shape.reverse.collect do |i| var = Variable.new Hornetseye::INDEX( i ) term = term.element var var end.reverse order.collect { |o| variables[o] }. inject(term) { |retval,var| Lambda.new var, retval } end |
- (Class) typecode
Element-type of this term
294 295 296 |
# File 'lib/multiarray/node.rb', line 294 def typecode self.class.typecode end |
- (Node) unmask(m, options = {})
Distribute values in a new array using a mask
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 |
# File 'lib/multiarray/operations.rb', line 834 def unmask( m, = {} ) = { :safe => true, :default => typecode.default }.merge default = [:default] default = typecode.new default unless default.matched? m.check_shape default if [ :safe ] if m.to_ubyte.sum > shape.last raise "#{m.to_ubyte.sum} value(s) of the mask are true but the last " + "dimension of the array for unmasking only has #{shape.last} value(s)" end end left = Hornetseye::MultiArray(typecode, dimension - 1 + m.dimension). coercion(default.typecode).new *(shape[1 .. -1] + m.shape) index = Hornetseye::Pointer(INT).new index.store INT.new(0) block = Unmask.new left, self, m, index, default if block.compilable? GCCFunction.run block else block.demand end left end |
- (Node) unroll(n = 1)
Reverse-cycle indices of array
309 310 311 312 313 314 315 316 317 |
# File 'lib/multiarray/operations.rb', line 309 def unroll( n = 1 ) if n < 0 roll -n else order = ( 0 ... dimension ).to_a n.times { order = [ order.last ] + order[ 0 ... -1 ] } transpose *order end end |
- (Node) warp(*field, options = {})
Warp an array
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
# File 'lib/multiarray/operations.rb', line 743 def warp( *field ) = field.last.is_a?( Hash ) ? field.pop : {} = { :safe => true, :default => typecode.default }.merge if [ :safe ] if field.size > dimension raise "Number of arrays for warp (#{field.size}) is greater than the " + "number of dimensions of source (#{dimension})" end Hornetseye::lazy do ( 0 ... field.size ). collect { |i| ( field[i] >= 0 ).and( field[i] < shape[i] ) }. inject :and end.conditional Lut.new( *( field + [ self ] ) ), [ :default ] else field.lut self, :safe => false end end |
- (Integer) width
Get width of two-dimensional array
308 309 310 |
# File 'lib/multiarray/node.rb', line 308 def width shape[0] end |