mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[python/ulab] Updated ulab
This commit is contained in:
@@ -169,19 +169,20 @@ port_src += $(addprefix python/port/,\
|
||||
mod/ulab/ulab_tools.c \
|
||||
mod/ulab/ndarray.c \
|
||||
mod/ulab/ndarray_properties.c \
|
||||
mod/ulab/numpy/approx/approx.c \
|
||||
mod/ulab/numpy/compare/compare.c \
|
||||
mod/ulab/numpy/approx.c \
|
||||
mod/ulab/numpy/compare.c \
|
||||
mod/ulab/ulab_create.c \
|
||||
mod/ulab/numpy/fft/fft.c \
|
||||
mod/ulab/numpy/fft/fft_tools.c \
|
||||
mod/ulab/numpy/filter/filter.c \
|
||||
mod/ulab/numpy/filter.c \
|
||||
mod/ulab/numpy/linalg/linalg.c \
|
||||
mod/ulab/numpy/linalg/linalg_tools.c \
|
||||
mod/ulab/numpy/numerical/numerical.c \
|
||||
mod/ulab/numpy/poly/poly.c \
|
||||
mod/ulab/numpy/stats/stats.c \
|
||||
mod/ulab/numpy/transform/transform.c \
|
||||
mod/ulab/numpy/vector/vector.c \
|
||||
mod/ulab/numpy/ndarray/ndarray_iter.c \
|
||||
mod/ulab/numpy/numerical.c \
|
||||
mod/ulab/numpy/poly.c \
|
||||
mod/ulab/numpy/stats.c \
|
||||
mod/ulab/numpy/transform.c \
|
||||
mod/ulab/numpy/vector.c \
|
||||
mod/ulab/numpy/numpy.c \
|
||||
mod/ulab/scipy/scipy.c \
|
||||
mod/ulab/user/user.c \
|
||||
|
||||
@@ -581,6 +581,10 @@ Q(listdir)
|
||||
|
||||
#if defined(INCLUDE_ULAB)
|
||||
// ulab QSTRs
|
||||
Q(reduced)
|
||||
Q(qr)
|
||||
Q(flat)
|
||||
Q(flatiter)
|
||||
Q(threshold)
|
||||
Q(edgeitems)
|
||||
Q(inplace)
|
||||
|
||||
21
python/port/mod/ulab/LICENSE
Normal file
21
python/port/mod/ulab/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Zoltán Vörös
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -16,11 +16,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/binary.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objtuple.h>
|
||||
#include <py/objint.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objint.h"
|
||||
|
||||
#include "ulab_tools.h"
|
||||
#include "ndarray.h"
|
||||
@@ -45,195 +45,6 @@ mp_uint_t ndarray_print_edgeitems = NDARRAY_PRINT_EDGEITEMS;
|
||||
//| possible. Numpy's documentation can be found at
|
||||
//| https://docs.scipy.org/doc/numpy/index.html"""
|
||||
//|
|
||||
//| from typing import Dict
|
||||
//|
|
||||
//| _DType = int
|
||||
//| """`ulab.int8`, `ulab.uint8`, `ulab.int16`, `ulab.uint16`, `ulab.float` or `ulab.bool`"""
|
||||
//|
|
||||
//| _float = float
|
||||
//| """Type alias of the bulitin float"""
|
||||
//|
|
||||
//| _bool = bool
|
||||
//| """Type alias of the bulitin bool"""
|
||||
//|
|
||||
//| _Index = Union[int, slice, ulab.ndarray, Tuple[Union[int, slice], ...]]
|
||||
//|
|
||||
|
||||
//| class ndarray:
|
||||
//| """1- and 2- dimensional ndarray"""
|
||||
//|
|
||||
//| def __init__(
|
||||
//| self,
|
||||
//| values: Union[ndarray, Iterable[Union[_float, _bool, Iterable[Any]]]],
|
||||
//| *,
|
||||
//| dtype: _DType = ulab.float
|
||||
//| ) -> None:
|
||||
//| """:param sequence values: Sequence giving the initial content of the ndarray.
|
||||
//| :param ~ulab._DType dtype: The type of ndarray values, `ulab.int8`, `ulab.uint8`, `ulab.int16`, `ulab.uint16`, `ulab.float` or `ulab.bool`
|
||||
//|
|
||||
//| The ``values`` sequence can either be another ~ulab.ndarray, sequence of numbers
|
||||
//| (in which case a 1-dimensional ndarray is created), or a sequence where each
|
||||
//| subsequence has the same length (in which case a 2-dimensional ndarray is
|
||||
//| created).
|
||||
//|
|
||||
//| Passing a `ulab.ndarray` and a different dtype can be used to convert an ndarray
|
||||
//| from one dtype to another.
|
||||
//|
|
||||
//| In many cases, it is more convenient to create an ndarray from a function
|
||||
//| like `zeros` or `linspace`.
|
||||
//|
|
||||
//| `ulab.ndarray` implements the buffer protocol, so it can be used in many
|
||||
//| places an `array.array` can be used."""
|
||||
//| ...
|
||||
//|
|
||||
//| shape: Tuple[int, ...]
|
||||
//| """The size of the array, a tuple of length 1 or 2"""
|
||||
//|
|
||||
//| size: int
|
||||
//| """The number of elements in the array"""
|
||||
//|
|
||||
//| itemsize: int
|
||||
//| """The size of a single item in the array"""
|
||||
//|
|
||||
//| strides: Tuple[int, ...]
|
||||
//| """Tuple of bytes to step in each dimension, a tuple of length 1 or 2"""
|
||||
//|
|
||||
//| def copy(self) -> ulab.ndarray:
|
||||
//| """Return a copy of the array"""
|
||||
//| ...
|
||||
//|
|
||||
//| def dtype(self) -> _DType:
|
||||
//| """Returns the dtype of the array"""
|
||||
//| ...
|
||||
//|
|
||||
//| def flatten(self, *, order: str = "C") -> ulab.ndarray:
|
||||
//| """:param order: Whether to flatten by rows ('C') or columns ('F')
|
||||
//|
|
||||
//| Returns a new `ulab.ndarray` object which is always 1 dimensional.
|
||||
//| If order is 'C' (the default", then the data is ordered in rows;
|
||||
//| If it is 'F', then the data is ordered in columns. "C" and "F" refer
|
||||
//| to the typical storage organization of the C and Fortran languages."""
|
||||
//| ...
|
||||
//|
|
||||
//| def reshape(self, shape: Tuple[int, ...]) -> ulab.ndarray:
|
||||
//| """Returns an ndarray containing the same data with a new shape."""
|
||||
//| ...
|
||||
//|
|
||||
//| def sort(self, *, axis: Optional[int] = 1) -> None:
|
||||
//| """:param axis: Whether to sort elements within rows (0), columns (1), or elements (None)"""
|
||||
//| ...
|
||||
//|
|
||||
//| def tobytes(self) -> bytearray:
|
||||
//| """Return the raw data bytes in the ndarray"""
|
||||
//| ...
|
||||
//|
|
||||
//| def transpose(self) -> ulab.ndarray:
|
||||
//| """Swap the rows and columns of a 2-dimensional ndarray"""
|
||||
//| ...
|
||||
//|
|
||||
//| def __add__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| """Adds corresponding elements of the two ndarrays, or adds a number to all
|
||||
//| elements of the ndarray. If both arguments are ndarrays, their sizes must match."""
|
||||
//| ...
|
||||
//| def __radd__(self, other: _float) -> ulab.ndarray: ...
|
||||
//|
|
||||
//| def __sub__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| """Subtracts corresponding elements of the two ndarrays, or subtracts a number from all
|
||||
//| elements of the ndarray. If both arguments are ndarrays, their sizes must match."""
|
||||
//| ...
|
||||
//| def __rsub__(self, other: _float) -> ulab.ndarray: ...
|
||||
//|
|
||||
//| def __mul__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| """Multiplies corresponding elements of the two ndarrays, or multiplies
|
||||
//| all elements of the ndarray by a number. If both arguments are ndarrays,
|
||||
//| their sizes must match."""
|
||||
//| ...
|
||||
//| def __rmul__(self, other: _float) -> ulab.ndarray: ...
|
||||
//|
|
||||
//| def __div__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| """Multiplies corresponding elements of the two ndarrays, or divides
|
||||
//| all elements of the ndarray by a number. If both arguments are ndarrays,
|
||||
//| their sizes must match."""
|
||||
//| ...
|
||||
//| def __rdiv__(self, other: _float) -> ulab.ndarray: ...
|
||||
//|
|
||||
//| def __pow__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| """Computes the power (x**y) of corresponding elements of the the two ndarrays,
|
||||
//| or one number and one ndarray. If both arguments are ndarrays, their sizes
|
||||
//| must match."""
|
||||
//| ...
|
||||
//| def __rpow__(self, other: _float) -> ulab.ndarray: ...
|
||||
//|
|
||||
//| def __inv__(self) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __neg__(self) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __pos__(self) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __abs__(self) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __len__(self) -> int:
|
||||
//| ...
|
||||
//| def __lt__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __le__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __gt__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| ...
|
||||
//| def __ge__(self, other: Union[ndarray, _float]) -> ulab.ndarray:
|
||||
//| ...
|
||||
//|
|
||||
//| def __iter__(self) -> Union[Iterator[ndarray], Iterator[_float]]:
|
||||
//| ...
|
||||
//|
|
||||
//| def __getitem__(self, index: _Index) -> Union[ndarray, _float]:
|
||||
//| """Retrieve an element of the ndarray."""
|
||||
//| ...
|
||||
//|
|
||||
//| def __setitem__(self, index: _Index, value: Union[ndarray, _float]) -> None:
|
||||
//| """Set an element of the ndarray."""
|
||||
//| ...
|
||||
//|
|
||||
//| _ArrayLike = Union[ndarray, List[_float], Tuple[_float], range]
|
||||
//| """`ulab.ndarray`, ``List[float]``, ``Tuple[float]`` or `range`"""
|
||||
//|
|
||||
//| int8: _DType
|
||||
//| """Type code for signed integers in the range -128 .. 127 inclusive, like the 'b' typecode of `array.array`"""
|
||||
//|
|
||||
//| int16: _DType
|
||||
//| """Type code for signed integers in the range -32768 .. 32767 inclusive, like the 'h' typecode of `array.array`"""
|
||||
//|
|
||||
//| float: _DType
|
||||
//| """Type code for floating point values, like the 'f' typecode of `array.array`"""
|
||||
//|
|
||||
//| uint8: _DType
|
||||
//| """Type code for unsigned integers in the range 0 .. 255 inclusive, like the 'H' typecode of `array.array`"""
|
||||
//|
|
||||
//| uint16: _DType
|
||||
//| """Type code for unsigned integers in the range 0 .. 65535 inclusive, like the 'h' typecode of `array.array`"""
|
||||
//|
|
||||
//| bool: _DType
|
||||
//| """Type code for boolean values"""
|
||||
//|
|
||||
//| def get_printoptions() -> Dict[str, int]:
|
||||
//| """Get printing options"""
|
||||
//| ...
|
||||
//|
|
||||
//| def set_printoptions(threshold: Optional[int] = None, edgeitems: Optional[int] = None) -> None:
|
||||
//| """Set printing options"""
|
||||
//| ...
|
||||
//|
|
||||
//| def ndinfo(array: ulab.ndarray) -> None:
|
||||
//| ...
|
||||
//|
|
||||
//| def array(
|
||||
//| values: Union[ndarray, Iterable[Union[_float, _bool, Iterable[Any]]]],
|
||||
//| *,
|
||||
//| dtype: _DType = ulab.float
|
||||
//| ) -> ulab.ndarray:
|
||||
//| """alternate constructor function for `ulab.ndarray`. Mirrors numpy.array"""
|
||||
//| ...
|
||||
|
||||
|
||||
#ifdef CIRCUITPY
|
||||
void ndarray_set_value(char typecode, void *p, size_t index, mp_obj_t val_in) {
|
||||
@@ -257,7 +68,7 @@ void ndarray_set_value(char typecode, void *p, size_t index, mp_obj_t val_in) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MICROPY_VERSION_MAJOR) && MICROPY_VERSION_MAJOR == 1 && MICROPY_VERSION_MINOR == 12
|
||||
#if defined(MICROPY_VERSION_MAJOR) && MICROPY_VERSION_MAJOR == 1 && MICROPY_VERSION_MINOR == 11
|
||||
|
||||
void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *result) {
|
||||
mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
@@ -581,11 +392,13 @@ static void ndarray_print_row(const mp_print_t *print, ndarray_obj_t * ndarray,
|
||||
mp_print_str(print, "]");
|
||||
}
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
static void ndarray_print_bracket(const mp_print_t *print, const size_t condition, const size_t shape, const char *string) {
|
||||
if(condition < shape) {
|
||||
mp_print_str(print, string);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ndarray_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
@@ -596,9 +409,13 @@ void ndarray_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t ki
|
||||
mp_print_str(print, "[]");
|
||||
if(self->ndim > 1) {
|
||||
mp_print_str(print, ", shape=(");
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
for(uint8_t ndim = self->ndim; ndim > 1; ndim--) {
|
||||
mp_printf(MP_PYTHON_PRINTER, "%d,", self->shape[ULAB_MAX_DIMS - ndim]);
|
||||
}
|
||||
#else
|
||||
mp_printf(MP_PYTHON_PRINTER, "%d,", self->shape[0]);
|
||||
#endif
|
||||
mp_printf(MP_PYTHON_PRINTER, "%d)", self->shape[ULAB_MAX_DIMS - 1]);
|
||||
}
|
||||
} else {
|
||||
@@ -1110,18 +927,6 @@ mp_obj_t ndarray_array_constructor(size_t n_args, const mp_obj_t *pos_args, mp_m
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_array_constructor_obj, 1, ndarray_array_constructor);
|
||||
|
||||
#ifdef CIRCUITPY
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
(void) type;
|
||||
mp_arg_check_num(n_args, kw_args, 1, 2, true);
|
||||
size_t n_kw = 0;
|
||||
if (kw_args != 0) {
|
||||
n_kw = kw_args->used;
|
||||
}
|
||||
mp_map_init_fixed_table(kw_args, n_kw, args + n_args);
|
||||
return ndarray_make_new_core(type, n_args, n_kw, args, kw_args);
|
||||
}
|
||||
#else
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
(void) type;
|
||||
mp_arg_check_num(n_args, n_kw, 1, 2, true);
|
||||
@@ -1129,7 +934,6 @@ mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
return ndarray_make_new_core(type, n_args, n_kw, args, &kw_args);
|
||||
}
|
||||
#endif
|
||||
|
||||
// broadcasting is used at a number of places, always include
|
||||
bool ndarray_can_broadcast(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t *ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
|
||||
@@ -1555,12 +1359,12 @@ mp_obj_t ndarray_iternext(mp_obj_t self_in) {
|
||||
|
||||
mp_obj_t ndarray_new_ndarray_iterator(mp_obj_t ndarray, mp_obj_iter_buf_t *iter_buf) {
|
||||
assert(sizeof(mp_obj_ndarray_it_t) <= sizeof(mp_obj_iter_buf_t));
|
||||
mp_obj_ndarray_it_t *o = (mp_obj_ndarray_it_t*)iter_buf;
|
||||
o->base.type = &mp_type_polymorph_iter;
|
||||
o->iternext = ndarray_iternext;
|
||||
o->ndarray = ndarray;
|
||||
o->cur = 0;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
mp_obj_ndarray_it_t *iter = (mp_obj_ndarray_it_t *)iter_buf;
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
iter->iternext = ndarray_iternext;
|
||||
iter->ndarray = ndarray;
|
||||
iter->cur = 0;
|
||||
return MP_OBJ_FROM_PTR(iter);
|
||||
}
|
||||
#endif /* NDARRAY_IS_ITERABLE */
|
||||
|
||||
@@ -1675,12 +1479,13 @@ mp_obj_t ndarray_itemsize(mp_obj_t self_in) {
|
||||
#if NDARRAY_HAS_SHAPE
|
||||
mp_obj_t ndarray_shape(mp_obj_t self_in) {
|
||||
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_t *items = m_new(mp_obj_t, self->ndim);
|
||||
for(uint8_t i=0; i < self->ndim; i++) {
|
||||
items[self->ndim - i - 1] = mp_obj_new_int(self->shape[ULAB_MAX_DIMS - i - 1]);
|
||||
uint8_t nitems = MAX(1, self->ndim);
|
||||
mp_obj_t *items = m_new(mp_obj_t, nitems);
|
||||
for(uint8_t i = 0; i < nitems; i++) {
|
||||
items[nitems - i - 1] = mp_obj_new_int(self->shape[ULAB_MAX_DIMS - i - 1]);
|
||||
}
|
||||
mp_obj_t tuple = mp_obj_new_tuple(self->ndim, items);
|
||||
m_del(mp_obj_t, items, self->ndim);
|
||||
mp_obj_t tuple = mp_obj_new_tuple(nitems, items);
|
||||
m_del(mp_obj_t, items, nitems);
|
||||
return tuple;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct _mp_obj_float_t {
|
||||
mp_float_t value;
|
||||
} mp_obj_float_t;
|
||||
|
||||
#if defined(MICROPY_VERSION_MAJOR) && MICROPY_VERSION_MAJOR == 1 && MICROPY_VERSION_MINOR == 12
|
||||
#if defined(MICROPY_VERSION_MAJOR) && MICROPY_VERSION_MAJOR == 1 && MICROPY_VERSION_MINOR == 11
|
||||
typedef struct _mp_obj_slice_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t start;
|
||||
@@ -49,6 +49,13 @@ typedef struct _mp_obj_slice_t {
|
||||
#define MP_ERROR_TEXT(x) x
|
||||
#endif
|
||||
|
||||
#if !defined(MP_TYPE_FLAG_EXTENDED)
|
||||
#define MP_TYPE_CALL call
|
||||
#define mp_type_get_call_slot(t) t->call
|
||||
#define MP_TYPE_FLAG_EXTENDED (0)
|
||||
#define MP_TYPE_EXTENDED_FIELDS(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
#if !CIRCUITPY
|
||||
#define translate(x) MP_ERROR_TEXT(x)
|
||||
#define ndarray_set_value(a, b, c, d) mp_binary_set_val_array(a, b, c, d)
|
||||
@@ -96,15 +103,14 @@ typedef struct _dtype_obj_t {
|
||||
|
||||
void ndarray_dtype_print(const mp_print_t *, mp_obj_t , mp_print_kind_t );
|
||||
|
||||
#ifdef CIRCUITPY
|
||||
mp_obj_t ndarray_dtype_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
#else
|
||||
mp_obj_t ndarray_dtype_make_new(const mp_obj_type_t *, size_t , size_t , const mp_obj_t *);
|
||||
#endif /* CIRCUITPY */
|
||||
#endif /* ULAB_HAS_DTYPE_OBJECT */
|
||||
|
||||
extern const mp_obj_type_t ndarray_flatiter_type;
|
||||
|
||||
mp_obj_t ndarray_new_ndarray_iterator(mp_obj_t , mp_obj_iter_buf_t *);
|
||||
|
||||
mp_obj_t ndarray_get_item(ndarray_obj_t *, void *);
|
||||
mp_float_t ndarray_get_float_value(void *, uint8_t );
|
||||
mp_float_t ndarray_get_float_index(void *, uint8_t , size_t );
|
||||
bool ndarray_object_is_array_like(mp_obj_t );
|
||||
@@ -135,11 +141,7 @@ ndarray_obj_t *ndarray_copy_view(ndarray_obj_t *);
|
||||
void ndarray_copy_array(ndarray_obj_t *, ndarray_obj_t *);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(ndarray_array_constructor_obj);
|
||||
#ifdef CIRCUITPY
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
#else
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *, size_t , size_t , const mp_obj_t *);
|
||||
#endif
|
||||
mp_obj_t ndarray_subscr(mp_obj_t , mp_obj_t , mp_obj_t );
|
||||
mp_obj_t ndarray_getiter(mp_obj_t , mp_obj_iter_buf_t *);
|
||||
bool ndarray_can_broadcast(ndarray_obj_t *, ndarray_obj_t *, uint8_t *, size_t *, int32_t *, int32_t *);
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <py/runtime.h>
|
||||
#include <py/objtuple.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "ndarray.h"
|
||||
#include "ndarray_operators.h"
|
||||
#include "ulab.h"
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ndarray.h"
|
||||
#include "numpy/ndarray/ndarray_iter.h"
|
||||
|
||||
#ifndef CIRCUITPY
|
||||
|
||||
@@ -51,6 +52,11 @@ void ndarray_properties_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
dest[0] = ndarray_dtype(self_in);
|
||||
break;
|
||||
#endif
|
||||
#if NDARRAY_HAS_FLATITER
|
||||
case MP_QSTR_flat:
|
||||
dest[0] = ndarray_flatiter_make_new(self_in);
|
||||
break;
|
||||
#endif
|
||||
#if NDARRAY_HAS_ITEMSIZE
|
||||
case MP_QSTR_itemsize:
|
||||
dest[0] = ndarray_itemsize(self_in);
|
||||
@@ -83,11 +89,13 @@ void ndarray_properties_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
} else {
|
||||
if(dest[1]) {
|
||||
switch(attr) {
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
#if NDARRAY_HAS_RESHAPE
|
||||
case MP_QSTR_shape:
|
||||
ndarray_reshape_core(self_in, dest[1], 1);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
||||
@@ -7,19 +7,20 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
|
||||
* 2020 Zoltán Vörös
|
||||
* 2020-2021 Zoltán Vörös
|
||||
*/
|
||||
|
||||
#ifndef _NDARRAY_PROPERTIES_
|
||||
#define _NDARRAY_PROPERTIES_
|
||||
|
||||
#include <py/runtime.h>
|
||||
#include <py/binary.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objarray.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ndarray.h"
|
||||
#include "numpy/ndarray/ndarray_iter.h"
|
||||
|
||||
#if CIRCUITPY
|
||||
typedef struct _mp_obj_property_t {
|
||||
@@ -37,6 +38,16 @@ STATIC const mp_obj_property_t ndarray_dtype_obj = {
|
||||
};
|
||||
#endif /* NDARRAY_HAS_DTYPE */
|
||||
|
||||
#if NDARRAY_HAS_FLATITER
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_flatiter_make_new_obj, ndarray_flatiter_make_new);
|
||||
STATIC const mp_obj_property_t ndarray_flat_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&ndarray_flatiter_make_new_obj,
|
||||
mp_const_none,
|
||||
mp_const_none },
|
||||
};
|
||||
#endif /* NDARRAY_HAS_FLATITER */
|
||||
|
||||
#if NDARRAY_HAS_ITEMSIZE
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_get_itemsize_obj, ndarray_itemsize);
|
||||
STATIC const mp_obj_property_t ndarray_itemsize_obj = {
|
||||
@@ -82,6 +93,7 @@ STATIC const mp_obj_property_t ndarray_strides_obj = {
|
||||
void ndarray_properties_attr(mp_obj_t , qstr , mp_obj_t *);
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_dtype_obj, ndarray_dtype);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_flatiter_make_new_obj, ndarray_flatiter_make_new);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_itemsize_obj, ndarray_itemsize);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_size_obj, ndarray_size);
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "approx.h"
|
||||
|
||||
//| """Numerical approximation methods"""
|
||||
@@ -28,17 +28,17 @@ const mp_obj_float_t approx_trapz_dx = {{&mp_type_float}, MICROPY_FLOAT_CONST(1.
|
||||
|
||||
#if ULAB_NUMPY_HAS_INTERP
|
||||
//| def interp(
|
||||
//| x: ulab.ndarray,
|
||||
//| xp: ulab.ndarray,
|
||||
//| fp: ulab.ndarray,
|
||||
//| x: ulab.numpy.ndarray,
|
||||
//| xp: ulab.numpy.ndarray,
|
||||
//| fp: ulab.numpy.ndarray,
|
||||
//| *,
|
||||
//| left: Optional[float] = None,
|
||||
//| right: Optional[float] = None
|
||||
//| ) -> ulab.ndarray:
|
||||
//| left: Optional[_float] = None,
|
||||
//| right: Optional[_float] = None
|
||||
//| ) -> ulab.numpy.ndarray:
|
||||
//| """
|
||||
//| :param ulab.ndarray x: The x-coordinates at which to evaluate the interpolated values.
|
||||
//| :param ulab.ndarray xp: The x-coordinates of the data points, must be increasing
|
||||
//| :param ulab.ndarray fp: The y-coordinates of the data points, same length as xp
|
||||
//| :param ulab.numpy.ndarray x: The x-coordinates at which to evaluate the interpolated values.
|
||||
//| :param ulab.numpy.ndarray xp: The x-coordinates of the data points, must be increasing
|
||||
//| :param ulab.numpy.ndarray fp: The y-coordinates of the data points, same length as xp
|
||||
//| :param left: Value to return for ``x < xp[0]``, default is ``fp[0]``.
|
||||
//| :param right: Value to return for ``x > xp[-1]``, default is ``fp[-1]``.
|
||||
//|
|
||||
@@ -136,10 +136,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(approx_interp_obj, 2, approx_interp);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_TRAPZ
|
||||
//| def trapz(y: ulab.ndarray, x: Optional[ulab.ndarray] = None, dx: float = 1.0) -> float:
|
||||
//| def trapz(y: ulab.numpy.ndarray, x: Optional[ulab.numpy.ndarray] = None, dx: _float = 1.0) -> _float:
|
||||
//| """
|
||||
//| :param 1D ulab.ndarray y: the values of the dependent variable
|
||||
//| :param 1D ulab.ndarray x: optional, the coordinates of the independent variable. Defaults to uniformly spaced values.
|
||||
//| :param 1D ulab.numpy.ndarray y: the values of the dependent variable
|
||||
//| :param 1D ulab.numpy.ndarray x: optional, the coordinates of the independent variable. Defaults to uniformly spaced values.
|
||||
//| :param float dx: the spacing between sample points, if x=None
|
||||
//|
|
||||
//| Returns the integral of y(x) using the trapezoidal rule.
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _APPROX_
|
||||
#define _APPROX_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
#define APPROX_EPS MICROPY_FLOAT_CONST(1.0e-4)
|
||||
#define APPROX_NONZDELTA MICROPY_FLOAT_CONST(0.05)
|
||||
@@ -13,13 +13,13 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray_operators.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray_operators.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "compare.h"
|
||||
|
||||
static mp_obj_t compare_function(mp_obj_t x1, mp_obj_t x2, uint8_t op) {
|
||||
@@ -89,7 +89,7 @@ static mp_obj_t compare_function(mp_obj_t x1, mp_obj_t x2, uint8_t op) {
|
||||
} else if(rhs->dtype == NDARRAY_INT16) {
|
||||
RUN_COMPARE_LOOP(NDARRAY_FLOAT, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
} else if(rhs->dtype == NDARRAY_FLOAT) {
|
||||
RUN_COMPARE_LOOP(NDARRAY_FLOAT, mp_float_t, uint8_t, mp_float_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
RUN_COMPARE_LOOP(NDARRAY_FLOAT, mp_float_t, uint16_t, mp_float_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
}
|
||||
} else if(lhs->dtype == NDARRAY_INT16) {
|
||||
if(rhs->dtype == NDARRAY_UINT8) {
|
||||
@@ -101,7 +101,7 @@ static mp_obj_t compare_function(mp_obj_t x1, mp_obj_t x2, uint8_t op) {
|
||||
} else if(rhs->dtype == NDARRAY_INT16) {
|
||||
RUN_COMPARE_LOOP(NDARRAY_INT16, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
} else if(rhs->dtype == NDARRAY_FLOAT) {
|
||||
RUN_COMPARE_LOOP(NDARRAY_FLOAT, mp_float_t, uint16_t, mp_float_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
RUN_COMPARE_LOOP(NDARRAY_FLOAT, mp_float_t, int16_t, mp_float_t, larray, lstrides, rarray, rstrides, ndim, shape, op);
|
||||
}
|
||||
} else if(lhs->dtype == NDARRAY_FLOAT) {
|
||||
if(rhs->dtype == NDARRAY_UINT8) {
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _COMPARE_
|
||||
#define _COMPARE_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
enum COMPARE_FUNCTION_TYPE {
|
||||
COMPARE_EQUAL,
|
||||
@@ -14,22 +14,23 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/builtin.h>
|
||||
#include <py/binary.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objarray.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "fft.h"
|
||||
|
||||
//| """Frequency-domain functions"""
|
||||
//|
|
||||
//| import ulab.numpy
|
||||
|
||||
|
||||
//| def fft(r: ulab.ndarray, c: Optional[ulab.ndarray] = None) -> Tuple[ulab.ndarray, ulab.ndarray]:
|
||||
//| def fft(r: ulab.numpy.ndarray, c: Optional[ulab.numpy.ndarray] = None) -> Tuple[ulab.numpy.ndarray, ulab.numpy.ndarray]:
|
||||
//| """
|
||||
//| :param ulab.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//| :param ulab.ndarray c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value
|
||||
//| :param ulab.numpy.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//| :param ulab.numpy.ndarray c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value
|
||||
//| :return tuple (r, c): The real and complex parts of the FFT
|
||||
//|
|
||||
//| Perform a Fast Fourier Transform from the time domain into the frequency domain
|
||||
@@ -48,10 +49,10 @@ static mp_obj_t fft_fft(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj, 1, 2, fft_fft);
|
||||
|
||||
//| def ifft(r: ulab.ndarray, c: Optional[ulab.ndarray] = None) -> Tuple[ulab.ndarray, ulab.ndarray]:
|
||||
//| def ifft(r: ulab.numpy.ndarray, c: Optional[ulab.numpy.ndarray] = None) -> Tuple[ulab.numpy.ndarray, ulab.numpy.ndarray]:
|
||||
//| """
|
||||
//| :param ulab.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//| :param ulab.ndarray c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value
|
||||
//| :param ulab.numpy.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//| :param ulab.numpy.ndarray c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value
|
||||
//| :return tuple (r, c): The real and complex parts of the inverse FFT
|
||||
//|
|
||||
//| Perform an Inverse Fast Fourier Transform from the frequeny domain into the time domain"""
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "../../ndarray.h"
|
||||
#include "../../ulab_tools.h"
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../scipy/signal/signal.h"
|
||||
#include "../ulab.h"
|
||||
#include "../scipy/signal/signal.h"
|
||||
#include "filter.h"
|
||||
|
||||
#if ULAB_NUMPY_HAS_CONVOLVE
|
||||
@@ -57,7 +57,7 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
|
||||
mp_float_t *outptr = (mp_float_t *)out->array;
|
||||
uint8_t *aarray = (uint8_t *)a->array;
|
||||
uint8_t *carray = (uint8_t *)c->array;
|
||||
|
||||
|
||||
int32_t off = len_c - 1;
|
||||
int32_t as = a->strides[ULAB_MAX_DIMS - 1] / a->itemsize;
|
||||
int32_t cs = c->strides[ULAB_MAX_DIMS - 1] / c->itemsize;
|
||||
@@ -13,8 +13,8 @@
|
||||
#ifndef _FILTER_
|
||||
#define _FILTER_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(filter_convolve_obj);
|
||||
#endif
|
||||
@@ -16,9 +16,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
@@ -364,7 +364,141 @@ static mp_obj_t linalg_norm(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_norm_obj, 1, linalg_norm);
|
||||
// MP_DEFINE_CONST_FUN_OBJ_1(linalg_norm_obj, linalg_norm);
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
//| def qr(m: ulab.numpy.ndarray) -> Tuple[ulab.numpy.ndarray, ulab.numpy.ndarray]:
|
||||
//| """
|
||||
//| :param m: a matrix
|
||||
//| :return tuple (Q, R):
|
||||
//|
|
||||
//| Factor the matrix a as QR, where Q is orthonormal and R is upper-triangular.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
|
||||
static mp_obj_t linalg_qr(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_mode, MP_ARG_OBJ, { .u_rom_obj = MP_ROM_QSTR(MP_QSTR_reduced) } },
|
||||
};
|
||||
|
||||
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("operation is defined for ndarrays only"));
|
||||
}
|
||||
ndarray_obj_t *source = MP_OBJ_TO_PTR(args[0].u_obj);
|
||||
if(source->ndim != 2) {
|
||||
mp_raise_ValueError(translate("operation is defined for 2D arrays only"));
|
||||
}
|
||||
|
||||
size_t m = source->shape[ULAB_MAX_DIMS - 2]; // rows
|
||||
size_t n = source->shape[ULAB_MAX_DIMS - 1]; // columns
|
||||
|
||||
ndarray_obj_t *Q = ndarray_new_dense_ndarray(2, ndarray_shape_vector(0, 0, m, m), NDARRAY_FLOAT);
|
||||
ndarray_obj_t *R = ndarray_new_dense_ndarray(2, source->shape, NDARRAY_FLOAT);
|
||||
|
||||
mp_float_t *qarray = (mp_float_t *)Q->array;
|
||||
mp_float_t *rarray = (mp_float_t *)R->array;
|
||||
|
||||
// simply copy the entries of source to a float array
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype);
|
||||
uint8_t *sarray = (uint8_t *)source->array;
|
||||
|
||||
for(size_t i = 0; i < m; i++) {
|
||||
for(size_t j = 0; j < n; j++) {
|
||||
*rarray++ = func(sarray);
|
||||
sarray += source->strides[ULAB_MAX_DIMS - 1];
|
||||
}
|
||||
sarray -= n * source->strides[ULAB_MAX_DIMS - 1];
|
||||
sarray += source->strides[ULAB_MAX_DIMS - 2];
|
||||
}
|
||||
rarray -= m * n;
|
||||
|
||||
// start with the unit matrix
|
||||
for(size_t i = 0; i < m; i++) {
|
||||
qarray[i * (m + 1)] = 1.0;
|
||||
}
|
||||
|
||||
for(size_t j = 0; j < n; j++) { // columns
|
||||
for(size_t i = m - 1; i > j; i--) { // rows
|
||||
mp_float_t c, s;
|
||||
// Givens matrix: note that numpy uses a strange form of the rotation
|
||||
// [[c s],
|
||||
// [s -c]]
|
||||
if(MICROPY_FLOAT_C_FUN(fabs)(rarray[i * n + j]) < LINALG_EPSILON) { // r[i, j]
|
||||
c = (rarray[(i - 1) * n + j] >= 0.0) ? 1.0 : -1.0; // r[i-1, j]
|
||||
s = 0.0;
|
||||
} else if(MICROPY_FLOAT_C_FUN(fabs)(rarray[(i - 1) * n + j]) < LINALG_EPSILON) { // r[i-1, j]
|
||||
c = 0.0;
|
||||
s = (rarray[i * n + j] >= 0.0) ? -1.0 : 1.0; // r[i, j]
|
||||
} else {
|
||||
mp_float_t t, u;
|
||||
if(MICROPY_FLOAT_C_FUN(fabs)(rarray[(i - 1) * n + j]) > MICROPY_FLOAT_C_FUN(fabs)(rarray[i * n + j])) { // r[i-1, j], r[i, j]
|
||||
t = rarray[i * n + j] / rarray[(i - 1) * n + j]; // r[i, j]/r[i-1, j]
|
||||
u = MICROPY_FLOAT_C_FUN(sqrt)(1 + t * t);
|
||||
c = -1.0 / u;
|
||||
s = c * t;
|
||||
} else {
|
||||
t = rarray[(i - 1) * n + j] / rarray[i * n + j]; // r[i-1, j]/r[i, j]
|
||||
u = MICROPY_FLOAT_C_FUN(sqrt)(1 + t * t);
|
||||
s = -1.0 / u;
|
||||
c = s * t;
|
||||
}
|
||||
}
|
||||
|
||||
mp_float_t r1, r2;
|
||||
// update R: multiply with the rotation matrix from the left
|
||||
for(size_t k = 0; k < n; k++) {
|
||||
r1 = rarray[(i - 1) * n + k]; // r[i-1, k]
|
||||
r2 = rarray[i * n + k]; // r[i, k]
|
||||
rarray[(i - 1) * n + k] = c * r1 + s * r2; // r[i-1, k]
|
||||
rarray[i * n + k] = s * r1 - c * r2; // r[i, k]
|
||||
}
|
||||
|
||||
// update Q: multiply with the transpose of the rotation matrix from the right
|
||||
for(size_t k = 0; k < m; k++) {
|
||||
r1 = qarray[k * m + (i - 1)];
|
||||
r2 = qarray[k * m + i];
|
||||
qarray[k * m + (i - 1)] = c * r1 + s * r2;
|
||||
qarray[k * m + i] = s * r1 - c * r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
GET_STR_DATA_LEN(args[1].u_obj, mode, len);
|
||||
if(memcmp(mode, "complete", 8) == 0) {
|
||||
tuple->items[0] = MP_OBJ_FROM_PTR(Q);
|
||||
tuple->items[1] = MP_OBJ_FROM_PTR(R);
|
||||
} else if(memcmp(mode, "reduced", 7) == 0) {
|
||||
size_t k = MAX(m, n) - MIN(m, n);
|
||||
ndarray_obj_t *q = ndarray_new_dense_ndarray(2, ndarray_shape_vector(0, 0, m, m - k), NDARRAY_FLOAT);
|
||||
ndarray_obj_t *r = ndarray_new_dense_ndarray(2, ndarray_shape_vector(0, 0, m - k, n), NDARRAY_FLOAT);
|
||||
mp_float_t *qa = (mp_float_t *)q->array;
|
||||
mp_float_t *ra = (mp_float_t *)r->array;
|
||||
for(size_t i = 0; i < m; i++) {
|
||||
memcpy(qa, qarray, (m - k) * q->itemsize);
|
||||
qa += (m - k);
|
||||
qarray += m;
|
||||
}
|
||||
for(size_t i = 0; i < m - k; i++) {
|
||||
memcpy(ra, rarray, n * r->itemsize);
|
||||
ra += n;
|
||||
rarray += n;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_FROM_PTR(q);
|
||||
tuple->items[1] = MP_OBJ_FROM_PTR(r);
|
||||
} else {
|
||||
mp_raise_ValueError(translate("mode must be complete, or reduced"));
|
||||
}
|
||||
return tuple;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_qr_obj, 1, linalg_qr);
|
||||
#endif
|
||||
|
||||
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) },
|
||||
@@ -381,6 +515,9 @@ STATIC const mp_rom_map_elem_t ulab_linalg_globals_table[] = {
|
||||
#if ULAB_LINALG_HAS_INV
|
||||
{ MP_ROM_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj },
|
||||
#endif
|
||||
#if ULAB_LINALG_HAS_QR
|
||||
{ MP_ROM_QSTR(MP_QSTR_qr), (mp_obj_t)&linalg_qr_obj },
|
||||
#endif
|
||||
#endif
|
||||
#if ULAB_LINALG_HAS_NORM
|
||||
{ MP_ROM_QSTR(MP_QSTR_norm), (mp_obj_t)&linalg_norm_obj },
|
||||
|
||||
@@ -23,4 +23,5 @@ MP_DECLARE_CONST_FUN_OBJ_1(linalg_det_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(linalg_eig_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(linalg_inv_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_norm_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_qr_obj);
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "linalg_tools.h"
|
||||
|
||||
|
||||
66
python/port/mod/ulab/numpy/ndarray/ndarray_iter.c
Normal file
66
python/port/mod/ulab/numpy/ndarray/ndarray_iter.c
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
/*
|
||||
* This file is part of the micropython-ulab project,
|
||||
*
|
||||
* https://github.com/v923z/micropython-ulab
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Zoltán Vörös
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ndarray_iter.h"
|
||||
|
||||
#ifdef NDARRAY_HAS_FLATITER
|
||||
mp_obj_t ndarray_flatiter_make_new(mp_obj_t self_in) {
|
||||
ndarray_flatiter_t *flatiter = m_new_obj(ndarray_flatiter_t);
|
||||
flatiter->base.type = &ndarray_flatiter_type;
|
||||
flatiter->iternext = ndarray_flatiter_next;
|
||||
flatiter->ndarray = MP_OBJ_TO_PTR(self_in);
|
||||
flatiter->cur = 0;
|
||||
return flatiter;
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_flatiter_next(mp_obj_t self_in) {
|
||||
ndarray_flatiter_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(self->ndarray);
|
||||
uint8_t *array = (uint8_t *)ndarray->array;
|
||||
|
||||
if(self->cur < ndarray->len) {
|
||||
uint32_t remainder = self->cur;
|
||||
uint8_t i = ULAB_MAX_DIMS - 1;
|
||||
do {
|
||||
size_t div = (remainder / ndarray->shape[i]);
|
||||
array += remainder * ndarray->strides[i];
|
||||
remainder -= div * ndarray->shape[i];
|
||||
i--;
|
||||
} while(i > ULAB_MAX_DIMS - ndarray->ndim);
|
||||
self->cur++;
|
||||
return ndarray_get_item(ndarray, array);
|
||||
}
|
||||
return MP_OBJ_STOP_ITERATION;
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_new_flatiterator(mp_obj_t flatiter_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
assert(sizeof(ndarray_flatiter_t) <= sizeof(mp_obj_iter_buf_t));
|
||||
ndarray_flatiter_t *iter = (ndarray_flatiter_t *)iter_buf;
|
||||
ndarray_flatiter_t *flatiter = MP_OBJ_TO_PTR(flatiter_in);
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
iter->iternext = ndarray_flatiter_next;
|
||||
iter->ndarray = flatiter->ndarray;
|
||||
iter->cur = 0;
|
||||
return MP_OBJ_FROM_PTR(iter);
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_get_flatiterator(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
return ndarray_new_flatiterator(o_in, iter_buf);
|
||||
}
|
||||
#endif /* NDARRAY_HAS_FLATITER */
|
||||
36
python/port/mod/ulab/numpy/ndarray/ndarray_iter.h
Normal file
36
python/port/mod/ulab/numpy/ndarray/ndarray_iter.h
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 2020-2021 Zoltán Vörös
|
||||
*/
|
||||
|
||||
#ifndef _NDARRAY_ITER_
|
||||
#define _NDARRAY_ITER_
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
|
||||
// TODO: take simply mp_obj_ndarray_it_t from ndarray.c
|
||||
typedef struct _mp_obj_ndarray_flatiter_t {
|
||||
mp_obj_base_t base;
|
||||
mp_fun_1_t iternext;
|
||||
mp_obj_t ndarray;
|
||||
size_t cur;
|
||||
} ndarray_flatiter_t;
|
||||
|
||||
mp_obj_t ndarray_get_flatiterator(mp_obj_t , mp_obj_iter_buf_t *);
|
||||
mp_obj_t ndarray_flatiter_make_new(mp_obj_t );
|
||||
mp_obj_t ndarray_flatiter_next(mp_obj_t );
|
||||
|
||||
#endif
|
||||
@@ -14,14 +14,14 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objint.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/builtin.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "numerical.h"
|
||||
|
||||
enum NUMERICAL_FUNCTION_TYPE {
|
||||
@@ -41,7 +41,33 @@ enum NUMERICAL_FUNCTION_TYPE {
|
||||
//| Most of these functions take an "axis" argument, which indicates whether to
|
||||
//| operate over the flattened array (None), or a particular axis (integer)."""
|
||||
//|
|
||||
//| from ulab import _ArrayLike
|
||||
//| from typing import Dict
|
||||
//|
|
||||
//| _ArrayLike = Union[ndarray, List[_float], Tuple[_float], range]
|
||||
//|
|
||||
//| _DType = int
|
||||
//| """`ulab.numpy.int8`, `ulab.numpy.uint8`, `ulab.numpy.int16`, `ulab.numpy.uint16`, `ulab.numpy.float` or `ulab.numpy.bool`"""
|
||||
//|
|
||||
//| from builtins import float as _float
|
||||
//| from builtins import bool as _bool
|
||||
//|
|
||||
//| int8: _DType
|
||||
//| """Type code for signed integers in the range -128 .. 127 inclusive, like the 'b' typecode of `array.array`"""
|
||||
//|
|
||||
//| int16: _DType
|
||||
//| """Type code for signed integers in the range -32768 .. 32767 inclusive, like the 'h' typecode of `array.array`"""
|
||||
//|
|
||||
//| float: _DType
|
||||
//| """Type code for floating point values, like the 'f' typecode of `array.array`"""
|
||||
//|
|
||||
//| uint8: _DType
|
||||
//| """Type code for unsigned integers in the range 0 .. 255 inclusive, like the 'H' typecode of `array.array`"""
|
||||
//|
|
||||
//| uint16: _DType
|
||||
//| """Type code for unsigned integers in the range 0 .. 65535 inclusive, like the 'h' typecode of `array.array`"""
|
||||
//|
|
||||
//| bool: _DType
|
||||
//| """Type code for boolean values"""
|
||||
//|
|
||||
|
||||
static void numerical_reduce_axes(ndarray_obj_t *ndarray, int8_t axis, size_t *shape, int32_t *strides) {
|
||||
@@ -78,8 +104,7 @@ static mp_obj_t numerical_all_any(mp_obj_t oin, mp_obj_t axis, uint8_t optype) {
|
||||
}
|
||||
// always get a float, so that we don't have to resolve the dtype later
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(ndarray->dtype);
|
||||
// We set results to true here because it crash if it is NULL
|
||||
ndarray_obj_t *results = mp_const_true;
|
||||
ndarray_obj_t *results = NULL;
|
||||
uint8_t *rarray = NULL;
|
||||
shape_strides _shape_strides = tools_reduce_axes(ndarray, axis);
|
||||
if(axis != mp_const_none) {
|
||||
@@ -153,8 +178,16 @@ static mp_obj_t numerical_all_any(mp_obj_t oin, mp_obj_t axis, uint8_t optype) {
|
||||
array -= _shape_strides.strides[ULAB_MAX_DIMS - 2] * _shape_strides.shape[ULAB_MAX_DIMS - 2];
|
||||
array += _shape_strides.strides[ULAB_MAX_DIMS - 3];
|
||||
i++;
|
||||
} while(i < _shape_strides.shape[ULAB_MAX_DIMS - 3])
|
||||
} while(i < _shape_strides.shape[ULAB_MAX_DIMS - 3]);
|
||||
#endif
|
||||
if(axis == mp_const_none) {
|
||||
// the innermost loop fell through, so return the result here
|
||||
if(!anytype) {
|
||||
return mp_const_false;
|
||||
} else {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
} else if(mp_obj_is_int(oin) || mp_obj_is_float(oin)) {
|
||||
return mp_obj_is_true(oin) ? mp_const_true : mp_const_false;
|
||||
@@ -265,7 +298,7 @@ static mp_obj_t numerical_sum_mean_std_ndarray(ndarray_obj_t *ndarray, mp_obj_t
|
||||
if(ndarray->dtype == NDARRAY_FLOAT) {
|
||||
return mp_obj_new_float(M * ndarray->len);
|
||||
} else {
|
||||
return mp_obj_new_int((int32_t)(M * ndarray->len));
|
||||
return mp_obj_new_int((int32_t)MICROPY_FLOAT_C_FUN(round)(M * ndarray->len));
|
||||
}
|
||||
} else if(optype == NUMERICAL_MEAN) {
|
||||
return mp_obj_new_float(M);
|
||||
@@ -551,6 +584,7 @@ static mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inpla
|
||||
int8_t ax = 0;
|
||||
if(axis == mp_const_none) {
|
||||
// flatten the array
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
for(uint8_t i=0; i < ULAB_MAX_DIMS - 1; i++) {
|
||||
ndarray->shape[i] = 0;
|
||||
ndarray->strides[i] = 0;
|
||||
@@ -558,6 +592,7 @@ static mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inpla
|
||||
ndarray->shape[ULAB_MAX_DIMS - 1] = ndarray->len;
|
||||
ndarray->strides[ULAB_MAX_DIMS - 1] = ndarray->itemsize;
|
||||
ndarray->ndim = 1;
|
||||
#endif
|
||||
} else {
|
||||
ax = mp_obj_get_int(axis);
|
||||
if(ax < 0) ax += ndarray->ndim;
|
||||
@@ -630,7 +665,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmin_obj, 1, numerical_argmin);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ARGSORT
|
||||
//| def argsort(array: ulab.ndarray, *, axis: int = -1) -> ulab.ndarray:
|
||||
//| def argsort(array: ulab.numpy.ndarray, *, axis: int = -1) -> ulab.numpy.ndarray:
|
||||
//| """Returns an array which gives indices into the input array from least to greatest."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -739,7 +774,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argsort_obj, 1, numerical_argsort);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_CROSS
|
||||
//| def cross(a: ulab.ndarray, b: ulab.ndarray) -> ulab.ndarray:
|
||||
//| def cross(a: ulab.numpy.ndarray, b: ulab.numpy.ndarray) -> ulab.numpy.ndarray:
|
||||
//| """Return the cross product of two vectors of length 3"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -817,7 +852,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(numerical_cross_obj, numerical_cross);
|
||||
#endif /* ULAB_NUMERICAL_HAS_CROSS */
|
||||
|
||||
#if ULAB_NUMPY_HAS_DIFF
|
||||
//| def diff(array: ulab.ndarray, *, n: int = 1, axis: int = -1) -> ulab.ndarray:
|
||||
//| def diff(array: ulab.numpy.ndarray, *, n: int = 1, axis: int = -1) -> ulab.numpy.ndarray:
|
||||
//| """Return the numerical derivative of successive elements of the array, as
|
||||
//| an array. axis=None is not supported."""
|
||||
//| ...
|
||||
@@ -898,7 +933,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_diff_obj, 1, numerical_diff);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_FLIP
|
||||
//| def flip(array: ulab.ndarray, *, axis: Optional[int] = None) -> ulab.ndarray:
|
||||
//| def flip(array: ulab.numpy.ndarray, *, axis: Optional[int] = None) -> ulab.numpy.ndarray:
|
||||
//| """Returns a new array that reverses the order of the elements along the
|
||||
//| given axis, or along all axes if axis is None."""
|
||||
//| ...
|
||||
@@ -946,7 +981,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_flip_obj, 1, numerical_flip);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_MINMAX
|
||||
//| def max(array: _ArrayLike, *, axis: Optional[int] = None) -> float:
|
||||
//| def max(array: _ArrayLike, *, axis: Optional[int] = None) -> _float:
|
||||
//| """Return the maximum element of the 1D array"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -959,7 +994,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_max_obj, 1, numerical_max);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_MEAN
|
||||
//| def mean(array: _ArrayLike, *, axis: Optional[int] = None) -> float:
|
||||
//| def mean(array: _ArrayLike, *, axis: Optional[int] = None) -> _float:
|
||||
//| """Return the mean element of the 1D array, as a number if axis is None, otherwise as an array."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -972,7 +1007,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_mean_obj, 1, numerical_mean);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_MEDIAN
|
||||
//| def median(array: ulab.ndarray, *, axis: int = -1) -> ulab.ndarray:
|
||||
//| def median(array: ulab.numpy.ndarray, *, axis: int = -1) -> ulab.numpy.ndarray:
|
||||
//| """Find the median value in an array along the given axis, or along all axes if axis is None."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -1072,7 +1107,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_median_obj, 1, numerical_median);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_MINMAX
|
||||
//| def min(array: _ArrayLike, *, axis: Optional[int] = None) -> float:
|
||||
//| def min(array: _ArrayLike, *, axis: Optional[int] = None) -> _float:
|
||||
//| """Return the minimum element of the 1D array"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -1085,7 +1120,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_min_obj, 1, numerical_min);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ROLL
|
||||
//| def roll(array: ulab.ndarray, distance: int, *, axis: Optional[int] = None) -> None:
|
||||
//| def roll(array: ulab.numpy.ndarray, distance: int, *, axis: Optional[int] = None) -> None:
|
||||
//| """Shift the content of a vector by the positions given as the second
|
||||
//| argument. If the ``axis`` keyword is supplied, the shift is applied to
|
||||
//| the given axis. The array is modified in place."""
|
||||
@@ -1250,7 +1285,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_roll_obj, 2, numerical_roll);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_SORT
|
||||
//| def sort(array: ulab.ndarray, *, axis: int = -1) -> ulab.ndarray:
|
||||
//| def sort(array: ulab.numpy.ndarray, *, axis: int = -1) -> ulab.numpy.ndarray:
|
||||
//| """Sort the array along the given axis, or along all axes if axis is None.
|
||||
//| The array is modified in place."""
|
||||
//| ...
|
||||
@@ -1289,7 +1324,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj, 1, numerical_sort_inplace
|
||||
#endif /* NDARRAY_HAS_SORT */
|
||||
|
||||
#if ULAB_NUMPY_HAS_STD
|
||||
//| def std(array: _ArrayLike, *, axis: Optional[int] = None, ddof: int = 0) -> float:
|
||||
//| def std(array: _ArrayLike, *, axis: Optional[int] = None, ddof: int = 0) -> _float:
|
||||
//| """Return the standard deviation of the array, as a number if axis is None, otherwise as an array."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -1326,7 +1361,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_std_obj, 1, numerical_std);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_SUM
|
||||
//| def sum(array: _ArrayLike, *, axis: Optional[int] = None) -> Union[float, int, ulab.ndarray]:
|
||||
//| def sum(array: _ArrayLike, *, axis: Optional[int] = None) -> Union[_float, int, ulab.numpy.ndarray]:
|
||||
//| """Return the sum of the array, as a number if axis is None, otherwise as an array."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _NUMERICAL_
|
||||
#define _NUMERICAL_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
// TODO: implement cumsum
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
} while(0)
|
||||
|
||||
#define RUN_MEAN_STD(type, array, rarray, ss, div, isStd) do {\
|
||||
RUN_MEAN_STD1(type, (array), (results), (rarray), (ss), (div), (isStd));\
|
||||
RUN_MEAN_STD1(type, (array), (rarray), (ss), (div), (isStd));\
|
||||
} while(0)
|
||||
|
||||
#define RUN_ARGMIN(ndarray, type, array, results, rarray, shape, strides, index, op) do {\
|
||||
@@ -444,7 +444,7 @@
|
||||
#endif
|
||||
|
||||
#if ULAB_MAX_DIMS == 4
|
||||
#define RUN_SUM(type, array, results, rarray, shape, strides, index) do {\
|
||||
#define RUN_SUM(type, array, results, rarray, ss) do {\
|
||||
size_t j = 0;\
|
||||
do {\
|
||||
size_t k = 0;\
|
||||
@@ -14,26 +14,45 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "numpy.h"
|
||||
#include "../ulab_create.h"
|
||||
#include "approx/approx.h"
|
||||
#include "compare/compare.h"
|
||||
#include "approx.h"
|
||||
#include "compare.h"
|
||||
#include "fft/fft.h"
|
||||
#include "filter/filter.h"
|
||||
#include "filter.h"
|
||||
#include "linalg/linalg.h"
|
||||
#include "numerical/numerical.h"
|
||||
#include "stats/stats.h"
|
||||
#include "transform/transform.h"
|
||||
#include "poly/poly.h"
|
||||
#include "vector/vector.h"
|
||||
#include "numerical.h"
|
||||
#include "stats.h"
|
||||
#include "transform.h"
|
||||
#include "poly.h"
|
||||
#include "vector.h"
|
||||
|
||||
//| """Compatibility layer for numpy"""
|
||||
//|
|
||||
|
||||
//| class ndarray: ...
|
||||
|
||||
//| def get_printoptions() -> Dict[str, int]:
|
||||
//| """Get printing options"""
|
||||
//| ...
|
||||
//|
|
||||
//| def set_printoptions(threshold: Optional[int] = None, edgeitems: Optional[int] = None) -> None:
|
||||
//| """Set printing options"""
|
||||
//| ...
|
||||
//|
|
||||
//| def ndinfo(array: ulab.numpy.ndarray) -> None:
|
||||
//| ...
|
||||
//|
|
||||
//| def array(
|
||||
//| values: Union[ndarray, Iterable[Union[_float, _bool, Iterable[Any]]]],
|
||||
//| *,
|
||||
//| dtype: _DType = ulab.numpy.float
|
||||
//| ) -> ulab.numpy.ndarray:
|
||||
//| """alternate constructor function for `ulab.numpy.ndarray`. Mirrors numpy.array"""
|
||||
//| ...
|
||||
|
||||
// math constants
|
||||
#if ULAB_NUMPY_HAS_E
|
||||
#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C
|
||||
@@ -127,7 +146,9 @@ static const mp_rom_map_elem_t ulab_numpy_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_concatenate), (mp_obj_t)&create_concatenate_obj },
|
||||
#endif
|
||||
#if ULAB_NUMPY_HAS_DIAG
|
||||
{ MP_ROM_QSTR(MP_QSTR_diag), (mp_obj_t)&create_diag_obj },
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
{ MP_ROM_QSTR(MP_QSTR_diag), (mp_obj_t)&create_diag_obj },
|
||||
#endif
|
||||
#endif
|
||||
#if ULAB_NUMPY_HAS_EMPTY
|
||||
{ MP_ROM_QSTR(MP_QSTR_empty), (mp_obj_t)&create_zeros_obj },
|
||||
@@ -210,10 +231,14 @@ static const mp_rom_map_elem_t ulab_numpy_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_diff), (mp_obj_t)&numerical_diff_obj },
|
||||
#endif
|
||||
#if ULAB_NUMPY_HAS_DOT
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dot), (mp_obj_t)&transform_dot_obj },
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dot), (mp_obj_t)&transform_dot_obj },
|
||||
#endif
|
||||
#endif
|
||||
#if ULAB_NUMPY_HAS_TRACE
|
||||
{ MP_ROM_QSTR(MP_QSTR_trace), (mp_obj_t)&stats_trace_obj },
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
{ MP_ROM_QSTR(MP_QSTR_trace), (mp_obj_t)&stats_trace_obj },
|
||||
#endif
|
||||
#endif
|
||||
#if ULAB_NUMPY_HAS_FLIP
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flip), (mp_obj_t)&numerical_flip_obj },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* This file is part of the micropython-ulab project,
|
||||
* This file is part of the micropython-ulab project,
|
||||
*
|
||||
* https://github.com/v923z/micropython-ulab
|
||||
*
|
||||
@@ -12,13 +12,13 @@
|
||||
* 2020 Taku Fukada
|
||||
*/
|
||||
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/objarray.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../linalg/linalg_tools.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "linalg/linalg_tools.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "poly.h"
|
||||
|
||||
#if ULAB_NUMPY_HAS_POLYFIT
|
||||
@@ -32,7 +32,7 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
mp_float_t *x, *XT, *y, *prod;
|
||||
|
||||
if(n_args == 2) { // only the y values are supplied
|
||||
// TODO: this is actually not enough: the first argument can very well be a matrix,
|
||||
// TODO: this is actually not enough: the first argument can very well be a matrix,
|
||||
// in which case we are between the rock and a hard place
|
||||
leny = (size_t)mp_obj_get_int(mp_obj_len_maybe(args[0]));
|
||||
deg = (uint8_t)mp_obj_get_int(args[1]);
|
||||
@@ -64,8 +64,8 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
y = m_new(mp_float_t, leny);
|
||||
fill_array_iterable(y, args[1]);
|
||||
}
|
||||
|
||||
// one could probably express X as a function of XT,
|
||||
|
||||
// one could probably express X as a function of XT,
|
||||
// and thereby save RAM, because X is used only in the product
|
||||
XT = m_new(mp_float_t, (deg+1)*leny); // XT is a matrix of shape (deg+1, len) (rows, columns)
|
||||
for(size_t i=0; i < leny; i++) { // column index
|
||||
@@ -74,15 +74,15 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
XT[i+j*leny] = XT[i+(j-1)*leny]*x[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prod = m_new(mp_float_t, (deg+1)*(deg+1)); // the product matrix is of shape (deg+1, deg+1)
|
||||
mp_float_t sum;
|
||||
for(uint8_t i=0; i < deg+1; i++) { // column index
|
||||
for(uint8_t j=0; j < deg+1; j++) { // row index
|
||||
sum = 0.0;
|
||||
for(size_t k=0; k < lenx; k++) {
|
||||
// (j, k) * (k, i)
|
||||
// Note that the second matrix is simply the transpose of the first:
|
||||
// (j, k) * (k, i)
|
||||
// Note that the second matrix is simply the transpose of the first:
|
||||
// X(k, i) = XT(i, k) = XT[k*lenx+i]
|
||||
sum += XT[j*lenx+k]*XT[i*lenx+k]; // X[k*(deg+1)+i];
|
||||
}
|
||||
@@ -90,15 +90,15 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
}
|
||||
if(!linalg_invert_matrix(prod, deg+1)) {
|
||||
// Although X was a Vandermonde matrix, whose inverse is guaranteed to exist,
|
||||
// we bail out here, if prod couldn't be inverted: if the values in x are not all
|
||||
// Although X was a Vandermonde matrix, whose inverse is guaranteed to exist,
|
||||
// we bail out here, if prod couldn't be inverted: if the values in x are not all
|
||||
// distinct, prod is singular
|
||||
m_del(mp_float_t, XT, (deg+1)*lenx);
|
||||
m_del(mp_float_t, x, lenx);
|
||||
m_del(mp_float_t, y, lenx);
|
||||
m_del(mp_float_t, prod, (deg+1)*(deg+1));
|
||||
mp_raise_ValueError(translate("could not invert Vandermonde matrix"));
|
||||
}
|
||||
}
|
||||
// at this point, we have the inverse of X^T * X
|
||||
// y is a column vector; x is free now, we can use it for storing intermediate values
|
||||
for(uint8_t i=0; i < deg+1; i++) { // row index
|
||||
@@ -110,12 +110,12 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
// XT is no longer needed
|
||||
m_del(mp_float_t, XT, (deg+1)*leny);
|
||||
|
||||
|
||||
ndarray_obj_t *beta = ndarray_new_linear_array(deg+1, NDARRAY_FLOAT);
|
||||
mp_float_t *betav = (mp_float_t *)beta->array;
|
||||
// x[0..(deg+1)] contains now the product X^T * y; we can get rid of y
|
||||
m_del(float, y, leny);
|
||||
|
||||
|
||||
// now, we calculate beta, i.e., we apply prod = (X^T * X)^(-1) on x = X^T * y; x is a column vector now
|
||||
for(uint8_t i=0; i < deg+1; i++) {
|
||||
sum = 0.0;
|
||||
@@ -127,7 +127,7 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
|
||||
m_del(mp_float_t, x, lenx);
|
||||
m_del(mp_float_t, prod, (deg+1)*(deg+1));
|
||||
for(uint8_t i=0; i < (deg+1)/2; i++) {
|
||||
// We have to reverse the array, for the leading coefficient comes first.
|
||||
// We have to reverse the array, for the leading coefficient comes first.
|
||||
SWAP(mp_float_t, betav[i], betav[deg-i]);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(beta);
|
||||
@@ -147,13 +147,13 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
||||
mp_float_t *p = m_new(mp_float_t, plen);
|
||||
mp_obj_iter_buf_t p_buf;
|
||||
mp_obj_t p_item, p_iterable = mp_getiter(o_p, &p_buf);
|
||||
uint8_t i = 0;
|
||||
uint8_t i = 0;
|
||||
while((p_item = mp_iternext(p_iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
p[i] = mp_obj_get_float(p_item);
|
||||
i++;
|
||||
}
|
||||
|
||||
// polynomials are going to be of type float, except, when both
|
||||
// polynomials are going to be of type float, except, when both
|
||||
// the coefficients and the independent variable are integers
|
||||
ndarray_obj_t *ndarray;
|
||||
if(mp_obj_is_type(o_x, &ulab_ndarray_type)) {
|
||||
@@ -161,10 +161,10 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
||||
uint8_t *sarray = (uint8_t *)source->array;
|
||||
ndarray = ndarray_new_dense_ndarray(source->ndim, source->shape, NDARRAY_FLOAT);
|
||||
mp_float_t *array = (mp_float_t *)ndarray->array;
|
||||
|
||||
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype);
|
||||
|
||||
// TODO: these loops are really nothing, but the re-impplementation of
|
||||
// TODO: these loops are really nothing, but the re-impplementation of
|
||||
// ITERATE_VECTOR from vectorise.c. We could pass a function pointer here
|
||||
#if ULAB_MAX_DIMS > 3
|
||||
size_t i = 0;
|
||||
@@ -207,7 +207,7 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
||||
sarray += source->strides[ULAB_MAX_DIMS - 4];
|
||||
i++;
|
||||
} while(i < source->shape[ULAB_MAX_DIMS - 4]);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
// o_x had better be a one-dimensional standard iterable
|
||||
ndarray = ndarray_new_linear_array(mp_obj_get_int(mp_obj_len_maybe(o_x)), NDARRAY_FLOAT);
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* This file is part of the micropython-ulab project,
|
||||
* This file is part of the micropython-ulab project,
|
||||
*
|
||||
* https://github.com/v923z/micropython-ulab
|
||||
*
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _POLY_
|
||||
#define _POLY_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_2(poly_polyval_obj);
|
||||
@@ -15,18 +15,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "stats.h"
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
#if ULAB_NUMPY_HAS_TRACE
|
||||
|
||||
//| def trace(m: ulab.numpy.ndarray) -> float:
|
||||
//| def trace(m: ulab.numpy.ndarray) -> _float:
|
||||
//| """
|
||||
//| :param m: a square matrix
|
||||
//|
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _STATS_
|
||||
#define _STATS_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(stats_trace_obj);
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "transform.h"
|
||||
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
#if ULAB_NUMPY_HAS_DOT
|
||||
//| def dot(m1: ulab.numpy.ndarray, m2: ulab.numpy.ndarray) -> Union[ulab.numpy.ndarray, float]:
|
||||
//| def dot(m1: ulab.numpy.ndarray, m2: ulab.numpy.ndarray) -> Union[ulab.numpy.ndarray, _float]:
|
||||
//| """
|
||||
//| :param ~ulab.numpy.ndarray m1: a matrix, or a vector
|
||||
//| :param ~ulab.numpy.ndarray m2: a matrix, or a vector
|
||||
@@ -87,3 +87,4 @@ mp_obj_t transform_dot(mp_obj_t _m1, mp_obj_t _m2) {
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(transform_dot_obj, transform_dot);
|
||||
#endif
|
||||
#endif
|
||||
@@ -15,12 +15,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "transform.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_2(transform_dot_obj);
|
||||
@@ -15,13 +15,13 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/binary.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objarray.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "vector.h"
|
||||
|
||||
//| """Element-by-element functions
|
||||
@@ -30,8 +30,6 @@
|
||||
//| applying the function to every element in the array. This is typically
|
||||
//| much more efficient than expressing the same operation as a Python loop."""
|
||||
//|
|
||||
//| from ulab import _DType, _ArrayLike
|
||||
//|
|
||||
|
||||
static mp_obj_t vectorise_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float_t)) {
|
||||
// Return a single value, if o_in is not iterable
|
||||
@@ -111,7 +109,7 @@ static mp_obj_t vectorise_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float
|
||||
}
|
||||
|
||||
#if ULAB_NUMPY_HAS_ACOS
|
||||
//| def acos(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def acos(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse cosine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -121,7 +119,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acos_obj, vectorise_acos);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ACOSH
|
||||
//| def acosh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def acosh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse hyperbolic cosine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -131,7 +129,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acosh_obj, vectorise_acosh);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ASIN
|
||||
//| def asin(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def asin(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse sine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -141,7 +139,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asin_obj, vectorise_asin);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ASINH
|
||||
//| def asinh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def asinh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse hyperbolic sine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -151,7 +149,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asinh_obj, vectorise_asinh);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_AROUND
|
||||
//| def around(a: _ArrayLike, *, decimals: int = 0) -> ulab.ndarray:
|
||||
//| def around(a: _ArrayLike, *, decimals: int = 0) -> ulab.numpy.ndarray:
|
||||
//| """Returns a new float array in which each element is rounded to
|
||||
//| ``decimals`` places."""
|
||||
//| ...
|
||||
@@ -221,7 +219,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(vectorise_around_obj, 1, vectorise_around);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ATAN
|
||||
//| def atan(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def atan(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse tangent function; the return values are in the
|
||||
//| range [-pi/2,pi/2]."""
|
||||
//| ...
|
||||
@@ -232,7 +230,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atan_obj, vectorise_atan);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ARCTAN2
|
||||
//| def arctan2(ya: _ArrayLike, xa: _ArrayLike) -> ulab.ndarray:
|
||||
//| def arctan2(ya: _ArrayLike, xa: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse tangent function of y/x; the return values are in
|
||||
//| the range [-pi, pi]."""
|
||||
//| ...
|
||||
@@ -315,7 +313,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(vectorise_arctan2_obj, vectorise_arctan2);
|
||||
#endif /* ULAB_VECTORISE_HAS_ARCTAN2 */
|
||||
|
||||
#if ULAB_NUMPY_HAS_ATANH
|
||||
//| def atanh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def atanh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the inverse hyperbolic tangent function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -325,7 +323,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atanh_obj, vectorise_atanh);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_CEIL
|
||||
//| def ceil(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def ceil(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Rounds numbers up to the next whole number"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -335,7 +333,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_ceil_obj, vectorise_ceil);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_COS
|
||||
//| def cos(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def cos(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the cosine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -345,7 +343,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_cos_obj, vectorise_cos);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_COSH
|
||||
//| def cosh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def cosh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the hyperbolic cosine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -355,7 +353,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_cosh_obj, vectorise_cosh);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_DEGREES
|
||||
//| def degrees(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def degrees(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Converts angles from radians to degrees"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -372,7 +370,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_degrees_obj, vectorise_degrees);
|
||||
#endif
|
||||
|
||||
#if ULAB_SCIPY_SPECIAL_HAS_ERF
|
||||
//| def erf(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def erf(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the error function, which has applications in statistics"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -382,7 +380,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erf_obj, vectorise_erf);
|
||||
#endif
|
||||
|
||||
#if ULAB_SCIPY_SPECIAL_HAS_ERFC
|
||||
//| def erfc(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def erfc(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the complementary error function, which has applications in statistics"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -392,7 +390,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erfc_obj, vectorise_erfc);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_EXP
|
||||
//| def exp(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def exp(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the exponent function."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -402,7 +400,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_exp_obj, vectorise_exp);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_EXPM1
|
||||
//| def expm1(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def expm1(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes $e^x-1$. In certain applications, using this function preserves numeric accuracy better than the `exp` function."""
|
||||
//| ...
|
||||
//|
|
||||
@@ -412,7 +410,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_expm1_obj, vectorise_expm1);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_FLOOR
|
||||
//| def floor(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def floor(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Rounds numbers up to the next whole number"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -422,7 +420,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_floor_obj, vectorise_floor);
|
||||
#endif
|
||||
|
||||
#if ULAB_SCIPY_SPECIAL_HAS_GAMMA
|
||||
//| def gamma(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def gamma(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the gamma function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -432,7 +430,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_gamma_obj, vectorise_gamma);
|
||||
#endif
|
||||
|
||||
#if ULAB_SCIPY_SPECIAL_HAS_GAMMALN
|
||||
//| def lgamma(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def lgamma(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the natural log of the gamma function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -442,7 +440,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_lgamma_obj, vectorise_lgamma);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_LOG
|
||||
//| def log(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def log(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the natural log"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -452,7 +450,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log_obj, vectorise_log);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_LOG10
|
||||
//| def log10(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def log10(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the log base 10"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -462,7 +460,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log10_obj, vectorise_log10);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_LOG2
|
||||
//| def log2(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def log2(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the log base 2"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -472,7 +470,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log2_obj, vectorise_log2);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_RADIANS
|
||||
//| def radians(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def radians(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Converts angles from degrees to radians"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -489,7 +487,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_radians_obj, vectorise_radians);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_SIN
|
||||
//| def sin(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def sin(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the sine function"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -499,7 +497,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sin_obj, vectorise_sin);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_SINH
|
||||
//| def sinh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def sinh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the hyperbolic sine"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -509,7 +507,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sinh_obj, vectorise_sinh);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_SQRT
|
||||
//| def sqrt(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def sqrt(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the square root"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -519,7 +517,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sqrt_obj, vectorise_sqrt);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_TAN
|
||||
//| def tan(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def tan(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the tangent"""
|
||||
//| ...
|
||||
//|
|
||||
@@ -529,7 +527,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tan_obj, vectorise_tan);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_TANH
|
||||
//| def tanh(a: _ArrayLike) -> ulab.ndarray:
|
||||
//| def tanh(a: _ArrayLike) -> ulab.numpy.ndarray:
|
||||
//| """Computes the hyperbolic tangent"""
|
||||
//| ...
|
||||
|
||||
@@ -549,7 +547,7 @@ static mp_obj_t vectorise_vectorized_function_call(mp_obj_t self_in, size_t n_ar
|
||||
ndarray_obj_t *ndarray = ndarray_new_dense_ndarray(source->ndim, source->shape, self->otypes);
|
||||
for(size_t i=0; i < source->len; i++) {
|
||||
avalue[0] = mp_binary_get_val_array(source->dtype, source->array, i);
|
||||
fvalue = self->type->call(self->fun, 1, 0, avalue);
|
||||
fvalue = self->type->MP_TYPE_CALL(self->fun, 1, 0, avalue);
|
||||
ndarray_set_value(self->otypes, ndarray->array, i, fvalue);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(ndarray);
|
||||
@@ -561,14 +559,14 @@ static mp_obj_t vectorise_vectorized_function_call(mp_obj_t self_in, size_t n_ar
|
||||
mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
|
||||
size_t i=0;
|
||||
while ((avalue[0] = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
fvalue = self->type->call(self->fun, 1, 0, avalue);
|
||||
fvalue = self->type->MP_TYPE_CALL(self->fun, 1, 0, avalue);
|
||||
ndarray_set_value(self->otypes, ndarray->array, i, fvalue);
|
||||
i++;
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(ndarray);
|
||||
} else if(mp_obj_is_int(args[0]) || mp_obj_is_float(args[0])) {
|
||||
ndarray_obj_t *ndarray = ndarray_new_linear_array(1, self->otypes);
|
||||
fvalue = self->type->call(self->fun, 1, 0, args);
|
||||
fvalue = self->type->MP_TYPE_CALL(self->fun, 1, 0, args);
|
||||
ndarray_set_value(self->otypes, ndarray->array, 0, fvalue);
|
||||
return MP_OBJ_FROM_PTR(ndarray);
|
||||
} else {
|
||||
@@ -579,15 +577,18 @@ static mp_obj_t vectorise_vectorized_function_call(mp_obj_t self_in, size_t n_ar
|
||||
|
||||
const mp_obj_type_t vectorise_function_type = {
|
||||
{ &mp_type_type },
|
||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
||||
.name = MP_QSTR_,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
.call = vectorise_vectorized_function_call,
|
||||
)
|
||||
};
|
||||
|
||||
//| def vectorize(
|
||||
//| f: Union[Callable[[int], float], Callable[[float], float]],
|
||||
//| f: Union[Callable[[int], _float], Callable[[_float], _float]],
|
||||
//| *,
|
||||
//| otypes: Optional[_DType] = None
|
||||
//| ) -> Callable[[_ArrayLike], ulab.ndarray]:
|
||||
//| ) -> Callable[[_ArrayLike], ulab.numpy.ndarray]:
|
||||
//| """
|
||||
//| :param callable f: The function to wrap
|
||||
//| :param otypes: List of array types that may be returned by the function. None is interpreted to mean the return value is float.
|
||||
@@ -605,7 +606,7 @@ static mp_obj_t vectorise_vectorize(size_t n_args, const mp_obj_t *pos_args, mp_
|
||||
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);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(args[0].u_obj);
|
||||
if(type->call == NULL) {
|
||||
if(mp_type_get_call_slot(type) == NULL) {
|
||||
mp_raise_TypeError(translate("first argument must be a callable"));
|
||||
}
|
||||
mp_obj_t _otypes = args[1].u_obj;
|
||||
@@ -12,8 +12,8 @@
|
||||
#ifndef _VECTOR_
|
||||
#define _VECTOR_
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../ulab.h"
|
||||
#include "../ndarray.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_acos_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_acosh_obj);
|
||||
@@ -7,31 +7,31 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Vikas Udupa
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ulab_tools.h"
|
||||
#include "../../numpy/linalg/linalg_tools.h"
|
||||
#include "linalg.h"
|
||||
|
||||
#if ULAB_SCIPY_HAS_LINALG_MODULE
|
||||
//|
|
||||
//| import ulab.scipy
|
||||
//| import ulab.numpy
|
||||
//|
|
||||
//| """Linear algebra functions"""
|
||||
//|
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
|
||||
#define TOLERANCE 0.0000001
|
||||
|
||||
//| def solve_triangular(A: ulab.numpy.ndarray, b: ulab.numpy.ndarray, lower: bool) -> ulab.numpy.ndarray:
|
||||
//| """
|
||||
//| :param ~ulab.numpy.ndarray A: a matrix
|
||||
@@ -46,9 +46,9 @@
|
||||
//|
|
||||
|
||||
static mp_obj_t solve_triangular(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
|
||||
|
||||
size_t i, j;
|
||||
|
||||
|
||||
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} } ,
|
||||
@@ -64,7 +64,7 @@ static mp_obj_t solve_triangular(size_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
|
||||
ndarray_obj_t *A = MP_OBJ_TO_PTR(args[0].u_obj);
|
||||
ndarray_obj_t *b = MP_OBJ_TO_PTR(args[1].u_obj);
|
||||
|
||||
|
||||
if(!ndarray_is_dense(A) || !ndarray_is_dense(b)) {
|
||||
mp_raise_TypeError(translate("input must be a dense ndarray"));
|
||||
}
|
||||
@@ -82,7 +82,7 @@ static mp_obj_t solve_triangular(size_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
|
||||
// check if input matrix A is singular
|
||||
for (i = 0; i < A_rows; i++) {
|
||||
if (MICROPY_FLOAT_C_FUN(fabs)(get_A_ele(A_arr)) < TOLERANCE)
|
||||
if (MICROPY_FLOAT_C_FUN(fabs)(get_A_ele(A_arr)) < LINALG_EPSILON)
|
||||
mp_raise_ValueError(translate("input matrix is singular"));
|
||||
A_arr += A->strides[ULAB_MAX_DIMS - 2];
|
||||
A_arr += A->strides[ULAB_MAX_DIMS - 1];
|
||||
@@ -92,7 +92,7 @@ static mp_obj_t solve_triangular(size_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
|
||||
ndarray_obj_t *x = ndarray_new_dense_ndarray(b->ndim, b->shape, NDARRAY_FLOAT);
|
||||
mp_float_t *x_arr = (mp_float_t *)x->array;
|
||||
|
||||
|
||||
if (mp_obj_is_true(args[2].u_obj)) {
|
||||
// Solve the lower triangular matrix by iterating each row of A.
|
||||
// Start by finding the first unknown using the first row.
|
||||
@@ -166,7 +166,7 @@ static mp_obj_t cho_solve(mp_obj_t _L, mp_obj_t _b) {
|
||||
|
||||
ndarray_obj_t *L = MP_OBJ_TO_PTR(_L);
|
||||
ndarray_obj_t *b = MP_OBJ_TO_PTR(_b);
|
||||
|
||||
|
||||
if(!ndarray_is_dense(L) || !ndarray_is_dense(b)) {
|
||||
mp_raise_TypeError(translate("input must be a dense ndarray"));
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../../ndarray.h"
|
||||
#include "../../ulab.h"
|
||||
@@ -30,7 +30,7 @@ static mp_float_t optimize_python_call(const mp_obj_type_t *type, mp_obj_t fun,
|
||||
// where f is defined in python. Takes a float, returns a float.
|
||||
// The array of mp_obj_t type must be supplied, as must the number of parameters (a, b, c...) in nparams
|
||||
fargs[0] = mp_obj_new_float(x);
|
||||
return mp_obj_get_float(type->call(fun, nparams+1, 0, fargs));
|
||||
return mp_obj_get_float(type->MP_TYPE_CALL(fun, nparams+1, 0, fargs));
|
||||
}
|
||||
|
||||
#if ULAB_SCIPY_OPTIMIZE_HAS_BISECT
|
||||
@@ -70,7 +70,7 @@ STATIC mp_obj_t optimize_bisect(size_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
|
||||
mp_obj_t fun = args[0].u_obj;
|
||||
const mp_obj_type_t *type = mp_obj_get_type(fun);
|
||||
if(type->call == NULL) {
|
||||
if(mp_type_get_call_slot(type) == NULL) {
|
||||
mp_raise_TypeError(translate("first argument must be a function"));
|
||||
}
|
||||
mp_float_t xtol = mp_obj_get_float(args[3].u_obj);
|
||||
@@ -140,7 +140,7 @@ STATIC mp_obj_t optimize_fmin(size_t n_args, const mp_obj_t *pos_args, mp_map_t
|
||||
|
||||
mp_obj_t fun = args[0].u_obj;
|
||||
const mp_obj_type_t *type = mp_obj_get_type(fun);
|
||||
if(type->call == NULL) {
|
||||
if(mp_type_get_call_slot(type) == NULL) {
|
||||
mp_raise_TypeError(translate("first argument must be a function"));
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ mp_obj_t optimize_curve_fit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
||||
|
||||
mp_obj_t fun = args[0].u_obj;
|
||||
const mp_obj_type_t *type = mp_obj_get_type(fun);
|
||||
if(type->call == NULL) {
|
||||
if(mp_type_get_call_slot(type) == NULL) {
|
||||
mp_raise_TypeError(translate("first argument must be a function"));
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ static mp_obj_t optimize_newton(size_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
|
||||
mp_obj_t fun = args[0].u_obj;
|
||||
const mp_obj_type_t *type = mp_obj_get_type(fun);
|
||||
if(type->call == NULL) {
|
||||
if(mp_type_get_call_slot(type) == NULL) {
|
||||
mp_raise_TypeError(translate("first argument must be a function"));
|
||||
}
|
||||
mp_float_t x = mp_obj_get_float(args[1].u_obj);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "../ulab.h"
|
||||
#include "optimize/optimize.h"
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../ndarray.h"
|
||||
#include "../../numpy/fft/fft_tools.h"
|
||||
|
||||
#if ULAB_SCIPY_SIGNAL_HAS_SPECTROGRAM
|
||||
//| def spectrogram(r: ulab.ndarray) -> ulab.ndarray:
|
||||
//| import ulab.numpy
|
||||
//|
|
||||
//| def spectrogram(r: ulab.numpy.ndarray) -> ulab.numpy.ndarray:
|
||||
//| """
|
||||
//| :param ulab.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//| :param ulab.numpy.ndarray r: A 1-dimension array of values whose size is a power of 2
|
||||
//|
|
||||
//| Computes the spectrum of the input signal. This is the absolute value of the (complex-valued) fft of the signal.
|
||||
//| This function is similar to scipy's ``scipy.signal.spectrogram``."""
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "../../ulab.h"
|
||||
#include "../../numpy/vector/vector.h"
|
||||
#include "../../numpy/vector.h"
|
||||
|
||||
static const mp_rom_map_elem_t ulab_scipy_special_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_special) },
|
||||
|
||||
@@ -14,27 +14,26 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/binary.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/objarray.h>
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ulab_create.h"
|
||||
#include "ndarray.h"
|
||||
#include "ndarray_properties.h"
|
||||
#include "numpy/ndarray/ndarray_iter.h"
|
||||
|
||||
#include "numpy/numpy.h"
|
||||
#include "scipy/scipy.h"
|
||||
#include "numpy/fft/fft.h"
|
||||
#include "numpy/linalg/linalg.h"
|
||||
// TODO: we should get rid of this; array.sort depends on it
|
||||
#include "numpy/numerical/numerical.h"
|
||||
#include "numpy/numerical.h"
|
||||
|
||||
#include "user/user.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#define ULAB_VERSION 3.1.0
|
||||
#define ULAB_VERSION 3.3.8
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#define ULAB_VERSION_STRING xstr(ULAB_VERSION) xstr(-) xstr(ULAB_MAX_DIMS) xstr(D)
|
||||
@@ -70,6 +69,9 @@ STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {
|
||||
#if NDARRAY_HAS_DTYPE
|
||||
{ MP_ROM_QSTR(MP_QSTR_dtype), MP_ROM_PTR(&ndarray_dtype_obj) },
|
||||
#endif
|
||||
#if NDARRAY_HAS_FLATITER
|
||||
{ MP_ROM_QSTR(MP_QSTR_flat), MP_ROM_PTR(&ndarray_flat_obj) },
|
||||
#endif
|
||||
#if NDARRAY_HAS_ITEMSIZE
|
||||
{ MP_ROM_QSTR(MP_QSTR_itemsize), MP_ROM_PTR(&ndarray_itemsize_obj) },
|
||||
#endif
|
||||
@@ -89,12 +91,15 @@ STATIC MP_DEFINE_CONST_DICT(ulab_ndarray_locals_dict, ulab_ndarray_locals_dict_t
|
||||
|
||||
const mp_obj_type_t ulab_ndarray_type = {
|
||||
{ &mp_type_type },
|
||||
.flags = MP_TYPE_FLAG_EXTENDED
|
||||
#if defined(MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) && defined(MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)
|
||||
.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST,
|
||||
| MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST,
|
||||
#endif
|
||||
.name = MP_QSTR_ndarray,
|
||||
.print = ndarray_print,
|
||||
.make_new = ndarray_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
#if NDARRAY_IS_SLICEABLE
|
||||
.subscr = ndarray_subscr,
|
||||
#endif
|
||||
@@ -111,7 +116,7 @@ const mp_obj_type_t ulab_ndarray_type = {
|
||||
.attr = ndarray_properties_attr,
|
||||
#endif
|
||||
.buffer_p = { .get_buffer = ndarray_get_buffer, },
|
||||
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
|
||||
)
|
||||
};
|
||||
|
||||
#if ULAB_HAS_DTYPE_OBJECT
|
||||
@@ -123,6 +128,16 @@ const mp_obj_type_t ulab_dtype_type = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if NDARRAY_HAS_FLATITER
|
||||
const mp_obj_type_t ndarray_flatiter_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_flatiter,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
.getiter = ndarray_get_flatiterator,
|
||||
)
|
||||
};
|
||||
#endif
|
||||
|
||||
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) },
|
||||
|
||||
@@ -34,16 +34,22 @@
|
||||
|
||||
// Determines, whether scipy is defined in ulab. The sub-modules and functions
|
||||
// of scipy have to be defined separately
|
||||
#ifndef ULAB_HAS_SCIPY
|
||||
#define ULAB_HAS_SCIPY (1)
|
||||
#endif
|
||||
|
||||
// The maximum number of dimensions the firmware should be able to support
|
||||
// Possible values lie between 1, and 4, inclusive
|
||||
#ifndef ULAB_MAX_DIMS
|
||||
#define ULAB_MAX_DIMS 2
|
||||
#endif
|
||||
|
||||
// By setting this constant to 1, iteration over array dimensions will be implemented
|
||||
// as a function (ndarray_rewind_array), instead of writing out the loops in macros
|
||||
// This reduces firmware size at the expense of speed
|
||||
#ifndef ULAB_HAS_FUNCTION_ITERATOR
|
||||
#define ULAB_HAS_FUNCTION_ITERATOR (0)
|
||||
#endif
|
||||
|
||||
// If NDARRAY_IS_ITERABLE is 1, the ndarray object defines its own iterator function
|
||||
// This option saves approx. 250 bytes of flash space
|
||||
@@ -80,12 +86,8 @@
|
||||
// 2 kB in the two-dimensional case, and around 4 kB in the four-dimensional case.
|
||||
|
||||
#ifndef NDARRAY_BINARY_USES_FUN_POINTER
|
||||
#if defined(DEVICE_N0100)
|
||||
#define NDARRAY_BINARY_USES_FUN_POINTER (1)
|
||||
#else
|
||||
#define NDARRAY_BINARY_USES_FUN_POINTER (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NDARRAY_HAS_BINARY_OP_ADD
|
||||
#define NDARRAY_HAS_BINARY_OP_ADD (1)
|
||||
@@ -262,6 +264,12 @@
|
||||
#define ULAB_NUMPY_HAS_NDINFO (1)
|
||||
#endif
|
||||
|
||||
// if this constant is set to 1, the interpreter can iterate
|
||||
// over the flat array without copying any data
|
||||
#ifndef NDARRAY_HAS_FLATITER
|
||||
#define NDARRAY_HAS_FLATITER (1)
|
||||
#endif
|
||||
|
||||
// frombuffer adds 600 bytes to the firmware
|
||||
#ifndef ULAB_NUMPY_HAS_FROMBUFFER
|
||||
#define ULAB_NUMPY_HAS_FROMBUFFER (1)
|
||||
@@ -367,6 +375,10 @@
|
||||
#define ULAB_LINALG_HAS_NORM (1)
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_LINALG_HAS_QR
|
||||
#define ULAB_LINALG_HAS_QR (1)
|
||||
#endif
|
||||
|
||||
// the FFT module; functions of the fft module still have
|
||||
// to be defined separately
|
||||
#ifndef ULAB_NUMPY_HAS_FFT_MODULE
|
||||
@@ -638,7 +650,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_HAS_UTILS_MODULE
|
||||
#define ULAB_HAS_UTILS_MODULE (0)
|
||||
#define ULAB_HAS_UTILS_MODULE (1)
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ulab_create.h"
|
||||
@@ -89,24 +89,6 @@ static ndarray_obj_t *create_linspace_arange(mp_float_t start, mp_float_t step,
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ARANGE
|
||||
//| @overload
|
||||
//| def arange(stop: _float, step: _float = 1, *, dtype: _DType = ulab.float) -> ulab.ndarray: ...
|
||||
//| @overload
|
||||
//| def arange(start: _float, stop: _float, step: _float = 1, *, dtype: _DType = ulab.float) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: start
|
||||
//| First value in the array, optional, defaults to 0
|
||||
//| .. param: stop
|
||||
//| Final value in the array
|
||||
//| .. param: step
|
||||
//| Difference between consecutive elements, optional, defaults to 1.0
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//|
|
||||
//| Return a new 1-D array with elements ranging from ``start`` to ``stop``, with step size ``step``."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
mp_obj_t create_arange(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 } },
|
||||
@@ -157,17 +139,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_arange_obj, 1, create_arange);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_CONCATENATE
|
||||
//| def concatenate(arrays: Tuple[ulab.ndarray], *, axis: int = 0) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: arrays
|
||||
//| tuple of ndarrays
|
||||
//| .. param: axis
|
||||
//| axis along which the arrays will be joined
|
||||
//|
|
||||
//| Join a sequence of arrays along an existing axis."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
mp_obj_t create_concatenate(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 } },
|
||||
@@ -281,17 +252,8 @@ mp_obj_t create_concatenate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(create_concatenate_obj, 1, create_concatenate);
|
||||
#endif
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
#if ULAB_NUMPY_HAS_DIAG
|
||||
//| def diag(a: ulab.ndarray, *, k: int = 0) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: a
|
||||
//| an ndarray
|
||||
//| .. param: k
|
||||
//| Offset of the diagonal from the main diagonal. Can be positive or negative.
|
||||
//|
|
||||
//| Return specified diagonals."""
|
||||
//| ...
|
||||
//|
|
||||
mp_obj_t create_diag(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 } },
|
||||
@@ -353,14 +315,7 @@ mp_obj_t create_diag(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(create_diag_obj, 1, create_diag);
|
||||
#endif /* ULAB_NUMPY_HAS_DIAG */
|
||||
|
||||
#if ULAB_MAX_DIMS > 1
|
||||
#if ULAB_NUMPY_HAS_EYE
|
||||
//| def eye(size: int, *, M: Optional[int] = None, k: int = 0, dtype: _DType = ulab.float) -> ulab.ndarray:
|
||||
//| """Return a new square array of size, with the diagonal elements set to 1
|
||||
//| and the other elements set to 0."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
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 } },
|
||||
@@ -407,19 +362,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_eye_obj, 1, create_eye);
|
||||
#endif /* ULAB_MAX_DIMS > 1 */
|
||||
|
||||
#if ULAB_NUMPY_HAS_FULL
|
||||
//| def full(shape: Union[int, Tuple[int, ...]], fill_value: Union[_float, _bool], *, dtype: _DType = ulab.float) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: shape
|
||||
//| Shape of the array, either an integer (for a 1-D array) or a tuple of integers (for tensors of higher rank)
|
||||
//| .. param: fill_value
|
||||
//| scalar, the value with which the array is filled
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//|
|
||||
//| Return a new array of the given shape with all elements set to 0."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
mp_obj_t create_full(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_obj = MP_OBJ_NULL } },
|
||||
@@ -440,35 +382,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_full_obj, 0, create_full);
|
||||
|
||||
|
||||
#if ULAB_NUMPY_HAS_LINSPACE
|
||||
//| def linspace(
|
||||
//| start: _float,
|
||||
//| stop: _float,
|
||||
//| *,
|
||||
//| dtype: _DType = ulab.float,
|
||||
//| num: int = 50,
|
||||
//| endpoint: _bool = True,
|
||||
//| retstep: _bool = False
|
||||
//| ) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: start
|
||||
//| First value in the array
|
||||
//| .. param: stop
|
||||
//| Final value in the array
|
||||
//| .. param int: num
|
||||
//| Count of values in the array.
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//| .. param bool: endpoint
|
||||
//| Whether the ``stop`` value is included. Note that even when
|
||||
//| endpoint=True, the exact ``stop`` value may not be included due to the
|
||||
//| inaccuracy of floating point arithmetic.
|
||||
// .. param bool: retstep,
|
||||
//| If True, return (`samples`, `step`), where `step` is the spacing between samples.
|
||||
//|
|
||||
//| Return a new 1-D array with ``num`` elements ranging from ``start`` to ``stop`` linearly."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
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 } },
|
||||
@@ -506,37 +419,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_linspace_obj, 2, create_linspace);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_LOGSPACE
|
||||
//| def logspace(
|
||||
//| start: _float,
|
||||
//| stop: _float,
|
||||
//| *,
|
||||
//| dtype: _DType = ulab.float,
|
||||
//| num: int = 50,
|
||||
//| endpoint: _bool = True,
|
||||
//| base: _float = 10.0
|
||||
//| ) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: start
|
||||
//| First value in the array
|
||||
//| .. param: stop
|
||||
//| Final value in the array
|
||||
//| .. param int: num
|
||||
//| Count of values in the array. Defaults to 50.
|
||||
//| .. param: base
|
||||
//| The base of the log space. The step size between the elements in
|
||||
//| ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform. Defaults to 10.0.
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//| .. param bool: endpoint
|
||||
//| Whether the ``stop`` value is included. Note that even when
|
||||
//| endpoint=True, the exact ``stop`` value may not be included due to the
|
||||
//| inaccuracy of floating point arithmetic. Defaults to True.
|
||||
//|
|
||||
//| Return a new 1-D array with ``num`` evenly spaced elements on a log scale.
|
||||
//| The sequence starts at ``base ** start``, and ends with ``base ** stop``."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
const mp_obj_float_t create_float_const_ten = {{&mp_type_float}, MICROPY_FLOAT_CONST(10.0)};
|
||||
|
||||
mp_obj_t create_logspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
@@ -593,16 +475,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_logspace_obj, 2, create_logspace);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ONES
|
||||
//| def ones(shape: Union[int, Tuple[int, ...]], *, dtype: _DType = ulab.float) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: shape
|
||||
//| Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array)
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//|
|
||||
//| Return a new array of the given shape with all elements set to 1."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
mp_obj_t create_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
@@ -622,16 +494,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(create_ones_obj, 0, create_ones);
|
||||
#endif
|
||||
|
||||
#if ULAB_NUMPY_HAS_ZEROS
|
||||
//| def zeros(shape: Union[int, Tuple[int, ...]], *, dtype: _DType = ulab.float) -> ulab.ndarray:
|
||||
//| """
|
||||
//| .. param: shape
|
||||
//| Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array)
|
||||
//| .. param: dtype
|
||||
//| Type of values in the array
|
||||
//|
|
||||
//| Return a new array of the given shape with all elements set to 0."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
mp_obj_t create_zeros(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <py/runtime.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ndarray.h"
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
#include "user.h"
|
||||
|
||||
#if ULAB_HAS_USER_MODULE
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/misc.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
#include "utils.h"
|
||||
|
||||
#if ULAB_HAS_UTILS_MODULE
|
||||
|
||||
Reference in New Issue
Block a user