I'm dealing with a MATLAB to Python code porting and I've been struggling to reproduce what this part of code does using Numpy slicing because it allows negative indexing:
A_new = [A(:, 1:i-1) v1 v2 A(:, i 1:size(A,2))];
Let's see a few cases:
i = 1;
A = [1; 1; 1; 1; 1];
v1 = [1; 1; 0; 0; 0];
v2 = [0; 0; 1; 1; 1];
A(:, 1:i-1) % column slicer is 1:i-1 which is 1:0 and therefore returns empty
Empty matrix: 5-by-0
A(:, i 1:size(A,2)) % column slicer is i 1:size(A,2) which is 2:1 and therefore returns empty
Empty matrix: 5-by-0
[A(:, 1:i-1) v1 v2 A(:, i 1:size(A,2))] % the result is just v1 and v2 stacked:
1 0
1 0
0 1
0 1
0 1
i = 1;
A = [1 0; 1 0; 0 1; 0 1; 0 1];
v1 = [0; 1; 0; 0; 0];
v2 = [1; 0; 0; 0; 0];
A(:, 1:i-1) % column slicer is 1:i-1 which is 1:0 and therefore returns empty
Empty matrix: 5-by-0
A(:, i 1:size(A,2)) % column slicer is i 1:size(A,2) which is 2:2 and therefore returns
0
0
1
1
1
[A(:, 1:i-1) v1 v2 A(:, i 1:size(A,2))] % the result is v1, v2 and last column of A stacked:
0 1 0
1 0 0
0 0 1
0 0 1
0 0 1
I'm not assuming it's correct and there are probably better approaches to achieve the same result, but this is how I replicated it in Python:
z, k = A.shape
ls = np.zeros((z, 0), dtype=float) if i - 1 < 0 else A[:, 0:(i - 1)]
rs = np.zeros((z, 0), dtype=float) if k < i 1 else A[:, (i 1):k]
a_new = np.hstack((ls, v1, v2, rs))
The first case works as expected. The second one is failing:
i = 0
A = np.asarray([[1., 0.], [1., 0.], [0., 1.], [0., 1.], [0., 1.]])
v1 = np.asarray([[0., 1., 0., 0., 0.]]).T
v2 = np.asarray([[1., 0., 0., 0., 0.]]).T
# LS: i - 1 < 0 | 0 - 1 < 0 | -1 < 0 ... LS is correctly evaluated as np.zeros((z, 0), dtype=float)
# RS: k < i 1 | 1 < 0 1 | 1 < 1 ... therefore RS is evaluated as A[:, (i 1):k]
# This should translate into A[:, 1:1] and take the last column of A, but instead it returns an empty ndarray with the following error:
File "...\lib\site-packages\numpy\core\_methods.py", line 44, in _amin
return umr_minimum(a, axis, None, out, keepdims, initial, where)
ValueError: zero-size array to reduction operation minimum which has no identity
CodePudding user response:
First in your code:
z, k = a.shape
I think it's:
z, k = A.shape
Because you didn't define the variable a
in the code python.
Now we check the shape of the variables in the python code a_new = np.hstack((ls, v1, v2, rs))
:
print(ls.shape)
print(v1.shape)
print(v2.shape)
print(rs.shape)
The outputs :
(5, 0)
(1, 5)
(1, 5)
(5, 1)
So we know that the problem is the inconsistent dimension when calling the function np.hstack
, just adjust the dimension of v1, v2
during defining theses two variables by transposing the vector:
v1 = np.asarray([[0., 1., 0., 0., 0.]]).T
v2 = np.asarray([[1., 0., 0., 0., 0.]]).T
Then we got:
a_new = np.hstack((ls, v1, v2, rs))
print(a_new )
[[0. 1. 0.]
[1. 0. 0.]
[0. 0. 1.]
[0. 0. 1.]
[0. 0. 1.]]
CodePudding user response:
If A
is (5,1), then this indexing produces two (5,0) arrays:
In [141]: A = np.ones((5,1),int)
In [142]: i=0; A[:,:A.shape[1]-2], A[:,i 1:]
Out[142]: (array([], shape=(5, 0), dtype=int64),
array([], shape=(5, 0), dtype=int64))
For a (5,2), the result is a (5,0) and (5,1)
In [143]: A = np.ones((5,2),int)
In [144]: i=0; A[:,:A.shape[1]-2], A[:,i 1:]
Out[144]:
(array([], shape=(5, 0), dtype=int64),
array([[1],
[1],
[1],
[1],
[1]]))
To fully test this I'd need to fireup Octave
, and try some other A
shapes, and other i
.