Arrays 用Fortran语言将矩阵分解成子矩阵

Arrays 用Fortran语言将矩阵分解成子矩阵,arrays,matrix,fortran,Arrays,Matrix,Fortran,假设我有一个二维数组,第一列仅由两个整数1和2组成: 1 5 1 7 0.5 2 4 5 6 0.1 1 9 3 4 0.6 2 8 7 2 0.2 我想从中分离出两个矩阵,这样每个矩阵的第一列都包含相同的整数(因此第一个矩阵的第一列只包含整数1,第二个矩阵中的2也是如此)。 因此,它将成为: 1 5 1 7 0.5 1 9 3 4 0.6 及 我不知道该怎么开始。我开始考虑使用计数(因为我有一个更大的矩阵,在第一列

假设我有一个二维数组,第一列仅由两个整数1和2组成:

1 5 1 7 0.5                   
2 4 5 6 0.1       
1 9 3 4 0.6        
2 8 7 2 0.2  
我想从中分离出两个矩阵,这样每个矩阵的第一列都包含相同的整数(因此第一个矩阵的第一列只包含整数1,第二个矩阵中的2也是如此)。
因此,它将成为:

1 5 1 7 0.5
1 9 3 4 0.6  


我不知道该怎么开始。我开始考虑使用计数(因为我有一个更大的矩阵,在第一列中有10个不同的整数),然后根据每个整数的计数,我构造每个[sub]矩阵的维数。在那之后,我唯一能想到的就是计数(掩码),如果该值为真,则通过if语句将其添加到矩阵中

在Fortran的同一数组中不能有混合类型(
integer
real
),因此我假设所有数据都是二维数组中的
real

program split
  implicit none

  real, allocatable :: a(:, :), b(:, :)
  integer :: i, ids = 10
  integer, allocatable :: id(:), seq(:)

  a = reshape([real :: 1, 5, 1, 7, 0.5, &
                     & 2, 4, 5, 6, 0.1, &
                     & 1, 9, 3, 4, 0.6, &
                     & 2, 8, 7, 2, 0.2], [5, 4])
  seq = [(i, i = 1, size(a, 2))]
  do i = 1, ids
    print*, "i = ", i
    ! here we are creating a vector with all the line indices that start with i
    ! e.g. for i = 1 we get id = [1, 3], for i = 2 we get [2, 4], for i = 3 we get [], ...
    id =  pack(seq, a(1,:) == i)
    ! here we use a Fortran feature named vector-subscript
    b = a(:, id)
    print*, b
  end do
end

如果希望第一列(或任何列)为
整数
,可以将其声明为一个单独的数组,并使用相同的向量下标来收集所需的行。

您是否可以更清楚地了解您要实现的目标?另外,你能发布你已经尝试过的任何代码以及你得到的结果吗?我只能考虑用两个循环来实现这一点。一个用来计算每个数组的大小,另一个用来赋值。实际上我认为这是一个内在函数,但我仍然不确定OP在寻找什么。不清楚你对矩阵的意思是什么:你是指程序中的Fortran数组吗(您想从内存中已有的数组在程序中创建多个数组),或在文件中定期排列数字(您有一个输入文件,并想创建多个输出文件)?您提供的示例中有整数和实数,如果您考虑第一种情况,是否要将它们存储在同一数组中(必须是实数),或者可以将它们存储为两个(一个用于整数,一个用于实数)?如果不清楚,请原谅。是的,我有一个输入文件,我想用它创建多个输出文件。谢谢你通知我它们是真实的。因为我想将它们存储在同一个数组中。太好了!非常感谢!我只有一个问题。我正在用Fortran 90编写代码。对于你的2003版本,除了seq=[i…],我无法找到如何在F90中对其进行校正。
seq=(/(i,i=1,size(a,2))/)
但我在整个示例中使用的是自动分配,这在Fonrtran 90中不存在。您可能必须在之前使用
分配(seq(1:size(a,2))
来分配数组seq。所有其他可分配数组也都是如此。
program split
  implicit none

  real, allocatable :: a(:, :), b(:, :)
  integer :: i, ids = 10
  integer, allocatable :: id(:), seq(:)

  a = reshape([real :: 1, 5, 1, 7, 0.5, &
                     & 2, 4, 5, 6, 0.1, &
                     & 1, 9, 3, 4, 0.6, &
                     & 2, 8, 7, 2, 0.2], [5, 4])
  seq = [(i, i = 1, size(a, 2))]
  do i = 1, ids
    print*, "i = ", i
    ! here we are creating a vector with all the line indices that start with i
    ! e.g. for i = 1 we get id = [1, 3], for i = 2 we get [2, 4], for i = 3 we get [], ...
    id =  pack(seq, a(1,:) == i)
    ! here we use a Fortran feature named vector-subscript
    b = a(:, id)
    print*, b
  end do
end