2.48 extract submatrix from a larger matrix by removing row/column

2.48.1 Mathematica
2.48.2 Matlab
2.48.3 Fortran
2.48.4 Ada
2.48.5 Maple

Given 2D matrix \(A\) extract all submatrices by removing row/column.

For example, given the matrix \(\begin {pmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end {pmatrix} \) then the submatrix for \(\left ( 1,1\right ) \) is\(\begin {pmatrix} 5 & 6\\ 8 & 9 \end {pmatrix} \) obtained by removing the first row and the first column.

In Mathematica, ReplacePart can be used. In Matlab the [] operator can be used. In Fortran, the pack() function can be used.

2.48.1 Mathematica

mat={{1,2,3}, 
     {4,5,6}, 
     {7,8,9}}; 
{nRow, nCol} = Dimensions[mat]; 
Table[ReplacePart[mat,{{i},{i,_},{_,j}} 
      :>Sequence[],Heads-> False], 
         {i,nRow},{j,nCol}]; 
 
r=Flatten[%,1]
 

{{{5,6},{8,9}}, 
 {{4,6},{7,9}}, 
 {{4,5},{7,8}}, 
 {{2,3},{8,9}}, 
 {{1,3},{7,9}}, 
 {{1,2},{7,8}}, 
 {{2,3},{5,6}}, 
 {{1,3},{4,6}}, 
 {{1,2},{4,5}}}
 

 

2.48.2 Matlab

A=[1 2 3; 
   4 5 6; 
   7 8 9] 
 
for i=1:size(A,1) 
    for j=1:size(A,1) 
        B=A; 
        B(i,:)=[]; 
        B(:,j)=[] 
    end 
end
 

B = 
     5     6 
     8     9 
B = 
     4     6 
     7     9 
B = 
     4     5 
     7     8 
B = 
     2     3 
     8     9 
B = 
     1     3 
     7     9 
B = 
     1     2 
     7     8 
B = 
     2     3 
     5     6 
B = 
     1     3 
     4     6 
B = 
     1     2 
     4     5
 

 

2.48.3 Fortran

program t46

implicit none 
integer, parameter:: dp=kind(0.d0), n=3 
integer :: i,j,ii 
real(dp) :: A(n,n) = dble(reshape([ 1.0, 2.0, 3.0,  & 
                                    4.0, 5.0, 6.0,  & 
                                    7.0, 8.0, 9.0], & 
                                    shape(A),       & 
                                    order=[2,1])) 
real(dp) :: B(n-1,n-1) 
logical :: mask(n,n) 
DO i=1,n 
   DO j=1,n 
      mask = .true. 
      mask(:,j) = .false. 
      mask(i,:) = .false. 
      !-- extract submatrix 
      B = reshape(pack(A, mask),[n-1,n-1]) 
 
      DO ii=1,n-1 
         write(*,'(2F6.1)') B(ii,:) 
      END DO 
      write(*,'(/)') 
   END DO 
END DO 
end program t46

compile and run

>gfortran -std=f2008 -fcheck=all -Wall -Wextra -Wconversion-extra t46.f90 
>./a.out 
   5.0   6.0 
   8.0   9.0 
 
   4.0   6.0 
   7.0   9.0 
 
   4.0   5.0 
   7.0   8.0 
 
   2.0   3.0 
   8.0   9.0 
 
   1.0   3.0 
   7.0   9.0 
 
   1.0   2.0 
   7.0   8.0 
 
   2.0   3.0 
   5.0   6.0 
 
   1.0   3.0 
   4.0   6.0 
 
   1.0   2.0 
   4.0   5.0
 

2.48.4 Ada

with Ada.Text_Io; use Ada.Text_Io; 
with Ada.Float_Text_Io; use Ada.Float_Text_Io; 
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays; 
procedure foo is 
    A : constant Real_Matrix := 
             (( 1.0,  2.0,  3.0), 
              ( 4.0,  5.0,  6.0), 
              ( 7.0,  8.0,  9.0)); 
    B : real_matrix(1 .. 2, 1 .. 2); 
    -- Thanks goes to Dmitry A. Kazakov 
    -- for providing this function 
    function Exclude (A : Real_Matrix; I, J : Integer) 
       return Real_Matrix is 
       AI, AJ : Integer := A'First (1); 
    begin 
       return B : Real_Matrix(1..A'Length(1)-1,1..A'Length(2)-1) do 
          AI := A'First (1); 
          for BI in B'Range (1) loop 
             if AI = I then 
                AI := AI + 1; 
             end if; 
             AJ := A'First (2); 
             for BJ in B'Range (2) loop 
                if AJ = J then 
                   AJ := AJ + 1; 
                end if; 
                B (BI, BJ) := A (AI, AJ); 
                AJ := AJ + 1; 
             end loop; 
             AI := AI + 1; 
          end loop; 
       end return; 
    end Exclude; 
 
    -- Function to print a 2D matrix 
    procedure put(A: Real_Matrix) is 
    begin 
     for I in A'range(1) loop 
      for J in A'range(2) loop 
          put(A(I,J)); 
      end loop; 
      new_line; 
     end loop; 
    end put; 
 
begin 
    FOR I in A'range(1) LOOP 
      FOR J in A'range(2) LOOP 
          B := Exclude (A, I, J); 
          put(B); 
          new_line(1); 
      END LOOP; 
    END LOOP; 
end foo;

compile and run

>gnatmake foo.adb 
gcc-4.6 -c foo.adb 
gnatbind -x foo.ali 
gnatlink foo.ali 
>./foo 
 >./foo 
  5.00000E+00 6.00000E+00 
  8.00000E+00 9.00000E+00 
 
  4.00000E+00 6.00000E+00 
  7.00000E+00 9.00000E+00 
 
  4.00000E+00 5.00000E+00 
  7.00000E+00 8.00000E+00 
 
  2.00000E+00 3.00000E+00 
  8.00000E+00 9.00000E+00 
 
  1.00000E+00 3.00000E+00 
  7.00000E+00 9.00000E+00 
 
  1.00000E+00 2.00000E+00 
  7.00000E+00 8.00000E+00 
 
  2.00000E+00 3.00000E+00 
  5.00000E+00 6.00000E+00 
 
  1.00000E+00 3.00000E+00 
  4.00000E+00 6.00000E+00 
 
  1.00000E+00 2.00000E+00 
  4.00000E+00 5.00000E+00
 

2.48.5 Maple

del:=proc(A::Matrix,idx::list)::Matrix; 
     local B; 
     B:=LinearAlgebra:-DeleteRow(A,idx[1]); 
     B:=LinearAlgebra:-DeleteColumn(B,idx[2]); 
     return B; 
end proc; 
 
A:=Matrix([[1,2,3],[4,5,6],[7,8,9]]): 
r:=map2(del,A,[indices(A,indexorder)]);
 

\[ \left [\left [\begin {array}{cc} 5 & 6 \\ 8 & 9 \end {array}\right ], \left [\begin {array}{cc} 4 & 6 \\ 7 & 9 \end {array}\right ], \left [\begin {array}{cc} 4 & 5 \\ 7 & 8 \end {array}\right ], \left [\begin {array}{cc} 2 & 3 \\ 8 & 9 \end {array}\right ], \left [\begin {array}{cc} 1 & 3 \\ 7 & 9 \end {array}\right ], \left [\begin {array}{cc} 1 & 2 \\ 7 & 8 \end {array}\right ], \left [\begin {array}{cc} 2 & 3 \\ 5 & 6 \end {array}\right ], \left [\begin {array}{cc} 1 & 3 \\ 4 & 6 \end {array}\right ], \left [\begin {array}{cc} 1 & 2 \\ 4 & 5 \end {array}\right ]\right ] \]