[Numpy-discussion] Functions for indexing into certain parts of an array (2d)
Fernando Perez
fperez.net@gmail....
Sat Jun 6 13:45:09 CDT 2009
On Sat, Jun 6, 2009 at 11:35 AM, Gael
Varoquaux<gael.varoquaux@normalesup.org> wrote:
> I think they need examples. Right now, it is not clear at all to me what
> they do.
Cheers,
f
# With doctests, set to be repeatable by seeding the rng.
def structured_rand_arr(size, sample_func=np.random.random,
ltfac=None, utfac=None, fill_diag=None):
"""Make a structured random 2-d array of shape (size,size).
If no optional arguments are given, a symmetric array is returned.
Parameters
----------
size : int
Determines the shape of the output array: (size,size).
sample_func : function, optional.
Must be a function which when called with a 2-tuple of ints, returns a
2-d array of that shape. By default, np.random.random is used, but any
other sampling function can be used as long as matches this API.
utfac : float, optional
Multiplicative factor for the lower triangular part of the matrix.
ltfac : float, optional
Multiplicative factor for the lower triangular part of the matrix.
fill_diag : float, optional
If given, use this value to fill in the diagonal. Otherwise the diagonal
will contain random elements.
Examples
--------
>>> np.random.seed(0)
>>> structured_rand_arr(4)
array([[ 0.5488, 0.7152, 0.6028, 0.5449],
[ 0.7152, 0.6459, 0.4376, 0.8918],
[ 0.6028, 0.4376, 0.7917, 0.5289],
[ 0.5449, 0.8918, 0.5289, 0.0871]])
>>> structured_rand_arr(4,ltfac=-10,utfac=10,fill_diag=0.5)
array([[ 0.5 , 8.3262, 7.7816, 8.7001],
[-8.3262, 0.5 , 4.6148, 7.8053],
[-7.7816, -4.6148, 0.5 , 9.4467],
[-8.7001, -7.8053, -9.4467, 0.5 ]])
"""
# Make a random array from the given sampling function
mat0 = sample_func((size,size))
# And the empty one we'll then fill in to return
mat = np.empty_like(mat0)
# Extract indices for upper-triangle, lower-triangle and diagonal
uidx = triu_indices(size,1)
lidx = tril_indices(size,-1)
didx = diag_indices(size)
# Extract each part from the original and copy it to the output, possibly
# applying multiplicative factors. We check the factors instead of
# defaulting to 1.0 to avoid unnecessary floating point multiplications
# which could be noticeable for very large sizes.
if utfac:
mat[uidx] = utfac * mat0[uidx]
else:
mat[uidx] = mat0[uidx]
if ltfac:
mat[lidx] = ltfac * mat0.T[lidx]
else:
mat[lidx] = mat0.T[lidx]
# If fill_diag was provided, use it; otherwise take the values in the
# diagonal from the original random array.
if fill_diag is not None:
mat[didx] = fill_diag
else:
mat[didx] = mat0[didx]
return mat
def symm_rand_arr(size,sample_func=np.random.random,fill_diag=None):
"""Make a symmetric random 2-d array of shape (size,size).
Parameters
----------
n : int
Size of the output array.
fill_diag : float, optional
If given, use this value to fill in the diagonal. Useful for
Examples
--------
>>> np.random.seed(0)
>>> symm_rand_arr(4)
array([[ 0.5488, 0.7152, 0.6028, 0.5449],
[ 0.7152, 0.6459, 0.4376, 0.8918],
[ 0.6028, 0.4376, 0.7917, 0.5289],
[ 0.5449, 0.8918, 0.5289, 0.0871]])
>>> symm_rand_arr(4,fill_diag=4)
array([[ 4. , 0.8326, 0.7782, 0.87 ],
[ 0.8326, 4. , 0.4615, 0.7805],
[ 0.7782, 0.4615, 4. , 0.9447],
[ 0.87 , 0.7805, 0.9447, 4. ]])
"""
return structured_rand_arr(size,sample_func,fill_diag=fill_diag)
def antisymm_rand_arr(size,sample_func=np.random.random):
"""Make an anti-symmetric random 2-d array of shape (size,size).
Parameters
----------
n : int
Size of the output array.
Examples
--------
>>> np.random.seed(0)
>>> antisymm_rand_arr(4)
array([[ 0. , 0.7152, 0.6028, 0.5449],
[-0.7152, 0. , 0.4376, 0.8918],
[-0.6028, -0.4376, 0. , 0.5289],
[-0.5449, -0.8918, -0.5289, 0. ]])
"""
return structured_rand_arr(size,sample_func,ltfac=-1.0,fill_diag=0)
More information about the Numpy-discussion
mailing list