I'm struggling with a reconstruction of a large sparse array. What I'm trying to do is to rearrange a 2 dimensional array (respresenting a system matrix for a given system of equations) such that I add up certain columns and rows and only take a submatrix of the original one.
To be more specific:
Let Kmat
be a large sparse array with the dimensions 44000x44000.
The vectors From1
, From2
and From3
give specific row/column numbers from where I want to take the values, which are added to the row/column numbers given in the vectors To1
, To2
and To3
.
The dimensions of these vectors are much smaller, e.g. 300 to 400 entries.
Therefore, I want to perform:
(* adding rows *)
Kmat[[;; , To1[[ ;; ]] ]] += Kmat[[;; , From1[[ ;; ]] ]];
Kmat[[;; , To2[[ ;; ]] ]] += Kmat[[;; , From2[[ ;; ]] ]];
Kmat[[;; , To3[[ ;; ]] ]] += Kmat[[;; , From3[[ ;; ]] ]];
(* adding columns *)
Kmat[[To1[[ ;; ]] ]] += Kmat[[From1[[ ;; ]] ]];
Kmat[[To2[[ ;; ]] ]] += Kmat[[From2[[ ;; ]] ]];
Kmat[[To3[[ ;; ]] ]] += Kmat[[From3[[ ;; ]] ]];
And then I only want to take a submatrix defined by the indices in the vector take
with the dimensions around 43000:
Kmatnew = Kmat[[takes,takes]];
This all takes only about 0.1 seconds on my machine, which I would consider to be not expensive at all, but I repeat this a few thousand times which definitely adds up in my computation... I aim to do very efficient computing and that is definitely one of the bottlenecks of my code.
My first idea:
Try to use Map
in some way, but I was not succesful in findiing a solution using Map
...
My second idea:
Define a compile function with Compile
, but unfortunately that does not work with sparse arrays.
I'd be very happy about some useful hints and ideas...
########################################
Edit 25th July 2022: Add a small example to illustrate:
Let's take an example in the dimensions 10x10:
dim = 10;
Kmat = Table[RandomInteger[10], {i, dim}, {j, dim}];
This results in e.g.
Kmat =
{{10, 10, 1, 2, 4, 3, 8, 2, 6, 6},
{7, 0, 5, 0, 7, 2, 3, 6, 6, 3},
{1,4, 3, 9, 8, 4, 8, 2, 5, 2},
{0, 5, 0, 5, 7, 3, 0, 8, 10, 0},
{10, 6, 1, 6, 7, 1, 5, 6, 0, 1},
{2, 9, 7, 3, 5, 7, 6, 8, 4, 9},
{5, 4, 5, 0, 5, 1, 1, 2, 2, 10},
{2, 9, 0, 3, 10, 1, 9, 10, 0, 8},
{0, 7, 4, 10, 5, 7, 8, 0, 9, 10},
{10, 10, 3, 9, 1, 1, 9, 3, 0, 4}};
We want to add the rows/columns in From
to the rows/colums in To
. Then, we take whats left if we leave out the From
s.
To1 = {1, 3}; To2 = {2, 4}; To3 = {1};
From1 = {6, 8}; From2 = {7, 9}; From3 = {7};
Takes = Complement[Range[dim], Union[From1, From2, From3]];
Now we perform the upper procedure to add:
(* adding rows *)
Kmat[[;; , To1[[ ;; ]]]] += Kmat[[;; , From1[[ ;; ]]]];
Kmat[[;; , To2[[ ;; ]]]] += Kmat[[;; , From2[[ ;; ]]]];
Kmat[[;; , To3[[ ;; ]]]] += Kmat[[;; , From3[[ ;; ]]]];
(* adding columns *)
Kmat[[To1[[ ;; ]]]] += Kmat[[From1[[ ;; ]]]];
Kmat[[To2[[ ;; ]]]] += Kmat[[From2[[ ;; ]]]];
Kmat[[To3[[ ;; ]]]] += Kmat[[From3[[ ;; ]]]];
And this should result in
Kmat =
{{43, 38, 25, 17, 14, 11, 15, 12, 12, 25},
{19, 8, 18, 8, 12, 3, 4, 8, 8, 13},
{25, 30, 15, 17, 18, 5, 17, 12, 5, 10},
{18, 20, 12, 34, 12, 10, 8, 8, 19, 10},
{16, 11, 7, 6, 7, 1, 5, 6, 0, 1},
{15, 15, 15, 7, 5, 7, 6, 8, 4, 9},
{7, 5, 7, 2, 5, 1, 1, 2, 2, 10},
{12, 18, 10, 3, 10, 1, 9, 10, 0, 8},
{15, 15, 4, 19, 5, 7, 8, 0, 9, 10},
{20, 19, 6, 9, 1, 1, 9, 3, 0, 4}}
Then, we take the Take
s:
Kmatnew = Kmat[[Takes, Takes]];
and Kmatnew results in
Kmatnew =
{{43, 38, 25, 17, 14, 25},
{19, 8, 18, 8, 12, 13},
{25, 30, 15, 17, 18, 10},
{18, 20, 12, 34, 12, 10},
{16, 11, 7, 6, 7, 1},
{20, 19, 6, 9, 1, 4}}
Sorry for the long post!
SparseArray[]
. Could you consider using a matrix from e.g.ExampleData["Matrix"]
as an example? $\endgroup$ExampleData[{"Matrix", "685BUS"}]
looks similar to what I'm dealing with, only my matrix is much bigger. I also just fixed the numbering of theFrom
vectors in my original post, since I falsely usedFrom1
in all lines. Please pardon me! $\endgroup$