Mathematica Asked by Kiril Danilchenko on January 6, 2021

I am interested in replacing all elements in a diagonal of a sparse matrix with zero. Currently, I do it in the following manner:

```
spA = SparseArray[{{1, 1} -> 1, {2, 2} -> 2, {3, 3} -> 3, {1, 3} -> 4}]
withOutDiagonalELements = DeleteCases[ArrayRules[spA], {a_, a_} -> _];
spAwd = SparseArray@Append[withOutDiagonalELements, {_, _} -> 0.0];
```

Any suggestions on how to do it more efficiently?

```
removeDiagonal =
# SparseArray[SparseArray`SparseArrayRemoveDiagonal[#]["NonzeroPositions"] -> 1,
Dimensions[#]] &;
removeDiagonal[spA]
```

SparseArray[<4>,{3,3}]

```
removeDiagonal[spA] // MatrixForm // TeXForm
```

$left( begin{array}{ccc} 0 & 0 & 4 0 & 0 & 0 0 & 0 & 0 end{array} right)$

```
removeDiagonal[spA]["NonzeroPositions"]
```

{{1,3}}

**Some timings:**

```
f1 = removeDiagonal;
f2 = SparseArray[# - DiagonalMatrix[Diagonal[#, 0], 0,
Dimensions[#]]] &; (* Henrik Shumacher *)
f3 = With[{zeros = 1 - IdentityMatrix[Dimensions@#, SparseArray]}, #*
zeros] &; (* Mr. Wizard *)
f4 = ReplacePart[#, {i_, i_} :> 0] &; (* tomd *)
m1 = SparseArray[Tuples[RandomSample[Range[101], 100], {2}] -> 1, {101, 101}];
m2 = SparseArray[Tuples[RandomSample[Range[100000], 100], {2}] -> 1, {100000, 100000}];
m = m1;
t11 = First[RepeatedTiming[r11 = f1 @ m ;]];
t21 = First[RepeatedTiming[r21 = f2 @ m;]];
t31 = First[RepeatedTiming[ r31 = f3 @ m;]];
t41 = First[RepeatedTiming[ r41 = f4 @ m;]];
r11 == r21 == r31 == r41
```

True

```
m = m2;
t12 = First[RepeatedTiming[r12 = f1 @ m ;]];
t22 = First[RepeatedTiming[r22 = f2 @ m;]];
t32 = First[RepeatedTiming[ r32 = f3 @ m;]];
t42 = "n/a"; (* b/c computation exceeded the limitation of free plan on Wolfram Cloud *)
r12 == r22 == r32
```

True

```
{{"dimensions", "non-zero elements", "f1", "f2", "f3", "f4"},
{{101, 101}, 100, t11, t21, t31, t41},
{{100000, 100000}, 100, t12, t22, t32, t42}} // Grid[#, Dividers -> All] & // TeXForm
```

$smallbegin{array}{|c|c|c|c|c|c|} hline text{dimensions} & text{non-zero elements} & text{f1} & text{f2} & text{f3} & text{f4} hline {101,101} & 100 & 0.000322 & 0.000279 & 0.000131 & 0.00487 hline {100000,100000} & 100 & 0.0017 & 0.0053 & 0.004 & text{n/a} hline end{array}$

Correct answer by kglr on January 6, 2021

You can multiply a binary matrix by your Sparse Array, and that matrix may itself be a `SparseArray`

.

```
spA = SparseArray[{{1, 1} -> 1, {2, 2} -> 2, {3, 3} -> 3, {1, 3} -> 4}];
zeros = 1 - IdentityMatrix[Dimensions @ spA, SparseArray];
spA*zeros // Grid
```

$begin{array}{ccc} 0 & 0 & 4 0 & 0 & 0 0 & 0 & 0 end{array}$

See also `Band`

and `DiagonalMatrix`

for other tools to construct the zeros array.

Answered by Mr.Wizard on January 6, 2021

```
ReplacePart[spA, {i_, i_} :> 0]
```

and

```
Diagonal[ReplacePart[spA, {i_, i_} :> 0]] // Normal
```

{0, 0, 0}

In general:

```
ReplacePart[spA, {i_, i_} :> {a, b, c}[[i]]]
```

Answered by user1066 on January 6, 2021

Just subtract the diagonal matrix:

```
SparseArray[spA - DiagonalMatrix[Diagonal[spA]]]
```

As Mr. Wizard pointed out, if `spA`

is not a square matrix, one can use

```
k = 0;
SparseArray[spA - DiagonalMatrix[Diagonal[spA, k], k, Dimensions[spA]]]
```

Here, `k`

stands for the number of the diagonal you what to delete. `k = 0`

stands for the main diagonal, `k = 1`

for the first diagonal *above* the main diagonal, `k = -1`

for the first diagonal below the main diagonal etc.

Answered by Henrik Schumacher on January 6, 2021

Two methods to add a list to the diagonal of a sparse matrix are given as below. The performance varies greatly.

```
n = 100000;
a = RandomReal[1, n];
Ksp = SparseArray[{{i_, i_} :> a[[i]]}, Length[a]];
Ksp2 = Ksp;
```

**Method 1**

```
t1 = Timing[Do[Ksp[[i, i]] += a[[i]], {i, Length[a]}]][[1]]
```

33.7742

**Method 2**

```
t2 = Timing[Ksp2 += SparseArray[{{i_, i_} :> a[[i]]}, Length[a]]][[1]]
```

0.0312002

*Compare:*

```
t1/t2
```

1082.5

Answered by hlren on January 6, 2021

Get help from others!

Recent Answers

- Joshua Engel on Why fry rice before boiling?
- haakon.io on Why fry rice before boiling?
- Peter Machado on Why fry rice before boiling?
- Jon Church on Why fry rice before boiling?
- Lex on Does Google Analytics track 404 page responses as valid page views?

Recent Questions

- How can I transform graph image into a tikzpicture LaTeX code?
- How Do I Get The Ifruit App Off Of Gta 5 / Grand Theft Auto 5
- Iv’e designed a space elevator using a series of lasers. do you know anybody i could submit the designs too that could manufacture the concept and put it to use
- Need help finding a book. Female OP protagonist, magic
- Why is the WWF pending games (“Your turn”) area replaced w/ a column of “Bonus & Reward”gift boxes?

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP