# Minor matrix

in `R`, I can use negative indices to construct a minor matrix easily, like:

``````> M <- matrix(1:9, nr = 3L);
> M
[,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> M[-1L, -2L];
[,1] [,2]
[1,]    2    8
[2,]    3    9
``````

however, how to construct a minor matrix in Julia (I cannot find one in docs)? More generally, how to exclude some elements in indexing of `Julia` (negative indexing is used for counting from the end)?

Thanks!

You can use `setdiff`. For example:

``````julia> M = reshape(1:9, 3,3)
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
1  4  7
2  5  8
3  6  9

julia> M[setdiff(1:end, 1), setdiff(1:end, 2)]
2×2 Array{Int64,2}:
2  8
3  9
``````

Even more efficient would be to write a specialized function for this, which avoids allocating index arrays:

``````julia> function minor(A, i, j)
m, n = size(A)
B = similar(A, m-1, n-1)
for j′=1:j-1, i′=1:i-1; B[i′,j′]=A[i′,j′]; end
for j′=1:j-1, i′=i+1:m; B[i′-1,j′]=A[i′,j′]; end
for j′=j+1:n, i′=1:i-1; B[i′,j′-1]=A[i′,j′]; end
for j′=j+1:n, i′=i+1:m; B[i′-1,j′-1]=A[i′,j′]; end
return B
end

julia> minor(M, 1, 2)
2×2 Array{Int64,2}:
2  8
3  9
``````

A nice thing about Julia is that you are not limited to digging through “built-in” functions hoping to find one that does just what you want — there is no performance problem with user-written loops, so in critical cases you can write your own function.

3 Likes
``````julia> struct SkipRange <: AbstractVector{Int}
start::Int
stop::Int
skip::Int
end

julia> Base.length(s::SkipRange)=s.stop-s.start-1;

julia> Base.size(s::SkipRange) = (length(s),)

julia> Base.getindex(s::SkipRange, i) = s.start+i-1 < s.skip ? s.start+i-1 : s.start+i

julia> A=reshape(collect(1:25), 5, 5)
5×5 Array{Int64,2}:
1   6  11  16  21
2   7  12  17  22
3   8  13  18  23
4   9  14  19  24
5  10  15  20  25

julia> sx=SkipRange(1,5,2); sy = SkipRange(1,5,1);

julia> A[sx,sy]
4×4 Array{Int64,2}:
6  11  16  21
8  13  18  23
9  14  19  24
10  15  20  25

julia> view(A,sx,sy)
4×4 view(::Array{Int64,2}, [1, 3, 4, 5], [2, 3, 4, 5]) with eltype Int64:
6  11  16  21
8  13  18  23
9  14  19  24
10  15  20  25

julia> typeof(view(A,sx,sy))
SubArray{Int64,2,Array{Int64,2},Tuple{SkipRange,SkipRange},false}
``````

Pulling a copy instead of a view may be more efficient for many linear algebra operations (use BLAS instead of fallback), but sometimes you need to operate inplace.

5 Likes

corrections of terminology:
minor should be a scalar: it’s the determinant of a submatrix (i.e. that “minor” I called) of a matrix with a row and a column deleted.

It’s standard, if technically imprecise, to refer to both the determinant of the submatrix and the submatrix itself as “minor”, by metonymy.