I start with a square matrix with odd size. I keep the original version of this matrix. Now, I extract the non-zero elements from the matrix, which lie everywhere except the $3\times3$ block in the center of the matrix, flatten them out and do some manipulations. These manipulations required me to remove the zero elements. Now I want to unflatten these elements into their original positions in the matrix and retrieve the matrix as a whole. I tried assigning labels to each of the elements but that becomes cumbersome. (I am working with a multidimensional array; the matrix here is just for example). How can I do this easily?
a = SparseArray[RandomChoice[Range[10], {10, 5}]];
a[[Range[2, 4], Range[2, 4]]] = 0;
SparseArray[a["NonzeroPositions"] -> manipulations[a["NonzeroValues"]]]
Where manipulations is the function you want to perform on the flattened values
-
$\begingroup$ I need to flatten the non-zero entries to do the manipulations (not needed but this is because I am finding the nullspace of the a bunch of vectors stored on those positions of nonzero entries in the matrix.) $\endgroup$ – cleanplay Apr 20 '18 at 16:45
-
$\begingroup$ In the above code
a["NonzeroValues"]
gives flattened non zero entries of the matrixa
$\endgroup$ – no-one Apr 23 '18 at 15:41
Here's a function that is similar to @no-one's, but packaged differently:
nonzeroMap[func_, array_] := Replace[SparseArray[array],
Verbatim[SparseArray][a__, {b__, c_}] :> Normal @ SparseArray[a,{b,func/@c}]
]
A SparseArray
object stores the nonzero elements in the last position of the last argument. So, the above function converts the input array into a SparseArray, maps func
onto the nonzero elements, and then converts back to a normal array. Here are a couple examples:
random matrix
m = RandomInteger[3, {4,4}];
m //TeXForm
$\left( \begin{array}{cccc} 3 & 3 & 2 & 0 \\ 2 & 0 & 2 & 0 \\ 1 & 3 & 2 & 0 \\ 1 & 0 & 2 & 0 \\ \end{array} \right)$
nonzeroMap[1/#&, m] //TeXForm
$\left( \begin{array}{cccc} \frac{1}{3} & \frac{1}{3} & \frac{1}{2} & 0 \\ \frac{1}{2} & 0 & \frac{1}{2} & 0 \\ 1 & \frac{1}{3} & \frac{1}{2} & 0 \\ 1 & 0 & \frac{1}{2} & 0 \\ \end{array} \right)$
random array
a = RandomInteger[3, {3,3,3}];
a //TeXForm
$\left( \begin{array}{ccc} \{2,1,2\} & \{3,3,2\} & \{2,0,2\} \\ \{1,1,1\} & \{0,3,1\} & \{2,2,0\} \\ \{2,3,1\} & \{3,0,3\} & \{0,1,0\} \\ \end{array} \right)$
nonzeroMap[1/#&, a] //TeXForm
$\left( \begin{array}{ccc} \left\{\frac{1}{2},1,\frac{1}{2}\right\} & \left\{\frac{1}{3},\frac{1}{3},\frac{1}{2}\right\} & \left\{\frac{1}{2},0,\frac{1}{2}\right\} \\ \{1,1,1\} & \left\{0,\frac{1}{3},1\right\} & \left\{\frac{1}{2},\frac{1}{2},0\right\} \\ \left\{\frac{1}{2},\frac{1}{3},1\right\} & \left\{\frac{1}{3},0,\frac{1}{3}\right\} & \{0,1,0\} \\ \end{array} \right)$
SparseArray
andArrayRules
. $\endgroup$ – Anton Antonov Apr 20 '18 at 15:34matrix={{a,b,c,d},{e,f,g,h},{i,j,k,l},{m,n,o,p}};(*for example*) For[y=2,y<=3,y++,For[z=2,z<=3,z++, matrix[[y,z]]=""]];(*or another placeholder*) manipulated=doSomeManipulations[Flatten[matrix]]; Partition[manipulated,4]//MatrixForm
$\endgroup$ – Bill Apr 20 '18 at 15:53