Arrays 用Fortran语言将矩阵分解成子矩阵
假设我有一个二维数组,第一列仅由两个整数1和2组成: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 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