[Numpy-discussion] s are mutable scalars

Huaiyu Zhu huaiyu_zhu at yahoo.com
Tue Sep 17 00:05:01 EDT 2002


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