Re: DirectSum (feature request)
- To: mathgroup at smc.vnet.net
- Subject: [mg97879] Re: [mg97780] DirectSum (feature request)
- From: Adriano Pascoletti <adriano.pascoletti at dimi.uniud.it>
- Date: Tue, 24 Mar 2009 05:33:40 -0500 (EST)
- References: <200903211019.FAA14747@smc.vnet.net>
A solution based on ArrayPad (new in v. 7):given a list of k square matrices {A_1,A_2,...,A_k} of order {n_1, n_2,...,n_k} respectively, in the direct sum the rows of Ai are padded with n_1+...+n_{i-1} zeros on the left and n_{i+1}+...+n_k on the right: MatDirSum[sqMatrices_] := Module[{t, dims, rowPaddings}, dims = Prepend[Length /@ sqMatrices, 0]; t = Total[dims]; rowPaddings = Rest[FoldList[#1 + {#2[[1]], -#2[[2]]} & , {0, t}, Partition[dims, 2, 1]]]; Join @@ MapThread[ArrayPad[#1, {{0}, #2}] & , {sqMatrices, rowPaddings}]]; Test: In[6]:= sqMatrices = {Array[a1[#1, #2] & , {3, 3}], Array[a2[#1, #2] & , {4, 4}], Array[a3[#1, #2] & , {1, 1}], Array[a4[#1, #2] & , {2, 2}]}; In[8]:= MatDirSum[sqMatrices] Out[8]= {{a1[1, 1], a1[1, 2], a1[1, 3], 0, 0, 0, 0, 0, 0, 0}, {a1[2, 1], a1[2, 2], a1[2, 3], 0, 0, 0, 0, 0, 0, 0}, {a1[3, 1], a1[3, 2], a1[3, 3], 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, a2[1, 1], a2[1, 2], a2[1, 3], a2[1, 4], 0, 0, 0}, {0, 0, 0, a2[2, 1], a2[2, 2], a2[2, 3], a2[2, 4], 0, 0, 0}, {0, 0, 0, a2[3, 1], a2[3, 2], a2[3, 3], a2[3, 4], 0, 0, 0}, {0, 0, 0, a2[4, 1], a2[4, 2], a2[4, 3], a2[4, 4], 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, a3[1, 1], 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, a4[1, 1], a4[1, 2]}, {0, 0, 0, 0, 0, 0, 0, 0, a4[2, 1], a4[2, 2]}} Adriano Pascoletti 2009/3/21 Maris Ozols <marozols at gmail.com> > Taking a direct sum of a given list of matrices is a very common task > (unless you are a quantum physicist and use only KroneckerProduct). > Unfortunately there is no built-in function (that I know of) for doing > this in Mathematica. The closest thing we have is ArrayFlatten. So I > usually do something like this to compute a direct sum: > > DirectSum[Ms_] := Module[{n = Length[Ms], z, i}, > z = ConstantArray[0, n]; > ArrayFlatten@Table[ReplacePart[z, i -> Ms[[i]]], {i, 1, n}] > ]; > > Is there a better way of doing this? > > Note: A nice way to implement it would be > > DirectSum[Ms_] := ArrayFlatten@DiagonalMatrix[Ms]; > > Unfortunately this gives "DiagonalMatrix::vector" error, since > DiagonalMatrix is not flexible enough to accept a list of matrices. > The way DiagonalMatrix is used in the above code might cause some > confusion for beginners, but in general I don't see why DiagonalMatrix > should be limited in this way. > > ~Maris Ozols~ > >
- References:
- DirectSum (feature request)
- From: Maris Ozols <marozols@gmail.com>
- DirectSum (feature request)