multiarray 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Makefile ADDED
@@ -0,0 +1,73 @@
1
+ .SUFFIXES:
2
+ .SUFFIXES: .gem .o .cc .hh .rb .tar .gz .bz2
3
+
4
+ RUBY_VERSION = 1.8
5
+ MULTIARRAY_VERSION = 0.2.0
6
+
7
+ CP = cp
8
+ RM = rm -f
9
+ MKDIR = mkdir -p
10
+ GEM = gem$(RUBY_VERSION)
11
+ RUBY = ruby$(RUBY_VERSION)
12
+ TAR = tar
13
+ GIT = git
14
+ SITELIBDIR = $(shell $(RUBY) -r mkmf -e "puts \"\#{Config::CONFIG['sitelibdir']}\"")
15
+
16
+ MAIN = Makefile source.gemspec README COPYING
17
+ LIB = $(wildcard lib/*.rb)
18
+ PKG_LIB = $(wildcard lib/multiarray/*.rb)
19
+ TEST = $(wildcard test/*.rb)
20
+ DOC = $(wildcard doc/*.rb)
21
+ SOURCES = $(MAIN) $(LIB) $(PKG_LIB) $(TEST) $(DOC)
22
+
23
+ all:: target
24
+
25
+ target::
26
+
27
+ gem:: multiarray-$(MULTIARRAY_VERSION).gem
28
+
29
+ install:: $(LIB) $(PKG_LIB)
30
+ $(MKDIR) $(SITELIBDIR)
31
+ $(MKDIR) $(SITELIBDIR)/multiarray
32
+ $(CP) $(LIB) $(SITELIBDIR)
33
+ $(CP) $(PKG_LIB) $(SITELIBDIR)/multiarray
34
+
35
+ uninstall::
36
+ $(RM) $(addprefix $(SITELIBDIR)/,$(notdir $(LIB))) $(addprefix $(SITELIBDIR)/multiarray/,$(notdir $(PKG_LIB)))
37
+
38
+ install-gem:: multiarray-$(MULTIARRAY_VERSION).gem
39
+ $(GEM) install --local $<
40
+
41
+ uninstall-gem::
42
+ $(GEM) uninstall multiarray || echo Nothing to uninstall
43
+
44
+ check:: $(LIB) $(PKG_LIB) $(TEST)
45
+ $(RUBY) -rrubygems -Ilib -Itest test/ts_multiarray.rb
46
+
47
+ push-gem:: multiarray-$(MULTIARRAY_VERSION).gem
48
+ echo Pushing $< in 3 seconds!
49
+ sleep 3
50
+ $(GEM) push $<
51
+
52
+ push-git::
53
+ echo Pushing to origin in 3 seconds!
54
+ sleep 3
55
+ $(GIT) push origin master
56
+
57
+ dist:: dist-gzip
58
+
59
+ dist-gzip:: multiarray-$(MULTIARRAY_VERSION).tar.gz
60
+
61
+ dist-bzip2:: multiarray-$(MULTIARRAY_VERSION).tar.bz2
62
+
63
+ multiarray-$(MULTIARRAY_VERSION).gem: $(SOURCES)
64
+ $(GEM) build source.gemspec
65
+
66
+ multiarray-$(MULTIARRAY_VERSION).tar.gz: $(SOURCES)
67
+ $(TAR) czf $@ $(SOURCES)
68
+
69
+ multiarray-$(MULTIARRAY_VERSION).tar.bz2: $(SOURCES)
70
+ $(TAR) cjf $@ $(SOURCES)
71
+
72
+ clean::
73
+ rm -f *~ lib/*~ lib/multiarray/*~ test/*~ doc/*~ *.gem
data/README ADDED
@@ -0,0 +1 @@
1
+ This Ruby-extension defines Hornetseye::MultiArray and other native datatypes. Hornetseye::MultiArray provides multi-dimensional Ruby arrays with elements of same type. The extension is designed to be mostly compatible with Masahiro Tanaka's NArray. However it allows the definition of custom element types and operations on them. This work was also inspired by Ronald Garcia's boost::multi_array and by Todd Veldhuizen's Blitz++.
data/lib/multiarray.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'malloc'
2
+ require 'multiarray/storage'
3
+ require 'multiarray/list'
4
+ require 'multiarray/memory'
5
+ require 'multiarray/type_operation'
6
+ require 'multiarray/type'
7
+ require 'multiarray/descriptortype'
8
+ require 'multiarray/int'
9
+ require 'multiarray/composite_type'
10
+ require 'multiarray/sequence_operation'
11
+ require 'multiarray/sequence'
12
+ require 'multiarray/multiarray'
13
+
14
+ class Proc
15
+
16
+ unless method_defined? :bind
17
+ def bind( object )
18
+ block, time = self, Time.now
19
+ ( class << object; self end ).class_eval do
20
+ method_name = "__bind_#{time.to_i}_#{time.usec}"
21
+ define_method method_name, &block
22
+ method = instance_method method_name
23
+ remove_method method_name
24
+ method
25
+ end.bind object
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ class Object
32
+
33
+ unless method_defined? :instance_exec
34
+ def instance_exec( *arguments, &block )
35
+ block.bind( self )[ *arguments ]
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,34 @@
1
+ module Hornetseye
2
+
3
+ class CompositeType < Type
4
+
5
+ class << self
6
+
7
+ attr_accessor :element_type
8
+ attr_accessor :num_elements
9
+
10
+ def memory
11
+ element_type.memory
12
+ end
13
+
14
+ def bytesize
15
+ element_type.bytesize * num_elements
16
+ end
17
+
18
+ def basetype
19
+ element_type.basetype
20
+ end
21
+
22
+ end
23
+
24
+ def element_type
25
+ self.class.element_type
26
+ end
27
+
28
+ def num_elements
29
+ self.class.num_elements
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,19 @@
1
+ module Hornetseye
2
+
3
+ class DescriptorType < Type
4
+
5
+ class << self
6
+
7
+ def pack( value )
8
+ [ value ].pack descriptor
9
+ end
10
+
11
+ def unpack( value )
12
+ value.unpack( descriptor ).first
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,97 @@
1
+ module Hornetseye
2
+
3
+ class INT_ < DescriptorType
4
+
5
+ class << self
6
+
7
+ attr_accessor :bits
8
+ attr_accessor :signed
9
+
10
+ def memory
11
+ Memory
12
+ end
13
+
14
+ def bytesize
15
+ bits / 8
16
+ end
17
+
18
+ def default
19
+ 0
20
+ end
21
+
22
+ def inspect
23
+ to_s
24
+ end
25
+
26
+ def to_s
27
+ case [ bits, signed ]
28
+ when [ 8, true ]
29
+ 'BYTE'
30
+ when [ 8, false ]
31
+ 'UBYTE'
32
+ when [ 16, true ]
33
+ 'SINT'
34
+ when [ 16, false ]
35
+ 'USINT'
36
+ when [ 32, true ]
37
+ 'INT'
38
+ when [ 32, false ]
39
+ 'UINT'
40
+ when [ 64, true ]
41
+ 'LONG'
42
+ when [ 64, false ]
43
+ 'ULONG'
44
+ else
45
+ "INT(#{bits.to_s},#{ signed ? "SIGNED" : "UNSIGNED" })"
46
+ end
47
+ end
48
+
49
+ def descriptor
50
+ case [ bits, signed ]
51
+ when [ 8, true ]
52
+ 'c'
53
+ when [ 8, false ]
54
+ 'C'
55
+ when [ 16, true ]
56
+ 's'
57
+ when [ 16, false ]
58
+ 'S'
59
+ when [ 32, true ]
60
+ 'i'
61
+ when [ 32, false ]
62
+ 'I'
63
+ when [ 64, true ]
64
+ 'q'
65
+ when [ 64, false ]
66
+ 'Q'
67
+ else
68
+ raise "No descriptor for packing/unpacking #{self}"
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ UNSIGNED = false
77
+ SIGNED = true
78
+
79
+ def INT( bits, signed )
80
+ retval = Class.new INT_
81
+ retval.bits = bits
82
+ retval.signed = signed
83
+ retval
84
+ end
85
+
86
+ module_function :INT
87
+
88
+ BYTE = INT 8, SIGNED
89
+ UBYTE = INT 8, UNSIGNED
90
+ SINT = INT 16, SIGNED
91
+ USINT = INT 16, UNSIGNED
92
+ INT = INT 32, SIGNED
93
+ UINT = INT 32, UNSIGNED
94
+ LONG = INT 64, SIGNED
95
+ ULONG = INT 64, UNSIGNED
96
+
97
+ end
@@ -0,0 +1,48 @@
1
+ module Hornetseye
2
+
3
+ class List < Storage
4
+
5
+ class << self
6
+
7
+ def alloc( size )
8
+ List.new Array.new( size )
9
+ end
10
+
11
+ def import( arr )
12
+ List.new arr
13
+ end
14
+
15
+ end
16
+
17
+ attr_accessor :offset
18
+
19
+ def initialize( arr )
20
+ super arr
21
+ @offset = 0
22
+ end
23
+
24
+ def load( typecode )
25
+ @data[ @offset ]
26
+ end
27
+
28
+ def store( typecode, value )
29
+ @data[ @offset ] = value
30
+ end
31
+
32
+ def import( data )
33
+ @data[ @offset ... @offset + data.size ] = data
34
+ end
35
+
36
+ def export( size )
37
+ @data[ @offset ... @offset + size ]
38
+ end
39
+
40
+ def +( offset )
41
+ retval = List.new @data
42
+ retval.offset = @offset + offset
43
+ retval
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,45 @@
1
+ module Hornetseye
2
+
3
+ class Memory < Storage
4
+
5
+ class << self
6
+
7
+ def alloc( bytesize )
8
+ Memory.new Malloc.new( bytesize )
9
+ end
10
+
11
+ def import( str )
12
+ retval = alloc str.bytesize
13
+ retval.import str
14
+ retval
15
+ end
16
+
17
+ end
18
+
19
+ def initialize( ptr )
20
+ super ptr
21
+ end
22
+
23
+ def load( typecode )
24
+ typecode.unpack export( typecode.bytesize )
25
+ end
26
+
27
+ def store( typecode, value )
28
+ import typecode.pack( value )
29
+ end
30
+
31
+ def import( data )
32
+ @data.write data
33
+ end
34
+
35
+ def export( bytesize )
36
+ @data.read bytesize
37
+ end
38
+
39
+ def +( offset )
40
+ Memory.new @data + offset
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,13 @@
1
+ module Hornetseye
2
+
3
+ def MultiArray( element_type, *shape )
4
+ if shape.empty?
5
+ element_type
6
+ else
7
+ MultiArray Sequence( element_type, shape.first ), *shape[ 1 .. -1 ]
8
+ end
9
+ end
10
+
11
+ module_function :MultiArray
12
+
13
+ end
@@ -0,0 +1,139 @@
1
+ module Hornetseye
2
+
3
+ class Sequence_ < CompositeType
4
+
5
+ class << self
6
+
7
+ attr_accessor :stride
8
+
9
+ def inspect
10
+ to_s
11
+ end
12
+
13
+ def default
14
+ retval = new
15
+ retval.set
16
+ retval
17
+ end
18
+
19
+ def to_s
20
+ "Sequence(#{element_type.to_s},#{num_elements.to_s})"
21
+ end
22
+
23
+ def typecode
24
+ element_type.typecode
25
+ end
26
+
27
+ def empty?
28
+ num_elements == 0
29
+ end
30
+
31
+ def shape
32
+ element_type.shape + [ num_elements ]
33
+ end
34
+
35
+ end
36
+
37
+ def stride
38
+ self.class.stride
39
+ end
40
+
41
+ def inspect( indent = nil, lines = nil )
42
+ if indent
43
+ prepend = ''
44
+ else
45
+ prepend = "#{self.class.inspect}:\n"
46
+ indent = 0
47
+ lines = 0
48
+ end
49
+ if empty?
50
+ retval = '[]'
51
+ else
52
+ retval = '[ '
53
+ for i in 0 ... num_elements
54
+ x = at i
55
+ if x.is_a? Sequence_
56
+ if i > 0
57
+ retval += ",\n "
58
+ lines += 1
59
+ if lines >= 10
60
+ retval += '...' if indent == 0
61
+ break
62
+ end
63
+ retval += ' ' * indent
64
+ end
65
+ str = x.inspect indent + 1, lines
66
+ lines += str.count "\n"
67
+ retval += str
68
+ if lines >= 10
69
+ retval += '...' if indent == 0
70
+ break
71
+ end
72
+ else
73
+ retval += ', ' if i > 0
74
+ str = x.inspect
75
+ if retval.size + str.size >= 74 - '...'.size -
76
+ '[ ]'.size * indent.succ
77
+ retval += '...'
78
+ break
79
+ else
80
+ retval += str
81
+ end
82
+ end
83
+ end
84
+ retval += ' ]' unless lines >= 10
85
+ end
86
+ prepend + retval
87
+ end
88
+
89
+ def to_a
90
+ ( 0 ... num_elements ).collect do |i|
91
+ x = at i
92
+ x.is_a?( Sequence_ ) ? x.to_a : x
93
+ end
94
+ end
95
+
96
+ def set( value = typecode.default )
97
+ if value.is_a? Array
98
+ for i in 0 ... num_elements
99
+ assign i, i < value.size ? value[ i ] : typecode.default
100
+ end
101
+ else
102
+ op( value ) { |x| set x }
103
+ end
104
+ value
105
+ end
106
+
107
+ def get
108
+ self
109
+ end
110
+
111
+ def sel( *indices )
112
+ if indices.empty?
113
+ super *indices
114
+ else
115
+ unless ( 0 ... num_elements ).member? indices.last
116
+ raise "Index must be in 0 ... #{num_elements} " +
117
+ "(was #{indices.last.inspect})"
118
+ end
119
+ element_memory = @memory + indices.last * stride * typecode.bytesize
120
+ element_type.new( :memory => element_memory ).sel *indices[ 0 ... -1 ]
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ Sequence_.class_eval { include SequenceOperation }
127
+
128
+ def Sequence( element_type, num_elements,
129
+ stride = element_type.size )
130
+ retval = Class.new Sequence_
131
+ retval.element_type = element_type
132
+ retval.num_elements = num_elements
133
+ retval.stride = stride
134
+ retval
135
+ end
136
+
137
+ module_function :Sequence
138
+
139
+ end