Hi Ben,
On Fri, 15 May 2020 at 18:07 Benjamin Root <ben.v.root@xxxxxxxxx> wrote:
> The documentation for the strided access to variables specify a pointer to
> ptrdiff_t types, which I infer means that I could specify a negative value
> to read/write in a dimension in reverse. However, when I gave this a shot,
> specifying a -1 for the latitude dimension of one of my datasets, the C
> api came back and said I had an illegal stride.
>
> Is there any way to read/write dimensions in reverse order, much like
> python's [::-1] with the C-API, or am I going to have to flip the data
> around myself (I'd like to avoid the copy, as well as all of the fun code
> to do so for an arbitrary dimension). At the very least, are there helper
> functions for this?
That's not supported by the C API:
https://github.com/Unidata/netcdf-c/blob/64d821b/libdispatch/dvarget.c#L245-L248
https://github.com/Unidata/netcdf-c/blob/b0e0d81/libhdf5/hdf5var.c#L1845-L1847
Flipping the data around doesn't necessarily require a copy; it can be
done in-place with a complexity of N/2 swaps (`std::reverse` in C++). But
yes doing it for an arbitrary dimension rather than the full array will
require some index calculations. I think something like this might do the
job, albeit not the most efficient approach (untested):
1. Get the variable values along that dimension, and reverse.
2. Flatten the N-D indexes into 1-D indexes by calculating an inner
product with the strides. In NumPy this is `ravel_multi_index`; in C++
I use `std::inner_product` in <numeric>.
3. Copy the reversed elements back into the original array using the 1-D
indexes.
I have some code here in a simple `get_var1` iterator which does the
reverse operation, unraveling a 1-D index into an N-D index given the
shape (`unravel_index` in NumPy).
https://github.com/jbuonagurio/ncpp/blob/717bb1e/include/ncpp/variable.hpp#L421-L495
I'm sure there are more clever ways. I would use a multidimensional
'array view' library if you can and your data are stored contiguously.
I mostly work in C++ so not sure about other options, but I know that
xtensor and the reference implementation of the `std::mdspan` proposal
support arbitrary strides.
- John Buonagurio