Compare commits

...

66 commits

Author SHA1 Message Date
c66509f66e add test of boolean slicing 2020-03-30 15:34:26 -05:00
53c158bde3 ndarray.c: circuitpython needs translate() for mp_raise 2020-03-30 15:34:01 -05:00
cbe41034a3 ndarray.h: provide mp_obj_is_bool for circuitpython 2020-03-30 15:33:45 -05:00
Zoltán Vörös
b3562ae78c Boolean indexing raises TypeError, if index is not of Boolean type 2020-03-30 12:58:04 +02:00
Zoltán Vörös
ea4a7422ef fixing Boolean indexing issue 2020-03-30 12:45:54 +02:00
Zoltán Vörös
a91b36986d
Merge pull request #65 from jepler/slice-length-crash
slice_length: avoid implementation-defined division by negative number
2020-03-17 08:15:48 +01:00
3dc52575f0 slice_length: avoid implementation-defined division by negative number
In CircuitPython (only), a the slice assignment to [-1👎-3] of an
ndarray of length 1 caused a crash.  This appears to be because in
CircuitPython, the internal pointer of an empty array was NULL rather than
pointing at some memory which happened to be valid and assignable.

This appears to be a corner case of how integer promotion rules work in C.
The expression `slice.stop - slice.start + (slice.step + correction)`
is type `unsigned long` and on a LP64 platform its value is
18446744073709551614.  This led to the function returning that this slice
had length 1 instead, during the automated tests.

By casting to signed types capable of holding indices and sizes, the
problem is corrected on both platforms.
2020-03-16 22:09:39 -05:00
Zoltán Vörös
155e6eea60
Merge pull request #63 from v923z/round
added around and arctan2 to the vector sub-module, and extended ndarray initialisation options
2020-03-16 22:19:05 +01:00
Zoltán Vörös
94e5b304d2 added arctan2 to vectorise.c 2020-03-16 19:36:37 +01:00
Zoltán Vörös
49e2e68f9b added around to vectorise.c, and implemented array initialiation from another ndarray 2020-03-12 17:28:23 +01:00
Zoltán Vörös
3e53136a93 ndarrays can now be initialised from ndarrays 2020-03-12 07:17:54 +01:00
Zoltán Vörös
7ec399c58b
Merge pull request #62 from v923z/cholesky-test
added tests for linalg, and poly
2020-03-11 21:38:35 +01:00
Zoltán Vörös
47fd7964e8 generated .exp test files 2020-03-11 21:31:36 +01:00
Zoltán Vörös
e3a74453a8 trying to fix test routines 2020-03-11 18:53:06 +01:00
Zoltán Vörös
18d13e4252 added tests for inv, and det 2020-03-11 17:15:30 +01:00
Zoltán Vörös
cb1b1d352b added test files for the poly sub-module 2020-03-11 07:31:00 +01:00
Zoltán Vörös
c354657eda added test files for the Cholesky decomposition 2020-03-11 07:04:26 +01:00
Zoltán Vörös
037cd6e733 re-named spectrum->spectrogram, updated manual 2020-03-10 21:11:44 +01:00
Jeff Epler
1095994a4a
Merge pull request #59 from v923z/cholesky
added Cholesky decomposition to linalg.c, updated documentation
2020-03-10 14:51:48 -05:00
Jeff Epler
ea2bf3c236
Merge pull request #57 from v923z/spectrum
moved spectrum to extras module
2020-03-10 14:51:37 -05:00
Zoltán Vörös
525fbb6527 added Cholesky decomposition to linalg.c, updated documentation 2020-03-10 20:40:11 +01:00
Zoltán Vörös
5d0eab244b added function declarations to linalg.h 2020-03-09 21:22:31 +01:00
Zoltán Vörös
6b3d43846f moved spectrum to extras module 2020-03-09 20:47:58 +01:00
Jeff Epler
8241546378
Merge pull request #56 from v923z/workflow
include only code changes in workflow file
2020-03-07 20:31:00 -06:00
Zoltán Vörös
0434045293
Update README.md
Clarified statement on CP builds.
2020-03-07 09:46:50 +01:00
Zoltán Vörös
34c2355a2a tried to fix workflow file 2020-03-07 09:36:10 +01:00
Zoltán Vörös
0faa89e3a5 tried to fix workflow file 2020-03-07 09:33:48 +01:00
Zoltán Vörös
c0979509b4 run CI only for changes in code/, and tests/ 2020-03-07 09:31:30 +01:00
Zoltán Vörös
ef2c91c1fb
Merge pull request #55 from v923z/readme
updated readme
2020-03-06 21:18:54 +01:00
Zoltán Vörös
fb1153d3b3 updated readme 2020-03-06 21:15:49 +01:00
Zoltán Vörös
847c7f9d63
Merge pull request #54 from v923z/readme
updated readme
2020-03-06 18:31:04 +01:00
Zoltán Vörös
ab8b5fe4b1 updated readme 2020-03-06 18:27:59 +01:00
Zoltán Vörös
700e3ff1ac
Merge pull request #53 from v923z/jepler-patch-1
Update README.md with circuitpython mentions
2020-03-05 19:24:42 +01:00
Jeff Epler
a35c4ff1d8
Update README.md with circuitpython mentions 2020-03-05 07:22:22 -06:00
Zoltán Vörös
a6ebfc1ade
Merge pull request #52 from codemee/master
Deleting "#define MODULE_ULAB_ENABLED (1)"
2020-03-02 07:57:33 +01:00
codemee
882294dabf
Deleting "#define MODULE_ULAB_ENABLED (1)"
Since the micropython.mk file has added the following line

```
CFLAGS_EXTRA = -DMODULE_ULAB_ENABLED=1
```

There's no need to add #define MODULE_ULAB_ENABLED (1) in the mpconfigport.h.Or it would make redefined errors while compiling code.
2020-03-02 12:26:19 +08:00
Zoltán Vörös
adda973b56
Merge pull request #50 from jepler/slicing-fixes
Slicing fixes
2020-03-01 18:47:59 +01:00
Jeff Epler
903016ec44 slicing: add test of slice assignment
This tests that ulab and python3/numpy match on various slice assignments
that preserve the length of the array.  slice assignments that change
the length of the array are not tested.

Unlike the case of "load slice", this case of "modify slice" is not
compared to the built in list type, since "modify slice" is only
implemented in micropython for simple (stride=1) slices.
2020-02-29 17:11:56 -06:00
Jeff Epler
380b8b0347 Add new test of slicing
Closes: #32
2020-02-29 17:00:53 -06:00
Jeff Epler
f9fabc5079 Fix handling of negative indices
I don't know why, but mp_seq_get_fast_slice_indexes adjusts "stop" in a
surprising way, and that led to the (remaining) differences in slicing
between ulab and built-in lists.

    // If the index is negative then stop points to the last item, not after it
    if (indexes->step < 0) {
        indexes->stop++;
    }

Call the underlying routine, mp_obj_slice_indices, instead.
2020-02-29 17:00:42 -06:00
Jeff Epler
585513ce76 Return empty slices as empty ndarrays, not exceptions
This matches the behavior of built-in lists as well as numpy
2020-02-29 16:57:59 -06:00
Jeff Epler
2ea9656d3f build: include debug information (may also disable optimization)
.. this makes it much more pleasant to trace down problems using gdb.
2020-02-29 16:57:09 -06:00
Jeff Epler
66b89de8c7 Always include creation functions 2020-02-27 14:07:04 -06:00
Jeff Epler
844b85018b
Merge pull request #49 from jepler/gitignore
ignore files created by ./build.sh
2020-02-27 13:58:25 -06:00
Jeff Epler
1c1a693a2b
Merge pull request #48 from v923z/create
created new create sub-module for ndarray initialisation functions
2020-02-27 13:58:14 -06:00
Jeff Epler
f81e950513 ignore files created by ./build.sh 2020-02-27 13:56:09 -06:00
Jeff Epler
ffff7606c8 fix tests after 'eye' was moved 2020-02-27 13:53:29 -06:00
Zoltán Vörös
bee25781b9 added new source file... 2020-02-27 20:46:52 +01:00
Zoltán Vörös
47bf2ec9a7 created new create sub-module for ndarray initialisation functions 2020-02-27 20:39:13 +01:00
Jeff Epler
badeee48df
Merge pull request #47 from jepler/local-build-script
a script to build and run tests locally
2020-02-27 10:12:03 -06:00
Jeff Epler
e370e56a15 a script to build and run tests locally 2020-02-27 10:11:34 -06:00
Jeff Epler
db5f1f85bb
Merge pull request #46 from jepler/ndarray-properties-sort
Ndarray properties sort
2020-02-27 10:11:17 -06:00
Jeff Epler
2bddc94df5
Merge pull request #45 from jepler/move-ones-zeros
Move zeros(), ones() to base ulab module
2020-02-27 10:08:29 -06:00
Jeff Epler
aa5ef4afb9 Enable sort method in circuitpython 2020-02-27 10:06:33 -06:00
Jeff Epler
d99d834d87 Enable properties in circuitpython
I verified that these work for us as coded.
2020-02-27 10:06:27 -06:00
Jeff Epler
83479f115b Move zeros(), ones() to base ulab module 2020-02-27 10:05:50 -06:00
924dc7012a
Merge pull request #44 from jepler/circuitpy-fixes
Circuitpy fixes
2020-02-27 09:29:43 -06:00
Jeff Epler
daaacac16f Remove CIRCUITPY special cases 2020-02-27 08:56:07 -06:00
Jeff Epler
aa4d53e292 Use circuitpy-compat for none 2020-02-27 08:56:04 -06:00
3febd79aa0
Merge pull request #41 from v923z/2dim
Split ulab into multiple modules
2020-02-26 11:29:17 -06:00
Zoltán Vörös
7e2be88dff Merge branch '2dim' of github.com:v923z/micropython-ulab into 2dim
added circuitpython-related stuff to code and manual
2020-02-26 18:06:19 +01:00
Zoltán Vörös
e0e840f6d5 added circuitpython-related stuff to the manual 2020-02-26 18:05:49 +01:00
102ba5032e add missing expected-file 2020-02-18 21:40:31 -06:00
b83ed3e2ca add more tests 2020-02-18 21:36:49 -06:00
1e5ebe739d numerical: add __name__ 2020-02-18 21:27:05 -06:00
Zoltán Vörös
8300de7f11 backup commit, absolutely nothing essential 2020-02-16 19:53:30 +01:00
42 changed files with 3112 additions and 6228 deletions

View file

