[Numpy-discussion] rank-0 arrays are mutable scalars
Huaiyu Zhu
huaiyu_zhu at yahoo.com
Tue Sep 17 00:12:04 CDT 2002
Oops, the subject line was somehow cut off. Please use this one if you
follow up. - Huaiyu
On Tue, 17 Sep 2002, Huaiyu Zhu wrote:
Some of the choices between rank-0 arrays and new scalar types
might be resolved by enumerating the properties desired of them.
Most properties of rank-0 arrays could be fixed by consistency
requirements alone, using operations that reduce array dimensions.
Let a = ones((2,3,4))
b = sum(a)
c = sum(b)
d = sum(c)
Property 1: the shape of an array is a tuple of integers
a.shape == (2, 3, 4)
b.shape == (3, 4)
c.shape == (4,)
d.shape == ()
Property 2: rank(a) == len(a.shape)
rank(a) == 3 == len(a.shape)
rank(b) == 2 == len(b.shape)
rank(c) == 1 == len(c.shape)
rank(d) == 0 == len(d.shape)
Property 3: len(a) == a.shape[0]
len(a) == 2 == a.shape[0]
len(b) == 3 == b.shape[0]
len(c) == 4 == c.shape[0]
len(d) == Exception == d.shape[0]
# Currently the last is wrong?
Property 4: size(a) == product(a.shape)
size(a) == 24 == product(a.shape)
size(b) == 12 == product(b.shape)
size(c) == 4 == product(c.shape)
size(d) == 1 == product(d.shape)
# Currently the last is wrong
Property 5: rank-0 array behaves as mutable numbers when used as value
array(2) is similar to 2
array(2.0) is similar to 2.0
array(2j) is similar to 2j
# This is a summary of many concrete properties.
Property 6: Indexing reduces rank. Slicing preserves rank.
a[:,:,:].shape = (2, 3, 4)
a[1,:,:].shape = (3, 4)
a[1,1,:].shape = (4,)
a[1,1,1].shape = ()
Property 7: Indexing by tuple of ints gives scalar.
a[1,1,1] == 1
b[1,1] == 2
c[1,] == 6
d[()] == 24
# So rank-0 array indexed by empty tuple should be scalar.
# Currently the last is wrong
Property 8: Indexing by tuple of slices gives array.
a[:,:,:] == ones((2,3,4))
b[:,:] == ones((3,4)) * 2
c[:] == ones((,4)) * 6
d[()] == ones(()) * 24
# So rank-0 array indexed by empty tuple should be rank-0 array.
# Currently the last is wrong
Property 9: Indexing as lvalues
a[1,1,1] = 2
b[1,1] = 2
c[1,] = 2
d[()] = 2
Property 10: Indexing and slicing as lvalues
a[:,:,:] = ones((2, 3, 4))
a[1,:,:] = ones((3, 4))
a[1,1,:] = ones((4,))
a[1,1,1] = ones(())
# But the last is wrong.
Conclusion 1: rank-0 arrays are equivalent to scalars.
See properties 7 and 8.
Conclusion 2: rank-0 arrays are mutable.
See property 9.
Conclusion 3: shape(scalar), size(scalar) are all defined, but len(scalar)
should not be defined.
See conclusion 1 and properties 1, 2, 3, 4.
Conclusion 4: A missing axis is similar to having dimension 1.
See property 4.
Conclusion 5: rank-0 int arrays should be allowed to act as indices.
See property 5.
Conclusion 6: rank-0 arrays should not be hashable except by object id.
See conclusion 2.
Discussions:
- These properties correspond to the current implementation quite well,
except a few rough edges.
- Mutable scalars are useful in their own rights.
- Is there substantial difference in overhead between rank-0 arrays and
scalars?
- How to write literal values? array(1) is too many characters.
- For rank-1 and rank-0 arrays, Python notation distinguishes:
c[1] vs c[1,]
d[] vs d[()]
Should these be used to handle semantic difference between indexing
and slicing? Should d[] be syntactically allowed?
Hope these observations help.
Huaiyu
More information about the Numpy-discussion
mailing list