Velocity Reviews > Putting together a larger matrix from smaller matrices

# Putting together a larger matrix from smaller matrices

Matjaz Bezovnik
Guest
Posts: n/a

 08-25-2009
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

Peter Otten
Guest
Posts: n/a

 08-25-2009
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[offff+N, offff+N] = m
off += N
print b

Peter

Matjaz Bezovnik
Guest
Posts: n/a

 08-25-2009
On Tue, 25 Aug 2009 08:26:44 -0700, Scott David Daniels
<(E-Mail Removed)> 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
>(E-Mail Removed)

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

sturlamolden
Guest
Posts: n/a

 08-25-2009
On 25 Aug, 17:37, Matjaz Bezovnik <(E-Mail Removed)> 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

Robert Kern
Guest
Posts: n/a

 08-25-2009
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
an underlying truth."
-- Umberto Eco