@ -3,6 +3,10 @@ name: Build CI
on:
push:
pull_request:
paths:
- 'code/'
- 'tests/'
- '.github/workflows/'
release:
types: [published]
check_suite:

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/micropython
/*.exp
/*.out

View file

@ -1,25 +1,32 @@
# micropython-ulab
ulab is a numpy-like array manipulation library for micropython.
The module is written in C, defines compact containers for numerical
data, and is fast.
`ulab` is a `numpy`-like array manipulation library for `micropython` and `CircuitPython`.
The module is written in C, defines compact containers for numerical
data, and is fast. The library is a software-only standard `micropython` user module,
i.e., it has no hardware dependencies, and can be compiled for any platform.
The `float` implementation of `micropython` (`float`, or `double`) is automatically detected.
Documentation can be found under https://micropython-ulab.readthedocs.io/en/latest/
The source for the manual is in https://github.com/v923z/micropython-ulab/blob/master/docs/ulab-manual.ipynb,
while developer help is in https://github.com/v923z/micropython-ulab/blob/master/docs/ulab.ipynb.
Documentation can be found under https://micropython-ulab.readthedocs.io/en/latest/.
# Firmware
Firmware for pyboard.v.1.1, and PYBD_SF6 is updated once in a while, and can be downloaded
from https://github.com/v923z/micropython-ulab/releases.
Firmware for pyboard.v.1.1, and PYBD_SF6 is released once in a while, and can be downloaded
from https://github.com/v923z/micropython-ulab/releases. Since a number of features can be
set in the firmware (threading, support for SD card, LEDs, user switch etc.), and it is
impossible to create something that suits everyone, these releases should only be used for
quick testing of `ulab`. Otherwise, compilation from the source is required with
the appropriate settings, which are usually defined in the `mpconfigboard.h` file of the port
in question.
`ulab` is also included in most development builds of `CircuitPython` for SAMD51 and nRF microcontrollers.
## Compiling
If you want to try the latest version of `ulab`, or your hardware is
If you want to try the latest version of `ulab` on micropython, or your hardware is
different to pyboard.v.1.1, or PYBD_SF6, the firmware can be compiled
from the source by following these steps:
First, you have to clone the micropython repository by running
First, you have to clone the `micropython` repository by running
```
git clone https://github.com/micropython/micropython.git
@ -30,18 +37,13 @@ on the command line. This will create a new repository with the name `micropytho
git clone https://github.com/v923z/micropython-ulab.git ulab
```
Then you have to include `ulab` in the compilation process by editing `mpconfigport.h` of the directory of the port for which you want to compile, so, still on the command line, navigate to `micropython/ports/unix`, or `micropython/ports/stm32`, or whichever port is your favourite, and edit the `mpconfigport.h` file there. All you have to do is add a single line at the end:
```
#define MODULE_ULAB_ENABLED (1)
```
This line will inform the compiler that you want `ulab` in the resulting firmware. If you don't have the cross-compiler installed, your might want to do that now, for instance on Linux by executing
If you don't have the cross-compiler installed, your might want to do that now, for instance on Linux by executing
```
sudo apt-get install gcc-arm-none-eabi
```
If that was successful, you can try to run the make command in the port's directory as
If this step was successful, you can try to run the `make` command in the port's directory as
```
make BOARD=PYBV11 USER_C_MODULES=../../../ulab all
```
@ -49,8 +51,9 @@ which will prepare the firmware for pyboard.v.11. Similarly,
```
make BOARD=PYBD_SF6 USER_C_MODULES=../../../ulab all
```
will compile for the SF6 member of the PYBD series. Provided that you managed to compile the firmware, you would upload that by running
either
will compile for the SF6 member of the PYBD series. If your target is `unix`, you don't need to specify the `BOARD` parameter.
Provided that you managed to compile the firmware, you would upload that by running either
```
dfu-util --alt 0 -D firmware.dfu
```

17
build.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/sh
set -e
HERE="$(dirname -- "$(readlink -f -- "${0}")" )"
[ -e micropython/py/py.mk ] || git clone https://github.com/micropython/micropython
[ -e micropython/lib/libffi/autogen.sh ] || (cd micropython && git submodule update --init lib/libffi )
#git clone https://github.com/micropython/micropython
make -C micropython/mpy-cross -j$(nproc)
make -C micropython/ports/unix -j$(nproc) deplibs
make -C micropython/ports/unix -j$(nproc) USER_C_MODULES="${HERE}" DEBUG=1 STRIP=:
if ! env MICROPY_MICROPYTHON=micropython/ports/unix/micropython micropython/tests/run-tests -d tests; then
for exp in *.exp; do
testbase=$(basename $exp .exp);
echo -e "\nFAILURE $testbase";
diff -u $testbase.exp $testbase.out;
done
fi

155
code/create.c Normal file
View file

@ -0,0 +1,155 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
* 2019-2020 Zoltán Vörös
*/
#include "py/obj.h"
#include "py/runtime.h"
#include "create.h"
mp_obj_t create_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t kind) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} } ,
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint8_t dtype = args[1].u_int;
if(!MP_OBJ_IS_INT(args[0].u_obj) && !MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
}
ndarray_obj_t *ndarray = NULL;
if(MP_OBJ_IS_INT(args[0].u_obj)) {
size_t n = mp_obj_get_int(args[0].u_obj);
ndarray = create_new_ndarray(1, n, dtype);
} else if(MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0].u_obj);
if(tuple->len != 2) {
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
}
ndarray = create_new_ndarray(mp_obj_get_int(tuple->items[0]),
mp_obj_get_int(tuple->items[1]), dtype);
}
if(kind == 1) {
mp_obj_t one = mp_obj_new_int(1);
for(size_t i=0; i < ndarray->array->len; i++) {
mp_binary_set_val_array(dtype, ndarray->array->items, i, one);
}
}
return MP_OBJ_FROM_PTR(ndarray);
}
mp_obj_t create_zeros(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return create_zeros_ones(n_args, pos_args, kw_args, 0);
}
MP_DEFINE_CONST_FUN_OBJ_KW(create_zeros_obj, 0, create_zeros);
mp_obj_t create_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return create_zeros_ones(n_args, pos_args, kw_args, 1);
}
MP_DEFINE_CONST_FUN_OBJ_KW(create_ones_obj, 0, create_ones);
mp_obj_t create_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_M, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_k, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
size_t n = args[0].u_int, m;
int16_t k = args[2].u_int;
uint8_t dtype = args[3].u_int;
if(args[1].u_rom_obj == mp_const_none) {
m = n;
} else {
m = mp_obj_get_int(args[1].u_rom_obj);
}
ndarray_obj_t *ndarray = create_new_ndarray(m, n, dtype);
mp_obj_t one = mp_obj_new_int(1);
size_t i = 0;
if((k >= 0) && (k < n)) {
while(k < n) {
mp_binary_set_val_array(dtype, ndarray->array->items, i*n+k, one);
k++;
i++;
}
} else if((k < 0) && (-k < m)) {
k = -k;
i = 0;
while(k < m) {
mp_binary_set_val_array(dtype, ndarray->array->items, k*n+i, one);
k++;
i++;
}
}
return MP_OBJ_FROM_PTR(ndarray);
}
MP_DEFINE_CONST_FUN_OBJ_KW(create_eye_obj, 0, create_eye);
mp_obj_t create_linspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_num, MP_ARG_INT, {.u_int = 50} },
{ MP_QSTR_endpoint, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_true} },
{ MP_QSTR_retstep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_false} },
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(2, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint16_t len = args[2].u_int;
if(len < 2) {
mp_raise_ValueError(translate("number of points must be at least 2"));
}
mp_float_t value, step;
value = mp_obj_get_float(args[0].u_obj);
uint8_t typecode = args[5].u_int;
if(args[3].u_obj == mp_const_true) step = (mp_obj_get_float(args[1].u_obj)-value)/(len-1);
else step = (mp_obj_get_float(args[1].u_obj)-value)/len;
ndarray_obj_t *ndarray = create_new_ndarray(1, len, typecode);
if(typecode == NDARRAY_UINT8) {
uint8_t *array = (uint8_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (uint8_t)value;
} else if(typecode == NDARRAY_INT8) {
int8_t *array = (int8_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (int8_t)value;
} else if(typecode == NDARRAY_UINT16) {
uint16_t *array = (uint16_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (uint16_t)value;
} else if(typecode == NDARRAY_INT16) {
int16_t *array = (int16_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (int16_t)value;
} else {
mp_float_t *array = (mp_float_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = value;
}
if(args[4].u_obj == mp_const_false) {
return MP_OBJ_FROM_PTR(ndarray);
} else {
mp_obj_t tuple[2];
tuple[0] = ndarray;
tuple[1] = mp_obj_new_float(step);
return mp_obj_new_tuple(2, tuple);
}
}
MP_DEFINE_CONST_FUN_OBJ_KW(create_linspace_obj, 2, create_linspace);

29
code/create.h Normal file
View file

@ -0,0 +1,29 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
* 2019-2020 Zoltán Vörös
*/
#ifndef _CREATE_
#define _CREATE_
#include "ulab.h"
#include "ndarray.h"
/*
mp_obj_t create_zeros(size_t , const mp_obj_t *, mp_map_t *);
mp_obj_t create_ones(size_t , const mp_obj_t *, mp_map_t *);
mp_obj_t create_eye(size_t , const mp_obj_t *, mp_map_t *);
mp_obj_t create_linspace(size_t , const mp_obj_t *, mp_map_t *);
*/
MP_DECLARE_CONST_FUN_OBJ_KW(create_ones_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(create_zeros_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(create_eye_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(create_linspace_obj);
#endif

View file

@ -19,13 +19,24 @@
#if ULAB_EXTRAS_MODULE
STATIC const mp_rom_map_elem_t ulab_filter_globals_table[] = {
mp_obj_t extras_spectrogram(size_t n_args, const mp_obj_t *args) {
if(n_args == 2) {
return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_SPECTRUM);
} else {
return fft_fft_ifft_spectrum(n_args, args[0], mp_const_none, FFT_SPECTRUM);
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(extras_spectrogram_obj, 1, 2, extras_spectrogram);
STATIC const mp_rom_map_elem_t ulab_extras_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_extras) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_spectrogram), (mp_obj_t)&extras_spectrogram_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_ulab_extras_globals, ulab_extras_globals_table);
mp_obj_module_t ulab_filter_module = {
mp_obj_module_t ulab_extras_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_extras_globals,
};

View file

@ -14,6 +14,7 @@
#include "ulab.h"
#include "ndarray.h"
#include "fft.h"
#if ULAB_EXTRAS_MODULE

View file

@ -23,12 +23,6 @@
#if ULAB_FFT_MODULE
enum FFT_TYPE {
FFT_FFT,
FFT_IFFT,
FFT_SPECTRUM,
};
void fft_kernel(mp_float_t *real, mp_float_t *imag, int n, int isign) {
// This is basically a modification of four1 from Numerical Recipes
// The main difference is that this function takes two arrays, one
@ -172,22 +166,10 @@ mp_obj_t fft_ifft(size_t n_args, const mp_obj_t *args) {
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj, 1, 2, fft_ifft);
mp_obj_t fft_spectrum(size_t n_args, const mp_obj_t *args) {
if(n_args == 2) {
return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_SPECTRUM);
} else {
return fft_fft_ifft_spectrum(n_args, args[0], mp_const_none, FFT_SPECTRUM);
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj, 1, 2, fft_spectrum);
#if !CIRCUITPY
STATIC const mp_rom_map_elem_t ulab_fft_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_fft) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_fft), (mp_obj_t)&fft_fft_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifft), (mp_obj_t)&fft_ifft_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_spectrum), (mp_obj_t)&fft_spectrum_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_ulab_fft_globals, ulab_fft_globals_table);
@ -196,6 +178,5 @@ mp_obj_module_t ulab_fft_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_fft_globals,
};
#endif
#endif

View file

@ -19,6 +19,12 @@
#define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; }
enum FFT_TYPE {
FFT_FFT,
FFT_IFFT,
FFT_SPECTRUM,
};
#if ULAB_FFT_MODULE
extern mp_obj_module_t ulab_fft_module;
@ -27,5 +33,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj);
mp_obj_t fft_fft_ifft_spectrum(size_t , mp_obj_t , mp_obj_t , uint8_t );
#endif
#endif

View file

@ -84,7 +84,6 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
MP_DEFINE_CONST_FUN_OBJ_KW(filter_convolve_obj, 2, filter_convolve);
#if !CIRCUITPY
STATIC const mp_rom_map_elem_t ulab_filter_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_filter) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_convolve), (mp_obj_t)&filter_convolve_obj },
@ -96,6 +95,5 @@ mp_obj_module_t ulab_filter_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_filter_globals,
};
#endif
#endif

View file

