# Delete a specific row and Colum in matrix

I have a matrix of size nn and I have a list containing specific nodes in the graph in each iteration I have to remove the specific row and corresponding column based on the value in the list, how do I can know the specific row and column since the size of the matrix decreasing.
for example, I have the following 4
4 matrix

``````L=[8 -1 -1 0; -1 6 -1 0; -1 -1 5 0; 0 0 0 7]
``````

if the list is the following
`a=[2,3]`
so I have to delete the second row and column the matrix will be
`L=[8 -1 0; -1 5 0; 0 0 7]`
now I have to delete the third row and column in the original matrix which is the second one now, I want a general way to use it even with huge matrices and I have to do it one by one because I know it’s possible do it all by once, I am using the following function for deleting

`L = L[1:end .!= a[i], 1:end .!= a[i]]`

You can use

``````L[setdiff(axes(L, 1), a), setdiff(axes(L, 2), a)]
``````

or

`````` L[.!in.(axes(L, 1), (a,)), .!in.(axes(L, 2), (a,))]
``````

You should benchmark to check which is faster for your arrays.

2 Likes

It would be cool, btw, if this worked:

`````` L[.!in.(:, (a,)), .!in.(:, (a,))]
``````

which it seems like it should, since this does work:

`````` L[.!in.(begin:end, (a,)), .!in.(begin:end, (a,))]
``````

Do you really need to delete them? Deleting a row or a column of a matrix can be very slow. One way to avoid really deleting it could be:

``````A = rand(10,10)
i,j = trues(10), trues(10)
i = false; j = false #to remove 3rd row and 4th column
B = @view A[i,j] # B is an AstractMatrix
i = false
C = @view A[i,j] # C has also row 7 deleted etc
``````

If you really need to delete them, you could do `A = A[i,j]`

1 Like

This would return a non-contiguous view, which is possible, but could have very negative performance consequences when you want to use the view. Contiguous or regularly spaced views are better than irregular ones like this.

of course, it may depend on what is the use of the modified matrix if a view or a copy is preferable

Thank you so much, but what you mentioned is the way of deleting the rows all at once, my problem is actually after deleting one row and column the indices of the rows and columns in the new matrix and all I need is a way to get the right indecies after each delete

Honestly, it sounds like a matrix may be a poor choice of data structure for the types of operations you want to perform. If you give a little more information about the algorithm you are trying to implement, we might be able to suggest a better data structure.

I have the following code where I am trying to calculate the smallest eigenvalue of the laplacian matrix, for that, I sort the nodes of the graph based on their degrees and start deleting the corresponding row and column for each node and check the value after each delete, the problem that when I start deleting the indices changed as I explained before so I need a way to get the right index after each delete, here is the code

``````using Laplacians
using LinearAlgebra
using Graphs

function eg()
###########################################
L=Matrix(laplacian_matrix(G))
eigen_values=eigvals(L)
min_deg = sortperm(degree(G))
L = L[1:end .!= min_deg, 1:end .!= min_deg]
eigen_values=eigvals(L)
min_eign = eigen_values
first_eigen=0
counter=1
for i in 2:nv(G)
if min_eign >= first_eigen && size(L) > 3
first_eigen = eigen_values
if min_deg[i] > size(L)
L = L[1:end .!= size(L), 1:end .!= size(L)]
else
L = L[1:end .!= min_deg[i], 1:end .!= min_deg[i]]
end
counter+=1

eigen_values=eigvals(L)
min_eign=eigen_values
else
break
end
end
println("min_eign=",min_eign)
println("counter=",counter)
end
eg()
``````

of course you can use any graph you have

Without making any consideration on the suitability of the thought structure, I propose an idea to obtain the indices as desired by the OP.
The implementation changes if, by any chance, the indexes to be used are sorted, for example, in ascending order.

``````a=[11,5,2,3,7,1]

function relindex(a)
for i in eachindex(a)
end
end

relindex(a)

function sortrelindex(a)
for i in eachindex(a)
end
end

sortrelindex(sort(a))
``````

Hi
thank you so much, but unfortunately I don’t have the option of sorting the indices because it represents something as it is other than that the solution you proposed is totally fine by I need it without changing anything on the list of indices the first function tries to do exactly that. Whatever the list of indexes.
Try it and see if it’s right for you.

If you look at the code I proposed, you incrementally modify the vector `i` using always the indices of the original matrix

I’ve tried to add another data structure to keep track of new indices:

``````# NEW functions dyn_ind
delrenum!(md, n) = ( md[n] = 0 ; for i in n+1:length(md) md[i] = ifelse(md[i]==0, 0, md[i]-1) ; end; md)
lastnode(md) = findlast(!=(0),md)

function eg()
###########################################
L=Matrix(laplacian_matrix(G))
eigen_values=eigvals(L)
min_deg = sortperm(degree(G))
dyn_ind = collect(1:size(L,1))   # NEW
L = L[1:end .!= min_deg, 1:end .!= min_deg]
delrenum!(dyn_ind, min_deg)   # NEW
eigen_values=eigvals(L)
min_eign = eigen_values
first_eigen=0
counter=1
for i in 2:nv(G)
if min_eign >= first_eigen && size(L,1) > 3
first_eigen = eigen_values
if dyn_ind[min_deg[i]] == 0
L = L[1:end .!= size(L,1), 1:end .!= size(L,1)]
delrenum!(dyn_ind, lastnode(dyn_ind))   # NEW
else
L = L[1:end .!= dyn_ind[min_deg[i]], 1:end .!= dyn_ind[min_deg[i]]]
delrenum!(dyn_ind, min_deg[i])   # NEW
end
counter+=1

eigen_values=eigvals(L)
min_eign=eigen_values
else
break
end
end
println("min_eign=",min_eign)
println("counter=",counter)
end
``````

I think there might still be a problem, when the `min_deg` row to delete has already been deleted by the last row of `L` deletion step. But perhaps I haven’t dug enough into the workings of the algorithm.

Hope this helps.