diff options
| author | Tyge Løvset <[email protected]> | 2023-01-29 17:24:33 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-01-29 17:24:33 +0100 |
| commit | 209bf743e0c1253a4bc81d2ffb6897f657a84c8a (patch) | |
| tree | 9631a2a79e1890cb7c46515aae0ef105710ad59c /docs/cspan_api.md | |
| parent | a344b43728ff40a2e1ee25f2f1b592f33432aee7 (diff) | |
| download | STC-modified-209bf743e0c1253a4bc81d2ffb6897f657a84c8a.tar.gz STC-modified-209bf743e0c1253a4bc81d2ffb6897f657a84c8a.zip | |
Some method renaming in cspan: cspan_multidim() ctor => cspan_md(). cspan_atN() => cspan_submdN().
cstr_replace_ex() merged as overload of cstr_replace().
Diffstat (limited to 'docs/cspan_api.md')
| -rw-r--r-- | docs/cspan_api.md | 110 |
1 files changed, 86 insertions, 24 deletions
diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 32ef49c4..c4cb7c16 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -1,9 +1,8 @@ # STC [cspan](../include/stc/cspan.h): Multi-dimensional Array View  -The **cspan** is templated non-owning multi-dimensional view of an array. - -See the c++ classes [std::span](https://en.cppreference.com/w/cpp/container/span) and +The **cspan** is templated non-owning multi-dimensional view of an array. See the c++ classes +[std::span](https://en.cppreference.com/w/cpp/container/span) and [std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan) for similar functionality. ## Header file and declaration @@ -18,17 +17,14 @@ using_cspan3(S, ValueType); // define span types S, S2, S3 with rank using_cspan4(S, ValueType); // define span types S, S2, S3, S4 with ranks 1, 2, 3, 4. ``` ## Methods -Note that `cspan_multidim()`, `cmake_from*()`, `cspan_atN()`, `and cspan_subspanN()` require a (safe) cast to its span-type +Note that `cspan_md()`, `cmake_from*()`, `cspan_atN()`, `and cspan_subspanN()` require a (safe) cast to its span-type on assignment, but not on initialization of a span variable. All functions are type-safe, and arguments are side-effect safe, except for SpanType arg. which must not have side-effects. ```c +SpanTypeN cspan_md(ValueType* data, size_t xdim, ...); // create a multi-dimensional cspan SpanType cspan_make(T SpanType, {v1, v2, ...}); // make a 1d-dimensional cspan from values -SpanTypeN cspan_multidim(ValueType* data, size_t xdim, ...); // create a multi-dimensional cspan SpanType cspan_from(STCContainer* cnt); // create a 1d cspan from a compatible STC container SpanType cspan_from_array(ValueType array[]); // create a 1d cspan from a C array -SpanType cspan_flatten(SpanTypeN* span); // create a 1d cspan from a multidim span -void cspan_resize(SpanTypeN* self, size_t xdim, ...); // change the extent of each dimension - size_t cspan_size(const SpanTypeN* self); // return number of elements unsigned cspan_rank(const SpanTypeN* self); // return number of dimensions size_t cspan_index(const SpanTypeN* self, size_t x, ...); // index of element @@ -37,13 +33,15 @@ ValueType* cspan_at(SpanTypeN* self, size_t x, ...); // at(): ValueType* cspan_front(SpanTypeN* self); ValueType* cspan_back(SpanTypeN* self); -SpanType cspan_at2(SpanType2* self, size_t x); // return a 1d subspan from a 2d span. -SpanTypeN cspan_at3(SpanType3* self, size_t x, ...); // return a 1d or 2d subspan from a 3d span. -SpanTypeN cspan_at4(SpanType4* self, size_t x, ...); // number of args determines rank of output span. + // return a subspan of lower rank: +SpanType cspan_submd2(SpanType2* self, size_t x); // return a 1d subspan from a 2d span. +SpanTypeN cspan_submd3(SpanType3* self, size_t x, ...); // return a 1d or 2d subspan from a 3d span. +SpanTypeN cspan_submd4(SpanType4* self, size_t x, ...); // number of args determines rank of output span. + // return a sliced span of same rank: void cspan_slice(SpanTypeN* self, {x0,x1}, {y0,y1},...); // slice multidim span into a md subspan. - // return a subspan of same rank: + // return a subspan of same rank. Like e.g. cspan_slice(&ms3, {offset, offset+count}, {0}, {0}); SpanType cspan_subspan(const SpanType* self, size_t offset, size_t count); SpanType2 cspan_subspan2(const SpanType2 self, size_t offset, size_t count); SpanType3 cspan_subspan3(const SpanType3 self, size_t offset, size_t count); @@ -61,9 +59,73 @@ void SpanType_next(SpanTypeN_iter* it); | SpanTypeN`_value` | `ValueType` | The ValueType | | SpanTypeN`_iter` | `struct { ValueType *ref; ... }` | Iterator type | -## Example +## Example 1 + +The *cspan_slice()* function is similar to pythons numpy multi-dimensional arrays slicing, e.g.: +```py +import numpy as np +ms3 = np.array((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24), int) + +ms3 = np.reshape(ms3, (2, 3, 4)) +ss3 = ms3[:, 1:3, 2:] +ss2 = ss3[1] + +for i in range(ss2.shape[0]): + for j in range(ss2.shape[1]): + print(" {}".format(ss2[i, j]), end='') +print('') + +for i in ss2.flat: + print(" {}".format(i), end='') +# 19 20 23 24 +# 19 20 23 24 +``` +... can be done in C with STC: +```c +#include <c11/fmt.h> +#include <stc/cspan.h> +using_cspan3(myspan, int); // define myspan, myspan2, myspan3. + +int main() { + int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; + + myspan3 ms3 = cspan_md(arr, 2, 3, 4), ss3 = ms3; + cspan_slice(&ss3, {0}, {1,3}, {2,}); + myspan2 ss2 = cspan_submd3(&ss3, 1); + + c_FORRANGE (i, ss2.dim[0]) + c_FORRANGE (j, ss2.dim[1]) + fmt_print(" {}", *cspan_at(&ss2, i, j)); + puts(""); + + c_FOREACH (i, myspan2, ss2) + fmt_print(" {}", *i.ref); +} +``` +... or (mostly) in C++23: +```c++ +#include <print> +#include <mdspan> +#include <tuple> + +int main() { + int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; + + std::mdspan ms3(arr, 2, 3, 4); + auto ss3 = std::submdspan(ms3, std::full_extent, std::tuple{1,3}, std::tuple{2,4}); + auto ss2 = std::submdspan(ss3, 1, std::full_extent, std::full_extent); + + for (std::size_t i = 0; i < ss2.extent(0); ++i) + for (std::size_t j = 0; j < ss2.extent(1); ++j) + std::print(" {}", ss2[i, j]); + std::println(); + + // mdspan can't printed as a flat array, afaik. +} +``` +## Example 2 ```c -#include <stdio.h> +#include <c11/fmt.h> #include <stc/cspan.h> #define i_val float #include <stc/cstack.h> @@ -79,33 +141,33 @@ int main() cstack_float_push(&vec, i); // define "span3[xd][yd][zd]" - Span3 span3 = cspan_multidim(vec.data, xd, yd, zd); + Span3 span3 = cspan_md(vec.data, xd, yd, zd); *cspan_at(&span3, 4, 3, 2) = 3.14159f; - printf("index: %d", (int)cspan_index(&span3, 4, 3, 2)); + fmt_print("index: {}", cspan_index(&span3, 4, 3, 2)); - Span span1 = cspan_at3(&span3, 4, 3); + Span span1 = cspan_submd3(&span3, 4, 3); printf("\niterate span1: "); c_FOREACH (i, Span, span1) - printf("%g ", *i.ref); + fmt_print("{} ", *i.ref); - Span2 span2 = cspan_at3(&span3, 4); + Span2 span2 = cspan_submd3(&span3, 4); printf("\niterate span2: "); c_FOREACH (i, Span2, span2) - printf("%g ", *i.ref); + fmt_print("{} ", *i.ref); puts("\niterate span3 by dimensions:"); c_FORRANGE (i, span3.dim[0]) { c_FORRANGE (j, span3.dim[1]) { c_FORRANGE (k, span3.dim[2]) - printf(" %2g", *cspan_at(&span3, i, j, k)); + fmt_printf(" {:2}", *cspan_at(&span3, i, j, k)); printf(" |"); } puts(""); } - printf("%g\n", *cspan_at(&span3, 4, 3, 2)); - printf("%g\n", *cspan_at(&span2, 3, 2)); - printf("%g\n", *cspan_at(&span1, 2)); + fmt_println("{}", *cspan_at(&span3, 4, 3, 2)); + fmt_println("{}", *cspan_at(&span2, 3, 2)); + fmt_println("{}", *cspan_at(&span1, 2)); } } ``` |