@ -167,95 +167,6 @@ mp_obj_t linalg_dot(mp_obj_t _m1, mp_obj_t _m2) {
MP_DEFINE_CONST_FUN_OBJ_2(linalg_dot_obj, linalg_dot);
mp_obj_t linalg_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t kind) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} } ,
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint8_t dtype = args[1].u_int;
if(!MP_OBJ_IS_INT(args[0].u_obj) && !MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
}
ndarray_obj_t *ndarray = NULL;
if(MP_OBJ_IS_INT(args[0].u_obj)) {
size_t n = mp_obj_get_int(args[0].u_obj);
ndarray = create_new_ndarray(1, n, dtype);
} else if(MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0].u_obj);
if(tuple->len != 2) {
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
}
ndarray = create_new_ndarray(mp_obj_get_int(tuple->items[0]),
mp_obj_get_int(tuple->items[1]), dtype);
}
if(kind == 1) {
mp_obj_t one = mp_obj_new_int(1);
for(size_t i=0; i < ndarray->array->len; i++) {
mp_binary_set_val_array(dtype, ndarray->array->items, i, one);
}
}
return MP_OBJ_FROM_PTR(ndarray);
}
mp_obj_t linalg_zeros(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return linalg_zeros_ones(n_args, pos_args, kw_args, 0);
}
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_zeros_obj, 0, linalg_zeros);
mp_obj_t linalg_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return linalg_zeros_ones(n_args, pos_args, kw_args, 1);
}
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_ones_obj, 0, linalg_ones);
mp_obj_t linalg_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_M, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_k, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
size_t n = args[0].u_int, m;
int16_t k = args[2].u_int;
uint8_t dtype = args[3].u_int;
if(args[1].u_rom_obj == mp_const_none) {
m = n;
} else {
m = mp_obj_get_int(args[1].u_rom_obj);
}
ndarray_obj_t *ndarray = create_new_ndarray(m, n, dtype);
mp_obj_t one = mp_obj_new_int(1);
size_t i = 0;
if((k >= 0) && (k < n)) {
while(k < n) {
mp_binary_set_val_array(dtype, ndarray->array->items, i*n+k, one);
k++;
i++;
}
} else if((k < 0) && (-k < m)) {
k = -k;
i = 0;
while(k < m) {
mp_binary_set_val_array(dtype, ndarray->array->items, k*n+i, one);
k++;
i++;
}
}
return MP_OBJ_FROM_PTR(ndarray);
}
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_eye_obj, 0, linalg_eye);
mp_obj_t linalg_det(mp_obj_t oin) {
if(!MP_OBJ_IS_TYPE(oin, &ulab_ndarray_type)) {
mp_raise_TypeError(translate("function defined for ndarrays only"));
@ -424,17 +335,73 @@ mp_obj_t linalg_eig(mp_obj_t oin) {
MP_DEFINE_CONST_FUN_OBJ_1(linalg_eig_obj, linalg_eig);
#if !CIRCUITPY
mp_obj_t linalg_cholesky(mp_obj_t oin) {
if(!MP_OBJ_IS_TYPE(oin, &ulab_ndarray_type)) {
mp_raise_TypeError(translate("function is defined for ndarrays only"));
}
ndarray_obj_t *in = MP_OBJ_TO_PTR(oin);
if(in->m != in->n) {
mp_raise_ValueError(translate("input must be square matrix"));
}
ndarray_obj_t *L = create_new_ndarray(in->n, in->n, NDARRAY_FLOAT);
mp_float_t *array = (mp_float_t *)L->array->items;
size_t pos = 0;
for(size_t m=0; m < in->m; m++) { // rows
for(size_t n=0; n < in->n; n++) { // columns
array[m*in->m+n] = ndarray_get_float_value(in->array->items, in->array->typecode, pos++);
}
}
// make sure the matrix is symmetric
for(size_t m=0; m < in->m; m++) { // rows
for(size_t n=m+1; n < in->n; n++) { // columns
// compare entry (m, n) to (n, m)
if(epsilon < MICROPY_FLOAT_C_FUN(fabs)(array[m*in->n + n] - array[n*in->n + m])) {
mp_raise_ValueError(translate("input matrix is asymmetric"));
}
}
}
// this is actually not needed, but Cholesky in numpy returns the lower triangular matrix
for(size_t i=0; i < in->m; i++) { // rows
for(size_t j=i+1; j < in->n; j++) { // columns
array[i*in->m + j] = 0.0;
}
}
mp_float_t sum = 0.0;
for(size_t i=0; i < in->m; i++) { // rows
for(size_t j=0; j <= i; j++) { // columns
sum = array[i*in->m + j];
for(size_t k=0; k < j; k++) {
sum -= array[i*in->n + k] * array[j*in->n + k];
}
if(i == j) {
if(sum <= 0.0) {
mp_raise_ValueError(translate("matrix is not positive definite"));
} else {
array[i*in->m+i] = MICROPY_FLOAT_C_FUN(sqrt)(sum);
}
} else {
array[i*in->m + j] = sum / array[j*in->m+j];
}
}
}
return MP_OBJ_FROM_PTR(L);
}
MP_DEFINE_CONST_FUN_OBJ_1(linalg_cholesky_obj, linalg_cholesky);
STATIC const mp_rom_map_elem_t ulab_linalg_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_linalg) },
{ MP_ROM_QSTR(MP_QSTR_size), (mp_obj_t)&linalg_size_obj },
{ MP_ROM_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj },
{ MP_ROM_QSTR(MP_QSTR_dot), (mp_obj_t)&linalg_dot_obj },
{ MP_ROM_QSTR(MP_QSTR_zeros), (mp_obj_t)&linalg_zeros_obj },
{ MP_ROM_QSTR(MP_QSTR_ones), (mp_obj_t)&linalg_ones_obj },
{ MP_ROM_QSTR(MP_QSTR_eye), (mp_obj_t)&linalg_eye_obj },
{ MP_ROM_QSTR(MP_QSTR_det), (mp_obj_t)&linalg_det_obj },
{ MP_ROM_QSTR(MP_QSTR_eig), (mp_obj_t)&linalg_eig_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_linalg) },
{ MP_ROM_QSTR(MP_QSTR_size), (mp_obj_t)&linalg_size_obj },
{ MP_ROM_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj },
{ MP_ROM_QSTR(MP_QSTR_dot), (mp_obj_t)&linalg_dot_obj },
{ MP_ROM_QSTR(MP_QSTR_det), (mp_obj_t)&linalg_det_obj },
{ MP_ROM_QSTR(MP_QSTR_eig), (mp_obj_t)&linalg_eig_obj },
{ MP_ROM_QSTR(MP_QSTR_cholesky), (mp_obj_t)&linalg_cholesky_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_ulab_linalg_globals, ulab_linalg_globals_table);
@ -443,6 +410,5 @@ mp_obj_module_t ulab_linalg_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_linalg_globals,
};
#endif
#endif

View file

@ -31,5 +31,11 @@ bool linalg_invert_matrix(mp_float_t *, size_t );
extern mp_obj_module_t ulab_linalg_module;
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_size_obj);
MP_DECLARE_CONST_FUN_OBJ_1(linalg_inv_obj);
MP_DECLARE_CONST_FUN_OBJ_2(linalg_dot_obj);
MP_DECLARE_CONST_FUN_OBJ_1(linalg_det_obj);
MP_DECLARE_CONST_FUN_OBJ_1(linalg_eig_obj);
#endif
#endif

View file

@ -3,6 +3,7 @@ USERMODULES_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(USERMODULES_DIR)/ndarray.c
SRC_USERMOD += $(USERMODULES_DIR)/create.c
SRC_USERMOD += $(USERMODULES_DIR)/linalg.c
SRC_USERMOD += $(USERMODULES_DIR)/vectorise.c
SRC_USERMOD += $(USERMODULES_DIR)/poly.c

View file

@ -167,8 +167,27 @@ STATIC uint8_t ndarray_init_helper(size_t n_args, const mp_obj_t *pos_args, mp_m
STATIC mp_obj_t ndarray_make_new_core(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args, mp_map_t *kw_args) {
uint8_t dtype = ndarray_init_helper(n_args, args, kw_args);
if(MP_OBJ_IS_TYPE(args[0], &ulab_ndarray_type)) {
ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(args[0]);
ndarray_obj_t *ndarray_new = create_new_ndarray(ndarray->m, ndarray->n, dtype);
mp_obj_t item;
if((ndarray->array->typecode == NDARRAY_FLOAT) &&(dtype != NDARRAY_FLOAT)) {
for(size_t i=0; i < ndarray->array->len; i++) {
mp_float_t f = ndarray_get_float_value(ndarray->array->items, ndarray->array->typecode, i);
item = mp_obj_new_int((int32_t)MICROPY_FLOAT_C_FUN(floor)(f));
mp_binary_set_val_array(dtype, ndarray_new->array->items, i, item);
}
} else {
for(size_t i=0; i < ndarray->array->len; i++) {
item = mp_binary_get_val_array(ndarray->array->typecode, ndarray->array->items, i);
mp_binary_set_val_array(dtype, ndarray_new->array->items, i, item);
}
}
return MP_OBJ_FROM_PTR(ndarray_new);
}
size_t len1, len2=0, i=0;
size_t len1, len2 = 0, i = 0;
mp_obj_t len_in = mp_obj_len_maybe(args[0]);
if (len_in == MP_OBJ_NULL) {
mp_raise_ValueError(translate("first argument must be an iterable"));
@ -232,9 +251,9 @@ mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
#endif
size_t slice_length(mp_bound_slice_t slice) {
int32_t len, correction = 1;
ssize_t len, correction = 1;
if(slice.step > 0) correction = -1;
len = (slice.stop - slice.start + (slice.step + correction)) / slice.step;
len = (ssize_t)(slice.stop - slice.start + (slice.step + correction)) / slice.step;
if(len < 0) return 0;
return (size_t)len;
}
@ -246,10 +265,10 @@ size_t true_length(mp_obj_t bool_list) {
mp_obj_t item, iterable = mp_getiter(bool_list, &iter_buf);
size_t trues = 0;
while((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if(!MP_OBJ_IS_TYPE(item, &mp_type_bool)) {
// numpy seems to be a little bit inconsistent in when an index is considered
// to be True/False. Bail out immediately, if the items are not True/False
return 0;
if(!mp_obj_is_bool(item)) {
// numpy seems to be a little bit inconsistent in when an index is considered
// to be True/False. Bail out immediately, if the items are not True/False
mp_raise_TypeError(translate("wrong index type"));
}
if(mp_obj_is_true(item)) {
trues++;
@ -262,7 +281,7 @@ mp_bound_slice_t generate_slice(mp_uint_t n, mp_obj_t index) {
// micropython seems to have difficulties with negative steps
mp_bound_slice_t slice;
if(MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_seq_get_fast_slice_indexes(n, index, &slice);
mp_obj_slice_indices(index, n, &slice);
} else if(MP_OBJ_IS_INT(index)) {
int32_t _index = mp_obj_get_int(index);
if(_index < 0) {
@ -391,10 +410,6 @@ mp_obj_t iterate_slice_list(ndarray_obj_t *ndarray, size_t m, size_t n,
mp_bound_slice_t row, mp_bound_slice_t column,
mp_obj_t row_list, mp_obj_t column_list,
ndarray_obj_t *values) {
if((m == 0) || (n == 0)) {
mp_raise_msg(&mp_type_IndexError, translate("empty index range"));
}
if(values != NULL) {
return insert_slice_list(ndarray, m, n, row, column, row_list, column_list, values);
}

View file

@ -25,7 +25,9 @@
#define FLOAT_TYPECODE 'd'
#endif
#if !CIRCUITPY
#if CIRCUITPY
#define mp_obj_is_bool(o) (MP_OBJ_IS_TYPE((o), &mp_type_bool))
#else
#define translate(x) x
#endif

View file

@ -20,43 +20,42 @@
#include "ndarray.h"
#if CIRCUITPY
typedef struct _mp_obj_property_t {
mp_obj_base_t base;
mp_obj_t proxy[3]; // getter, setter, deleter
} mp_obj_property_t;
/* v923z: it is not at all clear to me, why this must be declared; it should already be in obj.h */
typedef struct _mp_obj_none_t {
mp_obj_base_t base;
} mp_obj_none_t;
const mp_obj_type_t mp_type_NoneType;
const mp_obj_none_t mp_const_none_obj = {{&mp_type_NoneType}};
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_get_shape_obj, ndarray_shape);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_get_size_obj, ndarray_size);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_get_itemsize_obj, ndarray_itemsize);
MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten);
STATIC const mp_obj_property_t ndarray_shape_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&ndarray_get_shape_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
mp_const_none,
mp_const_none },
};
STATIC const mp_obj_property_t ndarray_size_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&ndarray_get_size_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
mp_const_none,
mp_const_none },
};
STATIC const mp_obj_property_t ndarray_itemsize_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&ndarray_get_itemsize_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
mp_const_none,
mp_const_none },
};
#else
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_size_obj, ndarray_size);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_itemsize_obj, ndarray_itemsize);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape);
#endif
#endif

View file

@ -31,57 +31,6 @@ enum NUMERICAL_FUNCTION_TYPE {
NUMERICAL_STD,
};
mp_obj_t numerical_linspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
{ MP_QSTR_num, MP_ARG_INT, {.u_int = 50} },
{ MP_QSTR_endpoint, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_true} },
{ MP_QSTR_retstep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_false} },
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(2, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint16_t len = args[2].u_int;
if(len < 2) {
mp_raise_ValueError(translate("number of points must be at least 2"));
}
mp_float_t value, step;
value = mp_obj_get_float(args[0].u_obj);
uint8_t typecode = args[5].u_int;
if(args[3].u_obj == mp_const_true) step = (mp_obj_get_float(args[1].u_obj)-value)/(len-1);
else step = (mp_obj_get_float(args[1].u_obj)-value)/len;
ndarray_obj_t *ndarray = create_new_ndarray(1, len, typecode);
if(typecode == NDARRAY_UINT8) {
uint8_t *array = (uint8_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (uint8_t)value;
} else if(typecode == NDARRAY_INT8) {
int8_t *array = (int8_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (int8_t)value;
} else if(typecode == NDARRAY_UINT16) {
uint16_t *array = (uint16_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (uint16_t)value;
} else if(typecode == NDARRAY_INT16) {
int16_t *array = (int16_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = (int16_t)value;
} else {
mp_float_t *array = (mp_float_t *)ndarray->array->items;
for(size_t i=0; i < len; i++, value += step) array[i] = value;
}
if(args[4].u_obj == mp_const_false) {
return MP_OBJ_FROM_PTR(ndarray);
} else {
mp_obj_t tuple[2];
tuple[0] = ndarray;
tuple[1] = mp_obj_new_float(step);
return mp_obj_new_tuple(2, tuple);
}
}
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_linspace_obj, 2, numerical_linspace);
void axis_sorter(ndarray_obj_t *ndarray, mp_obj_t axis, size_t *m, size_t *n, size_t *N,
size_t *increment, size_t *len, size_t *start_inc) {
if(axis == mp_const_none) { // flatten the array
@ -730,9 +679,8 @@ mp_obj_t numerical_argsort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argsort_obj, 1, numerical_argsort);
#if !CIRCUITPY
STATIC const mp_rom_map_elem_t ulab_numerical_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_linspace), (mp_obj_t)&numerical_linspace_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_numerical) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&numerical_sum_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mean), (mp_obj_t)&numerical_mean_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_std), (mp_obj_t)&numerical_std_obj },
@ -753,6 +701,5 @@ mp_obj_module_t ulab_numerical_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_numerical_globals,
};
#endif
#endif

