This is a follow-up question from here: Define a 4d matrix without for loop
I have a 400x400 2d matrix reshaped from a 4d matrix H(i,j,k,l),
H(0,0,0,0) H (0,0,0,1) ... H(0,0,0,N)... H(0,0,1,0) ... H(0,0,N,N)
H(0,1,0,0) H (0,1,0,1) ... H(0,1,0,N)... H(0,1,1,0) ... H(0,1,N,N)
...
H(1,0,0,0) H (1,0,0,1) ... H(1,0,0,N)... H(1,0,1,0) ... H(1,0,N,N)
...
H(N,N,0,0) H (N,N,0,1) ... H(N,N,0,N)... H(N,N,1,0) ... H(N,N,N,N)
now I would like to modify/delete some rows and columns like this:
- If i==j, then half this element
- If i>j OR k>l, then delete this element
I have checked the manual for DeleteCase and some other resources but have no luck yet. Does anyone has a idea how to implement it? Thanks.
UPDATED: Kglr has given the pre and post matrix forms in the answer. Thanks.
Answer
f1 = Partition[# @@@ Tuples[Range[0, #2], #2 + 1], (#2 + 1)^2] &;
m1 = f1[H, 3];
Use ReplaceAll
m2 = m1 /. H[i_, j_, k_, l_] /; (i > j || k > l) :> Sequence[] /.
H[i_, i_, k_, l_] :> H[i, i, k, l]/2 /. {} -> Style[0, Red];
Or DeleteCases
m2b = DeleteCases[m1, H[i_, j_, k_, l_] /; (i > j || k > l), 2] /.
a : H[i_, i_, _, _] :> a/2 /. {} -> Style[0, Red]
m2b == m2
True
Or, construct the original matrix using your conditions
m2c = ArrayReshape[ Array[Which[# > #2 || #3 > #4, foo, # == #2, H[##]/2, True, H[##]] &,
{4, 4, 4, 4}, {0, 0, 0, 0}], {16, 16}] /. foo -> Sequence[] /. {} -> Style[0, Red]
m2c == m2
True
Style[0,Red]
is for the purpose of checking if the right rows and columns are deleted. Replace Style[0,Red]
with Sequence[]
after verifying that f1
works as intended.
(In the following, H[a, b, c, d]
is replaced with H[abcd]
to see the entire matrix in the notebook window).
MatrixForm@(m1 /. H[a___] :> H[StringJoin[ToString /@ {a}]])
MatrixForm@(m2 /. H[a___] :> H[StringJoin[ToString /@ {a}]])
Comments
Post a Comment