rapydscript-ns 0.8.0
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.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,2101 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# License: Apache License 2.0
|
|
4
|
+
# numpy-like numerical array library for RapydScript
|
|
5
|
+
# Provides ndarray class and ~120 numpy-compatible functions.
|
|
6
|
+
###########################################################
|
|
7
|
+
|
|
8
|
+
# -------------------------------------------------------
|
|
9
|
+
# Module constants
|
|
10
|
+
# -------------------------------------------------------
|
|
11
|
+
nan = NaN
|
|
12
|
+
inf = Infinity
|
|
13
|
+
pi = Math.PI
|
|
14
|
+
e = Math.E
|
|
15
|
+
newaxis = None
|
|
16
|
+
|
|
17
|
+
# -------------------------------------------------------
|
|
18
|
+
# Internal helpers (no ndarray dependency)
|
|
19
|
+
# -------------------------------------------------------
|
|
20
|
+
def _coerce(val, dtype):
|
|
21
|
+
if dtype is 'int32':
|
|
22
|
+
return Math.trunc(+val)
|
|
23
|
+
elif dtype is 'bool':
|
|
24
|
+
return bool(val)
|
|
25
|
+
return +val
|
|
26
|
+
|
|
27
|
+
def _compute_size(shape):
|
|
28
|
+
s = 1
|
|
29
|
+
for d in shape:
|
|
30
|
+
s *= d
|
|
31
|
+
return s
|
|
32
|
+
|
|
33
|
+
def _compute_strides(shape):
|
|
34
|
+
n = shape.length
|
|
35
|
+
if n is 0:
|
|
36
|
+
return []
|
|
37
|
+
strides = []
|
|
38
|
+
for i in range(n):
|
|
39
|
+
strides.push(1)
|
|
40
|
+
i = n - 2
|
|
41
|
+
while i >= 0:
|
|
42
|
+
strides[i] = strides[i + 1] * shape[i + 1]
|
|
43
|
+
i -= 1
|
|
44
|
+
return strides
|
|
45
|
+
|
|
46
|
+
def _get_shape(obj):
|
|
47
|
+
if not Array.isArray(obj):
|
|
48
|
+
return []
|
|
49
|
+
if obj.length is 0:
|
|
50
|
+
return [0]
|
|
51
|
+
inner = _get_shape(obj[0])
|
|
52
|
+
result = [obj.length]
|
|
53
|
+
for s in inner:
|
|
54
|
+
result.push(s)
|
|
55
|
+
return result
|
|
56
|
+
|
|
57
|
+
def _flatten_to(obj, out):
|
|
58
|
+
if Array.isArray(obj):
|
|
59
|
+
for item in obj:
|
|
60
|
+
_flatten_to(item, out)
|
|
61
|
+
else:
|
|
62
|
+
out.push(obj)
|
|
63
|
+
|
|
64
|
+
def _make_filled(size, val, dtype):
|
|
65
|
+
cv = _coerce(val, dtype)
|
|
66
|
+
data = []
|
|
67
|
+
for i in range(size):
|
|
68
|
+
data.push(cv)
|
|
69
|
+
return data
|
|
70
|
+
|
|
71
|
+
# --- List reduction helpers ---
|
|
72
|
+
def _sum_list(data):
|
|
73
|
+
s = 0
|
|
74
|
+
for v in data:
|
|
75
|
+
s += v
|
|
76
|
+
return s
|
|
77
|
+
|
|
78
|
+
def _prod_list(data):
|
|
79
|
+
p = 1
|
|
80
|
+
for v in data:
|
|
81
|
+
p *= v
|
|
82
|
+
return p
|
|
83
|
+
|
|
84
|
+
def _min_list(data):
|
|
85
|
+
m = data[0]
|
|
86
|
+
for v in data:
|
|
87
|
+
if v < m:
|
|
88
|
+
m = v
|
|
89
|
+
return m
|
|
90
|
+
|
|
91
|
+
def _max_list(data):
|
|
92
|
+
m = data[0]
|
|
93
|
+
for v in data:
|
|
94
|
+
if v > m:
|
|
95
|
+
m = v
|
|
96
|
+
return m
|
|
97
|
+
|
|
98
|
+
def _mean_list(data):
|
|
99
|
+
return _sum_list(data) / data.length
|
|
100
|
+
|
|
101
|
+
def _var_list(data, ddof):
|
|
102
|
+
m = _mean_list(data)
|
|
103
|
+
s = 0
|
|
104
|
+
for v in data:
|
|
105
|
+
d = v - m
|
|
106
|
+
s += d * d
|
|
107
|
+
return s / (data.length - ddof)
|
|
108
|
+
|
|
109
|
+
def _std_list(data, ddof):
|
|
110
|
+
return Math.sqrt(_var_list(data, ddof))
|
|
111
|
+
|
|
112
|
+
def _argmin_list(data):
|
|
113
|
+
m = data[0]
|
|
114
|
+
idx = 0
|
|
115
|
+
for i in range(data.length):
|
|
116
|
+
if data[i] < m:
|
|
117
|
+
m = data[i]
|
|
118
|
+
idx = i
|
|
119
|
+
return idx
|
|
120
|
+
|
|
121
|
+
def _argmax_list(data):
|
|
122
|
+
m = data[0]
|
|
123
|
+
idx = 0
|
|
124
|
+
for i in range(data.length):
|
|
125
|
+
if data[i] > m:
|
|
126
|
+
m = data[i]
|
|
127
|
+
idx = i
|
|
128
|
+
return idx
|
|
129
|
+
|
|
130
|
+
def _broadcast_shapes(s1, s2):
|
|
131
|
+
n1 = s1.length
|
|
132
|
+
n2 = s2.length
|
|
133
|
+
n = Math.max(n1, n2)
|
|
134
|
+
result = []
|
|
135
|
+
for i in range(n):
|
|
136
|
+
d1 = 1
|
|
137
|
+
d2 = 1
|
|
138
|
+
if n1 - n + i >= 0:
|
|
139
|
+
d1 = s1[n1 - n + i]
|
|
140
|
+
if n2 - n + i >= 0:
|
|
141
|
+
d2 = s2[n2 - n + i]
|
|
142
|
+
if d1 is 1:
|
|
143
|
+
result.push(d2)
|
|
144
|
+
elif d2 is 1:
|
|
145
|
+
result.push(d1)
|
|
146
|
+
elif d1 is d2:
|
|
147
|
+
result.push(d1)
|
|
148
|
+
else:
|
|
149
|
+
raise ValueError("operands could not be broadcast together")
|
|
150
|
+
return result
|
|
151
|
+
|
|
152
|
+
# -------------------------------------------------------
|
|
153
|
+
# ndarray class
|
|
154
|
+
# -------------------------------------------------------
|
|
155
|
+
class ndarray:
|
|
156
|
+
def __init__(self, shape, dtype='float64', data=None, _nocopy=False):
|
|
157
|
+
if jstype(shape) is 'number':
|
|
158
|
+
shape = [int(shape)]
|
|
159
|
+
elif not Array.isArray(shape):
|
|
160
|
+
shape = list(shape)
|
|
161
|
+
self.shape = shape
|
|
162
|
+
self.dtype = dtype or 'float64'
|
|
163
|
+
self.ndim = shape.length
|
|
164
|
+
self.size = _compute_size(shape)
|
|
165
|
+
self.strides = _compute_strides(shape)
|
|
166
|
+
if data is not None:
|
|
167
|
+
if _nocopy:
|
|
168
|
+
self._data = data
|
|
169
|
+
else:
|
|
170
|
+
self._data = data.slice()
|
|
171
|
+
else:
|
|
172
|
+
self._data = _make_filled(self.size, 0, self.dtype)
|
|
173
|
+
self._update_indices()
|
|
174
|
+
|
|
175
|
+
def _update_indices(self):
|
|
176
|
+
if self.ndim is 1:
|
|
177
|
+
for i in range(self.size):
|
|
178
|
+
self[i] = self._data[i]
|
|
179
|
+
elif self.ndim >= 2:
|
|
180
|
+
row_shape = self.shape.slice(1)
|
|
181
|
+
row_size = _compute_size(row_shape)
|
|
182
|
+
for i in range(self.shape[0]):
|
|
183
|
+
row_data = self._data.slice(i * row_size, (i + 1) * row_size)
|
|
184
|
+
row = ndarray(row_shape, self.dtype, row_data, True)
|
|
185
|
+
self[i] = row
|
|
186
|
+
|
|
187
|
+
def __len__(self):
|
|
188
|
+
return self.shape[0] if self.ndim > 0 else 0
|
|
189
|
+
|
|
190
|
+
def __repr__(self):
|
|
191
|
+
return 'array(' + str(self.tolist()) + ')'
|
|
192
|
+
|
|
193
|
+
def __str__(self):
|
|
194
|
+
return self.__repr__()
|
|
195
|
+
|
|
196
|
+
def tolist(self):
|
|
197
|
+
if self.ndim is 0:
|
|
198
|
+
return self._data[0]
|
|
199
|
+
elif self.ndim is 1:
|
|
200
|
+
return self._data.slice()
|
|
201
|
+
else:
|
|
202
|
+
result = []
|
|
203
|
+
row_shape = self.shape.slice(1)
|
|
204
|
+
row_size = _compute_size(row_shape)
|
|
205
|
+
for i in range(self.shape[0]):
|
|
206
|
+
row_data = self._data.slice(i * row_size, (i + 1) * row_size)
|
|
207
|
+
row = ndarray(row_shape, self.dtype, row_data, True)
|
|
208
|
+
result.push(row.tolist())
|
|
209
|
+
return result
|
|
210
|
+
|
|
211
|
+
def item(self, *args):
|
|
212
|
+
if args.length is 0:
|
|
213
|
+
if self.size is 1:
|
|
214
|
+
return self._data[0]
|
|
215
|
+
raise IndexError("can only convert an array of size 1 to a Python scalar")
|
|
216
|
+
flat_idx = 0
|
|
217
|
+
for k in range(args.length):
|
|
218
|
+
flat_idx += args[k] * self.strides[k]
|
|
219
|
+
return self._data[flat_idx]
|
|
220
|
+
|
|
221
|
+
def itemset(self, *args):
|
|
222
|
+
val = args[args.length - 1]
|
|
223
|
+
flat_idx = 0
|
|
224
|
+
for k in range(args.length - 1):
|
|
225
|
+
flat_idx += args[k] * self.strides[k]
|
|
226
|
+
self._data[flat_idx] = _coerce(val, self.dtype)
|
|
227
|
+
if self.ndim is 1:
|
|
228
|
+
self[flat_idx] = self._data[flat_idx]
|
|
229
|
+
|
|
230
|
+
def copy(self):
|
|
231
|
+
return ndarray(self.shape.slice(), self.dtype, self._data.slice(), True)
|
|
232
|
+
|
|
233
|
+
def astype(self, dtype):
|
|
234
|
+
new_data = []
|
|
235
|
+
for v in self._data:
|
|
236
|
+
new_data.push(_coerce(v, dtype))
|
|
237
|
+
return ndarray(self.shape.slice(), dtype, new_data, True)
|
|
238
|
+
|
|
239
|
+
def reshape(self, *new_shape):
|
|
240
|
+
if new_shape.length is 1 and Array.isArray(new_shape[0]):
|
|
241
|
+
ns = new_shape[0].slice()
|
|
242
|
+
else:
|
|
243
|
+
ns = list(new_shape)
|
|
244
|
+
neg_idx = -1
|
|
245
|
+
known = 1
|
|
246
|
+
for i in range(ns.length):
|
|
247
|
+
if ns[i] < 0:
|
|
248
|
+
neg_idx = i
|
|
249
|
+
else:
|
|
250
|
+
known *= ns[i]
|
|
251
|
+
if neg_idx >= 0:
|
|
252
|
+
ns[neg_idx] = self.size // known
|
|
253
|
+
return ndarray(ns, self.dtype, self._data.slice(), True)
|
|
254
|
+
|
|
255
|
+
def ravel(self):
|
|
256
|
+
return ndarray([self.size], self.dtype, self._data.slice(), True)
|
|
257
|
+
|
|
258
|
+
def flatten(self):
|
|
259
|
+
return ndarray([self.size], self.dtype, self._data.slice(), True)
|
|
260
|
+
|
|
261
|
+
def transpose(self, axes=None):
|
|
262
|
+
if self.ndim is 1:
|
|
263
|
+
return ndarray(self.shape.slice(), self.dtype, self._data.slice(), True)
|
|
264
|
+
if axes is None:
|
|
265
|
+
axes = []
|
|
266
|
+
for i in range(self.ndim - 1, -1, -1):
|
|
267
|
+
axes.push(i)
|
|
268
|
+
new_shape = []
|
|
269
|
+
for ax in axes:
|
|
270
|
+
new_shape.push(self.shape[ax])
|
|
271
|
+
new_data = []
|
|
272
|
+
for i in range(self.size):
|
|
273
|
+
new_data.push(0)
|
|
274
|
+
t_strides = _compute_strides(new_shape)
|
|
275
|
+
for flat_i in range(self.size):
|
|
276
|
+
remaining = flat_i
|
|
277
|
+
src_flat = 0
|
|
278
|
+
for d in range(self.ndim):
|
|
279
|
+
coord = Math.floor(remaining / t_strides[d])
|
|
280
|
+
remaining = remaining % t_strides[d]
|
|
281
|
+
src_flat += coord * self.strides[axes[d]]
|
|
282
|
+
new_data[flat_i] = self._data[src_flat]
|
|
283
|
+
return ndarray(new_shape, self.dtype, new_data, True)
|
|
284
|
+
|
|
285
|
+
def sum(self, axis=None, keepdims=False):
|
|
286
|
+
return _reduce(self, axis, _sum_list, keepdims)
|
|
287
|
+
|
|
288
|
+
def prod(self, axis=None, keepdims=False):
|
|
289
|
+
return _reduce(self, axis, _prod_list, keepdims)
|
|
290
|
+
|
|
291
|
+
def min(self, axis=None):
|
|
292
|
+
return _reduce(self, axis, _min_list, False)
|
|
293
|
+
|
|
294
|
+
def max(self, axis=None):
|
|
295
|
+
return _reduce(self, axis, _max_list, False)
|
|
296
|
+
|
|
297
|
+
def mean(self, axis=None):
|
|
298
|
+
return _reduce(self, axis, _mean_list, False)
|
|
299
|
+
|
|
300
|
+
def std(self, axis=None, ddof=0):
|
|
301
|
+
captured_ddof = ddof
|
|
302
|
+
return _reduce(self, axis, def(data): return _std_list(data, captured_ddof);, False)
|
|
303
|
+
|
|
304
|
+
def variance(self, axis=None, ddof=0):
|
|
305
|
+
captured_ddof = ddof
|
|
306
|
+
return _reduce(self, axis, def(data): return _var_list(data, captured_ddof);, False)
|
|
307
|
+
|
|
308
|
+
def argmin(self, axis=None):
|
|
309
|
+
return _reduce(self, axis, _argmin_list, False)
|
|
310
|
+
|
|
311
|
+
def argmax(self, axis=None):
|
|
312
|
+
return _reduce(self, axis, _argmax_list, False)
|
|
313
|
+
|
|
314
|
+
def clip(self, a_min, a_max):
|
|
315
|
+
new_data = []
|
|
316
|
+
for v in self._data:
|
|
317
|
+
new_data.push(Math.min(Math.max(v, a_min), a_max))
|
|
318
|
+
return ndarray(self.shape.slice(), self.dtype, new_data, True)
|
|
319
|
+
|
|
320
|
+
def cumsum(self, axis=None):
|
|
321
|
+
data = self._data
|
|
322
|
+
result = []
|
|
323
|
+
s = 0
|
|
324
|
+
for v in data:
|
|
325
|
+
s += v
|
|
326
|
+
result.push(s)
|
|
327
|
+
return ndarray([result.length], self.dtype, result, True)
|
|
328
|
+
|
|
329
|
+
def cumprod(self, axis=None):
|
|
330
|
+
data = self._data
|
|
331
|
+
result = []
|
|
332
|
+
p = 1
|
|
333
|
+
for v in data:
|
|
334
|
+
p *= v
|
|
335
|
+
result.push(p)
|
|
336
|
+
return ndarray([result.length], self.dtype, result, True)
|
|
337
|
+
|
|
338
|
+
def squeeze(self, axis=None):
|
|
339
|
+
if axis is None:
|
|
340
|
+
new_shape = []
|
|
341
|
+
for d in self.shape:
|
|
342
|
+
if d is not 1:
|
|
343
|
+
new_shape.push(d)
|
|
344
|
+
if new_shape.length is 0:
|
|
345
|
+
new_shape = [1]
|
|
346
|
+
else:
|
|
347
|
+
new_shape = []
|
|
348
|
+
for i in range(self.shape.length):
|
|
349
|
+
if i is axis and self.shape[i] is 1:
|
|
350
|
+
pass
|
|
351
|
+
else:
|
|
352
|
+
new_shape.push(self.shape[i])
|
|
353
|
+
return ndarray(new_shape, self.dtype, self._data.slice(), True)
|
|
354
|
+
|
|
355
|
+
def T(self):
|
|
356
|
+
return self.transpose()
|
|
357
|
+
|
|
358
|
+
# -------------------------------------------------------
|
|
359
|
+
# Standalone helpers that use ndarray
|
|
360
|
+
# -------------------------------------------------------
|
|
361
|
+
def _reduce(arr, axis, fn, keepdims):
|
|
362
|
+
if axis is None:
|
|
363
|
+
result = fn(arr._data)
|
|
364
|
+
if keepdims:
|
|
365
|
+
shape = []
|
|
366
|
+
for i in range(arr.ndim):
|
|
367
|
+
shape.push(1)
|
|
368
|
+
return ndarray(shape, arr.dtype, [result], True)
|
|
369
|
+
return result
|
|
370
|
+
if axis < 0:
|
|
371
|
+
axis = arr.ndim + axis
|
|
372
|
+
out_shape = []
|
|
373
|
+
for i in range(arr.ndim):
|
|
374
|
+
if i is axis:
|
|
375
|
+
if keepdims:
|
|
376
|
+
out_shape.push(1)
|
|
377
|
+
else:
|
|
378
|
+
out_shape.push(arr.shape[i])
|
|
379
|
+
if out_shape.length is 0:
|
|
380
|
+
out_shape = [1]
|
|
381
|
+
out_size = _compute_size(out_shape)
|
|
382
|
+
out_data = []
|
|
383
|
+
out_strides = _compute_strides(out_shape)
|
|
384
|
+
for out_flat in range(out_size):
|
|
385
|
+
remaining = out_flat
|
|
386
|
+
out_multi = []
|
|
387
|
+
for d in range(out_shape.length):
|
|
388
|
+
coord = Math.floor(remaining / out_strides[d])
|
|
389
|
+
remaining = remaining % out_strides[d]
|
|
390
|
+
out_multi.push(coord)
|
|
391
|
+
slice_data = []
|
|
392
|
+
for j in range(arr.shape[axis]):
|
|
393
|
+
src_flat = 0
|
|
394
|
+
out_idx = 0
|
|
395
|
+
for d in range(arr.ndim):
|
|
396
|
+
if d is axis:
|
|
397
|
+
src_flat += j * arr.strides[d]
|
|
398
|
+
else:
|
|
399
|
+
if keepdims:
|
|
400
|
+
src_flat += out_multi[d] * arr.strides[d]
|
|
401
|
+
else:
|
|
402
|
+
src_flat += out_multi[out_idx] * arr.strides[d]
|
|
403
|
+
out_idx += 1
|
|
404
|
+
slice_data.push(arr._data[src_flat])
|
|
405
|
+
out_data.push(fn(slice_data))
|
|
406
|
+
return ndarray(out_shape, arr.dtype, out_data, True)
|
|
407
|
+
|
|
408
|
+
def _broadcast_to_flat(arr, target_shape):
|
|
409
|
+
target_size = _compute_size(target_shape)
|
|
410
|
+
target_strides = _compute_strides(target_shape)
|
|
411
|
+
result = []
|
|
412
|
+
target_ndim = target_shape.length
|
|
413
|
+
src_ndim = arr.ndim
|
|
414
|
+
for i in range(target_size):
|
|
415
|
+
remaining = i
|
|
416
|
+
src_flat = 0
|
|
417
|
+
for d in range(target_ndim):
|
|
418
|
+
coord = Math.floor(remaining / target_strides[d])
|
|
419
|
+
remaining = remaining % target_strides[d]
|
|
420
|
+
src_d = d - (target_ndim - src_ndim)
|
|
421
|
+
if src_d >= 0:
|
|
422
|
+
if arr.shape[src_d] > 1:
|
|
423
|
+
src_flat += coord * arr.strides[src_d]
|
|
424
|
+
result.push(arr._data[src_flat])
|
|
425
|
+
return result
|
|
426
|
+
|
|
427
|
+
def _apply_ufunc(a, fn):
|
|
428
|
+
a = asarray(a)
|
|
429
|
+
result_data = []
|
|
430
|
+
for v in a._data:
|
|
431
|
+
result_data.push(fn(v))
|
|
432
|
+
return ndarray(a.shape.slice(), a.dtype, result_data, True)
|
|
433
|
+
|
|
434
|
+
def _apply_ufunc2(a, b, fn):
|
|
435
|
+
a = asarray(a)
|
|
436
|
+
b = asarray(b)
|
|
437
|
+
bs = _broadcast_shapes(a.shape, b.shape)
|
|
438
|
+
same_a = a.shape.join(',') is bs.join(',')
|
|
439
|
+
same_b = b.shape.join(',') is bs.join(',')
|
|
440
|
+
if same_a and same_b:
|
|
441
|
+
result_data = []
|
|
442
|
+
for i in range(a.size):
|
|
443
|
+
result_data.push(fn(a._data[i], b._data[i]))
|
|
444
|
+
return ndarray(bs, 'float64', result_data, True)
|
|
445
|
+
a_data = _broadcast_to_flat(a, bs)
|
|
446
|
+
b_data = _broadcast_to_flat(b, bs)
|
|
447
|
+
result_data = []
|
|
448
|
+
for i in range(a_data.length):
|
|
449
|
+
result_data.push(fn(a_data[i], b_data[i]))
|
|
450
|
+
return ndarray(bs, 'float64', result_data, True)
|
|
451
|
+
|
|
452
|
+
# -------------------------------------------------------
|
|
453
|
+
# asarray / array (must be after ndarray class)
|
|
454
|
+
# -------------------------------------------------------
|
|
455
|
+
def asarray(a, dtype=None):
|
|
456
|
+
if isinstance(a, ndarray):
|
|
457
|
+
if dtype and dtype is not a.dtype:
|
|
458
|
+
return a.astype(dtype)
|
|
459
|
+
return a
|
|
460
|
+
if Array.isArray(a):
|
|
461
|
+
shp = _get_shape(a)
|
|
462
|
+
data = []
|
|
463
|
+
_flatten_to(a, data)
|
|
464
|
+
dt = dtype or 'float64'
|
|
465
|
+
coerced = []
|
|
466
|
+
for v in data:
|
|
467
|
+
coerced.push(_coerce(v, dt))
|
|
468
|
+
return ndarray(shp, dt, coerced, True)
|
|
469
|
+
# scalar
|
|
470
|
+
dt = dtype or 'float64'
|
|
471
|
+
return ndarray([1], dt, [_coerce(a, dt)], True)
|
|
472
|
+
|
|
473
|
+
def array(object, dtype=None):
|
|
474
|
+
return asarray(object, dtype)
|
|
475
|
+
|
|
476
|
+
# -------------------------------------------------------
|
|
477
|
+
# Array creation
|
|
478
|
+
# -------------------------------------------------------
|
|
479
|
+
def zeros(shape, dtype='float64'):
|
|
480
|
+
if jstype(shape) is 'number':
|
|
481
|
+
shape = [int(shape)]
|
|
482
|
+
elif not Array.isArray(shape):
|
|
483
|
+
shape = list(shape)
|
|
484
|
+
return ndarray(shape, dtype or 'float64')
|
|
485
|
+
|
|
486
|
+
def ones(shape, dtype='float64'):
|
|
487
|
+
if jstype(shape) is 'number':
|
|
488
|
+
shape = [int(shape)]
|
|
489
|
+
elif not Array.isArray(shape):
|
|
490
|
+
shape = list(shape)
|
|
491
|
+
dt = dtype or 'float64'
|
|
492
|
+
sz = _compute_size(shape)
|
|
493
|
+
data = _make_filled(sz, 1, dt)
|
|
494
|
+
return ndarray(shape, dt, data, True)
|
|
495
|
+
|
|
496
|
+
def empty(shape, dtype='float64'):
|
|
497
|
+
return zeros(shape, dtype)
|
|
498
|
+
|
|
499
|
+
def full(shape, fill_value, dtype=None):
|
|
500
|
+
if jstype(shape) is 'number':
|
|
501
|
+
shape = [int(shape)]
|
|
502
|
+
elif not Array.isArray(shape):
|
|
503
|
+
shape = list(shape)
|
|
504
|
+
dt = dtype or 'float64'
|
|
505
|
+
sz = _compute_size(shape)
|
|
506
|
+
data = _make_filled(sz, fill_value, dt)
|
|
507
|
+
return ndarray(shape, dt, data, True)
|
|
508
|
+
|
|
509
|
+
def arange(start, stop=None, step=1, dtype=None):
|
|
510
|
+
if stop is None:
|
|
511
|
+
stop = start
|
|
512
|
+
start = 0
|
|
513
|
+
if step is 0:
|
|
514
|
+
raise ValueError("arange: step cannot be zero")
|
|
515
|
+
data = []
|
|
516
|
+
x = start
|
|
517
|
+
if step > 0:
|
|
518
|
+
while x < stop:
|
|
519
|
+
data.push(x)
|
|
520
|
+
x += step
|
|
521
|
+
else:
|
|
522
|
+
while x > stop:
|
|
523
|
+
data.push(x)
|
|
524
|
+
x += step
|
|
525
|
+
dt = dtype or 'float64'
|
|
526
|
+
coerced = []
|
|
527
|
+
for v in data:
|
|
528
|
+
coerced.push(_coerce(v, dt))
|
|
529
|
+
return ndarray([coerced.length], dt, coerced, True)
|
|
530
|
+
|
|
531
|
+
def linspace(start, stop, num=50, endpoint=True, dtype=None):
|
|
532
|
+
if num < 0:
|
|
533
|
+
raise ValueError("linspace: num must be >= 0")
|
|
534
|
+
data = []
|
|
535
|
+
if num is 0:
|
|
536
|
+
return ndarray([0], dtype or 'float64', [], True)
|
|
537
|
+
if num is 1:
|
|
538
|
+
data.push(start)
|
|
539
|
+
else:
|
|
540
|
+
denom = endpoint and (num - 1) or num
|
|
541
|
+
for i in range(num):
|
|
542
|
+
data.push(start + i * (stop - start) / denom)
|
|
543
|
+
dt = dtype or 'float64'
|
|
544
|
+
coerced = []
|
|
545
|
+
for v in data:
|
|
546
|
+
coerced.push(_coerce(v, dt))
|
|
547
|
+
return ndarray([coerced.length], dt, coerced, True)
|
|
548
|
+
|
|
549
|
+
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
|
|
550
|
+
lin = linspace(start, stop, num, endpoint)
|
|
551
|
+
data = []
|
|
552
|
+
for v in lin._data:
|
|
553
|
+
data.push(Math.pow(base, v))
|
|
554
|
+
dt = dtype or 'float64'
|
|
555
|
+
coerced = []
|
|
556
|
+
for v in data:
|
|
557
|
+
coerced.push(_coerce(v, dt))
|
|
558
|
+
return ndarray([coerced.length], dt, coerced, True)
|
|
559
|
+
|
|
560
|
+
def eye(N, M=None, k=0, dtype='float64'):
|
|
561
|
+
if M is None:
|
|
562
|
+
M = N
|
|
563
|
+
dt = dtype or 'float64'
|
|
564
|
+
data = []
|
|
565
|
+
for i in range(N):
|
|
566
|
+
for j in range(M):
|
|
567
|
+
if j - i is k:
|
|
568
|
+
data.push(_coerce(1, dt))
|
|
569
|
+
else:
|
|
570
|
+
data.push(_coerce(0, dt))
|
|
571
|
+
return ndarray([N, M], dt, data, True)
|
|
572
|
+
|
|
573
|
+
def zeros_like(a, dtype=None):
|
|
574
|
+
a = asarray(a)
|
|
575
|
+
dt = dtype or a.dtype
|
|
576
|
+
data = _make_filled(a.size, 0, dt)
|
|
577
|
+
return ndarray(a.shape.slice(), dt, data, True)
|
|
578
|
+
|
|
579
|
+
def ones_like(a, dtype=None):
|
|
580
|
+
a = asarray(a)
|
|
581
|
+
dt = dtype or a.dtype
|
|
582
|
+
data = _make_filled(a.size, 1, dt)
|
|
583
|
+
return ndarray(a.shape.slice(), dt, data, True)
|
|
584
|
+
|
|
585
|
+
def full_like(a, fill_value, dtype=None):
|
|
586
|
+
a = asarray(a)
|
|
587
|
+
dt = dtype or a.dtype
|
|
588
|
+
data = _make_filled(a.size, fill_value, dt)
|
|
589
|
+
return ndarray(a.shape.slice(), dt, data, True)
|
|
590
|
+
|
|
591
|
+
# -------------------------------------------------------
|
|
592
|
+
# Array manipulation
|
|
593
|
+
# -------------------------------------------------------
|
|
594
|
+
def reshape(a, newshape):
|
|
595
|
+
a = asarray(a)
|
|
596
|
+
return a.reshape(newshape)
|
|
597
|
+
|
|
598
|
+
def ravel(a):
|
|
599
|
+
a = asarray(a)
|
|
600
|
+
return a.ravel()
|
|
601
|
+
|
|
602
|
+
def transpose(a, axes=None):
|
|
603
|
+
a = asarray(a)
|
|
604
|
+
return a.transpose(axes)
|
|
605
|
+
|
|
606
|
+
def concatenate(arrays, axis=0):
|
|
607
|
+
arrs = [asarray(x) for x in arrays]
|
|
608
|
+
if arrs.length is 0:
|
|
609
|
+
raise ValueError("concatenate: need at least one array")
|
|
610
|
+
if axis < 0:
|
|
611
|
+
axis = arrs[0].ndim + axis
|
|
612
|
+
# Only handles 1D and 2D
|
|
613
|
+
if arrs[0].ndim is 1 and axis is 0:
|
|
614
|
+
data = []
|
|
615
|
+
for a in arrs:
|
|
616
|
+
for v in a._data:
|
|
617
|
+
data.push(v)
|
|
618
|
+
return ndarray([data.length], arrs[0].dtype, data, True)
|
|
619
|
+
# 2D along axis 0 (vertical)
|
|
620
|
+
if axis is 0:
|
|
621
|
+
data = []
|
|
622
|
+
new_rows = 0
|
|
623
|
+
cols = arrs[0].shape[1]
|
|
624
|
+
for a in arrs:
|
|
625
|
+
new_rows += a.shape[0]
|
|
626
|
+
for v in a._data:
|
|
627
|
+
data.push(v)
|
|
628
|
+
return ndarray([new_rows, cols], arrs[0].dtype, data, True)
|
|
629
|
+
# 2D along axis 1 (horizontal)
|
|
630
|
+
if axis is 1:
|
|
631
|
+
rows = arrs[0].shape[0]
|
|
632
|
+
new_cols = 0
|
|
633
|
+
for a in arrs:
|
|
634
|
+
new_cols += a.shape[1]
|
|
635
|
+
data = []
|
|
636
|
+
for i in range(rows):
|
|
637
|
+
for a in arrs:
|
|
638
|
+
c = a.shape[1]
|
|
639
|
+
row_start = i * c
|
|
640
|
+
for j in range(c):
|
|
641
|
+
data.push(a._data[row_start + j])
|
|
642
|
+
return ndarray([rows, new_cols], arrs[0].dtype, data, True)
|
|
643
|
+
raise ValueError("concatenate: axis out of bounds")
|
|
644
|
+
|
|
645
|
+
def stack(arrays, axis=0):
|
|
646
|
+
arrs = [asarray(x) for x in arrays]
|
|
647
|
+
n = arrs.length
|
|
648
|
+
orig_shape = arrs[0].shape
|
|
649
|
+
if axis < 0:
|
|
650
|
+
axis = orig_shape.length + 1 + axis
|
|
651
|
+
new_shape = []
|
|
652
|
+
for i in range(orig_shape.length):
|
|
653
|
+
if i is axis:
|
|
654
|
+
new_shape.push(n)
|
|
655
|
+
new_shape.push(orig_shape[i])
|
|
656
|
+
if axis is orig_shape.length:
|
|
657
|
+
new_shape.push(n)
|
|
658
|
+
data = []
|
|
659
|
+
elem_size = _compute_size(orig_shape)
|
|
660
|
+
for i in range(n):
|
|
661
|
+
for v in arrs[i]._data:
|
|
662
|
+
data.push(v)
|
|
663
|
+
a = ndarray(new_shape, arrs[0].dtype, data, True)
|
|
664
|
+
return a
|
|
665
|
+
|
|
666
|
+
def hstack(tup):
|
|
667
|
+
arrs = [asarray(x) for x in tup]
|
|
668
|
+
if arrs[0].ndim is 1:
|
|
669
|
+
return concatenate(arrs, 0)
|
|
670
|
+
return concatenate(arrs, 1)
|
|
671
|
+
|
|
672
|
+
def vstack(tup):
|
|
673
|
+
arrs = [asarray(x) for x in tup]
|
|
674
|
+
if arrs[0].ndim is 1:
|
|
675
|
+
reshaped = [a.reshape([1, a.size]) for a in arrs]
|
|
676
|
+
return concatenate(reshaped, 0)
|
|
677
|
+
return concatenate(arrs, 0)
|
|
678
|
+
|
|
679
|
+
def split(ary, indices_or_sections, axis=0):
|
|
680
|
+
ary = asarray(ary)
|
|
681
|
+
n = ary.shape[axis]
|
|
682
|
+
if jstype(indices_or_sections) is 'number':
|
|
683
|
+
k = indices_or_sections
|
|
684
|
+
sz = n // k
|
|
685
|
+
indices = []
|
|
686
|
+
for i in range(1, k):
|
|
687
|
+
indices.push(i * sz)
|
|
688
|
+
else:
|
|
689
|
+
indices = list(indices_or_sections)
|
|
690
|
+
starts = [0]
|
|
691
|
+
for idx in indices:
|
|
692
|
+
starts.push(idx)
|
|
693
|
+
starts.push(n)
|
|
694
|
+
result = []
|
|
695
|
+
for i in range(starts.length - 1):
|
|
696
|
+
s = starts[i]
|
|
697
|
+
e = starts[i + 1]
|
|
698
|
+
if axis is 0 and ary.ndim is 1:
|
|
699
|
+
data = ary._data.slice(s, e)
|
|
700
|
+
result.push(ndarray([e - s], ary.dtype, data, True))
|
|
701
|
+
elif axis is 0:
|
|
702
|
+
cols = ary.shape[1]
|
|
703
|
+
data = ary._data.slice(s * cols, e * cols)
|
|
704
|
+
result.push(ndarray([e - s, cols], ary.dtype, data, True))
|
|
705
|
+
elif axis is 1:
|
|
706
|
+
rows = ary.shape[0]
|
|
707
|
+
new_cols = e - s
|
|
708
|
+
data = []
|
|
709
|
+
for r in range(rows):
|
|
710
|
+
for c in range(s, e):
|
|
711
|
+
data.push(ary._data[r * ary.shape[1] + c])
|
|
712
|
+
result.push(ndarray([rows, new_cols], ary.dtype, data, True))
|
|
713
|
+
return result
|
|
714
|
+
|
|
715
|
+
def hsplit(ary, indices_or_sections):
|
|
716
|
+
return split(ary, indices_or_sections, 1)
|
|
717
|
+
|
|
718
|
+
def vsplit(ary, indices_or_sections):
|
|
719
|
+
return split(ary, indices_or_sections, 0)
|
|
720
|
+
|
|
721
|
+
def squeeze(a, axis=None):
|
|
722
|
+
a = asarray(a)
|
|
723
|
+
return a.squeeze(axis)
|
|
724
|
+
|
|
725
|
+
def expand_dims(a, axis):
|
|
726
|
+
a = asarray(a)
|
|
727
|
+
if axis < 0:
|
|
728
|
+
axis = a.ndim + 1 + axis
|
|
729
|
+
new_shape = a.shape.slice()
|
|
730
|
+
new_shape.splice(axis, 0, 1)
|
|
731
|
+
return ndarray(new_shape, a.dtype, a._data.slice(), True)
|
|
732
|
+
|
|
733
|
+
def flip(m, axis=None):
|
|
734
|
+
m = asarray(m)
|
|
735
|
+
if axis is None:
|
|
736
|
+
data = m._data.slice()
|
|
737
|
+
data.reverse()
|
|
738
|
+
return ndarray(m.shape.slice(), m.dtype, data, True)
|
|
739
|
+
if axis < 0:
|
|
740
|
+
axis = m.ndim + axis
|
|
741
|
+
data = m._data.slice()
|
|
742
|
+
if m.ndim is 1:
|
|
743
|
+
data.reverse()
|
|
744
|
+
return ndarray(m.shape.slice(), m.dtype, data, True)
|
|
745
|
+
if m.ndim is 2:
|
|
746
|
+
rows = m.shape[0]
|
|
747
|
+
cols = m.shape[1]
|
|
748
|
+
new_data = []
|
|
749
|
+
if axis is 0:
|
|
750
|
+
for i in range(rows - 1, -1, -1):
|
|
751
|
+
for j in range(cols):
|
|
752
|
+
new_data.push(m._data[i * cols + j])
|
|
753
|
+
else:
|
|
754
|
+
for i in range(rows):
|
|
755
|
+
for j in range(cols - 1, -1, -1):
|
|
756
|
+
new_data.push(m._data[i * cols + j])
|
|
757
|
+
return ndarray(m.shape.slice(), m.dtype, new_data, True)
|
|
758
|
+
return m
|
|
759
|
+
|
|
760
|
+
def roll(a, shift, axis=None):
|
|
761
|
+
a = asarray(a)
|
|
762
|
+
if axis is None:
|
|
763
|
+
data = a._data.slice()
|
|
764
|
+
n = data.length
|
|
765
|
+
shift = ((shift % n) + n) % n
|
|
766
|
+
return ndarray([n], a.dtype, data.slice(n - shift).concat(data.slice(0, n - shift)), True)
|
|
767
|
+
rows = a.shape[0]
|
|
768
|
+
cols = a.shape[1] if a.ndim > 1 else 1
|
|
769
|
+
if axis is 0:
|
|
770
|
+
shift = ((shift % rows) + rows) % rows
|
|
771
|
+
data = a._data.slice((rows - shift) * cols).concat(a._data.slice(0, (rows - shift) * cols))
|
|
772
|
+
return ndarray(a.shape.slice(), a.dtype, data, True)
|
|
773
|
+
if axis is 1:
|
|
774
|
+
shift = ((shift % cols) + cols) % cols
|
|
775
|
+
new_data = []
|
|
776
|
+
for i in range(rows):
|
|
777
|
+
row = a._data.slice(i * cols, (i + 1) * cols)
|
|
778
|
+
new_row = row.slice(cols - shift).concat(row.slice(0, cols - shift))
|
|
779
|
+
for v in new_row:
|
|
780
|
+
new_data.push(v)
|
|
781
|
+
return ndarray(a.shape.slice(), a.dtype, new_data, True)
|
|
782
|
+
return a
|
|
783
|
+
|
|
784
|
+
def tile(A, reps):
|
|
785
|
+
A = asarray(A)
|
|
786
|
+
if jstype(reps) is 'number':
|
|
787
|
+
reps = [int(reps)]
|
|
788
|
+
data = A._data.slice()
|
|
789
|
+
n = reps[reps.length - 1]
|
|
790
|
+
new_data = []
|
|
791
|
+
for i in range(n):
|
|
792
|
+
for v in data:
|
|
793
|
+
new_data.push(v)
|
|
794
|
+
new_shape = [A.size * n]
|
|
795
|
+
return ndarray(new_shape, A.dtype, new_data, True)
|
|
796
|
+
|
|
797
|
+
def repeat(a, repeats, axis=None):
|
|
798
|
+
a = asarray(a)
|
|
799
|
+
if axis is None:
|
|
800
|
+
data = a._data
|
|
801
|
+
new_data = []
|
|
802
|
+
for v in data:
|
|
803
|
+
for i in range(repeats):
|
|
804
|
+
new_data.push(v)
|
|
805
|
+
return ndarray([new_data.length], a.dtype, new_data, True)
|
|
806
|
+
if a.ndim is 1:
|
|
807
|
+
new_data = []
|
|
808
|
+
for v in a._data:
|
|
809
|
+
for i in range(repeats):
|
|
810
|
+
new_data.push(v)
|
|
811
|
+
return ndarray([new_data.length], a.dtype, new_data, True)
|
|
812
|
+
rows = a.shape[0]
|
|
813
|
+
cols = a.shape[1]
|
|
814
|
+
new_data = []
|
|
815
|
+
if axis is 0:
|
|
816
|
+
for i in range(rows):
|
|
817
|
+
for r in range(repeats):
|
|
818
|
+
for j in range(cols):
|
|
819
|
+
new_data.push(a._data[i * cols + j])
|
|
820
|
+
return ndarray([rows * repeats, cols], a.dtype, new_data, True)
|
|
821
|
+
else:
|
|
822
|
+
for i in range(rows):
|
|
823
|
+
for j in range(cols):
|
|
824
|
+
for r in range(repeats):
|
|
825
|
+
new_data.push(a._data[i * cols + j])
|
|
826
|
+
return ndarray([rows, cols * repeats], a.dtype, new_data, True)
|
|
827
|
+
|
|
828
|
+
# -------------------------------------------------------
|
|
829
|
+
# Math ufuncs
|
|
830
|
+
# -------------------------------------------------------
|
|
831
|
+
def add(x1, x2):
|
|
832
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a + b;)
|
|
833
|
+
|
|
834
|
+
def subtract(x1, x2):
|
|
835
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a - b;)
|
|
836
|
+
|
|
837
|
+
def multiply(x1, x2):
|
|
838
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a * b;)
|
|
839
|
+
|
|
840
|
+
def divide(x1, x2):
|
|
841
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a / b;)
|
|
842
|
+
|
|
843
|
+
def true_divide(x1, x2):
|
|
844
|
+
return divide(x1, x2)
|
|
845
|
+
|
|
846
|
+
def floor_divide(x1, x2):
|
|
847
|
+
return _apply_ufunc2(x1, x2, def(a, b): return Math.floor(a / b);)
|
|
848
|
+
|
|
849
|
+
def power(x1, x2):
|
|
850
|
+
return _apply_ufunc2(x1, x2, def(a, b): return Math.pow(a, b);)
|
|
851
|
+
|
|
852
|
+
def mod(x1, x2):
|
|
853
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a % b;)
|
|
854
|
+
|
|
855
|
+
def remainder(x1, x2):
|
|
856
|
+
return mod(x1, x2)
|
|
857
|
+
|
|
858
|
+
def negative(x):
|
|
859
|
+
return _apply_ufunc(x, def(v): return -v;)
|
|
860
|
+
|
|
861
|
+
def absolute(x):
|
|
862
|
+
return _apply_ufunc(x, def(v): return Math.abs(v);)
|
|
863
|
+
|
|
864
|
+
def abs(x):
|
|
865
|
+
return absolute(x)
|
|
866
|
+
|
|
867
|
+
def sqrt(x):
|
|
868
|
+
return _apply_ufunc(x, def(v): return Math.sqrt(v);)
|
|
869
|
+
|
|
870
|
+
def square(x):
|
|
871
|
+
return _apply_ufunc(x, def(v): return v * v;)
|
|
872
|
+
|
|
873
|
+
def exp(x):
|
|
874
|
+
return _apply_ufunc(x, def(v): return Math.exp(v);)
|
|
875
|
+
|
|
876
|
+
def log(x):
|
|
877
|
+
return _apply_ufunc(x, def(v): return Math.log(v);)
|
|
878
|
+
|
|
879
|
+
def log2(x):
|
|
880
|
+
return _apply_ufunc(x, def(v): return Math.log(v) / Math.LN2;)
|
|
881
|
+
|
|
882
|
+
def log10(x):
|
|
883
|
+
return _apply_ufunc(x, def(v): return Math.log(v) / Math.LN10;)
|
|
884
|
+
|
|
885
|
+
def sin(x):
|
|
886
|
+
return _apply_ufunc(x, def(v): return Math.sin(v);)
|
|
887
|
+
|
|
888
|
+
def cos(x):
|
|
889
|
+
return _apply_ufunc(x, def(v): return Math.cos(v);)
|
|
890
|
+
|
|
891
|
+
def tan(x):
|
|
892
|
+
return _apply_ufunc(x, def(v): return Math.tan(v);)
|
|
893
|
+
|
|
894
|
+
def arcsin(x):
|
|
895
|
+
return _apply_ufunc(x, def(v): return Math.asin(v);)
|
|
896
|
+
|
|
897
|
+
def arccos(x):
|
|
898
|
+
return _apply_ufunc(x, def(v): return Math.acos(v);)
|
|
899
|
+
|
|
900
|
+
def arctan(x):
|
|
901
|
+
return _apply_ufunc(x, def(v): return Math.atan(v);)
|
|
902
|
+
|
|
903
|
+
def arctan2(y, x):
|
|
904
|
+
return _apply_ufunc2(y, x, def(a, b): return Math.atan2(a, b);)
|
|
905
|
+
|
|
906
|
+
def degrees(x):
|
|
907
|
+
return _apply_ufunc(x, def(v): return v * 180.0 / Math.PI;)
|
|
908
|
+
|
|
909
|
+
def rad2deg(x):
|
|
910
|
+
return degrees(x)
|
|
911
|
+
|
|
912
|
+
def radians(x):
|
|
913
|
+
return _apply_ufunc(x, def(v): return v * Math.PI / 180.0;)
|
|
914
|
+
|
|
915
|
+
def deg2rad(x):
|
|
916
|
+
return radians(x)
|
|
917
|
+
|
|
918
|
+
def around(a, decimals=0):
|
|
919
|
+
factor = Math.pow(10, decimals)
|
|
920
|
+
return _apply_ufunc(a, def(v): return Math.round(v * factor) / factor;)
|
|
921
|
+
|
|
922
|
+
def round_(a, decimals=0):
|
|
923
|
+
return around(a, decimals)
|
|
924
|
+
|
|
925
|
+
def ceil(x):
|
|
926
|
+
return _apply_ufunc(x, def(v): return Math.ceil(v);)
|
|
927
|
+
|
|
928
|
+
def floor(x):
|
|
929
|
+
return _apply_ufunc(x, def(v): return Math.floor(v);)
|
|
930
|
+
|
|
931
|
+
def _sign_fn(v):
|
|
932
|
+
if v > 0:
|
|
933
|
+
return 1
|
|
934
|
+
elif v < 0:
|
|
935
|
+
return -1
|
|
936
|
+
return 0
|
|
937
|
+
|
|
938
|
+
def sign(x):
|
|
939
|
+
return _apply_ufunc(x, _sign_fn)
|
|
940
|
+
|
|
941
|
+
def maximum(x1, x2):
|
|
942
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a if a >= b else b;)
|
|
943
|
+
|
|
944
|
+
def minimum(x1, x2):
|
|
945
|
+
return _apply_ufunc2(x1, x2, def(a, b): return a if a <= b else b;)
|
|
946
|
+
|
|
947
|
+
def hypot(x1, x2):
|
|
948
|
+
return _apply_ufunc2(x1, x2, def(a, b): return Math.sqrt(a * a + b * b);)
|
|
949
|
+
|
|
950
|
+
def clip(a, a_min, a_max):
|
|
951
|
+
a = asarray(a)
|
|
952
|
+
return a.clip(a_min, a_max)
|
|
953
|
+
|
|
954
|
+
# -------------------------------------------------------
|
|
955
|
+
# Reduction operations
|
|
956
|
+
# -------------------------------------------------------
|
|
957
|
+
def sum(a, axis=None, keepdims=False):
|
|
958
|
+
a = asarray(a)
|
|
959
|
+
return a.sum(axis, keepdims)
|
|
960
|
+
|
|
961
|
+
def prod(a, axis=None, keepdims=False):
|
|
962
|
+
a = asarray(a)
|
|
963
|
+
return a.prod(axis, keepdims)
|
|
964
|
+
|
|
965
|
+
def amin(a, axis=None):
|
|
966
|
+
a = asarray(a)
|
|
967
|
+
return a.min(axis)
|
|
968
|
+
|
|
969
|
+
def nanmin(a):
|
|
970
|
+
a = asarray(a)
|
|
971
|
+
data = []
|
|
972
|
+
for v in a._data:
|
|
973
|
+
if not isNaN(v):
|
|
974
|
+
data.push(v)
|
|
975
|
+
return _min_list(data)
|
|
976
|
+
|
|
977
|
+
def amax(a, axis=None):
|
|
978
|
+
a = asarray(a)
|
|
979
|
+
return a.max(axis)
|
|
980
|
+
|
|
981
|
+
def nanmax(a):
|
|
982
|
+
a = asarray(a)
|
|
983
|
+
data = []
|
|
984
|
+
for v in a._data:
|
|
985
|
+
if not isNaN(v):
|
|
986
|
+
data.push(v)
|
|
987
|
+
return _max_list(data)
|
|
988
|
+
|
|
989
|
+
def mean(a, axis=None):
|
|
990
|
+
a = asarray(a)
|
|
991
|
+
return a.mean(axis)
|
|
992
|
+
|
|
993
|
+
def nanmean(a):
|
|
994
|
+
a = asarray(a)
|
|
995
|
+
data = []
|
|
996
|
+
for v in a._data:
|
|
997
|
+
if not isNaN(v):
|
|
998
|
+
data.push(v)
|
|
999
|
+
return _mean_list(data)
|
|
1000
|
+
|
|
1001
|
+
def std(a, axis=None, ddof=0):
|
|
1002
|
+
a = asarray(a)
|
|
1003
|
+
return a.std(axis, ddof)
|
|
1004
|
+
|
|
1005
|
+
def nanstd(a, ddof=0):
|
|
1006
|
+
a = asarray(a)
|
|
1007
|
+
data = []
|
|
1008
|
+
for v in a._data:
|
|
1009
|
+
if not isNaN(v):
|
|
1010
|
+
data.push(v)
|
|
1011
|
+
return _std_list(data, ddof)
|
|
1012
|
+
|
|
1013
|
+
def variance(a, axis=None, ddof=0):
|
|
1014
|
+
a = asarray(a)
|
|
1015
|
+
return a.variance(axis, ddof)
|
|
1016
|
+
|
|
1017
|
+
def nanvar(a, ddof=0):
|
|
1018
|
+
a = asarray(a)
|
|
1019
|
+
data = []
|
|
1020
|
+
for v in a._data:
|
|
1021
|
+
if not isNaN(v):
|
|
1022
|
+
data.push(v)
|
|
1023
|
+
return _var_list(data, ddof)
|
|
1024
|
+
|
|
1025
|
+
def cumsum(a, axis=None):
|
|
1026
|
+
a = asarray(a)
|
|
1027
|
+
return a.cumsum(axis)
|
|
1028
|
+
|
|
1029
|
+
def cumprod(a, axis=None):
|
|
1030
|
+
a = asarray(a)
|
|
1031
|
+
return a.cumprod(axis)
|
|
1032
|
+
|
|
1033
|
+
def diff(a, n=1, axis=-1):
|
|
1034
|
+
a = asarray(a)
|
|
1035
|
+
data = a._data.slice()
|
|
1036
|
+
for iteration in range(n):
|
|
1037
|
+
new_data = []
|
|
1038
|
+
for i in range(data.length - 1):
|
|
1039
|
+
new_data.push(data[i + 1] - data[i])
|
|
1040
|
+
data = new_data
|
|
1041
|
+
return ndarray([data.length], a.dtype, data, True)
|
|
1042
|
+
|
|
1043
|
+
def argmin(a, axis=None):
|
|
1044
|
+
a = asarray(a)
|
|
1045
|
+
return a.argmin(axis)
|
|
1046
|
+
|
|
1047
|
+
def argmax(a, axis=None):
|
|
1048
|
+
a = asarray(a)
|
|
1049
|
+
return a.argmax(axis)
|
|
1050
|
+
|
|
1051
|
+
# -------------------------------------------------------
|
|
1052
|
+
# Sorting & Searching
|
|
1053
|
+
# -------------------------------------------------------
|
|
1054
|
+
def sort(a, axis=-1):
|
|
1055
|
+
a = asarray(a)
|
|
1056
|
+
if a.ndim is 1 or axis is None:
|
|
1057
|
+
data = a._data.slice()
|
|
1058
|
+
data.sort(def(x, y): return x - y;)
|
|
1059
|
+
return ndarray(a.shape.slice(), a.dtype, data, True)
|
|
1060
|
+
# 2D sort along last axis (axis=1 or axis=-1)
|
|
1061
|
+
if axis < 0:
|
|
1062
|
+
axis = a.ndim + axis
|
|
1063
|
+
rows = a.shape[0]
|
|
1064
|
+
cols = a.shape[1]
|
|
1065
|
+
new_data = []
|
|
1066
|
+
if axis is 1:
|
|
1067
|
+
for i in range(rows):
|
|
1068
|
+
row = a._data.slice(i * cols, (i + 1) * cols)
|
|
1069
|
+
row.sort(def(x, y): return x - y;)
|
|
1070
|
+
for v in row:
|
|
1071
|
+
new_data.push(v)
|
|
1072
|
+
elif axis is 0:
|
|
1073
|
+
for j in range(cols):
|
|
1074
|
+
col = []
|
|
1075
|
+
for i in range(rows):
|
|
1076
|
+
col.push(a._data[i * cols + j])
|
|
1077
|
+
col.sort(def(x, y): return x - y;)
|
|
1078
|
+
for i in range(rows):
|
|
1079
|
+
new_data[i * cols + j] = col[i]
|
|
1080
|
+
if new_data.length is 0:
|
|
1081
|
+
for i in range(a.size):
|
|
1082
|
+
new_data.push(a._data[i])
|
|
1083
|
+
return ndarray(a.shape.slice(), a.dtype, new_data, True)
|
|
1084
|
+
|
|
1085
|
+
def argsort(a, axis=-1):
|
|
1086
|
+
a = asarray(a)
|
|
1087
|
+
if a.ndim is 1:
|
|
1088
|
+
indices = []
|
|
1089
|
+
for i in range(a.size):
|
|
1090
|
+
indices.push(i)
|
|
1091
|
+
data = a._data.slice()
|
|
1092
|
+
indices.sort(def(i, j): return data[i] - data[j];)
|
|
1093
|
+
return ndarray([a.size], 'int32', indices, True)
|
|
1094
|
+
# Flatten and sort
|
|
1095
|
+
data = a._data.slice()
|
|
1096
|
+
indices = []
|
|
1097
|
+
for i in range(data.length):
|
|
1098
|
+
indices.push(i)
|
|
1099
|
+
indices.sort(def(i, j): return data[i] - data[j];)
|
|
1100
|
+
return ndarray([indices.length], 'int32', indices, True)
|
|
1101
|
+
|
|
1102
|
+
def searchsorted(a, v, side='left'):
|
|
1103
|
+
a = asarray(a)
|
|
1104
|
+
data = a._data
|
|
1105
|
+
if jstype(v) is 'number':
|
|
1106
|
+
lo = 0
|
|
1107
|
+
hi = data.length
|
|
1108
|
+
while lo < hi:
|
|
1109
|
+
mid = Math.floor((lo + hi) / 2)
|
|
1110
|
+
if side is 'left':
|
|
1111
|
+
if data[mid] < v:
|
|
1112
|
+
lo = mid + 1
|
|
1113
|
+
else:
|
|
1114
|
+
hi = mid
|
|
1115
|
+
else:
|
|
1116
|
+
if data[mid] <= v:
|
|
1117
|
+
lo = mid + 1
|
|
1118
|
+
else:
|
|
1119
|
+
hi = mid
|
|
1120
|
+
return lo
|
|
1121
|
+
v = asarray(v)
|
|
1122
|
+
result = []
|
|
1123
|
+
for val in v._data:
|
|
1124
|
+
result.push(searchsorted(a, val, side))
|
|
1125
|
+
return ndarray([result.length], 'int32', result, True)
|
|
1126
|
+
|
|
1127
|
+
def nonzero(a):
|
|
1128
|
+
a = asarray(a)
|
|
1129
|
+
indices = []
|
|
1130
|
+
for i in range(a.size):
|
|
1131
|
+
if a._data[i]:
|
|
1132
|
+
indices.push(i)
|
|
1133
|
+
result = ndarray([indices.length], 'int32', indices, True)
|
|
1134
|
+
return [result]
|
|
1135
|
+
|
|
1136
|
+
def where(condition, x=None, y=None):
|
|
1137
|
+
condition = asarray(condition)
|
|
1138
|
+
if x is None:
|
|
1139
|
+
return nonzero(condition)
|
|
1140
|
+
x = asarray(x)
|
|
1141
|
+
y = asarray(y)
|
|
1142
|
+
bs = _broadcast_shapes(_broadcast_shapes(condition.shape, x.shape), y.shape)
|
|
1143
|
+
c_data = _broadcast_to_flat(condition, bs)
|
|
1144
|
+
x_data = _broadcast_to_flat(x, bs)
|
|
1145
|
+
y_data = _broadcast_to_flat(y, bs)
|
|
1146
|
+
result_data = []
|
|
1147
|
+
for i in range(c_data.length):
|
|
1148
|
+
if c_data[i]:
|
|
1149
|
+
result_data.push(x_data[i])
|
|
1150
|
+
else:
|
|
1151
|
+
result_data.push(y_data[i])
|
|
1152
|
+
return ndarray(bs, 'float64', result_data, True)
|
|
1153
|
+
|
|
1154
|
+
# -------------------------------------------------------
|
|
1155
|
+
# Statistics
|
|
1156
|
+
# -------------------------------------------------------
|
|
1157
|
+
def median(a, axis=None):
|
|
1158
|
+
a = asarray(a)
|
|
1159
|
+
data = a._data.slice()
|
|
1160
|
+
data.sort(def(x, y): return x - y;)
|
|
1161
|
+
n = data.length
|
|
1162
|
+
if n % 2 is 1:
|
|
1163
|
+
return data[Math.floor(n / 2)]
|
|
1164
|
+
return (data[n // 2 - 1] + data[n // 2]) / 2.0
|
|
1165
|
+
|
|
1166
|
+
def percentile(a, q, axis=None):
|
|
1167
|
+
a = asarray(a)
|
|
1168
|
+
data = a._data.slice()
|
|
1169
|
+
data.sort(def(x, y): return x - y;)
|
|
1170
|
+
n = data.length
|
|
1171
|
+
idx = q / 100.0 * (n - 1)
|
|
1172
|
+
lo = Math.floor(idx)
|
|
1173
|
+
hi = Math.ceil(idx)
|
|
1174
|
+
if lo is hi:
|
|
1175
|
+
return data[lo]
|
|
1176
|
+
return data[lo] + (idx - lo) * (data[hi] - data[lo])
|
|
1177
|
+
|
|
1178
|
+
def corrcoef(x, y=None, rowvar=True):
|
|
1179
|
+
x = asarray(x)
|
|
1180
|
+
if y is not None:
|
|
1181
|
+
y = asarray(y)
|
|
1182
|
+
# Stack rows
|
|
1183
|
+
xdata = x._data.slice()
|
|
1184
|
+
ydata = y._data.slice()
|
|
1185
|
+
n = xdata.length
|
|
1186
|
+
mx = _mean_list(xdata)
|
|
1187
|
+
my = _mean_list(ydata)
|
|
1188
|
+
cxx = 0
|
|
1189
|
+
cyy = 0
|
|
1190
|
+
cxy = 0
|
|
1191
|
+
for i in range(n):
|
|
1192
|
+
cxx += (xdata[i] - mx) * (xdata[i] - mx)
|
|
1193
|
+
cyy += (ydata[i] - my) * (ydata[i] - my)
|
|
1194
|
+
cxy += (xdata[i] - mx) * (ydata[i] - my)
|
|
1195
|
+
cxx /= n
|
|
1196
|
+
cyy /= n
|
|
1197
|
+
cxy /= n
|
|
1198
|
+
r = cxy / Math.sqrt(cxx * cyy)
|
|
1199
|
+
data = [1.0, r, r, 1.0]
|
|
1200
|
+
return ndarray([2, 2], 'float64', data, True)
|
|
1201
|
+
return eye(x.shape[0])
|
|
1202
|
+
|
|
1203
|
+
def cov(m, y=None, rowvar=True, ddof=1):
|
|
1204
|
+
m = asarray(m)
|
|
1205
|
+
if y is not None:
|
|
1206
|
+
y = asarray(y)
|
|
1207
|
+
xdata = m._data.slice()
|
|
1208
|
+
ydata = y._data.slice()
|
|
1209
|
+
n = xdata.length
|
|
1210
|
+
mx = _mean_list(xdata)
|
|
1211
|
+
my = _mean_list(ydata)
|
|
1212
|
+
cxx = 0
|
|
1213
|
+
cyy = 0
|
|
1214
|
+
cxy = 0
|
|
1215
|
+
for i in range(n):
|
|
1216
|
+
cxx += (xdata[i] - mx) * (xdata[i] - mx)
|
|
1217
|
+
cyy += (ydata[i] - my) * (ydata[i] - my)
|
|
1218
|
+
cxy += (xdata[i] - mx) * (ydata[i] - my)
|
|
1219
|
+
cxx /= (n - ddof)
|
|
1220
|
+
cyy /= (n - ddof)
|
|
1221
|
+
cxy /= (n - ddof)
|
|
1222
|
+
data = [cxx, cxy, cxy, cyy]
|
|
1223
|
+
return ndarray([2, 2], 'float64', data, True)
|
|
1224
|
+
data = m._data.slice()
|
|
1225
|
+
n = data.length
|
|
1226
|
+
m_val = _mean_list(data)
|
|
1227
|
+
c = 0
|
|
1228
|
+
for v in data:
|
|
1229
|
+
c += (v - m_val) * (v - m_val)
|
|
1230
|
+
c /= (n - ddof)
|
|
1231
|
+
return ndarray([1, 1], 'float64', [c], True)
|
|
1232
|
+
|
|
1233
|
+
def histogram(a, bins=10, data_range=None):
|
|
1234
|
+
a = asarray(a)
|
|
1235
|
+
data = a._data.slice()
|
|
1236
|
+
if data_range is None:
|
|
1237
|
+
mn = _min_list(data)
|
|
1238
|
+
mx = _max_list(data)
|
|
1239
|
+
else:
|
|
1240
|
+
mn = data_range[0]
|
|
1241
|
+
mx = data_range[1]
|
|
1242
|
+
bin_edges = []
|
|
1243
|
+
for i in range(bins + 1):
|
|
1244
|
+
bin_edges.push(mn + i * (mx - mn) / bins)
|
|
1245
|
+
counts = _make_filled(bins, 0, 'int32')
|
|
1246
|
+
for v in data:
|
|
1247
|
+
if v < mn or v > mx:
|
|
1248
|
+
continue
|
|
1249
|
+
idx = Math.floor((v - mn) / (mx - mn) * bins)
|
|
1250
|
+
if idx is bins:
|
|
1251
|
+
idx = bins - 1
|
|
1252
|
+
counts[idx] += 1
|
|
1253
|
+
return [ndarray([bins], 'int32', counts, True), ndarray([bins + 1], 'float64', bin_edges, True)]
|
|
1254
|
+
|
|
1255
|
+
# -------------------------------------------------------
|
|
1256
|
+
# Linear algebra
|
|
1257
|
+
# -------------------------------------------------------
|
|
1258
|
+
def dot(a, b):
|
|
1259
|
+
a = asarray(a)
|
|
1260
|
+
b = asarray(b)
|
|
1261
|
+
if a.ndim is 1 and b.ndim is 1:
|
|
1262
|
+
s = 0
|
|
1263
|
+
for i in range(a.size):
|
|
1264
|
+
s += a._data[i] * b._data[i]
|
|
1265
|
+
return s
|
|
1266
|
+
if a.ndim is 2 and b.ndim is 2:
|
|
1267
|
+
return matmul(a, b)
|
|
1268
|
+
if a.ndim is 2 and b.ndim is 1:
|
|
1269
|
+
rows = a.shape[0]
|
|
1270
|
+
cols = a.shape[1]
|
|
1271
|
+
result_data = []
|
|
1272
|
+
for i in range(rows):
|
|
1273
|
+
s = 0
|
|
1274
|
+
for j in range(cols):
|
|
1275
|
+
s += a._data[i * cols + j] * b._data[j]
|
|
1276
|
+
result_data.push(s)
|
|
1277
|
+
return ndarray([rows], 'float64', result_data, True)
|
|
1278
|
+
return _apply_ufunc2(a, b, def(x, y): return x * y;)
|
|
1279
|
+
|
|
1280
|
+
def matmul(x1, x2):
|
|
1281
|
+
a = asarray(x1)
|
|
1282
|
+
b = asarray(x2)
|
|
1283
|
+
ra = a.shape[0]
|
|
1284
|
+
ca = a.shape[1]
|
|
1285
|
+
rb = b.shape[0]
|
|
1286
|
+
cb = b.shape[1]
|
|
1287
|
+
if ca is not rb:
|
|
1288
|
+
raise ValueError("matmul: dimension mismatch")
|
|
1289
|
+
result_data = []
|
|
1290
|
+
for i in range(ra):
|
|
1291
|
+
for j in range(cb):
|
|
1292
|
+
s = 0
|
|
1293
|
+
for k in range(ca):
|
|
1294
|
+
s += a._data[i * ca + k] * b._data[k * cb + j]
|
|
1295
|
+
result_data.push(s)
|
|
1296
|
+
return ndarray([ra, cb], 'float64', result_data, True)
|
|
1297
|
+
|
|
1298
|
+
def inner(a, b):
|
|
1299
|
+
a = asarray(a)
|
|
1300
|
+
b = asarray(b)
|
|
1301
|
+
if a.ndim is 1 and b.ndim is 1:
|
|
1302
|
+
return dot(a, b)
|
|
1303
|
+
return dot(a, b.transpose())
|
|
1304
|
+
|
|
1305
|
+
def outer(a, b):
|
|
1306
|
+
a = asarray(a).ravel()
|
|
1307
|
+
b = asarray(b).ravel()
|
|
1308
|
+
data = []
|
|
1309
|
+
for av in a._data:
|
|
1310
|
+
for bv in b._data:
|
|
1311
|
+
data.push(av * bv)
|
|
1312
|
+
return ndarray([a.size, b.size], 'float64', data, True)
|
|
1313
|
+
|
|
1314
|
+
def cross(a, b):
|
|
1315
|
+
a = asarray(a)
|
|
1316
|
+
b = asarray(b)
|
|
1317
|
+
if a.size is 3 and b.size is 3:
|
|
1318
|
+
ax = a._data[0]
|
|
1319
|
+
ay = a._data[1]
|
|
1320
|
+
az = a._data[2]
|
|
1321
|
+
bx = b._data[0]
|
|
1322
|
+
by = b._data[1]
|
|
1323
|
+
bz = b._data[2]
|
|
1324
|
+
data = [ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx]
|
|
1325
|
+
return ndarray([3], 'float64', data, True)
|
|
1326
|
+
if a.size is 2 and b.size is 2:
|
|
1327
|
+
return a._data[0] * b._data[1] - a._data[1] * b._data[0]
|
|
1328
|
+
raise ValueError("cross: incompatible dimensions")
|
|
1329
|
+
|
|
1330
|
+
def trace(a, offset=0, axis1=0, axis2=1):
|
|
1331
|
+
a = asarray(a)
|
|
1332
|
+
rows = a.shape[0]
|
|
1333
|
+
cols = a.shape[1]
|
|
1334
|
+
s = 0
|
|
1335
|
+
for i in range(rows):
|
|
1336
|
+
j = i + offset
|
|
1337
|
+
if j >= 0 and j < cols:
|
|
1338
|
+
s += a._data[i * cols + j]
|
|
1339
|
+
return s
|
|
1340
|
+
|
|
1341
|
+
def norm(x, ord=None, axis=None):
|
|
1342
|
+
x = asarray(x)
|
|
1343
|
+
data = x._data
|
|
1344
|
+
if ord is None:
|
|
1345
|
+
s = 0
|
|
1346
|
+
for v in data:
|
|
1347
|
+
s += v * v
|
|
1348
|
+
return Math.sqrt(s)
|
|
1349
|
+
if ord is 1:
|
|
1350
|
+
s = 0
|
|
1351
|
+
for v in data:
|
|
1352
|
+
s += Math.abs(v)
|
|
1353
|
+
return s
|
|
1354
|
+
if ord is 2:
|
|
1355
|
+
s = 0
|
|
1356
|
+
for v in data:
|
|
1357
|
+
s += v * v
|
|
1358
|
+
return Math.sqrt(s)
|
|
1359
|
+
# Generic Lp norm
|
|
1360
|
+
s = 0
|
|
1361
|
+
for v in data:
|
|
1362
|
+
s += Math.pow(Math.abs(v), ord)
|
|
1363
|
+
return Math.pow(s, 1.0 / ord)
|
|
1364
|
+
|
|
1365
|
+
def det(a):
|
|
1366
|
+
a = asarray(a)
|
|
1367
|
+
n = a.shape[0]
|
|
1368
|
+
if n is 2:
|
|
1369
|
+
return a._data[0] * a._data[3] - a._data[1] * a._data[2]
|
|
1370
|
+
if n is 3:
|
|
1371
|
+
d = a._data
|
|
1372
|
+
return (d[0] * (d[4] * d[8] - d[5] * d[7])
|
|
1373
|
+
- d[1] * (d[3] * d[8] - d[5] * d[6])
|
|
1374
|
+
+ d[2] * (d[3] * d[7] - d[4] * d[6]))
|
|
1375
|
+
raise ValueError("det: only 2x2 and 3x3 matrices supported")
|
|
1376
|
+
|
|
1377
|
+
# -------------------------------------------------------
|
|
1378
|
+
# Comparison / Logic
|
|
1379
|
+
# -------------------------------------------------------
|
|
1380
|
+
def _all_reduce_fn(data):
|
|
1381
|
+
for v in data:
|
|
1382
|
+
if not v:
|
|
1383
|
+
return False
|
|
1384
|
+
return True
|
|
1385
|
+
|
|
1386
|
+
def _any_reduce_fn(data):
|
|
1387
|
+
for v in data:
|
|
1388
|
+
if v:
|
|
1389
|
+
return True
|
|
1390
|
+
return False
|
|
1391
|
+
|
|
1392
|
+
def all(a, axis=None):
|
|
1393
|
+
a = asarray(a)
|
|
1394
|
+
if axis is None:
|
|
1395
|
+
for v in a._data:
|
|
1396
|
+
if not v:
|
|
1397
|
+
return False
|
|
1398
|
+
return True
|
|
1399
|
+
return _reduce(a, axis, _all_reduce_fn, False)
|
|
1400
|
+
|
|
1401
|
+
def any(a, axis=None):
|
|
1402
|
+
a = asarray(a)
|
|
1403
|
+
if axis is None:
|
|
1404
|
+
for v in a._data:
|
|
1405
|
+
if v:
|
|
1406
|
+
return True
|
|
1407
|
+
return False
|
|
1408
|
+
return _reduce(a, axis, _any_reduce_fn, False)
|
|
1409
|
+
|
|
1410
|
+
def isnan(a):
|
|
1411
|
+
return _apply_ufunc(a, def(v): return isNaN(v);)
|
|
1412
|
+
|
|
1413
|
+
def isinf(a):
|
|
1414
|
+
return _apply_ufunc(a, def(v): return not isFinite(v) and not isNaN(v);)
|
|
1415
|
+
|
|
1416
|
+
def isfinite(a):
|
|
1417
|
+
return _apply_ufunc(a, def(v): return isFinite(v);)
|
|
1418
|
+
|
|
1419
|
+
def array_equal(a1, a2):
|
|
1420
|
+
a1 = asarray(a1)
|
|
1421
|
+
a2 = asarray(a2)
|
|
1422
|
+
if a1.shape.join(',') is not a2.shape.join(','):
|
|
1423
|
+
return False
|
|
1424
|
+
for i in range(a1.size):
|
|
1425
|
+
if a1._data[i] is not a2._data[i]:
|
|
1426
|
+
return False
|
|
1427
|
+
return True
|
|
1428
|
+
|
|
1429
|
+
def equal(x1, x2):
|
|
1430
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a == b else 0;)
|
|
1431
|
+
|
|
1432
|
+
def not_equal(x1, x2):
|
|
1433
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a != b else 0;)
|
|
1434
|
+
|
|
1435
|
+
def greater(x1, x2):
|
|
1436
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a > b else 0;)
|
|
1437
|
+
|
|
1438
|
+
def less(x1, x2):
|
|
1439
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a < b else 0;)
|
|
1440
|
+
|
|
1441
|
+
def greater_equal(x1, x2):
|
|
1442
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a >= b else 0;)
|
|
1443
|
+
|
|
1444
|
+
def less_equal(x1, x2):
|
|
1445
|
+
return _apply_ufunc2(x1, x2, def(a, b): return 1 if a <= b else 0;)
|
|
1446
|
+
|
|
1447
|
+
def _logical_and_fn(a, b):
|
|
1448
|
+
return 1 if a and b else 0
|
|
1449
|
+
|
|
1450
|
+
def _logical_or_fn(a, b):
|
|
1451
|
+
return 1 if a or b else 0
|
|
1452
|
+
|
|
1453
|
+
def _logical_not_fn(v):
|
|
1454
|
+
return 1 if not v else 0
|
|
1455
|
+
|
|
1456
|
+
def _logical_xor_fn(a, b):
|
|
1457
|
+
return 1 if (a and not b) or (not a and b) else 0
|
|
1458
|
+
|
|
1459
|
+
def logical_and(x1, x2):
|
|
1460
|
+
return _apply_ufunc2(x1, x2, _logical_and_fn)
|
|
1461
|
+
|
|
1462
|
+
def logical_or(x1, x2):
|
|
1463
|
+
return _apply_ufunc2(x1, x2, _logical_or_fn)
|
|
1464
|
+
|
|
1465
|
+
def logical_not(x):
|
|
1466
|
+
return _apply_ufunc(x, _logical_not_fn)
|
|
1467
|
+
|
|
1468
|
+
def logical_xor(x1, x2):
|
|
1469
|
+
return _apply_ufunc2(x1, x2, _logical_xor_fn)
|
|
1470
|
+
|
|
1471
|
+
# -------------------------------------------------------
|
|
1472
|
+
# Shape / Type Utilities
|
|
1473
|
+
# -------------------------------------------------------
|
|
1474
|
+
def shape(a):
|
|
1475
|
+
a = asarray(a)
|
|
1476
|
+
return a.shape
|
|
1477
|
+
|
|
1478
|
+
def ndim(a):
|
|
1479
|
+
a = asarray(a)
|
|
1480
|
+
return a.ndim
|
|
1481
|
+
|
|
1482
|
+
def size(a):
|
|
1483
|
+
a = asarray(a)
|
|
1484
|
+
return a.size
|
|
1485
|
+
|
|
1486
|
+
# -------------------------------------------------------
|
|
1487
|
+
# Set Operations
|
|
1488
|
+
# -------------------------------------------------------
|
|
1489
|
+
def union1d(ar1, ar2):
|
|
1490
|
+
ar1 = asarray(ar1)
|
|
1491
|
+
ar2 = asarray(ar2)
|
|
1492
|
+
combined = ar1._data.concat(ar2._data)
|
|
1493
|
+
seen = {}
|
|
1494
|
+
unique = []
|
|
1495
|
+
for v in combined:
|
|
1496
|
+
key = str(v)
|
|
1497
|
+
if not seen[key]:
|
|
1498
|
+
seen[key] = True
|
|
1499
|
+
unique.push(v)
|
|
1500
|
+
unique.sort(def(a, b): return a - b;)
|
|
1501
|
+
return ndarray([unique.length], 'float64', unique, True)
|
|
1502
|
+
|
|
1503
|
+
def intersect1d(ar1, ar2):
|
|
1504
|
+
ar1 = asarray(ar1)
|
|
1505
|
+
ar2 = asarray(ar2)
|
|
1506
|
+
s = {}
|
|
1507
|
+
for v in ar2._data:
|
|
1508
|
+
s[str(v)] = True
|
|
1509
|
+
result = []
|
|
1510
|
+
seen = {}
|
|
1511
|
+
for v in ar1._data:
|
|
1512
|
+
key = str(v)
|
|
1513
|
+
if s[key] and not seen[key]:
|
|
1514
|
+
seen[key] = True
|
|
1515
|
+
result.push(v)
|
|
1516
|
+
result.sort(def(a, b): return a - b;)
|
|
1517
|
+
return ndarray([result.length], 'float64', result, True)
|
|
1518
|
+
|
|
1519
|
+
def setdiff1d(ar1, ar2):
|
|
1520
|
+
ar1 = asarray(ar1)
|
|
1521
|
+
ar2 = asarray(ar2)
|
|
1522
|
+
s = {}
|
|
1523
|
+
for v in ar2._data:
|
|
1524
|
+
s[str(v)] = True
|
|
1525
|
+
result = []
|
|
1526
|
+
seen = {}
|
|
1527
|
+
for v in ar1._data:
|
|
1528
|
+
key = str(v)
|
|
1529
|
+
if not s[key] and not seen[key]:
|
|
1530
|
+
seen[key] = True
|
|
1531
|
+
result.push(v)
|
|
1532
|
+
result.sort(def(a, b): return a - b;)
|
|
1533
|
+
return ndarray([result.length], 'float64', result, True)
|
|
1534
|
+
|
|
1535
|
+
def in1d(ar1, ar2):
|
|
1536
|
+
ar1 = asarray(ar1)
|
|
1537
|
+
ar2 = asarray(ar2)
|
|
1538
|
+
s = {}
|
|
1539
|
+
for v in ar2._data:
|
|
1540
|
+
s[str(v)] = True
|
|
1541
|
+
result = []
|
|
1542
|
+
for v in ar1._data:
|
|
1543
|
+
result.push(1 if s[str(v)] else 0)
|
|
1544
|
+
return ndarray([result.length], 'bool', result, True)
|
|
1545
|
+
|
|
1546
|
+
# -------------------------------------------------------
|
|
1547
|
+
# Additional Shape Helpers
|
|
1548
|
+
# -------------------------------------------------------
|
|
1549
|
+
def diag(v, k=0):
|
|
1550
|
+
v = asarray(v)
|
|
1551
|
+
if v.ndim is 1:
|
|
1552
|
+
n = v.size + Math.abs(k)
|
|
1553
|
+
data = _make_filled(n * n, 0, v.dtype)
|
|
1554
|
+
for i in range(v.size):
|
|
1555
|
+
if k >= 0:
|
|
1556
|
+
data[(i) * n + (i + k)] = v._data[i]
|
|
1557
|
+
else:
|
|
1558
|
+
data[(i - k) * n + i] = v._data[i]
|
|
1559
|
+
return ndarray([n, n], v.dtype, data, True)
|
|
1560
|
+
else:
|
|
1561
|
+
n = v.shape[0]
|
|
1562
|
+
m = v.shape[1]
|
|
1563
|
+
result = []
|
|
1564
|
+
for i in range(n):
|
|
1565
|
+
j = i + k
|
|
1566
|
+
if j >= 0 and j < m:
|
|
1567
|
+
result.push(v._data[i * m + j])
|
|
1568
|
+
return ndarray([result.length], v.dtype, result, True)
|
|
1569
|
+
|
|
1570
|
+
def tril(m, k=0):
|
|
1571
|
+
m = asarray(m)
|
|
1572
|
+
rows = m.shape[0]
|
|
1573
|
+
cols = m.shape[1]
|
|
1574
|
+
data = m._data.slice()
|
|
1575
|
+
for i in range(rows):
|
|
1576
|
+
for j in range(cols):
|
|
1577
|
+
if j - i > k:
|
|
1578
|
+
data[i * cols + j] = 0
|
|
1579
|
+
return ndarray(m.shape.slice(), m.dtype, data, True)
|
|
1580
|
+
|
|
1581
|
+
def triu(m, k=0):
|
|
1582
|
+
m = asarray(m)
|
|
1583
|
+
rows = m.shape[0]
|
|
1584
|
+
cols = m.shape[1]
|
|
1585
|
+
data = m._data.slice()
|
|
1586
|
+
for i in range(rows):
|
|
1587
|
+
for j in range(cols):
|
|
1588
|
+
if j - i < k:
|
|
1589
|
+
data[i * cols + j] = 0
|
|
1590
|
+
return ndarray(m.shape.slice(), m.dtype, data, True)
|
|
1591
|
+
|
|
1592
|
+
def atleast_1d(*arys):
|
|
1593
|
+
result = []
|
|
1594
|
+
for a in arys:
|
|
1595
|
+
a = asarray(a)
|
|
1596
|
+
if a.ndim is 0:
|
|
1597
|
+
result.push(ndarray([1], a.dtype, a._data.slice(), True))
|
|
1598
|
+
else:
|
|
1599
|
+
result.push(a)
|
|
1600
|
+
if result.length is 1:
|
|
1601
|
+
return result[0]
|
|
1602
|
+
return result
|
|
1603
|
+
|
|
1604
|
+
def atleast_2d(*arys):
|
|
1605
|
+
result = []
|
|
1606
|
+
for a in arys:
|
|
1607
|
+
a = asarray(a)
|
|
1608
|
+
if a.ndim is 0:
|
|
1609
|
+
result.push(ndarray([1, 1], a.dtype, a._data.slice(), True))
|
|
1610
|
+
elif a.ndim is 1:
|
|
1611
|
+
result.push(ndarray([1, a.size], a.dtype, a._data.slice(), True))
|
|
1612
|
+
else:
|
|
1613
|
+
result.push(a)
|
|
1614
|
+
if result.length is 1:
|
|
1615
|
+
return result[0]
|
|
1616
|
+
return result
|
|
1617
|
+
|
|
1618
|
+
def column_stack(tup):
|
|
1619
|
+
arrs = []
|
|
1620
|
+
for a in tup:
|
|
1621
|
+
a = asarray(a)
|
|
1622
|
+
if a.ndim is 1:
|
|
1623
|
+
arrs.push(ndarray([a.size, 1], a.dtype, a._data.slice(), True))
|
|
1624
|
+
else:
|
|
1625
|
+
arrs.push(a)
|
|
1626
|
+
return concatenate(arrs, 1)
|
|
1627
|
+
|
|
1628
|
+
def dstack(tup):
|
|
1629
|
+
arrs = [asarray(a) for a in tup]
|
|
1630
|
+
data = []
|
|
1631
|
+
for a in arrs:
|
|
1632
|
+
for v in a._data:
|
|
1633
|
+
data.push(v)
|
|
1634
|
+
total = data.length
|
|
1635
|
+
return ndarray([total], arrs[0].dtype, data, True)
|
|
1636
|
+
|
|
1637
|
+
def broadcast_to(array, shape):
|
|
1638
|
+
array = asarray(array)
|
|
1639
|
+
if jstype(shape) is 'number':
|
|
1640
|
+
shape = [int(shape)]
|
|
1641
|
+
elif not Array.isArray(shape):
|
|
1642
|
+
shape = list(shape)
|
|
1643
|
+
bs = _broadcast_shapes(array.shape, shape)
|
|
1644
|
+
data = _broadcast_to_flat(array, bs)
|
|
1645
|
+
return ndarray(bs, array.dtype, data, True)
|
|
1646
|
+
|
|
1647
|
+
# -------------------------------------------------------
|
|
1648
|
+
# Additional Numeric Utilities
|
|
1649
|
+
# -------------------------------------------------------
|
|
1650
|
+
def nan_to_num(x, nan=0.0):
|
|
1651
|
+
x = asarray(x)
|
|
1652
|
+
data = []
|
|
1653
|
+
for v in x._data:
|
|
1654
|
+
if isNaN(v):
|
|
1655
|
+
data.push(nan)
|
|
1656
|
+
elif not isFinite(v) and v > 0:
|
|
1657
|
+
data.push(1.7976931348623157e+308)
|
|
1658
|
+
elif not isFinite(v) and v < 0:
|
|
1659
|
+
data.push(-1.7976931348623157e+308)
|
|
1660
|
+
else:
|
|
1661
|
+
data.push(v)
|
|
1662
|
+
return ndarray(x.shape.slice(), x.dtype, data, True)
|
|
1663
|
+
|
|
1664
|
+
def fix(x):
|
|
1665
|
+
return _apply_ufunc(x, def(v): return Math.trunc(v);)
|
|
1666
|
+
|
|
1667
|
+
def ptp(a, axis=None):
|
|
1668
|
+
a = asarray(a)
|
|
1669
|
+
if axis is None:
|
|
1670
|
+
return _max_list(a._data) - _min_list(a._data)
|
|
1671
|
+
mx = _reduce(a, axis, _max_list, False)
|
|
1672
|
+
mn = _reduce(a, axis, _min_list, False)
|
|
1673
|
+
return subtract(mx, mn)
|
|
1674
|
+
|
|
1675
|
+
def _count_nonzero_fn(data):
|
|
1676
|
+
c = 0
|
|
1677
|
+
for v in data:
|
|
1678
|
+
if v:
|
|
1679
|
+
c += 1
|
|
1680
|
+
return c
|
|
1681
|
+
|
|
1682
|
+
def count_nonzero(a, axis=None):
|
|
1683
|
+
a = asarray(a)
|
|
1684
|
+
if axis is None:
|
|
1685
|
+
count = 0
|
|
1686
|
+
for v in a._data:
|
|
1687
|
+
if v:
|
|
1688
|
+
count += 1
|
|
1689
|
+
return count
|
|
1690
|
+
return _reduce(a, axis, _count_nonzero_fn, False)
|
|
1691
|
+
|
|
1692
|
+
def bincount(x, weights=None, minlength=0):
|
|
1693
|
+
x = asarray(x)
|
|
1694
|
+
mx = int(_max_list(x._data)) + 1
|
|
1695
|
+
n = Math.max(mx, minlength)
|
|
1696
|
+
counts = _make_filled(n, 0, 'float64')
|
|
1697
|
+
if weights is None:
|
|
1698
|
+
for v in x._data:
|
|
1699
|
+
counts[int(v)] += 1
|
|
1700
|
+
else:
|
|
1701
|
+
weights = asarray(weights)
|
|
1702
|
+
for i in range(x.size):
|
|
1703
|
+
counts[int(x._data[i])] += weights._data[i]
|
|
1704
|
+
return ndarray([n], 'float64', counts, True)
|
|
1705
|
+
|
|
1706
|
+
def ediff1d(ary, to_end=None, to_begin=None):
|
|
1707
|
+
ary = asarray(ary)
|
|
1708
|
+
data = ary._data
|
|
1709
|
+
result = []
|
|
1710
|
+
if to_begin is not None:
|
|
1711
|
+
b = asarray(to_begin)
|
|
1712
|
+
for v in b._data:
|
|
1713
|
+
result.push(v)
|
|
1714
|
+
for i in range(data.length - 1):
|
|
1715
|
+
result.push(data[i + 1] - data[i])
|
|
1716
|
+
if to_end is not None:
|
|
1717
|
+
e = asarray(to_end)
|
|
1718
|
+
for v in e._data:
|
|
1719
|
+
result.push(v)
|
|
1720
|
+
return ndarray([result.length], ary.dtype, result, True)
|
|
1721
|
+
|
|
1722
|
+
def average(a, axis=None, weights=None):
|
|
1723
|
+
a = asarray(a)
|
|
1724
|
+
if weights is None:
|
|
1725
|
+
return mean(a, axis)
|
|
1726
|
+
weights = asarray(weights)
|
|
1727
|
+
s = 0
|
|
1728
|
+
ws = 0
|
|
1729
|
+
for i in range(a.size):
|
|
1730
|
+
s += a._data[i] * weights._data[i]
|
|
1731
|
+
ws += weights._data[i]
|
|
1732
|
+
return s / ws
|
|
1733
|
+
|
|
1734
|
+
def interp(x, xp, fp):
|
|
1735
|
+
xp = asarray(xp)
|
|
1736
|
+
fp = asarray(fp)
|
|
1737
|
+
if jstype(x) is 'number':
|
|
1738
|
+
if x <= xp._data[0]:
|
|
1739
|
+
return fp._data[0]
|
|
1740
|
+
if x >= xp._data[xp.size - 1]:
|
|
1741
|
+
return fp._data[fp.size - 1]
|
|
1742
|
+
for i in range(xp.size - 1):
|
|
1743
|
+
if xp._data[i] <= x and x <= xp._data[i + 1]:
|
|
1744
|
+
t = (x - xp._data[i]) / (xp._data[i + 1] - xp._data[i])
|
|
1745
|
+
return fp._data[i] + t * (fp._data[i + 1] - fp._data[i])
|
|
1746
|
+
return fp._data[fp.size - 1]
|
|
1747
|
+
x = asarray(x)
|
|
1748
|
+
result = []
|
|
1749
|
+
for v in x._data:
|
|
1750
|
+
result.push(interp(v, xp, fp))
|
|
1751
|
+
return ndarray([result.length], 'float64', result, True)
|
|
1752
|
+
|
|
1753
|
+
def trapz(y, x=None, dx=1.0, axis=-1):
|
|
1754
|
+
y = asarray(y)
|
|
1755
|
+
data = y._data
|
|
1756
|
+
if x is not None:
|
|
1757
|
+
x = asarray(x)
|
|
1758
|
+
xdata = x._data
|
|
1759
|
+
s = 0
|
|
1760
|
+
for i in range(data.length - 1):
|
|
1761
|
+
s += (data[i] + data[i + 1]) / 2.0 * (xdata[i + 1] - xdata[i])
|
|
1762
|
+
return s
|
|
1763
|
+
s = 0
|
|
1764
|
+
for i in range(data.length - 1):
|
|
1765
|
+
s += (data[i] + data[i + 1]) / 2.0 * dx
|
|
1766
|
+
return s
|
|
1767
|
+
|
|
1768
|
+
def convolve(a, v, mode='full'):
|
|
1769
|
+
a = asarray(a)
|
|
1770
|
+
v = asarray(v)
|
|
1771
|
+
adata = a._data
|
|
1772
|
+
vdata = v._data
|
|
1773
|
+
na = adata.length
|
|
1774
|
+
nv = vdata.length
|
|
1775
|
+
full_len = na + nv - 1
|
|
1776
|
+
result = _make_filled(full_len, 0, 'float64')
|
|
1777
|
+
for i in range(na):
|
|
1778
|
+
for j in range(nv):
|
|
1779
|
+
result[i + j] += adata[i] * vdata[j]
|
|
1780
|
+
if mode is 'full':
|
|
1781
|
+
return ndarray([full_len], 'float64', result, True)
|
|
1782
|
+
elif mode is 'same':
|
|
1783
|
+
start = Math.floor((nv - 1) / 2)
|
|
1784
|
+
return ndarray([na], 'float64', result.slice(start, start + na), True)
|
|
1785
|
+
else: # valid
|
|
1786
|
+
vlen = na - nv + 1
|
|
1787
|
+
if vlen <= 0:
|
|
1788
|
+
return ndarray([0], 'float64', [], True)
|
|
1789
|
+
start = nv - 1
|
|
1790
|
+
return ndarray([vlen], 'float64', result.slice(start, start + vlen), True)
|
|
1791
|
+
|
|
1792
|
+
# -------------------------------------------------------
|
|
1793
|
+
# Polynomial
|
|
1794
|
+
# -------------------------------------------------------
|
|
1795
|
+
def polyval(p, x):
|
|
1796
|
+
p = asarray(p)
|
|
1797
|
+
if jstype(x) is 'number':
|
|
1798
|
+
result = 0
|
|
1799
|
+
for v in p._data:
|
|
1800
|
+
result = result * x + v
|
|
1801
|
+
return result
|
|
1802
|
+
x = asarray(x)
|
|
1803
|
+
out = []
|
|
1804
|
+
for xv in x._data:
|
|
1805
|
+
result = 0
|
|
1806
|
+
for v in p._data:
|
|
1807
|
+
result = result * xv + v
|
|
1808
|
+
out.push(result)
|
|
1809
|
+
return ndarray([out.length], 'float64', out, True)
|
|
1810
|
+
|
|
1811
|
+
def polyfit(x, y, deg):
|
|
1812
|
+
x = asarray(x)
|
|
1813
|
+
y = asarray(y)
|
|
1814
|
+
n = x.size
|
|
1815
|
+
# Build Vandermonde matrix
|
|
1816
|
+
A = []
|
|
1817
|
+
for i in range(n):
|
|
1818
|
+
row = []
|
|
1819
|
+
for j in range(deg + 1):
|
|
1820
|
+
row.push(Math.pow(x._data[i], deg - j))
|
|
1821
|
+
A.push(row)
|
|
1822
|
+
# Solve least squares via normal equations: (A^T A) c = A^T y
|
|
1823
|
+
# A^T A
|
|
1824
|
+
ATA = []
|
|
1825
|
+
for i in range(deg + 1):
|
|
1826
|
+
ATA.push(_make_filled(deg + 1, 0, 'float64'))
|
|
1827
|
+
for i in range(deg + 1):
|
|
1828
|
+
for j in range(deg + 1):
|
|
1829
|
+
s = 0
|
|
1830
|
+
for k in range(n):
|
|
1831
|
+
s += A[k][i] * A[k][j]
|
|
1832
|
+
ATA[i][j] = s
|
|
1833
|
+
# A^T y
|
|
1834
|
+
ATy = _make_filled(deg + 1, 0, 'float64')
|
|
1835
|
+
for i in range(deg + 1):
|
|
1836
|
+
s = 0
|
|
1837
|
+
for k in range(n):
|
|
1838
|
+
s += A[k][i] * y._data[k]
|
|
1839
|
+
ATy[i] = s
|
|
1840
|
+
# Gaussian elimination
|
|
1841
|
+
m = deg + 1
|
|
1842
|
+
aug = []
|
|
1843
|
+
for i in range(m):
|
|
1844
|
+
row = ATA[i].slice()
|
|
1845
|
+
row.push(ATy[i])
|
|
1846
|
+
aug.push(row)
|
|
1847
|
+
for col in range(m):
|
|
1848
|
+
# Find pivot
|
|
1849
|
+
pivot = col
|
|
1850
|
+
for row in range(col + 1, m):
|
|
1851
|
+
if Math.abs(aug[row][col]) > Math.abs(aug[pivot][col]):
|
|
1852
|
+
pivot = row
|
|
1853
|
+
temp = aug[col]
|
|
1854
|
+
aug[col] = aug[pivot]
|
|
1855
|
+
aug[pivot] = temp
|
|
1856
|
+
if Math.abs(aug[col][col]) < 1e-12:
|
|
1857
|
+
continue
|
|
1858
|
+
for row in range(m):
|
|
1859
|
+
if row is not col:
|
|
1860
|
+
factor = aug[row][col] / aug[col][col]
|
|
1861
|
+
for c in range(m + 1):
|
|
1862
|
+
aug[row][c] -= factor * aug[col][c]
|
|
1863
|
+
result = []
|
|
1864
|
+
for i in range(m):
|
|
1865
|
+
result.push(aug[i][m] / aug[i][i])
|
|
1866
|
+
return ndarray([result.length], 'float64', result, True)
|
|
1867
|
+
|
|
1868
|
+
# -------------------------------------------------------
|
|
1869
|
+
# numpy.random sub-module
|
|
1870
|
+
# -------------------------------------------------------
|
|
1871
|
+
_np_rand_state = {
|
|
1872
|
+
'key': [],
|
|
1873
|
+
'key_i': 0,
|
|
1874
|
+
'key_j': 0
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
_np_rand_get_byte = def():
|
|
1878
|
+
_np_rand_state.key_i = (_np_rand_state.key_i + 1) % 256
|
|
1879
|
+
_np_rand_state.key_j = (_np_rand_state.key_j + _np_rand_state.key[_np_rand_state.key_i]) % 256
|
|
1880
|
+
_np_rand_state.key[_np_rand_state.key_i], _np_rand_state.key[_np_rand_state.key_j] = \
|
|
1881
|
+
_np_rand_state.key[_np_rand_state.key_j], _np_rand_state.key[_np_rand_state.key_i]
|
|
1882
|
+
return _np_rand_state.key[(_np_rand_state.key[_np_rand_state.key_i] + \
|
|
1883
|
+
_np_rand_state.key[_np_rand_state.key_j]) % 256]
|
|
1884
|
+
|
|
1885
|
+
def _np_rand_uniform():
|
|
1886
|
+
n = 0
|
|
1887
|
+
m = 1
|
|
1888
|
+
for i in range(8):
|
|
1889
|
+
n += _np_rand_get_byte() * m
|
|
1890
|
+
m *= 256
|
|
1891
|
+
return v'n / 0x10000000000000000'
|
|
1892
|
+
|
|
1893
|
+
def _np_rand_init(x):
|
|
1894
|
+
_np_rand_state.key_i = _np_rand_state.key_j = 0
|
|
1895
|
+
for i in range(256):
|
|
1896
|
+
_np_rand_state.key[i] = i
|
|
1897
|
+
j = 0
|
|
1898
|
+
for i in range(256):
|
|
1899
|
+
j = (j + _np_rand_state.key[i] + x.charCodeAt(i % x.length)) % 256
|
|
1900
|
+
_np_rand_state.key[i], _np_rand_state.key[j] = _np_rand_state.key[j], _np_rand_state.key[i]
|
|
1901
|
+
|
|
1902
|
+
_np_rand_init(str(Date().getTime()))
|
|
1903
|
+
|
|
1904
|
+
class _NumpyRandom:
|
|
1905
|
+
def seed(self, seed_val):
|
|
1906
|
+
s = seed_val
|
|
1907
|
+
if jstype(s) is 'number':
|
|
1908
|
+
s = str(s)
|
|
1909
|
+
elif jstype(s) is not 'string':
|
|
1910
|
+
s = str(s)
|
|
1911
|
+
_np_rand_init(s)
|
|
1912
|
+
|
|
1913
|
+
def rand(self, *shape):
|
|
1914
|
+
if shape.length is 0:
|
|
1915
|
+
return _np_rand_uniform()
|
|
1916
|
+
shp = list(shape)
|
|
1917
|
+
sz = _compute_size(shp)
|
|
1918
|
+
data = []
|
|
1919
|
+
for i in range(sz):
|
|
1920
|
+
data.push(_np_rand_uniform())
|
|
1921
|
+
return ndarray(shp, 'float64', data, True)
|
|
1922
|
+
|
|
1923
|
+
def randn(self, *shape):
|
|
1924
|
+
if shape.length is 0:
|
|
1925
|
+
u1 = _np_rand_uniform()
|
|
1926
|
+
u2 = _np_rand_uniform()
|
|
1927
|
+
if u1 <= 0:
|
|
1928
|
+
u1 = 1e-300
|
|
1929
|
+
return Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2)
|
|
1930
|
+
shp = list(shape)
|
|
1931
|
+
sz = _compute_size(shp)
|
|
1932
|
+
data = []
|
|
1933
|
+
for i in range(sz):
|
|
1934
|
+
u1 = _np_rand_uniform()
|
|
1935
|
+
u2 = _np_rand_uniform()
|
|
1936
|
+
if u1 <= 0:
|
|
1937
|
+
u1 = 1e-300
|
|
1938
|
+
data.push(Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2))
|
|
1939
|
+
return ndarray(shp, 'float64', data, True)
|
|
1940
|
+
|
|
1941
|
+
def randint(self, low, high=None, size=None):
|
|
1942
|
+
if high is None:
|
|
1943
|
+
high = low
|
|
1944
|
+
low = 0
|
|
1945
|
+
def _one():
|
|
1946
|
+
return low + Math.floor(_np_rand_uniform() * (high - low))
|
|
1947
|
+
if size is None:
|
|
1948
|
+
return _one()
|
|
1949
|
+
if jstype(size) is 'number':
|
|
1950
|
+
size = [int(size)]
|
|
1951
|
+
sz = _compute_size(size)
|
|
1952
|
+
data = []
|
|
1953
|
+
for i in range(sz):
|
|
1954
|
+
data.push(_one())
|
|
1955
|
+
return ndarray(size, 'int32', data, True)
|
|
1956
|
+
|
|
1957
|
+
def random_sample(self, size=None):
|
|
1958
|
+
return self.rand(size) if size is not None else _np_rand_uniform()
|
|
1959
|
+
|
|
1960
|
+
def choice(self, a, size=None, replace=True):
|
|
1961
|
+
if jstype(a) is 'number':
|
|
1962
|
+
a = arange(a)
|
|
1963
|
+
else:
|
|
1964
|
+
a = asarray(a)
|
|
1965
|
+
n = a.size
|
|
1966
|
+
def _one():
|
|
1967
|
+
idx = Math.floor(_np_rand_uniform() * n)
|
|
1968
|
+
return a._data[idx]
|
|
1969
|
+
if size is None:
|
|
1970
|
+
return _one()
|
|
1971
|
+
if jstype(size) is 'number':
|
|
1972
|
+
size = [int(size)]
|
|
1973
|
+
sz = _compute_size(size)
|
|
1974
|
+
data = []
|
|
1975
|
+
for i in range(sz):
|
|
1976
|
+
data.push(_one())
|
|
1977
|
+
return ndarray(size, a.dtype, data, True)
|
|
1978
|
+
|
|
1979
|
+
def uniform(self, low=0.0, high=1.0, size=None):
|
|
1980
|
+
def _one():
|
|
1981
|
+
return low + _np_rand_uniform() * (high - low)
|
|
1982
|
+
if size is None:
|
|
1983
|
+
return _one()
|
|
1984
|
+
if jstype(size) is 'number':
|
|
1985
|
+
size = [int(size)]
|
|
1986
|
+
sz = _compute_size(size)
|
|
1987
|
+
data = []
|
|
1988
|
+
for i in range(sz):
|
|
1989
|
+
data.push(_one())
|
|
1990
|
+
return ndarray(size, 'float64', data, True)
|
|
1991
|
+
|
|
1992
|
+
def normal(self, loc=0.0, scale=1.0, size=None):
|
|
1993
|
+
def _one():
|
|
1994
|
+
u1 = _np_rand_uniform()
|
|
1995
|
+
u2 = _np_rand_uniform()
|
|
1996
|
+
if u1 <= 0:
|
|
1997
|
+
u1 = 1e-300
|
|
1998
|
+
z = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2)
|
|
1999
|
+
return loc + scale * z
|
|
2000
|
+
if size is None:
|
|
2001
|
+
return _one()
|
|
2002
|
+
if jstype(size) is 'number':
|
|
2003
|
+
size = [int(size)]
|
|
2004
|
+
sz = _compute_size(size)
|
|
2005
|
+
data = []
|
|
2006
|
+
for i in range(sz):
|
|
2007
|
+
data.push(_one())
|
|
2008
|
+
return ndarray(size, 'float64', data, True)
|
|
2009
|
+
|
|
2010
|
+
def permutation(self, x):
|
|
2011
|
+
if jstype(x) is 'number':
|
|
2012
|
+
a = arange(x)
|
|
2013
|
+
else:
|
|
2014
|
+
a = asarray(x).ravel()
|
|
2015
|
+
data = a._data.slice()
|
|
2016
|
+
n = data.length
|
|
2017
|
+
for i in range(n - 1, 0, -1):
|
|
2018
|
+
j = Math.floor(_np_rand_uniform() * (i + 1))
|
|
2019
|
+
temp = data[i]
|
|
2020
|
+
data[i] = data[j]
|
|
2021
|
+
data[j] = temp
|
|
2022
|
+
return ndarray([n], a.dtype, data, True)
|
|
2023
|
+
|
|
2024
|
+
random = _NumpyRandom()
|
|
2025
|
+
|
|
2026
|
+
# -------------------------------------------------------
|
|
2027
|
+
# numpy.linalg sub-module
|
|
2028
|
+
# -------------------------------------------------------
|
|
2029
|
+
class _NumpyLinAlg:
|
|
2030
|
+
def inv(self, a):
|
|
2031
|
+
a = asarray(a)
|
|
2032
|
+
n = a.shape[0]
|
|
2033
|
+
# Gauss-Jordan elimination with identity augmented
|
|
2034
|
+
aug = []
|
|
2035
|
+
for i in range(n):
|
|
2036
|
+
row = []
|
|
2037
|
+
for j in range(n):
|
|
2038
|
+
row.push(a._data[i * n + j])
|
|
2039
|
+
for j in range(n):
|
|
2040
|
+
row.push(1 if i is j else 0)
|
|
2041
|
+
aug.push(row)
|
|
2042
|
+
for col in range(n):
|
|
2043
|
+
# Find pivot
|
|
2044
|
+
pivot = col
|
|
2045
|
+
for row in range(col + 1, n):
|
|
2046
|
+
if Math.abs(aug[row][col]) > Math.abs(aug[pivot][col]):
|
|
2047
|
+
pivot = row
|
|
2048
|
+
temp = aug[col]
|
|
2049
|
+
aug[col] = aug[pivot]
|
|
2050
|
+
aug[pivot] = temp
|
|
2051
|
+
if Math.abs(aug[col][col]) < 1e-12:
|
|
2052
|
+
raise ValueError("linalg.inv: singular matrix")
|
|
2053
|
+
factor = aug[col][col]
|
|
2054
|
+
for c in range(2 * n):
|
|
2055
|
+
aug[col][c] /= factor
|
|
2056
|
+
for row in range(n):
|
|
2057
|
+
if row is not col:
|
|
2058
|
+
f = aug[row][col]
|
|
2059
|
+
for c in range(2 * n):
|
|
2060
|
+
aug[row][c] -= f * aug[col][c]
|
|
2061
|
+
result = []
|
|
2062
|
+
for i in range(n):
|
|
2063
|
+
for j in range(n):
|
|
2064
|
+
result.push(aug[i][n + j])
|
|
2065
|
+
return ndarray([n, n], 'float64', result, True)
|
|
2066
|
+
|
|
2067
|
+
def solve(self, a, b):
|
|
2068
|
+
a = asarray(a)
|
|
2069
|
+
b = asarray(b)
|
|
2070
|
+
n = a.shape[0]
|
|
2071
|
+
aug = []
|
|
2072
|
+
for i in range(n):
|
|
2073
|
+
row = []
|
|
2074
|
+
for j in range(n):
|
|
2075
|
+
row.push(a._data[i * n + j])
|
|
2076
|
+
row.push(b._data[i])
|
|
2077
|
+
aug.push(row)
|
|
2078
|
+
for col in range(n):
|
|
2079
|
+
pivot = col
|
|
2080
|
+
for row in range(col + 1, n):
|
|
2081
|
+
if Math.abs(aug[row][col]) > Math.abs(aug[pivot][col]):
|
|
2082
|
+
pivot = row
|
|
2083
|
+
temp = aug[col]
|
|
2084
|
+
aug[col] = aug[pivot]
|
|
2085
|
+
aug[pivot] = temp
|
|
2086
|
+
if Math.abs(aug[col][col]) < 1e-12:
|
|
2087
|
+
raise ValueError("linalg.solve: singular matrix")
|
|
2088
|
+
factor = aug[col][col]
|
|
2089
|
+
for c in range(n + 1):
|
|
2090
|
+
aug[col][c] /= factor
|
|
2091
|
+
for row in range(n):
|
|
2092
|
+
if row is not col:
|
|
2093
|
+
f = aug[row][col]
|
|
2094
|
+
for c in range(n + 1):
|
|
2095
|
+
aug[row][c] -= f * aug[col][c]
|
|
2096
|
+
result = []
|
|
2097
|
+
for i in range(n):
|
|
2098
|
+
result.push(aug[i][n])
|
|
2099
|
+
return ndarray([n], 'float64', result, True)
|
|
2100
|
+
|
|
2101
|
+
linalg = _NumpyLinAlg()
|