View file

@ -148,7 +148,6 @@ extern mp_obj_module_t ulab_numerical_module;
}\
} while(0)
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_linspace_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_min_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_max_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_argmin_obj);

View file

@ -197,7 +197,6 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj, 2, 3, poly_polyfit);
#if !CIRCUITPY
STATIC const mp_rom_map_elem_t ulab_poly_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_poly) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_polyval), (mp_obj_t)&poly_polyval_obj },
@ -210,6 +209,5 @@ mp_obj_module_t ulab_poly_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_poly_globals,
};
#endif
#endif

View file

@ -21,6 +21,7 @@
#include "ulab.h"
#include "ndarray.h"
#include "ndarray_properties.h"
#include "create.h"
#include "linalg.h"
#include "vectorise.h"
#include "poly.h"
@ -29,16 +30,20 @@
#include "numerical.h"
#include "extras.h"
STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.34.0");
STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.38.0");
MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten);
STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },
{ MP_ROM_QSTR(MP_QSTR_reshape), MP_ROM_PTR(&ndarray_reshape_obj) },
{ MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&ndarray_transpose_obj) },
{ MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },
{ MP_ROM_QSTR(MP_QSTR_shape), MP_ROM_PTR(&ndarray_shape_obj) },
{ MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&ndarray_size_obj) },
{ MP_ROM_QSTR(MP_QSTR_itemsize), MP_ROM_PTR(&ndarray_itemsize_obj) },
// { MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) },
#if CIRCUITPY
{ MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) },
#endif
};
STATIC MP_DEFINE_CONST_DICT(ulab_ndarray_locals_dict, ulab_ndarray_locals_dict_table);
@ -56,11 +61,14 @@ const mp_obj_type_t ulab_ndarray_type = {
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
};
#if !CIRCUITPY
STATIC const mp_map_elem_t ulab_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ulab) },
{ MP_ROM_QSTR(MP_QSTR___version__), MP_ROM_PTR(&ulab_version_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&ulab_ndarray_type },
{ MP_ROM_QSTR(MP_QSTR_zeros), (mp_obj_t)&create_zeros_obj },
{ MP_ROM_QSTR(MP_QSTR_ones), (mp_obj_t)&create_ones_obj },
{ MP_ROM_QSTR(MP_QSTR_eye), (mp_obj_t)&create_eye_obj },
{ MP_ROM_QSTR(MP_QSTR_linspace), (mp_obj_t)&create_linspace_obj },
#if ULAB_LINALG_MODULE
{ MP_ROM_QSTR(MP_QSTR_linalg), MP_ROM_PTR(&ulab_linalg_module) },
#endif
@ -101,4 +109,3 @@ mp_obj_module_t ulab_user_cmodule = {
};
MP_REGISTER_MODULE(MP_QSTR_ulab, ulab_user_cmodule, MODULE_ULAB_ENABLED);
#endif

View file

@ -12,6 +12,9 @@
#ifndef __ULAB__
#define __ULAB__
// create
#define ULAB_CREATE_MODULE (1)
// vectorise (all functions) takes approx. 3 kB of flash space
#define ULAB_VECTORISE_MODULE (1)
@ -31,6 +34,6 @@
#define ULAB_FILTER_MODULE (1)
// user-defined modules
#define ULAB_EXTRAS_MODULE (0)
#define ULAB_EXTRAS_MODULE (1)
#endif

View file

@ -135,11 +135,90 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tan_obj, vectorise_tan);
MATH_FUN_1(tanh, tanh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tanh_obj, vectorise_tanh);
#if !CIRCUITPY
mp_obj_t vectorise_around(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
{ MP_QSTR_decimals, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0 } }
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type)) {
mp_raise_TypeError(translate("first argument must be an ndarray"));
}
int8_t n = args[1].u_int;
mp_float_t mul = MICROPY_FLOAT_C_FUN(pow)(10.0, n);
ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(args[0].u_obj);
ndarray_obj_t *result = create_new_ndarray(ndarray->m, ndarray->n, NDARRAY_FLOAT);
mp_float_t *array = (mp_float_t *)result->array->items;
for(size_t i=0; i < ndarray->array->len; i++) {
mp_float_t f = ndarray_get_float_value(ndarray->array->items, ndarray->array->typecode, i);
*array++ = MICROPY_FLOAT_C_FUN(round)(f * mul) / mul;
}
return MP_OBJ_FROM_PTR(result);
}
MP_DEFINE_CONST_FUN_OBJ_KW(vectorise_around_obj, 1, vectorise_around);
mp_obj_t vectorise_arctan2(mp_obj_t x, mp_obj_t y) {
// the function is implemented for scalars and ndarrays only, with partial
// broadcasting: arguments must be either scalars, or ndarrays of equal size/shape
if(!(MP_OBJ_IS_INT(x) || mp_obj_is_float(x) || MP_OBJ_IS_TYPE(x, &ulab_ndarray_type)) &&
!(MP_OBJ_IS_INT(y) || mp_obj_is_float(y) || MP_OBJ_IS_TYPE(y, &ulab_ndarray_type))) {
mp_raise_TypeError(translate("arctan2 is implemented for scalars and ndarrays only"));
}
ndarray_obj_t *ndarray_x, *ndarray_y;
if(MP_OBJ_IS_INT(x) || mp_obj_is_float(x)) {
ndarray_x = create_new_ndarray(1, 1, NDARRAY_FLOAT);
mp_float_t *array_x = (mp_float_t *)ndarray_x->array->items;
*array_x = mp_obj_get_float(x);
} else {
ndarray_x = MP_OBJ_TO_PTR(x);
}
if(MP_OBJ_IS_INT(y) || mp_obj_is_float(y)) {
ndarray_y = create_new_ndarray(1, 1, NDARRAY_FLOAT);
mp_float_t *array_y = (mp_float_t *)ndarray_y->array->items;
*array_y = mp_obj_get_float(y);
} else {
ndarray_y = MP_OBJ_TO_PTR(y);
}
// check, whether partial broadcasting is possible here
if((ndarray_x->m != ndarray_y->m) || (ndarray_x->n != ndarray_y->n)) {
if((ndarray_x->array->len != 1) && (ndarray_y->array->len != 1)) {
mp_raise_ValueError(translate("operands could not be broadcast together"));
}
}
size_t xinc = 0, yinc = 0;
size_t m = MAX(ndarray_x->m, ndarray_y->m);
size_t n = MAX(ndarray_x->n, ndarray_y->n);
size_t len = MAX(ndarray_x->array->len, ndarray_y->array->len);
if(ndarray_x->array->len != 1) {
xinc = 1;
}
if(ndarray_y->array->len != 1) {
yinc = 1;
}
size_t posx = 0, posy = 0;
ndarray_obj_t *result = create_new_ndarray(m, n, NDARRAY_FLOAT);
mp_float_t *array_r = (mp_float_t *)result->array->items;
for(size_t i=0; i < len; i++) {
mp_float_t value_x = ndarray_get_float_value(ndarray_x->array->items, ndarray_x->array->typecode, posx);
mp_float_t value_y = ndarray_get_float_value(ndarray_y->array->items, ndarray_y->array->typecode, posy);
*array_r++ = MICROPY_FLOAT_C_FUN(atan2)(value_x, value_y);
posx += xinc;
posy += yinc;
}
return MP_OBJ_FROM_PTR(result);
}
MP_DEFINE_CONST_FUN_OBJ_2(vectorise_arctan2_obj, vectorise_arctan2);
STATIC const mp_rom_map_elem_t ulab_vectorise_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_vector) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&vectorise_acos_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&vectorise_acosh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_arctan2), (mp_obj_t)&vectorise_arctan2_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_around), (mp_obj_t)&vectorise_around_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&vectorise_asin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&vectorise_asinh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&vectorise_atan_obj },
@ -169,6 +248,5 @@ mp_obj_module_t ulab_vectorise_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_vectorise_globals,
};
#endif
#endif

View file

@ -18,11 +18,11 @@
# -- Project information -----------------------------------------------------
project = 'micropython-ulab'
copyright = '2019, Zoltán Vörös'
copyright = '2019-2020, Zoltán Vörös'
author = 'Zoltán Vörös'
# The full version, including alpha/beta/rc tags
release = '0.32'
release = '0.38.0'
# -- General configuration ---------------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,26 @@
Thu, 12 Mar 2020
version 0.38.0
added initialisation from ndarray, and the around function
Tue, 10 Mar 2020
version 0.37.0
added Cholesky decomposition to linalg.c
Thu, 27 Feb 2020
version 0.36.0
moved zeros, ones, eye and linspace into separate module (they are still bound at the top level)
Thu, 27 Feb 2020
version 0.35.0
Move zeros, ones back into top level ulab module
Tue, 18 Feb 2020

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
from ulab import linalg
print(linalg.eye(3))
import ulab
print(ulab.eye(3))

17
tests/cholesky.py Normal file
View file

@ -0,0 +1,17 @@
import ulab
from ulab import linalg
a = ulab.array([[1, 2], [2, 5]])
print(linalg.cholesky(a))
b = a = ulab.array([[25, 15, -5], [15, 18, 0], [-5, 0, 11]])
print(linalg.cholesky(b))
c = ulab.array([[18, 22, 54, 42], [22, 70, 86, 62], [54, 86, 174, 134], [42, 62, 134, 106]])
print(linalg.cholesky(c))
# this throw a ValueError exception
d = ulab.array([[25, 15, -5], [15, 18, 0], [-5, 0, 1]])

9
tests/cholesky.py.exp Normal file
View file

@ -0,0 +1,9 @@
array([[1.0, 0.0],
[2.0, 1.0]], dtype=float)
array([[5.0, 0.0, 0.0],
[3.0, 3.0, 0.0],
[-1.0, 1.0, 3.0]], dtype=float)
array([[4.242640687119285, 0.0, 0.0, 0.0],
[5.185449728701349, 6.565905201197403, 0.0, 0.0],
[12.72792206135786, 3.046038495400855, 1.649742247909068, 0.0],
[9.899494936611665, 1.624553864213789, 1.849711005231386, 1.392621247645583]], dtype=float)

12
tests/constructors.py Normal file
View file

@ -0,0 +1,12 @@
from ulab import linalg
import ulab
print(ulab.ones(3))
print(ulab.ones((2,3)))
print(ulab.zeros(3))
print(ulab.zeros((2,3)))
print(ulab.eye(3))
print(ulab.ones(1, dtype=ulab.int8))
print(ulab.ones(2, dtype=ulab.uint8))
print(ulab.ones(3, dtype=ulab.int16))
print(ulab.ones(4, dtype=ulab.uint16))
print(ulab.ones(5, dtype=ulab.float))

14
tests/constructors.py.exp Normal file
View file

@ -0,0 +1,14 @@
array([1.0, 1.0, 1.0], dtype=float)
array([[1.0, 1.0, 1.0],
[1.0, 1.0, 1.0]], dtype=float)
array([0.0, 0.0, 0.0], dtype=float)
array([[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0]], dtype=float)
array([[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0]], dtype=float)
array([1], dtype=int8)
array([1, 1], dtype=uint8)
array([1, 1, 1], dtype=int16)
array([1, 1, 1, 1], dtype=uint16)
array([1.0, 1.0, 1.0, 1.0, 1.0], dtype=float)

17
tests/linalg.py Normal file
View file

@ -0,0 +1,17 @@
import ulab
from ulab import linalg
a = ulab.array([[1, 2], [3, 4]])
print(linalg.inv(a))
b = ulab.array([[1, 2, 3], [4, 5, 6], [7, 8, 7]])
print(linalg.inv(b))
c = ulab.array([[1, 2, 0, 0], [0, 6, 7, 0], [0, 0, 8, 9], [0, 0, 15, 13]])
print(linalg.inv(c))
print(linalg.det(a))
print(linalg.det(b))
print(linalg.det(c))

12
tests/linalg.py.exp Normal file
View file

@ -0,0 +1,12 @@
array([[-2.0, 1.0],
[1.5, -0.5]], dtype=float)
array([[-2.166666666666667, 1.666666666666667, -0.5],
[2.333333333333333, -2.333333333333333, 1.0],
[-0.5, 1.0, -0.5]], dtype=float)
array([[1.0, -0.3333333333333333, -0.9784946236559136, 0.6774193548387095],
[0.0, 0.1666666666666667, 0.489247311827957, -0.3387096774193548],
[0.0, 0.0, -0.4193548387096775, 0.2903225806451613],
[-0.0, -0.0, 0.4838709677419355, -0.2580645161290323]], dtype=float)
-2.0
6.0
-186.0

