xnd 0.2.0dev3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|