You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran中如何根据文件动态分配维度各异的多个矩阵?

Fortran中创建多个维度不同的矩阵的实现方案

问题背景

假设程序执行时生成如下格式的输出文件:

1  2
2  2
3  1
.
.
.
n 5

文件每行规则:

  • 第i行的第二个数值表示第i个矩阵的第一维大小,结合已知的k,该矩阵的形状为(第二列数值, k)(例如第一行对应矩阵A(2,k),最后一行对应矩阵S(5,k))。

当所有矩阵的第一维大小相同时,可通过三维数组统一分配存储:

real, allocatable :: mymat(:,:,:)
allocate(mymat(n, 统一维度值, k))

但当前每个矩阵的第一维大小各不相同,需要创建n个独立维度的矩阵,具体实现方法如下:

实现方法:使用派生类型存储可分配数组

Fortran 2003及以后标准支持数组的数组(Array of Arrays),通过派生类型可轻松实现每个元素为独立可分配的二维矩阵。

步骤1:定义派生类型

先定义包含可分配二维数组的派生类型,用于存储单个矩阵:

type :: matrix_type
    real, allocatable :: data(:,:)  ! 存储单个矩阵的二维数组
end type matrix_type

步骤2:创建派生类型数组并分配内存

  1. 读取文件中所有第一维大小,存储到数组dim1_array(:)中(假设已完成读取);
  2. 分配派生类型数组的大小为n,对应n个矩阵;
  3. 循环为每个矩阵分配对应大小的内存:
type(matrix_type), allocatable :: mat_list(:)
integer, allocatable :: dim1_array(:)
integer :: i, n, k

! 假设已获取n和k的值,且dim1_array已读取完成(大小为n)
allocate(mat_list(n))

do i = 1, n
    ! 为第i个矩阵分配形状为(dim1_array(i), k)的内存
    allocate(mat_list(i)%data(dim1_array(i), k))
end do

步骤3:使用矩阵

分配完成后,可像普通二维数组一样访问每个矩阵的元素:

! 示例:给第3个矩阵的(1,2)位置赋值
mat_list(3)%data(1, 2) = 3.14

! 示例:遍历第i个矩阵的所有元素
do row = 1, size(mat_list(i)%data, 1)
    do col = 1, k
        print *, mat_list(i)%data(row, col)
    end do
end do

步骤4:释放内存

使用完成后,需逐个释放每个矩阵的内存,再释放派生类型数组:

do i = 1, n
    if (allocated(mat_list(i)%data)) then
        deallocate(mat_list(i)%data)
    end if
end do
deallocate(mat_list)

替代方案:使用指针数组

如果偏好指针操作,也可以用指针数组实现,需注意指针的关联和释放:

type :: ptr_mat
    real, pointer :: p(:,:)
end type ptr_mat

type(ptr_mat), allocatable :: mat_ptrs(:)
allocate(mat_ptrs(n))

do i = 1, n
    allocate(mat_ptrs(i)%p(dim1_array(i), k))
end do

! 使用方式类似:mat_ptrs(i)%p(row, col) = ...

! 释放内存
do i = 1, n
    if (associated(mat_ptrs(i)%p)) then
        deallocate(mat_ptrs(i)%p)
        nullify(mat_ptrs(i)%p)
    end if
end do
deallocate(mat_ptrs)

内容的提问来源于stack exchange,提问作者geom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:20:40