# How to assign the diagonal elements of part of matrix to a value?

I know that `diagind()` returns the index of the diagonal elements of matrix, in which we can assign them to a specific value such as in the below

``````aa=rand(9,9);
aa[diagind(aa)] .= 1
``````

However, lets say I am working on a part of the matrix `aa` such as `aa[5:7,5:7]` and I want to assign its diagonal elements to 1 (in other words aa[5,5]=1, aa[6,6]=1, aa[7,7]=1), how can I do that?

You can simply do:

``````aa[diagind(aa)[5:7]] .= 1
``````
3 Likes

Thank you very much!
@Seif_Shebl
How is about changing the diagonal elements of `aa[5:7,4:6]` (i.e., aa[5,4]=1, aa[6,5]=1, aa[7,6]=1)
I tried `aa[diagind(aa)[5:7,4:6]] .= 1` but it gives an error

``````ERROR: BoundsError: attempt to access 9-element StepRange{Int64, Int64} at index [5:7, 5:7]
Stacktrace:
``````

Not very elegant but you could do a comprehension:

``````  [aa[ind...] = 1 for ind in zip(5:7,4:6)]
``````

It could be very clearly (and with better performance) written with a for loop as well.

Never use a comprehension when you just want a `for` loop. A comprehension generates an array, so if you don’t want this array it is a pointless side effect, and it’s not any less compact to write `for ind in zip(5:7,4:6); aa[ind...] = 1; end` or `for j in 4:6; aa[j+1,j] = 1; end`

3 Likes

Thanks for noting it!

`diagind` takes an extra argument, so you could write

``````jl> aa[diagind(aa, -1)[4:6]] .= 1
``````
2 Likes

@DNF Great
How is about changing the diagonal elements of `aa[1:3,4:6]` (i.e., aa[1,4]=1, aa[2,5]=1, aa[3,6]=1)

``````jl> aa[diagind(aa,3)[1:3]] .= 1;
``````

Various combinations of this is possible. Just try some things.

Another approach is to use an extra step involving a `view`:

``````jl> av = view(aa, 5:7, 4:6);

jl> av[diagind(av)] .= 1;
``````

And then you could take more general and interesting slices as well, like

``````jl> av = @view aa[1:2:end, end:-2:1];

jl> av[diagind(av)] .= 1;

jl> aa
10×10 Matrix{Int64}:
0  0  0  0  0  0  0  0  0  1
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  1  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  1  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  1  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  1  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
``````
2 Likes

For speed, you should probably use a loop.

@DNF Yes, actually the speed is critical in my situation

Then you should try both and benchmark. Sometimes, the simple high-level versions are competitive.

1 Like