So your Octave code produces:
A =
{
[1,1] =
{
[1,1] = [](0x0)
[1,2] = [](0x0)
[1,3] = [](0x0)
[1,4] = [](0x0)
[1,5] = [](0x0)
[1,6] = [](0x0)
[1,7] = [](0x0)
[1,8] = [](0x0)
[1,9] = [](0x0)
[1,10] = [](0x0)
}
[1,2] =
{
[1,1] = [](0x0)
[1,2] = [](0x0)
[1,3] = [](0x0)
[1,4] = [](0x0)
[1,5] = [](0x0)
[1,6] = [](0x0)
[1,7] = [](0x0)
[1,8] = [](0x0)
[1,9] = [](0x0)
[1,10] = [](0x0)
}
...
[1,10] =
{
[1,1] = [](0x0)
[1,2] = [](0x0)
...
[1,9] = [](0x0)
[1,10] = [](0x0)
}
}
So A
is a cell that contains 10 cells, each with 10 0x0 matrices.
Cells are 2d (or higher) and contain any kind of object. python
lists are 1d and contain any kind of object. numpy
arrays are more like matrices, except they can be 0 or 1d. Another difference, MATLAB/Octave lets you 'grow' arrays and cells by just assigning to a higher index. You grow lists with .append
, and 'grow' arrays be concatenating several together to make a new one (no grow-in-place).
In [559]: A = []
In [560]: for i in range(10):
...: A.append([[] for _ in range(10)])
...:
In [561]: A
Out[561]:
[[[], [], [], [], [], [], [], [], [], []],
[[], [], [], [], [], [], [], [], [], []],
...
[[], [], [], [], [], [], [], [], [], []],
[[], [], [], [], [], [], [], [], [], []],
[[], [], [], [], [], [], [], [], [], []]]
Or if you want a list of lists of (0,0) arrays:
In [562]: A =[]
In [563]: for i in range(10):
...: A.append([np.zeros((0,0)) for _ in range(10)])
Or you could initial a multidimensional array:
In [565]: np.zeros((10,10,0,0),int)
Out[565]: array([], shape=(10, 10, 0, 0), dtype=int32)
In [566]: np.zeros((1,10,1,10,0,0),int)
Out[566]: array([], shape=(1, 10, 1, 10, 0, 0), dtype=int32)
Octave equivalent:
>> zeros(1,10,1,10,0,0)
ans = [](1x10x1x10x0x0)
numpy
also have object dtype lists which can contain 'anything'.
If I save the Octave A
to a mat file, and load it in numpy
I get:
In [569]: data = loadmat('test.mat')
In [570]: data
Out[570]:
{'A': array([[ array([[array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64)]], dtype=object),
array([[array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
...
array([[array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64),
array([], shape=(0, 0), dtype=float64)]], dtype=object)]], dtype=object),
'__globals__': [],
'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.0.0, 2017-07-08 02:13:25 UTC',
'__version__': '1.0'}
A
is an object dtype array containing object dtype arrays containing (0,0) float arrays:
In [572]: data['A'].shape
Out[572]: (1, 10)
In [573]: data['A'][0,0].shape
Out[573]: (1, 10)
In [574]: data['A'][0,0][0,0].shape
Out[574]: (0, 0)
Without the automatic growth behavior of MATLAB, it doesn't make much sense to initial an numpy
array to shape (0,0).
Simpler example
A simple example of creating arrays of differing size - in a list:
In [590]: A = [np.arange(i+3) for i in range(5)]
In [591]: A
Out[591]:
[array([0, 1, 2]),
array([0, 1, 2, 3]),
array([0, 1, 2, 3, 4]),
array([0, 1, 2, 3, 4, 5]),
array([0, 1, 2, 3, 4, 5, 6])]
I can save and reload it:
In [600]: savemat('test.mat', {'A':A})
In [601]: loadmat('test.mat')
Out[601]:
{'A': array([[array([[0, 1, 2]]), array([[0, 1, 2, 3]]),
array([[0, 1, 2, 3, 4]]), array([[0, 1, 2, 3, 4, 5]]),
array([[0, 1, 2, 3, 4, 5, 6]])]], dtype=object),
'__globals__': [],
'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Sun Jul 9 09:44:45 2017',
'__version__': '1.0'}
Note that this has converted the list of arrays into an object array of arrays.
Octave loads this as:
>> A
A =
{
[1,1] =
0 1 2
[1,2] =
0 1 2 3
[1,3] =
0 1 2 3 4
[1,4] =
0 1 2 3 4 5
[1,5] =
0 1 2 3 4 5 6
}