[SciPy-user] repmat

Alan G Isaac aisaac at american.edu
Tue Dec 6 21:07:47 CST 2005

On Tue, 06 Dec 2005, Aarre Laakso apparently wrote: 
> Can anyone give me a clue about how I might implement a fast workalike 
> for MATLAB's repmat function? 

> http://www.mathworks.com/access/helpdesk/help/techdoc/ref/repmat.html 

> The simple use case B = repmat(A,m,n) where A is an array and m,n are 
> positive integers would be sufficient for my needs. 

> I have pasted below my own attempt, which obviously involves way too 
> much copying, because it takes a couple of minutes to replicate a 
> 50-element row vector roughly 5000 times. It seems like repeat with some 
> tricky slicing might work, but I can't figure out how to do it. Or maybe 
> there's a better way? 

> Thanks for any help you can offer. 

> def repmat(A, *args): 
>     """ Replicate and tile an array. """ 

>     result = A 
>     new_size = args 
>     for axis in range(0, len(new_size)): 
>         copy_value = result 
>         num_copies = new_size[axis] 
>         for curr_copy in range(1, num_copies): 
>             result = concatenate((result, copy_value), axis) 

What you really want is not a matrix like this---much too 
costly!---but rather an instance of a repmat class (which
would keep only one copy of the data)!

In the meantime, you can try a Kronecker product for your 
purpose. (Below.)

Alan Isaac

def kroneckerproduct(a,b):
    '''Compute a otimes b where otimes is the Kronecker product operator.

    Note: the Kronecker product is also known as the matrix direct product
    or tensor product.  It is defined as follows for 2D arrays a and b
    where shape(a)=(m,n) and shape(b)=(p,q):
    c = a otimes b  => cij = a[i,j]*b  where cij is the ij-th submatrix of c.
    So shape(c)=(m*p,n*q).

     - `a`: 2-D array
     - `b`: 2-D array
    :see: http://en.wikipedia.org/wiki/Kronecker_product
    :see: http://www.scipy.org/mailinglists/mailman?fn=scipy-user/2003-September/002138.html
    :author: Nils Wagner
    :author: Alan G. Isaac
    :date: 2004-08-12
    :copyright: public domain
    :since: 2003-09-03
    :note: Contributed to numarray in Sept 2003.

    >>> print kroneckerproduct([[1,2]],[[3],[4]])
    [[3 6]
     [4 8]]
    >>> print kroneckerproduct([[1,2]],[[3,4]])
    [ [3 4 6 8]]
    >>> print kroneckerproduct([[1],[2]],[[3],[4]])
    a, b = asarray(a), asarray(b)
    if not (len(shape(a))==2 and len(shape(b))==2):
            raise ValueError, 'Input must be 2D arrays.'
    if not a.iscontiguous():
        a = reshape(a, a.shape)
    if not b.iscontiguous():
        b = reshape(b, b.shape)
    o = outerproduct(a,b)
    o.shape = a.shape + b.shape
    return concatenate(concatenate(o, axis=1), axis=1)

More information about the SciPy-user mailing list