根据输入i,j

时间:2018-08-10 05:18:44

标签: fortran matrix-multiplication

对于给定的3x3矩阵,例如: A = [3 1 -4; 2 5 6; 1 4 8]

如果我需要用于输入的次要矩阵(1,2) 次要= [2 6; 1 8]

我已经编写了一个程序来从文本文件中读取矩阵,并且我应该编写一个子例程以根据用户对i,j的输入从主矩阵A中提取次要矩阵。我对Fortran还是很陌生,不知道该怎么做。我做了一些非常绝望的尝试,但是我敢肯定有一种更干净的方法可以做到这一点。

我非常拼命,我为i和j的每个可能组合写了9 if函数,但这显然不是明智的选择。任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:4)

一种实现此目的的方法是,如@HighPerformanceMark在评论中所说,带有向量下标。您可以声明一个数组,其中包含要保留的行,列也要保留,并将它们作为索引传递给矩阵。像这样:

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

(我尚未测试,所以请告诉我是否有错误)

另一种选择是根据4个分配构造一个新矩阵,每个分配一个结果(受排除的行/列限制)。

我更喜欢第一个选项,因为它更具扩展性。您可以通过将数组作为参数传递来轻松扩展该函数以删除多行/多列,或对其进行调整以使其适用于更高维度。

答案 1 :(得分:0)

您可以使用 ac-implied-do RESHAPE来构造要保留的矩阵部分的掩码,然后用pack替换其余部分并用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

输出:

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