xnd 0.2.0dev3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +3 -0
- data/History.md +0 -0
- data/README.md +7 -0
- data/Rakefile +135 -0
- data/ext/ruby_xnd/extconf.rb +70 -0
- data/ext/ruby_xnd/float_pack_unpack.c +277 -0
- data/ext/ruby_xnd/float_pack_unpack.h +39 -0
- data/ext/ruby_xnd/gc_guard.c +36 -0
- data/ext/ruby_xnd/gc_guard.h +12 -0
- data/ext/ruby_xnd/include/xnd.h +449 -0
- data/ext/ruby_xnd/lib/libxnd.a +0 -0
- data/ext/ruby_xnd/lib/libxnd.so +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
- data/ext/ruby_xnd/memory_block_object.c +32 -0
- data/ext/ruby_xnd/memory_block_object.h +33 -0
- data/ext/ruby_xnd/ruby_xnd.c +1953 -0
- data/ext/ruby_xnd/ruby_xnd.h +61 -0
- data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
- data/ext/ruby_xnd/util.h +170 -0
- data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
- data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
- data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
- data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
- data/ext/ruby_xnd/xnd/Makefile.in +80 -0
- data/ext/ruby_xnd/xnd/README.rst +44 -0
- data/ext/ruby_xnd/xnd/config.guess +1530 -0
- data/ext/ruby_xnd/xnd/config.h.in +22 -0
- data/ext/ruby_xnd/xnd/config.sub +1782 -0
- data/ext/ruby_xnd/xnd/configure +4867 -0
- data/ext/ruby_xnd/xnd/configure.ac +164 -0
- data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
- data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
- data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
- data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
- data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
- data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
- data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
- data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
- data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
- data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
- data/ext/ruby_xnd/xnd/install-sh +527 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
- data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
- data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
- data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
- data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
- data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
- data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
- data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
- data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
- data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
- data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
- data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
- data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
- data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
- data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
- data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
- data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
- data/ext/ruby_xnd/xnd/setup.py +303 -0
- data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
- data/lib/ruby_xnd.so +0 -0
- data/lib/xnd.rb +306 -0
- data/lib/xnd/monkeys.rb +29 -0
- data/lib/xnd/version.rb +6 -0
- data/spec/debug_spec.rb +9 -0
- data/spec/gc_guard_spec.rb +10 -0
- data/spec/leakcheck.rb +9 -0
- data/spec/spec_helper.rb +877 -0
- data/spec/type_inference_spec.rb +81 -0
- data/spec/xnd_spec.rb +2921 -0
- data/xnd.gemspec +47 -0
- metadata +215 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
@ECHO OFF
|
2
|
+
echo.
|
3
|
+
<nul (set /p x="Running static library tests ... ")
|
4
|
+
echo.
|
5
|
+
echo.
|
6
|
+
dist32\runtest.exe
|
7
|
+
IF ERRORLEVEL 1 echo FAIL
|
8
|
+
echo.
|
9
|
+
<nul (set /p x="Running shared library tests ... ")
|
10
|
+
echo.
|
11
|
+
echo.
|
12
|
+
copy /y ..\ndtypes\libndtypes\libndtypes-0.2.0dev3.dll dist32
|
13
|
+
dist32\runtest_shared.exe
|
14
|
+
IF ERRORLEVEL 1 echo FAIL
|
15
|
+
|
16
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
@ECHO OFF
|
2
|
+
echo.
|
3
|
+
<nul (set /p x="Running static library tests ... ")
|
4
|
+
echo.
|
5
|
+
echo.
|
6
|
+
dist64\runtest.exe
|
7
|
+
IF ERRORLEVEL 1 echo FAIL
|
8
|
+
echo.
|
9
|
+
<nul (set /p x="Running shared library tests ... ")
|
10
|
+
echo.
|
11
|
+
echo.
|
12
|
+
copy /y ..\ndtypes\libndtypes\libndtypes-0.2.0dev3.dll dist64
|
13
|
+
dist64\runtest_shared.exe
|
14
|
+
IF ERRORLEVEL 1 echo FAIL
|
@@ -0,0 +1,29 @@
|
|
1
|
+
@ECHO off
|
2
|
+
|
3
|
+
if not exist dist32 mkdir dist32
|
4
|
+
if exist dist32\* del /q dist32\*
|
5
|
+
|
6
|
+
cd ..\libxnd
|
7
|
+
copy /y Makefile.vc Makefile
|
8
|
+
|
9
|
+
nmake /nologo clean
|
10
|
+
nmake /nologo
|
11
|
+
|
12
|
+
copy /y libxnd-0.2.0dev3.lib ..\vcbuild\dist32
|
13
|
+
copy /y libxnd-0.2.0dev3.dll ..\vcbuild\dist32
|
14
|
+
copy /y libxnd-0.2.0dev3.dll.lib ..\vcbuild\dist32
|
15
|
+
copy /y libxnd-0.2.0dev3.dll.exp ..\vcbuild\dist32
|
16
|
+
copy /y xnd.h ..\vcbuild\dist32
|
17
|
+
|
18
|
+
cd tests
|
19
|
+
copy /y Makefile.vc Makefile
|
20
|
+
nmake /nologo clean
|
21
|
+
nmake /nologo
|
22
|
+
|
23
|
+
copy /y runtest.exe ..\..\vcbuild\dist32
|
24
|
+
copy /y runtest_shared.exe ..\..\vcbuild\dist32
|
25
|
+
|
26
|
+
cd ..\..\vcbuild
|
27
|
+
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
@ECHO off
|
2
|
+
|
3
|
+
if not exist dist64 mkdir dist64
|
4
|
+
if exist dist64\* del /q dist64\*
|
5
|
+
|
6
|
+
cd ..\libxnd
|
7
|
+
copy /y Makefile.vc Makefile
|
8
|
+
|
9
|
+
nmake /nologo clean
|
10
|
+
nmake /nologo
|
11
|
+
|
12
|
+
copy /y libxnd-0.2.0dev3.lib ..\vcbuild\dist64
|
13
|
+
copy /y libxnd-0.2.0dev3.dll ..\vcbuild\dist64
|
14
|
+
copy /y libxnd-0.2.0dev3.dll.lib ..\vcbuild\dist64
|
15
|
+
copy /y libxnd-0.2.0dev3.dll.exp ..\vcbuild\dist64
|
16
|
+
copy /y xnd.h ..\vcbuild\dist64
|
17
|
+
|
18
|
+
cd tests
|
19
|
+
copy /y Makefile.vc Makefile
|
20
|
+
nmake /nologo clean
|
21
|
+
nmake /nologo
|
22
|
+
|
23
|
+
copy /y runtest.exe ..\..\vcbuild\dist64
|
24
|
+
copy /y runtest_shared.exe ..\..\vcbuild\dist64
|
25
|
+
|
26
|
+
cd ..\..\vcbuild
|
27
|
+
|
28
|
+
|
29
|
+
|
data/lib/ruby_xnd.so
ADDED
Binary file
|
data/lib/xnd.rb
ADDED
@@ -0,0 +1,306 @@
|
|
1
|
+
# BSD 3-Clause License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2018, Quansight and Sameer Deshmukh
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# * Neither the name of the copyright holder nor the names of its
|
17
|
+
# contributors may be used to endorse or promote products derived from
|
18
|
+
# this software without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
require 'ndtypes'
|
32
|
+
require "ruby_xnd.so"
|
33
|
+
|
34
|
+
require 'xnd/monkeys'
|
35
|
+
require 'xnd/version'
|
36
|
+
|
37
|
+
INF = Float::INFINITY
|
38
|
+
|
39
|
+
class RubyXND
|
40
|
+
class Ellipsis
|
41
|
+
def to_s
|
42
|
+
"..."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class XND < RubyXND
|
48
|
+
# Immutable array type used when specifying XND tuples without wanting to
|
49
|
+
# specify the type. It is highly recommended to simply specify the type
|
50
|
+
# and use Ruby Arrays for specifying the data.
|
51
|
+
#
|
52
|
+
# If you call #to_a or #value on XND after specifying data as XND::T, note
|
53
|
+
# that XND will return the data in the form of Ruby Arrays.
|
54
|
+
#
|
55
|
+
# The sole purpose for the existence of this class is the facilitation of
|
56
|
+
# type inference. Before passing to the C interface, all instaces of XND::T
|
57
|
+
# will be converted into Ruby Arrays.
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
#
|
61
|
+
# x = XND.new XND::T.new([])
|
62
|
+
# #=> XND([], type: ())
|
63
|
+
class T
|
64
|
+
include Enumerable
|
65
|
+
attr_reader :data
|
66
|
+
|
67
|
+
def initialize *args, &block
|
68
|
+
@data = args
|
69
|
+
end
|
70
|
+
|
71
|
+
def each &block
|
72
|
+
@data.each(&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def map &block
|
76
|
+
@data.map(&block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def map! &block
|
80
|
+
@data.map!(&block)
|
81
|
+
end
|
82
|
+
|
83
|
+
def [] *index
|
84
|
+
@data[index]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
MAX_DIM = NDTypes::MAX_DIM
|
89
|
+
|
90
|
+
# Methods for type inference.
|
91
|
+
module TypeInference
|
92
|
+
class << self
|
93
|
+
# Infer the type of a Ruby value. In general, types should be explicitly
|
94
|
+
# specified.
|
95
|
+
def type_of value, dtype: nil
|
96
|
+
NDTypes.new actual_type_of(value, dtype: dtype)
|
97
|
+
end
|
98
|
+
|
99
|
+
def actual_type_of value, dtype: nil
|
100
|
+
ret = nil
|
101
|
+
if value.is_a?(Array)
|
102
|
+
data, shapes = data_shapes value
|
103
|
+
opt = data.include? nil
|
104
|
+
|
105
|
+
if dtype.nil?
|
106
|
+
if data.nil?
|
107
|
+
dtype = 'float64'
|
108
|
+
else
|
109
|
+
dtype = choose_dtype(data)
|
110
|
+
|
111
|
+
data.each do |x|
|
112
|
+
if !x.nil?
|
113
|
+
t = actual_type_of(x)
|
114
|
+
if t != dtype
|
115
|
+
raise ValueError, "dtype mismatch: have t=#{t} and dtype=#{dtype}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
dtype = '?' + dtype if opt
|
122
|
+
end
|
123
|
+
|
124
|
+
t = dtype
|
125
|
+
var = shapes.map { |lst| lst.uniq.size > 1 || nil }.any?
|
126
|
+
shapes.each do |lst|
|
127
|
+
opt = lst.include? nil
|
128
|
+
lst.map! { |x| x.nil? ? 0 : x }
|
129
|
+
t = add_dim(opt: opt, shapes: lst, typ: t, use_var: var)
|
130
|
+
end
|
131
|
+
|
132
|
+
ret = t
|
133
|
+
elsif !dtype.nil?
|
134
|
+
raise TypeError, "dtype argument is only supported for Arrays."
|
135
|
+
elsif value.is_a? Hash
|
136
|
+
if value.keys.all? { |k| k.is_a?(String) }
|
137
|
+
ret = "{" + value.map { |k, v| "#{k} : #{actual_type_of(v)}"}.join(", ") + "}"
|
138
|
+
else
|
139
|
+
raise ValueError, "all hash keys must be String."
|
140
|
+
end
|
141
|
+
elsif value.is_a? XND::T # tuple
|
142
|
+
ret = "(" + value.map { |v| actual_type_of(v) }.join(",") + ")"
|
143
|
+
elsif value.nil?
|
144
|
+
ret = '?float64'
|
145
|
+
elsif value.is_a? Float
|
146
|
+
ret = 'float64'
|
147
|
+
elsif value.is_a? Complex
|
148
|
+
ret = 'complex128'
|
149
|
+
elsif value.is_a? Integer
|
150
|
+
ret = 'int64'
|
151
|
+
elsif value.is_a? String
|
152
|
+
ret = value.encoding == Encoding::ASCII_8BIT ? 'bytes' : 'string'
|
153
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
154
|
+
ret = 'bool'
|
155
|
+
else
|
156
|
+
raise ArgumentError, "cannot infer data type for: #{value}"
|
157
|
+
end
|
158
|
+
|
159
|
+
ret
|
160
|
+
end
|
161
|
+
|
162
|
+
def accumulate arr
|
163
|
+
result = []
|
164
|
+
arr.inject(0) do |memo, a|
|
165
|
+
result << memo + a
|
166
|
+
memo + a
|
167
|
+
end
|
168
|
+
|
169
|
+
result
|
170
|
+
end
|
171
|
+
|
172
|
+
# Construct a new dimension type based on the list of 'shapes' that
|
173
|
+
# are present in a dimension.
|
174
|
+
def add_dim *args, opt: false, shapes: nil, typ: nil, use_var: false
|
175
|
+
if use_var
|
176
|
+
offsets = [0] + accumulate(shapes)
|
177
|
+
return "#{opt ? '?' : ''}var(offsets=#{offsets}) * #{typ}"
|
178
|
+
else
|
179
|
+
n = shapes.uniq.size
|
180
|
+
shape = (n == 0 ? 0 : shapes[0])
|
181
|
+
return "#{shape} * #{typ}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Internal function for extracting the data and dimensions of nested arrays.
|
186
|
+
def search level, data, acc, minmax
|
187
|
+
raise(ValueError, "too many dimensions: #{level}") if level > MAX_DIM
|
188
|
+
|
189
|
+
current = acc[level]
|
190
|
+
if data.nil?
|
191
|
+
current << data
|
192
|
+
elsif data.is_a?(Array)
|
193
|
+
current << data.size
|
194
|
+
next_level = level + 1
|
195
|
+
minmax[1] = [next_level, minmax[1]].max
|
196
|
+
|
197
|
+
if !data
|
198
|
+
minmax[0] = [next_level, minmax[0]].min
|
199
|
+
else
|
200
|
+
data.each do |item|
|
201
|
+
search level+1, item, acc, minmax
|
202
|
+
end
|
203
|
+
end
|
204
|
+
else
|
205
|
+
acc[minmax[1]] << data
|
206
|
+
minmax[0] = [level, minmax[0]].min
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Extract array data and dimension shapes from a nested Array. The
|
211
|
+
# Array may contain nil for missing data or dimensions.
|
212
|
+
#
|
213
|
+
# @example
|
214
|
+
# data_shapes [[0, 1], [2, 3, 4], [5, 6, 7, 8]]
|
215
|
+
# #=> [[0, 1, 2, 3, 4, 5, 6, 7, 8], [[2, 3, 4], [3]]]
|
216
|
+
# # ^ ^ ^
|
217
|
+
# # | | `--- ndim=2: single shape 3
|
218
|
+
# # | `-- ndim=1: shapes 2, 3, 4
|
219
|
+
# # `--- ndim=0: extracted array data
|
220
|
+
def data_shapes tree
|
221
|
+
acc = Array.new(MAX_DIM + 1) { [] }
|
222
|
+
min_level = MAX_DIM + 1
|
223
|
+
max_level = 0
|
224
|
+
minmax = [min_level, max_level]
|
225
|
+
|
226
|
+
search max_level, tree, acc, minmax
|
227
|
+
|
228
|
+
min_level = minmax[0]
|
229
|
+
max_level = minmax[1]
|
230
|
+
|
231
|
+
if acc[max_level] && acc[max_level].all? { |a| a.nil? }
|
232
|
+
# min_level is not set in this special case. Hence the check.
|
233
|
+
elsif min_level != max_level
|
234
|
+
raise ValueError, "unbalanced tree: min depth #{min_level} and max depth #{max_level}"
|
235
|
+
end
|
236
|
+
|
237
|
+
data = acc[max_level]
|
238
|
+
shapes = acc[0...max_level].reverse
|
239
|
+
|
240
|
+
[data, shapes]
|
241
|
+
end
|
242
|
+
|
243
|
+
def choose_dtype array
|
244
|
+
array.each do |x|
|
245
|
+
return actual_type_of(x) if !x.nil?
|
246
|
+
end
|
247
|
+
|
248
|
+
'float64'
|
249
|
+
end
|
250
|
+
|
251
|
+
def convert_xnd_t_to_ruby_array data
|
252
|
+
if data.is_a?(XND::T)
|
253
|
+
data.map! do |d|
|
254
|
+
convert_xnd_t_to_ruby_array d
|
255
|
+
end
|
256
|
+
|
257
|
+
return data.data
|
258
|
+
elsif data.is_a? Hash
|
259
|
+
data.each do |k, v|
|
260
|
+
data[k] = convert_xnd_t_to_ruby_array v
|
261
|
+
end
|
262
|
+
elsif data.is_a? Array
|
263
|
+
data.map! do |d|
|
264
|
+
convert_xnd_t_to_ruby_array d
|
265
|
+
end
|
266
|
+
else
|
267
|
+
return data
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def initialize data, type: nil, dtype: nil, levels: nil, typedef: nil, dtypedef: nil
|
274
|
+
if [type, dtype, levels, typedef, dtypedef].count(nil) < 2
|
275
|
+
raise ArgumentError, "the 'type', 'dtype', 'levels' and 'typedef' arguments are "
|
276
|
+
"mutually exclusive."
|
277
|
+
end
|
278
|
+
|
279
|
+
if type
|
280
|
+
type = NDTypes.new(type) if type.is_a? String
|
281
|
+
elsif dtype
|
282
|
+
type = TypeInference.type_of data, dtype: dtype
|
283
|
+
elsif levels
|
284
|
+
args = levels.map { |l| l ? l : 'NA' }.join(', ')
|
285
|
+
t = "#{value.size} * categorical(#{args})"
|
286
|
+
type = NDTypes.new t
|
287
|
+
elsif typedef
|
288
|
+
type = NDTypes.new typedef
|
289
|
+
if type.abstract?
|
290
|
+
dtype = type.hidden_dtype
|
291
|
+
t = TypeInference.type_of data, dtype: dtype
|
292
|
+
type = NDTypes.instantiate typedef, t
|
293
|
+
end
|
294
|
+
elsif dtypedef
|
295
|
+
dtype = NDTypes.new dtypedef
|
296
|
+
type = TypeInference.type_of data, dtype: dtype
|
297
|
+
else
|
298
|
+
type = TypeInference.type_of data
|
299
|
+
data = TypeInference.convert_xnd_t_to_ruby_array data
|
300
|
+
end
|
301
|
+
|
302
|
+
super(type, data)
|
303
|
+
end
|
304
|
+
|
305
|
+
alias :to_a :value
|
306
|
+
end
|
data/lib/xnd/monkeys.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
class String
|
2
|
+
# Force encode string to ASCII-8BIT.
|
3
|
+
#
|
4
|
+
# Reference: https://idiosyncratic-ruby.com/56-us-ascii-8bit.html
|
5
|
+
# FIXME: Hopefully find a better way of doing this soon.
|
6
|
+
def b
|
7
|
+
self.force_encoding "ASCII-8BIT"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Encode string as UTF-16.
|
11
|
+
def u16!
|
12
|
+
self.encode! Encoding::UTF_16
|
13
|
+
end
|
14
|
+
|
15
|
+
# Encode string as UTF-16.
|
16
|
+
def u16
|
17
|
+
self.encode Encoding::UTF_16
|
18
|
+
end
|
19
|
+
|
20
|
+
# Encode string as UTF-32.
|
21
|
+
def u32!
|
22
|
+
self.encode! Encoding::UTF_32
|
23
|
+
end
|
24
|
+
|
25
|
+
# Encode string as UTF-32.
|
26
|
+
def u32
|
27
|
+
self.encode Encoding::UTF_32
|
28
|
+
end
|
29
|
+
end
|