i think this code handles n-d correctly (please verify), and i've hacked it to be polymorphic, but it's ugly. is there a better/more efficient way? i'm not sure it shares memory as much as possible. i want to avoid F ordering cuz i'm guessing numpy/python are happier with C. if i'm wrong on that, please enlighten me to any advantages of using F in this case.
specific questions (if this overall approach is best):
- does
array.array(.,numpy.ndarray.ravel)copy data? i suspect yes. would there be a way to share it instead? for instance, what would be the performance/memory sharing implications of usingnumpy.nditer(),numpy.ndarray.flat, ornumpy.ndarray.flatteninstead? see http://numpy-discussion.10968.n7.nabble.com/Why-ndarray-provides-four-ways-to-flatten-td38989.html - i need an
array.peekmethod, why isn't there one? - if i can't have
array.peek, isarray.appendas inefficient as i'm suspecting (copying the whole array again)? i could have usednumpy.insertornumpy.appendinstead (which cleans up the code because i don't have to special case the empty array), but i believe those do copy. - are there any negative implications of
F order? - i believe
numpy.reshapeandnumpy.transposeefficiently createviews without copying data -- but then, when the data is accessed, the access pattern will be all fragged up via the indirection through a bunch of layeredviews. doesn't this negate the whole point ofnumpy's contiguous memory layout in the first place? - in general, this type of information doesn't seem to be systematically laid out in any documentation i can find. do i have to resort to reading
array/ndarraysrc?
code
function f
sz = [2 4 3 2];
d = reshape(1:prod(sz),sz)
d = to_np(d)
d = from_np(d)
end
function p = to_np(p)
sz = size(p);
p = reshape(p,[1 numel(p)]); % Conversion to Python is only supported for 1-N vectors.
p = py.numpy.array(p); % if empty, type is always set to double cuz of https://github.com/numpy/numpy/issues/6028
p = p.reshape(num2cell(fliplr(sz)));
t = 0:length(sz)-1;
t(end-[1 0]) = t(end-[0 1]);
p = p.transpose(num2cell(t));
end
function p = from_np(p)
sz = cellfun(@double,cell(p.shape));
method = 1;
switch method
case 1
empty = any(sz == 0);
if empty
p = py.numpy.insert(p,0,0); % casts 0 to p's type so we can later pop it for use with matlab's cast
end
p = py.array.array(p.dtype.char,p.ravel); % does this copy data -- how share memory? any better to use py.numpy.nditer(p), p.flat, or p.flatten?
% http://numpy-discussion.10968.n7.nabble.com/Why-ndarray-provides-four-ways-to-flatten-td38989.html
c = p.pop(); % i can has peek?
if ~empty
p.append(c); % i suspect this could be very inefficient, does it copy the whole thing again?
end
case 2
p = py.numpy.insert(p,p.size,0); % numpy.insert / numpy.append copy the whole array, so maybe worse than array.append?
p = py.array.array(p.dtype.char,p); % numpy.insert already flattened p
c = p.pop();
end
p = cast(p,'like',c);
p = reshape(p,fliplr(sz));
t = 1:length(sz);
t([1 2]) = t([2 1]);
p = permute(p,t);
end
output
d(:,:,1,1) =
1 3 5 7
2 4 6 8
d(:,:,2,1) =
9 11 13 15
10 12 14 16
d(:,:,3,1) =
17 19 21 23
18 20 22 24
d(:,:,1,2) =
25 27 29 31
26 28 30 32
d(:,:,2,2) =
33 35 37 39
34 36 38 40
d(:,:,3,2) =
41 43 45 47
42 44 46 48
d =
Python ndarray with properties:
T: [1x1 py.numpy.ndarray]
base: [1x1 py.numpy.ndarray]
ctypes: [1x1 py.numpy.core._internal._ctypes]
dtype: [1x1 py.numpy.dtype]
flags: [1x1 py.numpy.flagsobj]
flat: [1x1 py.numpy.flatiter]
imag: [1x1 py.numpy.ndarray]
itemsize: 8
nbytes: 384
ndim: 4
real: [1x1 py.numpy.ndarray]
shape: [1x4 py.tuple]
size: 48
strides: [1x4 py.tuple]
[[[[ 1. 3. 5. 7.]
[ 2. 4. 6. 8.]]
[[ 9. 11. 13. 15.]
[ 10. 12. 14. 16.]]
[[ 17. 19. 21. 23.]
[ 18. 20. 22. 24.]]]
[[[ 25. 27. 29. 31.]
[ 26. 28. 30. 32.]]
[[ 33. 35. 37. 39.]
[ 34. 36. 38. 40.]]
[[ 41. 43. 45. 47.]
[ 42. 44. 46. 48.]]]]
d(:,:,1,1) =
1 3 5 7
2 4 6 8
d(:,:,2,1) =
9 11 13 15
10 12 14 16
d(:,:,3,1) =
17 19 21 23
18 20 22 24
d(:,:,1,2) =
25 27 29 31
26 28 30 32
d(:,:,2,2) =
33 35 37 39
34 36 38 40
d(:,:,3,2) =
41 43 45 47
42 44 46 48
py.numpypackage, right? You might get other ideas from howscipy.io.loadmatloads.matfiles. It has to work with theorder=Fissue. I believecellsare loaded as lists, andstructuresas dictionaries.loadmat, but i note that memory structure (i'll edit my question to make sure that emphasis comes across) may not be the same as storage structure, and certainly won't be "shared" (as in "no copies") in the way i'm looking for. :)numpypeople is that we aren't sure where the MATLABpyinterface leaves off, and familiarnumpycode begins. And these days the closest I get to MATLAB isoctave. So I can test things like.matinterfaces, but notpy.