Putting together a larger matrix from smaller matrices

Discussion in 'Python' started by Matjaz Bezovnik, Aug 25, 2009.

  1. Dear all,

    I'm but a layman so do not take offence at this maybe over simple
    question.

    This is something which is done often in FEM methods, and the alike.

    I have matrix A of 3x3 elements, and B, of the same number of
    elements, 3x3.

    What would be the most obvious way to assemble a matrix which:
    a11 a12 a13
    a21 a22 a23
    a31 a32 a33+b11 b12 b13
    b21 b22 b23
    b31 b32 b33

    (the missing elements = zero)

    (you see the pattern - if there was a third matrix C, it would
    "connect" to b33 on the main diagonal)


    Matjaz
    Matjaz Bezovnik, Aug 25, 2009
    #1
    1. Advertising

  2. Matjaz Bezovnik

    Peter Otten Guest

    Matjaz Bezovnik wrote:

    > This is something which is done often in FEM methods, and the alike.
    >
    > I have matrix A of 3x3 elements, and B, of the same number of
    > elements, 3x3.
    >
    > What would be the most obvious way to assemble a matrix which:
    > a11 a12 a13
    > a21 a22 a23
    > a31 a32 a33+b11 b12 b13
    > b21 b22 b23
    > b31 b32 b33
    >
    > (the missing elements = zero)
    >
    > (you see the pattern - if there was a third matrix C, it would
    > "connect" to b33 on the main diagonal)


    Unless there is a dedicated function:

    partial = [...] # list of matrices of shape NxN

    N = partial[0].shape[0]
    width = N*len(partial)
    b = numpy.zeros((width, width))

    off = 0
    for m in partial:
    b[off:eek:ff+N, off:eek:ff+N] = m
    off += N
    print b

    Peter
    Peter Otten, Aug 25, 2009
    #2
    1. Advertising

  3. On Tue, 25 Aug 2009 08:26:44 -0700, Scott David Daniels
    <> wrote:

    >Matjaz Bezovnik wrote:
    >
    >If you are using numpy (which it sounds like you are):
    >
    >IDLE 2.6.2
    > >>> import numpy as np
    > >>> v = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=float)
    > >>> v

    >array([[ 0., 1., 2.],
    > [ 3., 4., 5.],
    > [ 6., 7., 8.]])
    > >>> w = np.array([[10,11,12],[13,14,15],[16,17,18]], dtype=float)
    > >>> w

    >array([[ 10., 11., 12.],
    > [ 13., 14., 15.],
    > [ 16., 17., 18.]])
    > >>> r = np.zeros((6,6))
    > >>> r

    >array([[ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.]])
    > >>> r[:3,:3] = v
    > >>> r

    >array([[ 0., 1., 2., 0., 0., 0.],
    > [ 3., 4., 5., 0., 0., 0.],
    > [ 6., 7., 8., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.],
    > [ 0., 0., 0., 0., 0., 0.]])
    > >>> r[3:,3:] = w
    > >>> r

    >array([[ 0., 1., 2., 0., 0., 0.],
    > [ 3., 4., 5., 0., 0., 0.],
    > [ 6., 7., 8., 0., 0., 0.],
    > [ 0., 0., 0., 10., 11., 12.],
    > [ 0., 0., 0., 13., 14., 15.],
    > [ 0., 0., 0., 16., 17., 18.]])
    > >>>

    >
    >In general, make the right-sized array of zeros, and at various points:
    >and you can ssign to subranges of the result array:
    >
    > N = 3
    > result = np.zeros((len(parts) * N, len(parts) * N), dtype=float)
    > for n, chunk in enumerate(parts):
    > base = n * 3
    > result[base : base + 3, base : base + 3] = chunk
    >
    >--Scott David Daniels
    >




    Scott, thank you very much for the snippet.

    It is exactly what I looked for; simple to read and obvious as to what
    it does even a month later to a non-pythonist!

    Matjaz
    Matjaz Bezovnik, Aug 25, 2009
    #3
  4. Matjaz Bezovnik

    sturlamolden Guest

    On 25 Aug, 17:37, Matjaz Bezovnik <> wrote:

    > Scott, thank you very much for the snippet.
    >
    > It is exactly what I looked for; simple to read and obvious as to what
    > it does even a month later to a non-pythonist!



    Since you were talking about matrices, observe that numpy has a matrix
    subclass of ndarray, which e.g. changes the meaning of the * operator
    mean indicate matrix multiplication. Thus,

    >>> import numpy as np
    >>> np.eye(4)

    array([[ 1., 0., 0., 0.],
    [ 0., 1., 0., 0.],
    [ 0., 0., 1., 0.],
    [ 0., 0., 0., 1.]])
    >>> np.matrix(np.eye(4))

    matrix([[ 1., 0., 0., 0.],
    [ 0., 1., 0., 0.],
    [ 0., 0., 1., 0.],
    [ 0., 0., 0., 1.]])

    >>> a = np.ones((4,4))
    >>> a*a

    array([[ 1., 1., 1., 1.],
    [ 1., 1., 1., 1.],
    [ 1., 1., 1., 1.],
    [ 1., 1., 1., 1.]])
    >>> b = np.matrix(a)
    >>> b*b

    matrix([[ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.]])
    >>> b**2

    matrix([[ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.],
    [ 4., 4., 4., 4.]])
    >>> b**4

    matrix([[ 64., 64., 64., 64.],
    [ 64., 64., 64., 64.],
    [ 64., 64., 64., 64.],
    [ 64., 64., 64., 64.]])

    In Matlab, you use .* vs. * and .^ vs. ^ to obtain the same effect. In
    NumPy we use different classes for arrays and matrices.



    Sturla Molden
    sturlamolden, Aug 25, 2009
    #4
  5. Matjaz Bezovnik

    Robert Kern Guest

    On 2009-08-24 21:30 PM, Matjaz Bezovnik wrote:
    > Dear all,
    >
    > I'm but a layman so do not take offence at this maybe over simple
    > question.
    >
    > This is something which is done often in FEM methods, and the alike.
    >
    > I have matrix A of 3x3 elements, and B, of the same number of
    > elements, 3x3.
    >
    > What would be the most obvious way to assemble a matrix which:
    > a11 a12 a13
    > a21 a22 a23
    > a31 a32 a33+b11 b12 b13
    > b21 b22 b23
    > b31 b32 b33
    >
    > (the missing elements = zero)
    >
    > (you see the pattern - if there was a third matrix C, it would
    > "connect" to b33 on the main diagonal)


    You will certainly want to use numpy for this and ask questions on the numpy
    mailing list.

    http://www.scipy.org/Mailing_Lists

    I believe that someone recently posted a recipe for constructing such "block
    diagonal" arrays. I think it will be included in a future release of numpy.

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Aug 25, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Williams
    Replies:
    1
    Views:
    1,382
    Dylan Parry
    Jun 3, 2005
  2. heyo
    Replies:
    3
    Views:
    905
    Dan Pop
    Apr 1, 2004
  3. pete
    Replies:
    4
    Views:
    795
    Dan Pop
    Apr 2, 2004
  4. korean_dave
    Replies:
    3
    Views:
    253
    Gary Herron
    Nov 14, 2008
  5. Replies:
    5
    Views:
    140
    David Dorward
    Feb 9, 2005
Loading...

Share This Page