1
$\begingroup$

I want to specify a location replacement for matrix reorganization. For example, when I specify the location replacement rule to be {1, 2, 3, 4} -> {2, 3, 0, 0} (where 0 means the matrix element is replaced with 0), a 4-by-4 matrix Table[a[i, j], {i, 1, 4}, {j, 1, 4}] is recombined as follows:

{{0, 0, 0, 0}, {0, a[1, 1], a[1, 2], 0}, {0, a[2, 1], a[2, 2], 0}, {0, 0, 0, 0}}

When I specify the location replacement rule to be {1, 2, 3, 4} -> {3, 4, 0, 0} , a 4-by-4 matrix Table[a[i, j], {i, 1, 4}, {j, 1, 4}] is recombined as follows:

{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, a[1, 1], a[1, 2]}, {0, 0, a[2, 1], a[2, 2]}}

How can I write this custom function to implement this functionality?

$\endgroup$

2 Answers 2

3
$\begingroup$

I find your notation for describing the replacements most confusing. But one can do something like this:

A = Table[a[i, j], {i, 1, 4}, {j, 1, 4}];
ilist = {1, 2};
jlist = {2, 3};
B = SparseArray[
   Tuples[{ilist, jlist}] -> Flatten[A[[ilist, jlist]]],
   Dimensions[A]
   ];
Normal@B

{{0, a[1, 2], a[1, 3], 0}, {0, a[2, 2], a[2, 3], 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}

Here, ilist is the lists of rows that you want to preserve and jlist is the corresponding list of columns.

This is also possible:

B = ConstantArray[0, Dimensions[A]];
B[[ilist, jlist]] = A[[ilist, jlist]]

This, too; but it is rather slow:

ReplacePart[
 ConstantArray[0, Dimensions[A]],
 Thread[Tuples[{ilist, jlist}] -> Flatten[A[[ilist, jlist]]]]
 ]
$\endgroup$
4
  • $\begingroup$ I don't know if you have heard of the matrix displacement method in structural mechanics. I want to realize the assembly function of the stiffness matrix. I will modify this problem in detail tomorrow. $\endgroup$ Commented Apr 1, 2020 at 11:17
  • 2
    $\begingroup$ No, I do not know it and I obviously do not need to know it in order to produce the matrices that you are looking for. I observed that you have recently posted many posts that involve a lot of lingo from structural mechanics. In most of the cases, knowing this slang was actually not necessary to phrase or answer(!) your underlying question. This is not a forum on structural mechanics. $\endgroup$ Commented Apr 1, 2020 at 11:26
  • 6
    $\begingroup$ So my advice to you for future: Please to not assume that everybody here is knowledgeable in structural mechanics; instead, find the mathematical core of your problem and ask the question in a way that most people here can understand. Do not try to force everybody to learn structural mechanics. $\endgroup$ Commented Apr 1, 2020 at 11:27
  • 2
    $\begingroup$ Thank you very much for your suggestion. I will abstract the problem into the minimum demo code containing the problem in the future (minimal working example). I try not to use other professional terms in the problem. $\endgroup$ Commented Apr 2, 2020 at 1:13
0
$\begingroup$

I think writing code like this can fulfill the requirements:

A = Table[a[i, j], {i, 1, 6}, {j, 1, 6}];
f[x1_, x2_] := {x1[[1]], x2[[1]]} -> {x1[[2]], x2[[2]]}
rule1 = {1, 2, 3, 4, 5, 6} -> {1, 0, 2, 1, 0, 3}
rule2 = {1, 2, 3, 4, 5, 6} -> {1, 0, 4, 0, 0, 0}

s1 = DeleteCases[Flatten[Outer[f, Thread[rule1], Thread[rule1]]], 
   HoldPattern[{_, _} -> {a_, b_}] /; a == 0 || b == 0] /. 
  HoldPattern[
    x1_ -> x2_List] :> (x2 -> Part[A, x1 /. List -> Sequence])
s2 = DeleteCases[Flatten[Outer[f, Thread[rule2], Thread[rule2]]], 
   HoldPattern[{_, _} -> {a_, b_}] /; a == 0 || b == 0] /. 
  HoldPattern[
    x1_ -> x2_List] :> (x2 -> Part[A, x1 /. List -> Sequence])
B1 = SparseArray[Normal[Merge[s1, Total]], 4];
B2 = SparseArray[Normal[Merge[s2, Total]], 4];
Normal@B1
Normal@B2

Maybe this code can be simplified more succinctly and efficiently.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.