20
tests/operators.py Normal file
View file

@ -0,0 +1,20 @@
import ulab
a = ulab.ones(3)
print(a+a)
print(a-a)
print(a*a)
print(a/a)
print(a+2)
print(a-2)
print(a*2)
print(a/2)
print(a<1)
print(a<2)
print(a<=0)
print(a<=1)
print(a>1)
print(a>2)
print(a>=0)
print(a>=1)
#print(a==0) # These print just true or false. Is it right? is it a micropython limitation?
#print(a==1)

16
tests/operators.py.exp Normal file
View file

@ -0,0 +1,16 @@
array([2.0, 2.0, 2.0], dtype=float)
array([0.0, 0.0, 0.0], dtype=float)
array([1.0, 1.0, 1.0], dtype=float)
array([1.0, 1.0, 1.0], dtype=float)
array([3.0, 3.0, 3.0], dtype=float)
array([-1.0, -1.0, -1.0], dtype=float)
array([2.0, 2.0, 2.0], dtype=float)
array([0.5, 0.5, 0.5], dtype=float)
[False, False, False]
[True, True, True]
[False, False, False]
[True, True, True]
[False, False, False]
[False, False, False]
[True, True, True]
[True, True, True]

27
tests/poly.py Normal file
View file

@ -0,0 +1,27 @@
import ulab
from ulab import poly
from ulab import vector
# polynom evaluation
x = ulab.linspace(0, 10, num=9)
p = [1, 2, 3]
y = poly.polyval(p, x)
print(y)
# linear fit
x = ulab.linspace(-5, 5, num=11)
y = x + vector.sin(x)
p = poly.polyfit(x, y, 1)
print(p)
# quadratic fit
x = ulab.linspace(-5, 5, num=11)
y = x*x + vector.sin(x)*3.0
p = poly.polyfit(x, y, 2)
print(p)
# cubic fit
x = ulab.linspace(-5, 5, num=11)
y = x*x*x + vector.sin(x)*10.0
p = poly.polyfit(x, y, 3)
print(p)

4
tests/poly.py.exp Normal file
View file

@ -0,0 +1,4 @@
array([3.0, 7.0625, 14.25, 24.5625, 38.0, 54.56250000000001, 74.25000000000001, 97.06250000000001, 123.0], dtype=float)
array([0.9138471728743898, -8.074349270001139e-17], dtype=float)
array([1.0, -0.2584584813768293, 3.552713678800501e-15], dtype=float)
array([0.766798803225857, 0.0, 3.289453031323674, 0.0], dtype=float)

25
tests/slicing.py Normal file
View file

@ -0,0 +1,25 @@
try:
import ulab as np
except:
import numpy as np
for num in range(1,4):
for start in range(-num, num+1):
for end in range(-num, num+1):
for stride in (-3, -2, -1, 1, 2, 3):
l = list(range(num))
a = np.array(l, dtype=np.int8)
sl = l[start:end:stride]
ll = len(sl)
try:
sa = list(a[start:end:stride])
la = len(sa)
except IndexError as e:
sa = str(e)
la = -1
print("%2d [% d:% d:% d] %-24r %-24r%s" % (
num, start, end, stride, sl, sa, " ***" if sa != sl else ""))
a[start:end:stride] = np.ones(len(sl)) * -1
print("%2d [% d:% d:% d] %r" % (
num, start, end, stride, list(a)))

996
tests/slicing.py.exp Normal file
View file

