Extract the minor matrix from a 3x3 based on input i,j

自古美人都是妖i 提交于 2019-12-24 01:46:13

问题


For a given 3x3 matrix, for example: A = [3 1 -4 ; 2 5 6 ; 1 4 8]

If I need the minor matrix for entry (1,2) Minor = [2 6 ; 1 8]

I already wrote a program to read in the matrix from a text file, and I am supposed to write a subroutine to extract the minor matrix from the main matrix A based on the user inputs for i,j. I am very new to Fortran and have no clue how to do that. I made some very desperate attempts but I am sure there is a cleaner way to do that.

I got so desperate I wrote 9 if functions for each possible combination of i and j but that clearly is not a smart way for doing this. Any help is appreciated!


回答1:


One way to do this is, as @HighPerformanceMark said in the comment, with vector subscripts. You can declare an array with the rows you want to keep, and the same for columns, and pass them as indices to your matrix. Like this:

function minor(matrix, i, j)
  integer, intent(in) :: matrix(:,:), i, j
  integer :: minor(size(matrix, 1) - 1, size(matrix, 2) - 1)
  integer :: rows(size(matrix, 1) - 1), cols(size(matrix, 2) - 1), k

  rows = [(k, k = 1, i - 1), (k, k = i + 1, size(rows))]
  cols = [(k, k = 1, j - 1), (k, k = j + 1, size(cols))]
  minor = matrix(rows, cols)
end

(I didn't test it yet, so tell me if there is any error)

Another option would be constructing a new matrix from 4 assignments, one for each quadrant of the result (limited by the excluded row/column).

I like the first option more because it is more scalable. You could easily extend the function to remove multiple rows/columns by passing arrays as arguments, or adapt it to work on higher dimensions.




回答2:


You can use an ac-implied-do and RESHAPE to construct a mask of the parts of the matrix you want to preserve and then zap the rest with pack and reassemble with RESHAPE.

program minor
   implicit none
   integer A(3,3)
   integer, allocatable :: B(:,:)
   character(20) fmt
   integer i, j
   A = reshape([ &
       3,  1, -4, &
       2,  5,  6, &
       1,  4,  8], &
      shape(A), order = [2,1])
   write(fmt,'(*(g0))') '(a/',size(A,2),'(i3))'
   write(*,fmt) 'A =',transpose(A)
   B = reshape(pack(A,reshape([((all([i,j]/=[1,2]),i=1,size(A,1)), &
      j=1,size(A,2))],shape(A))),shape(A)-1)
   write(fmt,'(*(g0))') '(a/',size(B,2),'(i3))'
   write(*,fmt) 'B =',transpose(B)
end program minor

Output:

A =
  3  1 -4
  2  5  6
  1  4  8
B =
  2  6
  1  8


来源:https://stackoverflow.com/questions/51779432/extract-the-minor-matrix-from-a-3x3-based-on-input-i-j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!