multiarray 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +679 -0
- data/Makefile +73 -0
- data/README +1 -0
- data/lib/multiarray.rb +39 -0
- data/lib/multiarray/composite_type.rb +34 -0
- data/lib/multiarray/descriptortype.rb +19 -0
- data/lib/multiarray/int.rb +97 -0
- data/lib/multiarray/list.rb +48 -0
- data/lib/multiarray/memory.rb +45 -0
- data/lib/multiarray/multiarray.rb +13 -0
- data/lib/multiarray/sequence.rb +139 -0
- data/lib/multiarray/sequence_operation.rb +17 -0
- data/lib/multiarray/storage.rb +13 -0
- data/lib/multiarray/type.rb +108 -0
- data/lib/multiarray/type_operation.rb +12 -0
- data/source.gemspec +23 -0
- data/test/tc_int.rb +116 -0
- data/test/tc_sequence.rb +126 -0
- data/test/ts_multiarray.rb +4 -0
- metadata +85 -0
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,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,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
|