@ -0,0 +1,996 @@
1 [-1:-1:-3] [] []
1 [-1:-1:-3] [0]
1 [-1:-1:-2] [] []
1 [-1:-1:-2] [0]
1 [-1:-1:-1] [] []
1 [-1:-1:-1] [0]
1 [-1:-1: 1] [] []
1 [-1:-1: 1] [0]
1 [-1:-1: 2] [] []
1 [-1:-1: 2] [0]
1 [-1:-1: 3] [] []
1 [-1:-1: 3] [0]
1 [-1: 0:-3] [] []
1 [-1: 0:-3] [0]
1 [-1: 0:-2] [] []
1 [-1: 0:-2] [0]
1 [-1: 0:-1] [] []
1 [-1: 0:-1] [0]
1 [-1: 0: 1] [] []
1 [-1: 0: 1] [0]
1 [-1: 0: 2] [] []
1 [-1: 0: 2] [0]
1 [-1: 0: 3] [] []
1 [-1: 0: 3] [0]
1 [-1: 1:-3] [] []
1 [-1: 1:-3] [0]
1 [-1: 1:-2] [] []
1 [-1: 1:-2] [0]
1 [-1: 1:-1] [] []
1 [-1: 1:-1] [0]
1 [-1: 1: 1] [0] [0]
1 [-1: 1: 1] [-1]
1 [-1: 1: 2] [0] [0]
1 [-1: 1: 2] [-1]
1 [-1: 1: 3] [0] [0]
1 [-1: 1: 3] [-1]
1 [ 0:-1:-3] [] []
1 [ 0:-1:-3] [0]
1 [ 0:-1:-2] [] []
1 [ 0:-1:-2] [0]
1 [ 0:-1:-1] [] []
1 [ 0:-1:-1] [0]
1 [ 0:-1: 1] [] []
1 [ 0:-1: 1] [0]
1 [ 0:-1: 2] [] []
1 [ 0:-1: 2] [0]
1 [ 0:-1: 3] [] []
1 [ 0:-1: 3] [0]
1 [ 0: 0:-3] [] []
1 [ 0: 0:-3] [0]
1 [ 0: 0:-2] [] []
1 [ 0: 0:-2] [0]
1 [ 0: 0:-1] [] []
1 [ 0: 0:-1] [0]
1 [ 0: 0: 1] [] []
1 [ 0: 0: 1] [0]
1 [ 0: 0: 2] [] []
1 [ 0: 0: 2] [0]
1 [ 0: 0: 3] [] []
1 [ 0: 0: 3] [0]
1 [ 0: 1:-3] [] []
1 [ 0: 1:-3] [0]
1 [ 0: 1:-2] [] []
1 [ 0: 1:-2] [0]
1 [ 0: 1:-1] [] []
1 [ 0: 1:-1] [0]
1 [ 0: 1: 1] [0] [0]
1 [ 0: 1: 1] [-1]
1 [ 0: 1: 2] [0] [0]
1 [ 0: 1: 2] [-1]
1 [ 0: 1: 3] [0] [0]
1 [ 0: 1: 3] [-1]
1 [ 1:-1:-3] [] []
1 [ 1:-1:-3] [0]
1 [ 1:-1:-2] [] []
1 [ 1:-1:-2] [0]
1 [ 1:-1:-1] [] []
1 [ 1:-1:-1] [0]
1 [ 1:-1: 1] [] []
1 [ 1:-1: 1] [0]
1 [ 1:-1: 2] [] []
1 [ 1:-1: 2] [0]
1 [ 1:-1: 3] [] []
1 [ 1:-1: 3] [0]
1 [ 1: 0:-3] [] []
1 [ 1: 0:-3] [0]
1 [ 1: 0:-2] [] []
1 [ 1: 0:-2] [0]
1 [ 1: 0:-1] [] []
1 [ 1: 0:-1] [0]
1 [ 1: 0: 1] [] []
1 [ 1: 0: 1] [0]
1 [ 1: 0: 2] [] []
1 [ 1: 0: 2] [0]
1 [ 1: 0: 3] [] []
1 [ 1: 0: 3] [0]
1 [ 1: 1:-3] [] []
1 [ 1: 1:-3] [0]
1 [ 1: 1:-2] [] []
1 [ 1: 1:-2] [0]
1 [ 1: 1:-1] [] []
1 [ 1: 1:-1] [0]
1 [ 1: 1: 1] [] []
1 [ 1: 1: 1] [0]
1 [ 1: 1: 2] [] []
1 [ 1: 1: 2] [0]
1 [ 1: 1: 3] [] []
1 [ 1: 1: 3] [0]
2 [-2:-2:-3] [] []
2 [-2:-2:-3] [0, 1]
2 [-2:-2:-2] [] []
2 [-2:-2:-2] [0, 1]
2 [-2:-2:-1] [] []
2 [-2:-2:-1] [0, 1]
2 [-2:-2: 1] [] []
2 [-2:-2: 1] [0, 1]
2 [-2:-2: 2] [] []
2 [-2:-2: 2] [0, 1]
2 [-2:-2: 3] [] []
2 [-2:-2: 3] [0, 1]
2 [-2:-1:-3] [] []
2 [-2:-1:-3] [0, 1]
2 [-2:-1:-2] [] []
2 [-2:-1:-2] [0, 1]
2 [-2:-1:-1] [] []
2 [-2:-1:-1] [0, 1]
2 [-2:-1: 1] [0] [0]
2 [-2:-1: 1] [-1, 1]
2 [-2:-1: 2] [0] [0]
2 [-2:-1: 2] [-1, 1]
2 [-2:-1: 3] [0] [0]
2 [-2:-1: 3] [-1, 1]
2 [-2: 0:-3] [] []
2 [-2: 0:-3] [0, 1]
2 [-2: 0:-2] [] []
2 [-2: 0:-2] [0, 1]
2 [-2: 0:-1] [] []
2 [-2: 0:-1] [0, 1]
2 [-2: 0: 1] [] []
2 [-2: 0: 1] [0, 1]
2 [-2: 0: 2] [] []
2 [-2: 0: 2] [0, 1]
2 [-2: 0: 3] [] []
2 [-2: 0: 3] [0, 1]
2 [-2: 1:-3] [] []
2 [-2: 1:-3] [0, 1]
2 [-2: 1:-2] [] []
2 [-2: 1:-2] [0, 1]
2 [-2: 1:-1] [] []
2 [-2: 1:-1] [0, 1]
2 [-2: 1: 1] [0] [0]
2 [-2: 1: 1] [-1, 1]
2 [-2: 1: 2] [0] [0]
2 [-2: 1: 2] [-1, 1]
2 [-2: 1: 3] [0] [0]
2 [-2: 1: 3] [-1, 1]
2 [-2: 2:-3] [] []
2 [-2: 2:-3] [0, 1]
2 [-2: 2:-2] [] []
2 [-2: 2:-2] [0, 1]
2 [-2: 2:-1] [] []
2 [-2: 2:-1] [0, 1]
2 [-2: 2: 1] [0, 1] [0, 1]
2 [-2: 2: 1] [-1, -1]
2 [-2: 2: 2] [0] [0]
2 [-2: 2: 2] [-1, 1]
2 [-2: 2: 3] [0] [0]
2 [-2: 2: 3] [-1, 1]
2 [-1:-2:-3] [1] [1]
2 [-1:-2:-3] [0, -1]
2 [-1:-2:-2] [1] [1]
2 [-1:-2:-2] [0, -1]
2 [-1:-2:-1] [1] [1]
2 [-1:-2:-1] [0, -1]
2 [-1:-2: 1] [] []
2 [-1:-2: 1] [0, 1]
2 [-1:-2: 2] [] []
2 [-1:-2: 2] [0, 1]
2 [-1:-2: 3] [] []
2 [-1:-2: 3] [0, 1]
2 [-1:-1:-3] [] []
2 [-1:-1:-3] [0, 1]
2 [-1:-1:-2] [] []
2 [-1:-1:-2] [0, 1]
2 [-1:-1:-1] [] []
2 [-1:-1:-1] [0, 1]
2 [-1:-1: 1] [] []
2 [-1:-1: 1] [0, 1]
2 [-1:-1: 2] [] []
2 [-1:-1: 2] [0, 1]
2 [-1:-1: 3] [] []
2 [-1:-1: 3] [0, 1]
2 [-1: 0:-3] [1] [1]
2 [-1: 0:-3] [0, -1]
2 [-1: 0:-2] [1] [1]
2 [-1: 0:-2] [0, -1]
2 [-1: 0:-1] [1] [1]
2 [-1: 0:-1] [0, -1]
2 [-1: 0: 1] [] []
2 [-1: 0: 1] [0, 1]
2 [-1: 0: 2] [] []
2 [-1: 0: 2] [0, 1]
2 [-1: 0: 3] [] []
2 [-1: 0: 3] [0, 1]
2 [-1: 1:-3] [] []
2 [-1: 1:-3] [0, 1]
2 [-1: 1:-2] [] []
2 [-1: 1:-2] [0, 1]
2 [-1: 1:-1] [] []
2 [-1: 1:-1] [0, 1]
2 [-1: 1: 1] [] []
2 [-1: 1: 1] [0, 1]
2 [-1: 1: 2] [] []
2 [-1: 1: 2] [0, 1]
2 [-1: 1: 3] [] []
2 [-1: 1: 3] [0, 1]
2 [-1: 2:-3] [] []
2 [-1: 2:-3] [0, 1]
2 [-1: 2:-2] [] []
2 [-1: 2:-2] [0, 1]
2 [-1: 2:-1] [] []
2 [-1: 2:-1] [0, 1]
2 [-1: 2: 1] [1] [1]
2 [-1: 2: 1] [0, -1]
2 [-1: 2: 2] [1] [1]
2 [-1: 2: 2] [0, -1]
2 [-1: 2: 3] [1] [1]
2 [-1: 2: 3] [0, -1]
2 [ 0:-2:-3] [] []
2 [ 0:-2:-3] [0, 1]
2 [ 0:-2:-2] [] []
2 [ 0:-2:-2] [0, 1]
2 [ 0:-2:-1] [] []
2 [ 0:-2:-1] [0, 1]
2 [ 0:-2: 1] [] []
2 [ 0:-2: 1] [0, 1]
2 [ 0:-2: 2] [] []
2 [ 0:-2: 2] [0, 1]
2 [ 0:-2: 3] [] []
2 [ 0:-2: 3] [0, 1]
2 [ 0:-1:-3] [] []
2 [ 0:-1:-3] [0, 1]
2 [ 0:-1:-2] [] []
2 [ 0:-1:-2] [0, 1]
2 [ 0:-1:-1] [] []
2 [ 0:-1:-1] [0, 1]
2 [ 0:-1: 1] [0] [0]
2 [ 0:-1: 1] [-1, 1]
2 [ 0:-1: 2] [0] [0]
2 [ 0:-1: 2] [-1, 1]
2 [ 0:-1: 3] [0] [0]
2 [ 0:-1: 3] [-1, 1]
2 [ 0: 0:-3] [] []
2 [ 0: 0:-3] [0, 1]
2 [ 0: 0:-2] [] []
2 [ 0: 0:-2] [0, 1]
2 [ 0: 0:-1] [] []
2 [ 0: 0:-1] [0, 1]
2 [ 0: 0: 1] [] []
2 [ 0: 0: 1] [0, 1]
2 [ 0: 0: 2] [] []
2 [ 0: 0: 2] [0, 1]
2 [ 0: 0: 3] [] []
2 [ 0: 0: 3] [0, 1]
2 [ 0: 1:-3] [] []
2 [ 0: 1:-3] [0, 1]
2 [ 0: 1:-2] [] []
2 [ 0: 1:-2] [0, 1]
2 [ 0: 1:-1] [] []
2 [ 0: 1:-1] [0, 1]
2 [ 0: 1: 1] [0] [0]
2 [ 0: 1: 1] [-1, 1]
2 [ 0: 1: 2] [0] [0]
2 [ 0: 1: 2] [-1, 1]
2 [ 0: 1: 3] [0] [0]
2 [ 0: 1: 3] [-1, 1]
2 [ 0: 2:-3] [] []
2 [ 0: 2:-3] [0, 1]
2 [ 0: 2:-2] [] []
2 [ 0: 2:-2] [0, 1]
2 [ 0: 2:-1] [] []
2 [ 0: 2:-1] [0, 1]
2 [ 0: 2: 1] [0, 1] [0, 1]
2 [ 0: 2: 1] [-1, -1]
2 [ 0: 2: 2] [0] [0]
2 [ 0: 2: 2] [-1, 1]
2 [ 0: 2: 3] [0] [0]
2 [ 0: 2: 3] [-1, 1]
2 [ 1:-2:-3] [1] [1]
2 [ 1:-2:-3] [0, -1]
2 [ 1:-2:-2] [1] [1]
2 [ 1:-2:-2] [0, -1]
2 [ 1:-2:-1] [1] [1]
2 [ 1:-2:-1] [0, -1]
2 [ 1:-2: 1] [] []
2 [ 1:-2: 1] [0, 1]
2 [ 1:-2: 2] [] []
2 [ 1:-2: 2] [0, 1]
2 [ 1:-2: 3] [] []
2 [ 1:-2: 3] [0, 1]
2 [ 1:-1:-3] [] []
2 [ 1:-1:-3] [0, 1]
2 [ 1:-1:-2] [] []
2 [ 1:-1:-2] [0, 1]
2 [ 1:-1:-1] [] []
2 [ 1:-1:-1] [0, 1]
2 [ 1:-1: 1] [] []
2 [ 1:-1: 1] [0, 1]
2 [ 1:-1: 2] [] []
2 [ 1:-1: 2] [0, 1]
2 [ 1:-1: 3] [] []
2 [ 1:-1: 3] [0, 1]
2 [ 1: 0:-3] [1] [1]
2 [ 1: 0:-3] [0, -1]
2 [ 1: 0:-2] [1] [1]
2 [ 1: 0:-2] [0, -1]
2 [ 1: 0:-1] [1] [1]
2 [ 1: 0:-1] [0, -1]
2 [ 1: 0: 1] [] []
2 [ 1: 0: 1] [0, 1]
2 [ 1: 0: 2] [] []
2 [ 1: 0: 2] [0, 1]
2 [ 1: 0: 3] [] []
2 [ 1: 0: 3] [0, 1]
2 [ 1: 1:-3] [] []
2 [ 1: 1:-3] [0, 1]
2 [ 1: 1:-2] [] []
2 [ 1: 1:-2] [0, 1]
2 [ 1: 1:-1] [] []
2 [ 1: 1:-1] [0, 1]
2 [ 1: 1: 1] [] []
2 [ 1: 1: 1] [0, 1]
2 [ 1: 1: 2] [] []
2 [ 1: 1: 2] [0, 1]
2 [ 1: 1: 3] [] []
2 [ 1: 1: 3] [0, 1]
2 [ 1: 2:-3] [] []
2 [ 1: 2:-3] [0, 1]
2 [ 1: 2:-2] [] []
2 [ 1: 2:-2] [0, 1]
2 [ 1: 2:-1] [] []
2 [ 1: 2:-1] [0, 1]
2 [ 1: 2: 1] [1] [1]
2 [ 1: 2: 1] [0, -1]
2 [ 1: 2: 2] [1] [1]
2 [ 1: 2: 2] [0, -1]
2 [ 1: 2: 3] [1] [1]
2 [ 1: 2: 3] [0, -1]
2 [ 2:-2:-3] [1] [1]
2 [ 2:-2:-3] [0, -1]
2 [ 2:-2:-2] [1] [1]
2 [ 2:-2:-2] [0, -1]
2 [ 2:-2:-1] [1] [1]
2 [ 2:-2:-1] [0, -1]
2 [ 2:-2: 1] [] []
2 [ 2:-2: 1] [0, 1]
2 [ 2:-2: 2] [] []
2 [ 2:-2: 2] [0, 1]
2 [ 2:-2: 3] [] []
2 [ 2:-2: 3] [0, 1]
2 [ 2:-1:-3] [] []
2 [ 2:-1:-3] [0, 1]
2 [ 2:-1:-2] [] []
2 [ 2:-1:-2] [0, 1]
2 [ 2:-1:-1] [] []
2 [ 2:-1:-1] [0, 1]
2 [ 2:-1: 1] [] []
2 [ 2:-1: 1] [0, 1]
2 [ 2:-1: 2] [] []
2 [ 2:-1: 2] [0, 1]
2 [ 2:-1: 3] [] []
2 [ 2:-1: 3] [0, 1]
2 [ 2: 0:-3] [1] [1]
2 [ 2: 0:-3] [0, -1]
2 [ 2: 0:-2] [1] [1]
2 [ 2: 0:-2] [0, -1]
2 [ 2: 0:-1] [1] [1]
2 [ 2: 0:-1] [0, -1]
2 [ 2: 0: 1] [] []
2 [ 2: 0: 1] [0, 1]
2 [ 2: 0: 2] [] []
2 [ 2: 0: 2] [0, 1]
2 [ 2: 0: 3] [] []
2 [ 2: 0: 3] [0, 1]
2 [ 2: 1:-3] [] []
2 [ 2: 1:-3] [0, 1]
2 [ 2: 1:-2] [] []
2 [ 2: 1:-2] [0, 1]
2 [ 2: 1:-1] [] []
2 [ 2: 1:-1] [0, 1]
2 [ 2: 1: 1] [] []
2 [ 2: 1: 1] [0, 1]
2 [ 2: 1: 2] [] []
2 [ 2: 1: 2] [0, 1]
2 [ 2: 1: 3] [] []
2 [ 2: 1: 3] [0, 1]
2 [ 2: 2:-3] [] []
2 [ 2: 2:-3] [0, 1]
2 [ 2: 2:-2] [] []
2 [ 2: 2:-2] [0, 1]
2 [ 2: 2:-1] [] []
2 [ 2: 2:-1] [0, 1]
2 [ 2: 2: 1] [] []
2 [ 2: 2: 1] [0, 1]
2 [ 2: 2: 2] [] []
2 [ 2: 2: 2] [0, 1]
2 [ 2: 2: 3] [] []
2 [ 2: 2: 3] [0, 1]
3 [-3:-3:-3] [] []
3 [-3:-3:-3] [0, 1, 2]
3 [-3:-3:-2] [] []
3 [-3:-3:-2] [0, 1, 2]
3 [-3:-3:-1] [] []
3 [-3:-3:-1] [0, 1, 2]
3 [-3:-3: 1] [] []
3 [-3:-3: 1] [0, 1, 2]
3 [-3:-3: 2] [] []
3 [-3:-3: 2] [0, 1, 2]
3 [-3:-3: 3] [] []
3 [-3:-3: 3] [0, 1, 2]
3 [-3:-2:-3] [] []
3 [-3:-2:-3] [0, 1, 2]
3 [-3:-2:-2] [] []
3 [-3:-2:-2] [0, 1, 2]
3 [-3:-2:-1] [] []
3 [-3:-2:-1] [0, 1, 2]
3 [-3:-2: 1] [0] [0]
3 [-3:-2: 1] [-1, 1, 2]
3 [-3:-2: 2] [0] [0]
3 [-3:-2: 2] [-1, 1, 2]
3 [-3:-2: 3] [0] [0]
3 [-3:-2: 3] [-1, 1, 2]
3 [-3:-1:-3] [] []
3 [-3:-1:-3] [0, 1, 2]
3 [-3:-1:-2] [] []
3 [-3:-1:-2] [0, 1, 2]
3 [-3:-1:-1] [] []
3 [-3:-1:-1] [0, 1, 2]
3 [-3:-1: 1] [0, 1] [0, 1]
3 [-3:-1: 1] [-1, -1, 2]
3 [-3:-1: 2] [0] [0]
3 [-3:-1: 2] [-1, 1, 2]
3 [-3:-1: 3] [0] [0]
3 [-3:-1: 3] [-1, 1, 2]
3 [-3: 0:-3] [] []
3 [-3: 0:-3] [0, 1, 2]
3 [-3: 0:-2] [] []
3 [-3: 0:-2] [0, 1, 2]
3 [-3: 0:-1] [] []
3 [-3: 0:-1] [0, 1, 2]
3 [-3: 0: 1] [] []
3 [-3: 0: 1] [0, 1, 2]
3 [-3: 0: 2] [] []
3 [-3: 0: 2] [0, 1, 2]
3 [-3: 0: 3] [] []
3 [-3: 0: 3] [0, 1, 2]
3 [-3: 1:-3] [] []
3 [-3: 1:-3] [0, 1, 2]
3 [-3: 1:-2] [] []
3 [-3: 1:-2] [0, 1, 2]
3 [-3: 1:-1] [] []
3 [-3: 1:-1] [0, 1, 2]
3 [-3: 1: 1] [0] [0]
3 [-3: 1: 1] [-1, 1, 2]
3 [-3: 1: 2] [0] [0]
3 [-3: 1: 2] [-1, 1, 2]
3 [-3: 1: 3] [0] [0]
3 [-3: 1: 3] [-1, 1, 2]
3 [-3: 2:-3] [] []
3 [-3: 2:-3] [0, 1, 2]
3 [-3: 2:-2] [] []
3 [-3: 2:-2] [0, 1, 2]
3 [-3: 2:-1] [] []
3 [-3: 2:-1] [0, 1, 2]
3 [-3: 2: 1] [0, 1] [0, 1]
3 [-3: 2: 1] [-1, -1, 2]
3 [-3: 2: 2] [0] [0]
3 [-3: 2: 2] [-1, 1, 2]
3 [-3: 2: 3] [0] [0]
3 [-3: 2: 3] [-1, 1, 2]
3 [-3: 3:-3] [] []
3 [-3: 3:-3] [0, 1, 2]
3 [-3: 3:-2] [] []
3 [-3: 3:-2] [0, 1, 2]
3 [-3: 3:-1] [] []
3 [-3: 3:-1] [0, 1, 2]
3 [-3: 3: 1] [0, 1, 2] [0, 1, 2]
3 [-3: 3: 1] [-1, -1, -1]
3 [-3: 3: 2] [0, 2] [0, 2]
3 [-3: 3: 2] [-1, 1, -1]
3 [-3: 3: 3] [0] [0]
3 [-3: 3: 3] [-1, 1, 2]
3 [-2:-3:-3] [1] [1]
3 [-2:-3:-3] [0, -1, 2]
3 [-2:-3:-2] [1] [1]
3 [-2:-3:-2] [0, -1, 2]
3 [-2:-3:-1] [1] [1]
3 [-2:-3:-1] [0, -1, 2]
3 [-2:-3: 1] [] []
3 [-2:-3: 1] [0, 1, 2]
3 [-2:-3: 2] [] []
3 [-2:-3: 2] [0, 1, 2]
3 [-2:-3: 3] [] []
3 [-2:-3: 3] [0, 1, 2]
3 [-2:-2:-3] [] []
3 [-2:-2:-3] [0, 1, 2]
3 [-2:-2:-2] [] []
3 [-2:-2:-2] [0, 1, 2]
3 [-2:-2:-1] [] []
3 [-2:-2:-1] [0, 1, 2]
3 [-2:-2: 1] [] []
3 [-2:-2: 1] [0, 1, 2]
3 [-2:-2: 2] [] []
3 [-2:-2: 2] [0, 1, 2]
3 [-2:-2: 3] [] []
3 [-2:-2: 3] [0, 1, 2]
3 [-2:-1:-3] [] []
3 [-2:-1:-3] [0, 1, 2]
3 [-2:-1:-2] [] []
3 [-2:-1:-2] [0, 1, 2]
3 [-2:-1:-1] [] []
3 [-2:-1:-1] [0, 1, 2]
3 [-2:-1: 1] [1] [1]
3 [-2:-1: 1] [0, -1, 2]
3 [-2:-1: 2] [1] [1]
3 [-2:-1: 2] [0, -1, 2]
3 [-2:-1: 3] [1] [1]
3 [-2:-1: 3] [0, -1, 2]
3 [-2: 0:-3] [1] [1]
3 [-2: 0:-3] [0, -1, 2]
3 [-2: 0:-2] [1] [1]
3 [-2: 0:-2] [0, -1, 2]
3 [-2: 0:-1] [1] [1]
3 [-2: 0:-1] [0, -1, 2]
3 [-2: 0: 1] [] []
3 [-2: 0: 1] [0, 1, 2]
3 [-2: 0: 2] [] []
3 [-2: 0: 2] [0, 1, 2]
3 [-2: 0: 3] [] []
3 [-2: 0: 3] [0, 1, 2]
3 [-2: 1:-3] [] []
3 [-2: 1:-3] [0, 1, 2]
3 [-2: 1:-2] [] []
3 [-2: 1:-2] [0, 1, 2]
3 [-2: 1:-1] [] []
3 [-2: 1:-1] [0, 1, 2]
3 [-2: 1: 1] [] []
3 [-2: 1: 1] [0, 1, 2]
3 [-2: 1: 2] [] []
3 [-2: 1: 2] [0, 1, 2]
3 [-2: 1: 3] [] []
3 [-2: 1: 3] [0, 1, 2]
3 [-2: 2:-3] [] []
3 [-2: 2:-3] [0, 1, 2]
3 [-2: 2:-2] [] []
3 [-2: 2:-2] [0, 1, 2]
3 [-2: 2:-1] [] []
3 [-2: 2:-1] [0, 1, 2]
3 [-2: 2: 1] [1] [1]
3 [-2: 2: 1] [0, -1, 2]
3 [-2: 2: 2] [1] [1]
3 [-2: 2: 2] [0, -1, 2]
3 [-2: 2: 3] [1] [1]
3 [-2: 2: 3] [0, -1, 2]
3 [-2: 3:-3] [] []
3 [-2: 3:-3] [0, 1, 2]
3 [-2: 3:-2] [] []
3 [-2: 3:-2] [0, 1, 2]
3 [-2: 3:-1] [] []
3 [-2: 3:-1] [0, 1, 2]
3 [-2: 3: 1] [1, 2] [1, 2]
3 [-2: 3: 1] [0, -1, -1]
3 [-2: 3: 2] [1] [1]
3 [-2: 3: 2] [0, -1, 2]
3 [-2: 3: 3] [1] [1]
3 [-2: 3: 3] [0, -1, 2]
3 [-1:-3:-3] [2] [2]
3 [-1:-3:-3] [0, 1, -1]
3 [-1:-3:-2] [2] [2]
3 [-1:-3:-2] [0, 1, -1]
3 [-1:-3:-1] [2, 1] [2, 1]
3 [-1:-3:-1] [0, -1, -1]
3 [-1:-3: 1] [] []
3 [-1:-3: 1] [0, 1, 2]
3 [-1:-3: 2] [] []
3 [-1:-3: 2] [0, 1, 2]
3 [-1:-3: 3] [] []
3 [-1:-3: 3] [0, 1, 2]
3 [-1:-2:-3] [2] [2]
3 [-1:-2:-3] [0, 1, -1]
3 [-1:-2:-2] [2] [2]
3 [-1:-2:-2] [0, 1, -1]
3 [-1:-2:-1] [2] [2]
3 [-1:-2:-1] [0, 1, -1]
3 [-1:-2: 1] [] []
3 [-1:-2: 1] [0, 1, 2]
3 [-1:-2: 2] [] []
3 [-1:-2: 2] [0, 1, 2]
3 [-1:-2: 3] [] []
3 [-1:-2: 3] [0, 1, 2]
3 [-1:-1:-3] [] []
3 [-1:-1:-3] [0, 1, 2]
3 [-1:-1:-2] [] []
3 [-1:-1:-2] [0, 1, 2]
3 [-1:-1:-1] [] []
3 [-1:-1:-1] [0, 1, 2]
3 [-1:-1: 1] [] []
3 [-1:-1: 1] [0, 1, 2]
3 [-1:-1: 2] [] []
3 [-1:-1: 2] [0, 1, 2]
3 [-1:-1: 3] [] []
3 [-1:-1: 3] [0, 1, 2]
3 [-1: 0:-3] [2] [2]
3 [-1: 0:-3] [0, 1, -1]
3 [-1: 0:-2] [2] [2]
3 [-1: 0:-2] [0, 1, -1]
3 [-1: 0:-1] [2, 1] [2, 1]
3 [-1: 0:-1] [0, -1, -1]
3 [-1: 0: 1] [] []
3 [-1: 0: 1] [0, 1, 2]
3 [-1: 0: 2] [] []
3 [-1: 0: 2] [0, 1, 2]
3 [-1: 0: 3] [] []
3 [-1: 0: 3] [0, 1, 2]
3 [-1: 1:-3] [2] [2]
3 [-1: 1:-3] [0, 1, -1]
3 [-1: 1:-2] [2] [2]
3 [-1: 1:-2] [0, 1, -1]
3 [-1: 1:-1] [2] [2]
3 [-1: 1:-1] [0, 1, -1]
3 [-1: 1: 1] [] []
3 [-1: 1: 1] [0, 1, 2]
3 [-1: 1: 2] [] []
3 [-1: 1: 2] [0, 1, 2]
3 [-1: 1: 3] [] []
3 [-1: 1: 3] [0, 1, 2]
3 [-1: 2:-3] [] []
3 [-1: 2:-3] [0, 1, 2]
3 [-1: 2:-2] [] []
3 [-1: 2:-2] [0, 1, 2]
3 [-1: 2:-1] [] []
3 [-1: 2:-1] [0, 1, 2]
3 [-1: 2: 1] [] []
3 [-1: 2: 1] [0, 1, 2]
3 [-1: 2: 2] [] []
3 [-1: 2: 2] [0, 1, 2]
3 [-1: 2: 3] [] []
3 [-1: 2: 3] [0, 1, 2]
3 [-1: 3:-3] [] []
3 [-1: 3:-3] [0, 1, 2]
3 [-1: 3:-2] [] []
3 [-1: 3:-2] [0, 1, 2]
3 [-1: 3:-1] [] []
3 [-1: 3:-1] [0, 1, 2]
3 [-1: 3: 1] [2] [2]
3 [-1: 3: 1] [0, 1, -1]
3 [-1: 3: 2] [2] [2]
3 [-1: 3: 2] [0, 1, -1]
3 [-1: 3: 3] [2] [2]
3 [-1: 3: 3] [0, 1, -1]
3 [ 0:-3:-3] [] []
3 [ 0:-3:-3] [0, 1, 2]
3 [ 0:-3:-2] [] []
3 [ 0:-3:-2] [0, 1, 2]
3 [ 0:-3:-1] [] []
3 [ 0:-3:-1] [0, 1, 2]
3 [ 0:-3: 1] [] []
3 [ 0:-3: 1] [0, 1, 2]
3 [ 0:-3: 2] [] []
3 [ 0:-3: 2] [0, 1, 2]
3 [ 0:-3: 3] [] []
3 [ 0:-3: 3] [0, 1, 2]
3 [ 0:-2:-3] [] []
3 [ 0:-2:-3] [0, 1, 2]
3 [ 0:-2:-2] [] []
3 [ 0:-2:-2] [0, 1, 2]
3 [ 0:-2:-1] [] []
3 [ 0:-2:-1] [0, 1, 2]
3 [ 0:-2: 1] [0] [0]
3 [ 0:-2: 1] [-1, 1, 2]
3 [ 0:-2: 2] [0] [0]
3 [ 0:-2: 2] [-1, 1, 2]
3 [ 0:-2: 3] [0] [0]
3 [ 0:-2: 3] [-1, 1, 2]
3 [ 0:-1:-3] [] []
3 [ 0:-1:-3] [0, 1, 2]
3 [ 0:-1:-2] [] []
3 [ 0:-1:-2] [0, 1, 2]
3 [ 0:-1:-1] [] []
3 [ 0:-1:-1] [0, 1, 2]
3 [ 0:-1: 1] [0, 1] [0, 1]
3 [ 0:-1: 1] [-1, -1, 2]
3 [ 0:-1: 2] [0] [0]
3 [ 0:-1: 2] [-1, 1, 2]
3 [ 0:-1: 3] [0] [0]
3 [ 0:-1: 3] [-1, 1, 2]
3 [ 0: 0:-3] [] []
3 [ 0: 0:-3] [0, 1, 2]
3 [ 0: 0:-2] [] []
3 [ 0: 0:-2] [0, 1, 2]
3 [ 0: 0:-1] [] []
3 [ 0: 0:-1] [0, 1, 2]
3 [ 0: 0: 1] [] []
3 [ 0: 0: 1] [0, 1, 2]
3 [ 0: 0: 2] [] []
3 [ 0: 0: 2] [0, 1, 2]
3 [ 0: 0: 3] [] []
3 [ 0: 0: 3] [0, 1, 2]
3 [ 0: 1:-3] [] []
3 [ 0: 1:-3] [0, 1, 2]
3 [ 0: 1:-2] [] []
3 [ 0: 1:-2] [0, 1, 2]
3 [ 0: 1:-1] [] []
3 [ 0: 1:-1] [0, 1, 2]
3 [ 0: 1: 1] [0] [0]
3 [ 0: 1: 1] [-1, 1, 2]
3 [ 0: 1: 2] [0] [0]
3 [ 0: 1: 2] [-1, 1, 2]
3 [ 0: 1: 3] [0] [0]
3 [ 0: 1: 3] [-1, 1, 2]
3 [ 0: 2:-3] [] []
3 [ 0: 2:-3] [0, 1, 2]
3 [ 0: 2:-2] [] []
3 [ 0: 2:-2] [0, 1, 2]
3 [ 0: 2:-1] [] []
3 [ 0: 2:-1] [0, 1, 2]
3 [ 0: 2: 1] [0, 1] [0, 1]
3 [ 0: 2: 1] [-1, -1, 2]
3 [ 0: 2: 2] [0] [0]
3 [ 0: 2: 2] [-1, 1, 2]
3 [ 0: 2: 3] [0] [0]
3 [ 0: 2: 3] [-1, 1, 2]
3 [ 0: 3:-3] [] []
3 [ 0: 3:-3] [0, 1, 2]
3 [ 0: 3:-2] [] []
3 [ 0: 3:-2] [0, 1, 2]
3 [ 0: 3:-1] [] []
3 [ 0: 3:-1] [0, 1, 2]
3 [ 0: 3: 1] [0, 1, 2] [0, 1, 2]
3 [ 0: 3: 1] [-1, -1, -1]
3 [ 0: 3: 2] [0, 2] [0, 2]
3 [ 0: 3: 2] [-1, 1, -1]
3 [ 0: 3: 3] [0] [0]
3 [ 0: 3: 3] [-1, 1, 2]
3 [ 1:-3:-3] [1] [1]
3 [ 1:-3:-3] [0, -1, 2]
3 [ 1:-3:-2] [1] [1]
3 [ 1:-3:-2] [0, -1, 2]
3 [ 1:-3:-1] [1] [1]
3 [ 1:-3:-1] [0, -1, 2]
3 [ 1:-3: 1] [] []
3 [ 1:-3: 1] [0, 1, 2]
3 [ 1:-3: 2] [] []
3 [ 1:-3: 2] [0, 1, 2]
3 [ 1:-3: 3] [] []
3 [ 1:-3: 3] [0, 1, 2]
3 [ 1:-2:-3] [] []
3 [ 1:-2:-3] [0, 1, 2]
3 [ 1:-2:-2] [] []
3 [ 1:-2:-2] [0, 1, 2]
3 [ 1:-2:-1] [] []
3 [ 1:-2:-1] [0, 1, 2]
3 [ 1:-2: 1] [] []
3 [ 1:-2: 1] [0, 1, 2]
3 [ 1:-2: 2] [] []
3 [ 1:-2: 2] [0, 1, 2]
3 [ 1:-2: 3] [] []
3 [ 1:-2: 3] [0, 1, 2]
3 [ 1:-1:-3] [] []
3 [ 1:-1:-3] [0, 1, 2]
3 [ 1:-1:-2] [] []
3 [ 1:-1:-2] [0, 1, 2]
3 [ 1:-1:-1] [] []
3 [ 1:-1:-1] [0, 1, 2]
3 [ 1:-1: 1] [1] [1]
3 [ 1:-1: 1] [0, -1, 2]
3 [ 1:-1: 2] [1] [1]
3 [ 1:-1: 2] [0, -1, 2]
3 [ 1:-1: 3] [1] [1]
3 [ 1:-1: 3] [0, -1, 2]
3 [ 1: 0:-3] [1] [1]
3 [ 1: 0:-3] [0, -1, 2]
3 [ 1: 0:-2] [1] [1]
3 [ 1: 0:-2] [0, -1, 2]
3 [ 1: 0:-1] [1] [1]
3 [ 1: 0:-1] [0, -1, 2]
3 [ 1: 0: 1] [] []
3 [ 1: 0: 1] [0, 1, 2]
3 [ 1: 0: 2] [] []
3 [ 1: 0: 2] [0, 1, 2]
3 [ 1: 0: 3] [] []
3 [ 1: 0: 3] [0, 1, 2]
3 [ 1: 1:-3] [] []
3 [ 1: 1:-3] [0, 1, 2]
3 [ 1: 1:-2] [] []
3 [ 1: 1:-2] [0, 1, 2]
3 [ 1: 1:-1] [] []
3 [ 1: 1:-1] [0, 1, 2]
3 [ 1: 1: 1] [] []
3 [ 1: 1: 1] [0, 1, 2]
3 [ 1: 1: 2] [] []
3 [ 1: 1: 2] [0, 1, 2]
3 [ 1: 1: 3] [] []
3 [ 1: 1: 3] [0, 1, 2]
3 [ 1: 2:-3] [] []
3 [ 1: 2:-3] [0, 1, 2]
3 [ 1: 2:-2] [] []
3 [ 1: 2:-2] [0, 1, 2]
3 [ 1: 2:-1] [] []
3 [ 1: 2:-1] [0, 1, 2]
3 [ 1: 2: 1] [1] [1]
3 [ 1: 2: 1] [0, -1, 2]
3 [ 1: 2: 2] [1] [1]
3 [ 1: 2: 2] [0, -1, 2]
3 [ 1: 2: 3] [1] [1]
3 [ 1: 2: 3] [0, -1, 2]
3 [ 1: 3:-3] [] []
3 [ 1: 3:-3] [0, 1, 2]
3 [ 1: 3:-2] [] []
3 [ 1: 3:-2] [0, 1, 2]
3 [ 1: 3:-1] [] []
3 [ 1: 3:-1] [0, 1, 2]
3 [ 1: 3: 1] [1, 2] [1, 2]
3 [ 1: 3: 1] [0, -1, -1]
3 [ 1: 3: 2] [1] [1]
3 [ 1: 3: 2] [0, -1, 2]
3 [ 1: 3: 3] [1] [1]
3 [ 1: 3: 3] [0, -1, 2]
3 [ 2:-3:-3] [2] [2]
3 [ 2:-3:-3] [0, 1, -1]
3 [ 2:-3:-2] [2] [2]
3 [ 2:-3:-2] [0, 1, -1]
3 [ 2:-3:-1] [2, 1] [2, 1]
3 [ 2:-3:-1] [0, -1, -1]
3 [ 2:-3: 1] [] []
3 [ 2:-3: 1] [0, 1, 2]
3 [ 2:-3: 2] [] []
3 [ 2:-3: 2] [0, 1, 2]
3 [ 2:-3: 3] [] []
3 [ 2:-3: 3] [0, 1, 2]
3 [ 2:-2:-3] [2] [2]
3 [ 2:-2:-3] [0, 1, -1]
3 [ 2:-2:-2] [2] [2]
3 [ 2:-2:-2] [0, 1, -1]
3 [ 2:-2:-1] [2] [2]
3 [ 2:-2:-1] [0, 1, -1]
3 [ 2:-2: 1] [] []
3 [ 2:-2: 1] [0, 1, 2]
3 [ 2:-2: 2] [] []
3 [ 2:-2: 2] [0, 1, 2]
3 [ 2:-2: 3] [] []
3 [ 2:-2: 3] [0, 1, 2]
3 [ 2:-1:-3] [] []
3 [ 2:-1:-3] [0, 1, 2]
3 [ 2:-1:-2] [] []
3 [ 2:-1:-2] [0, 1, 2]
3 [ 2:-1:-1] [] []
3 [ 2:-1:-1] [0, 1, 2]
3 [ 2:-1: 1] [] []
3 [ 2:-1: 1] [0, 1, 2]
3 [ 2:-1: 2] [] []
3 [ 2:-1: 2] [0, 1, 2]
3 [ 2:-1: 3] [] []
3 [ 2:-1: 3] [0, 1, 2]
3 [ 2: 0:-3] [2] [2]
3 [ 2: 0:-3] [0, 1, -1]
3 [ 2: 0:-2] [2] [2]
3 [ 2: 0:-2] [0, 1, -1]
3 [ 2: 0:-1] [2, 1] [2, 1]
3 [ 2: 0:-1] [0, -1, -1]
3 [ 2: 0: 1] [] []
3 [ 2: 0: 1] [0, 1, 2]
3 [ 2: 0: 2] [] []
3 [ 2: 0: 2] [0, 1, 2]
3 [ 2: 0: 3] [] []
3 [ 2: 0: 3] [0, 1, 2]
3 [ 2: 1:-3] [2] [2]
3 [ 2: 1:-3] [0, 1, -1]
3 [ 2: 1:-2] [2] [2]
3 [ 2: 1:-2] [0, 1, -1]
3 [ 2: 1:-1] [2] [2]
3 [ 2: 1:-1] [0, 1, -1]
3 [ 2: 1: 1] [] []
3 [ 2: 1: 1] [0, 1, 2]
3 [ 2: 1: 2] [] []
3 [ 2: 1: 2] [0, 1, 2]
3 [ 2: 1: 3] [] []
3 [ 2: 1: 3] [0, 1, 2]
3 [ 2: 2:-3] [] []
3 [ 2: 2:-3] [0, 1, 2]
3 [ 2: 2:-2] [] []
3 [ 2: 2:-2] [0, 1, 2]
3 [ 2: 2:-1] [] []
3 [ 2: 2:-1] [0, 1, 2]
3 [ 2: 2: 1] [] []
3 [ 2: 2: 1] [0, 1, 2]
3 [ 2: 2: 2] [] []
3 [ 2: 2: 2] [0, 1, 2]
3 [ 2: 2: 3] [] []
3 [ 2: 2: 3] [0, 1, 2]
3 [ 2: 3:-3] [] []
3 [ 2: 3:-3] [0, 1, 2]
3 [ 2: 3:-2] [] []
3 [ 2: 3:-2] [0, 1, 2]
3 [ 2: 3:-1] [] []
3 [ 2: 3:-1] [0, 1, 2]
3 [ 2: 3: 1] [2] [2]
3 [ 2: 3: 1] [0, 1, -1]
3 [ 2: 3: 2] [2] [2]
3 [ 2: 3: 2] [0, 1, -1]
3 [ 2: 3: 3] [2] [2]
3 [ 2: 3: 3] [0, 1, -1]
3 [ 3:-3:-3] [2] [2]
3 [ 3:-3:-3] [0, 1, -1]
3 [ 3:-3:-2] [2] [2]
3 [ 3:-3:-2] [0, 1, -1]
3 [ 3:-3:-1] [2, 1] [2, 1]
3 [ 3:-3:-1] [0, -1, -1]
3 [ 3:-3: 1] [] []
3 [ 3:-3: 1] [0, 1, 2]
3 [ 3:-3: 2] [] []
3 [ 3:-3: 2] [0, 1, 2]
3 [ 3:-3: 3] [] []
3 [ 3:-3: 3] [0, 1, 2]
3 [ 3:-2:-3] [2] [2]
3 [ 3:-2:-3] [0, 1, -1]
3 [ 3:-2:-2] [2] [2]
3 [ 3:-2:-2] [0, 1, -1]
3 [ 3:-2:-1] [2] [2]
3 [ 3:-2:-1] [0, 1, -1]
3 [ 3:-2: 1] [] []
3 [ 3:-2: 1] [0, 1, 2]
3 [ 3:-2: 2] [] []
3 [ 3:-2: 2] [0, 1, 2]
3 [ 3:-2: 3] [] []
3 [ 3:-2: 3] [0, 1, 2]
3 [ 3:-1:-3] [] []
3 [ 3:-1:-3] [0, 1, 2]
3 [ 3:-1:-2] [] []
3 [ 3:-1:-2] [0, 1, 2]
3 [ 3:-1:-1] [] []
3 [ 3:-1:-1] [0, 1, 2]
3 [ 3:-1: 1] [] []
3 [ 3:-1: 1] [0, 1, 2]
3 [ 3:-1: 2] [] []
3 [ 3:-1: 2] [0, 1, 2]
3 [ 3:-1: 3] [] []
3 [ 3:-1: 3] [0, 1, 2]
3 [ 3: 0:-3] [2] [2]
3 [ 3: 0:-3] [0, 1, -1]
3 [ 3: 0:-2] [2] [2]
3 [ 3: 0:-2] [0, 1, -1]
3 [ 3: 0:-1] [2, 1] [2, 1]
3 [ 3: 0:-1] [0, -1, -1]
3 [ 3: 0: 1] [] []
3 [ 3: 0: 1] [0, 1, 2]
3 [ 3: 0: 2] [] []
3 [ 3: 0: 2] [0, 1, 2]
3 [ 3: 0: 3] [] []
3 [ 3: 0: 3] [0, 1, 2]
3 [ 3: 1:-3] [2] [2]
3 [ 3: 1:-3] [0, 1, -1]
3 [ 3: 1:-2] [2] [2]
3 [ 3: 1:-2] [0, 1, -1]
3 [ 3: 1:-1] [2] [2]
3 [ 3: 1:-1] [0, 1, -1]
3 [ 3: 1: 1] [] []
3 [ 3: 1: 1] [0, 1, 2]
3 [ 3: 1: 2] [] []
3 [ 3: 1: 2] [0, 1, 2]
3 [ 3: 1: 3] [] []
3 [ 3: 1: 3] [0, 1, 2]
3 [ 3: 2:-3] [] []
3 [ 3: 2:-3] [0, 1, 2]
3 [ 3: 2:-2] [] []
3 [ 3: 2:-2] [0, 1, 2]
3 [ 3: 2:-1] [] []
3 [ 3: 2:-1] [0, 1, 2]
3 [ 3: 2: 1] [] []
3 [ 3: 2: 1] [0, 1, 2]
3 [ 3: 2: 2] [] []
3 [ 3: 2: 2] [0, 1, 2]
3 [ 3: 2: 3] [] []
3 [ 3: 2: 3] [0, 1, 2]
3 [ 3: 3:-3] [] []
3 [ 3: 3:-3] [0, 1, 2]
3 [ 3: 3:-2] [] []
3 [ 3: 3:-2] [0, 1, 2]
3 [ 3: 3:-1] [] []
3 [ 3: 3:-1] [0, 1, 2]
3 [ 3: 3: 1] [] []
3 [ 3: 3: 1] [0, 1, 2]
3 [ 3: 3: 2] [] []
3 [ 3: 3: 2] [0, 1, 2]
3 [ 3: 3: 3] [] []
3 [ 3: 3: 3] [0, 1, 2]

8
tests/slicing2.py Normal file
View file

@ -0,0 +1,8 @@
try:
import ulab as np
except:
import numpy as np
a = np.array(range(9), dtype=np.float)
print("a:\t", list(a))
print("a < 5:\t", list(a[a < 5]))