Re: Summary:Ways to get Odd Columns&Rows of Matrix
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg667] Re: Summary:Ways to get Odd Columns&Rows of Matrix
- From: villegas (Robert Villegas)
- Date: Sat, 8 Apr 1995 03:31:30 -0500
> (* using Fold and Drop *) > (*From: bob Hanlon <hanlon at pafosu2.hq.af.mil>*) > (*works on matrices with even number of terms. > Not a good example of coding. > The use of Fold, Transpose and Drop are too complex. > Slow as well. [bob's original code is here:] > Fold[ Transpose[ Fold[ Drop, #, > Table[ {-k}, {k, Length[ u ]/2} ] ] ]&, > u, {1, 2} ] // MatrixForm > (* Select odd rows and columns from square matrix *) > Fold[ Transpose[ Fold[ Drop, #, > Table[ {-k-1}, {k, Length[ u ]/2} ] ] ]&, > u, {1, 2} ] // MatrixForm Actually, I thought Bob's solution was rather clever, even if not as practical for this application. The cumulative deletion of an element, moving one further from the end each time, is kind of neat, and I liked the Transpose for switching focus to the columns after doing the rows, too. I don't think this would have occurred to me. I think some of the weaknesses in terms of generality can be fixed, preserving the original ideas. I'm not sure it will be as general as the others, and not as fast, but it seems like a worthwhile programming and conceptual exercise. The code works from the end instead of the beginning, and would have to be changed if you wanted to apply it to an (odd x odd) matrix instead of (even x even). Perhaps Fold[Delete, #, 1 + Range[1/2 Length[#]] ]& This deletes element 2, then 3, then 4, et cetera, to the end or the (end - 1). I think Delete makes it just a tad easier because you don't have to wrap the position in a list. Also, the outer Fold needn't be a Fold, because it uses only one variable, #1, which is the previous expression in the sequence. You are just applying the same transformation several times (well, twice for a 2-dim matrix), so Nest will work. In[47]:= Nest[Transpose @ Fold[Delete, #, 1 + Range[1/2 Length[#]] ]&, Array[u, {6, 6}], 2] Out[47]= {{u[1, 1], u[1, 3], u[1, 5]}, {u[3, 1], u[3, 3], u[3, 5]}, > {u[5, 1], u[5, 3], u[5, 5]}} I think you can generalize it to an n-dimensional tensor, as well. Use the Transpose idea, giving a rotated list of dimensions as the second argument to Transpose in this case. An example for a 3D matrix: In[41]:= Nest[Transpose[Part[#, Range[1, Length[#], 2]], RotateRight @ Range[3]]&, Array[a, {5, 6, 7}], 3] //MatrixForm Out[41]//MatrixForm= a[1, 1, 1] a[1, 3, 1] a[1, 5, 1] a[1, 1, 3] a[1, 3, 3] a[1, 5, 3] a[1, 1, 5] a[1, 3, 5] a[1, 5, 5] a[1, 1, 7] a[1, 3, 7] a[1, 5, 7] a[3, 1, 1] a[3, 3, 1] a[3, 5, 1] a[3, 1, 3] a[3, 3, 3] a[3, 5, 3] a[3, 1, 5] a[3, 3, 5] a[3, 5, 5] a[3, 1, 7] a[3, 3, 7] a[3, 5, 7] a[5, 1, 1] a[5, 3, 1] a[5, 5, 1] a[5, 1, 3] a[5, 3, 3] a[5, 5, 3] a[5, 1, 5] a[5, 3, 5] a[5, 5, 5] a[5, 1, 7] a[5, 3, 7] a[5, 5, 7] I think this general coding will work for higher tensors. The levels of the tensor get rotated around a full cycle, and end up where they were originally: everyother[tensor_List] := With[{n = TensorRank[tensor]}, Nest[Transpose[Part[#, Range[1, Length[#], 2]], RotateRight @ Range[n]]&, tensor, n] ] A test, using a matrix whose entries are just the indices concatenated together, for compactness of display (I always use this sort of thing when I'm having difficulty visualizing what's going on with higher dimensional matrices): In[29]:= everyother[ Array[SequenceForm, {3, 4, 5, 6}] ] //MatrixForm Out[29]//MatrixForm= 1111 1113 1115 1311 1313 1315 1131 1133 1135 1331 1333 1335 1151 1153 1155 1351 1353 1355 3111 3113 3115 3311 3313 3315 3131 3133 3135 3331 3333 3335 3151 3153 3155 3351 3353 3355 Robby Villegas