如何在Fortran中初始化大数组?

亨宁克

我有一个Fortran函数,我想在编译时初始化一个大数组。下面是一个简化的工作示例,其中coeffin的参数fill_coefficients已大大减小。

如何在coeff不超过255个连续行每行最多132个字符的情况下编写类似的代码fill_coefficients实际上应该是PURE,这可能使得它coeff在运行时无法一次读取文件,然后存储结果。

文件“ main.f03”:

    PROGRAM main
        USE coefficients
        IMPLICIT NONE

        REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: matrix

        CALL fill_coefficients(matrix,2)

        PRINT *, "The first row of 'matrix':"
        PRINT *, matrix(1,:)
    END PROGRAM main

文件“ coefficients.f03”:

    MODULE coefficients
        USE iso_fortran_env
        IMPLICIT NONE

        INTEGER, PARAMETER :: dp = REAL64

    CONTAINS
        PURE SUBROUTINE fill_coefficients(my_coefficients, n)
            IMPLICIT NONE
            REAL(dp), ALLOCATABLE, DIMENSION(:,:), INTENT(OUT) :: my_coefficients
            INTEGER, INTENT(IN) :: n

            ! The size of the following array would be roughly 200 x 200 = 40.000.
            REAL(dp), DIMENSION(3,3), PARAMETER :: coeff = &
                RESHAPE ( &
                [ + 10.6770782520313112108115239655957106_dp, &
                - 854.166260162504896864921917247656850_dp, &
                - 85.4166260162504896864921917247656850_dp, &
                + 16250.5130995916556628551394756366716_dp, &
                + 6747.91345528378868523288314625648912_dp, &
                + 106.770782520313112108115239655957106_dp, &
                - 123256.191341449456617608232658836883_dp, &
                - 8328.12103658442274443298869316465429_dp, &
                + 500381.272281447399894682070647642979_dp ], &
                [3,3] )

            IF (ALLOCATED(my_coefficients)) DEALLOCATE(my_coefficients)
            ALLOCATE(my_coefficients(n,n))

            my_coefficients = coeff(1:n,1:n)
        END SUBROUTINE fill_coefficients
    END MODULE coefficients

输出:

The first row of 'matrix': 10.677078252031311 16250.513099591655

伊恩

从维护的角度(也许是在注释中建议的),我会将数据读入一个单独的非纯子例程的模块变量中,该例程在程序启动时被调用一次。fill_coefficients然后成为该模块变量的简单赋值,并且仍然可以是PURE。

MODULE coefficients
  IMPLICIT NONE
  ...
  ! Could be PUBLIC, PROTECTED, then you could directly 
  ! assign from it and dispense with fill_coefficients 
  ! altogether.
  REAL(dp), PRIVATE :: coeff(200,200)
CONTAINS
  SUBROUTINE init
    INTEGER :: unit 
    OPEN( NEWUNIT=unit,  &
          FILE='lots-of-numbers.bin',  &
          FORM='UNFORMATTED',  &
!         ACCESS='STREAM',  &    ! Maybe - depending on how you write it.
          STATUS='OLD' )
    READ (unit) coeff
    CLOSE(unit)
  END SUBROUTINE init

  PURE SUBROUTINE fill_coefficients(my_coefficients, n)
    ! implicit none already in force due to the statement in 
    ! the specification part of the host module.
    ! IMPLICIT NONE    
    REAL(dp), ALLOCATABLE, DIMENSION(:,:), INTENT(OUT) :: my_coefficients
    INTEGER, INTENT(IN) :: n

    ! This test is redundant - my_coefficients is INTENT(OUT) so 
    ! it must be not allocated at this point.
    ! IF (ALLOCATED(my_coefficients)) DEALLOCATE(my_coefficients)

    ! This allocate statement is redundant - allocation will 
    ! happen automatically under F2003 with the assignment.
    ! ALLOCATE(my_coefficients(n,n))

    my_coefficients = coeff(1:n,1:n)
  END SUBROUTINE fill_coefficients
END MODULE coefficients

如果必须将其coeff作为编译时参数,则将其组装为源代码可管理的块-也许逐列。每个声明的限制是行长(132)和连续行数(255)。

REAL(dp), PARAMETER :: column_1(200) = [  &
     + 10.6770782520313112108115239655957106_dp, &
     - 854.166260162504896864921917247656850_dp, &
     - 85.4166260162504896864921917247656850_dp, &
     ... ]
REAL(dp), PARAMETER :: column_2(200) = [ ... ]
...
REAL(dp), PARAMETER :: column_200(200) = [ ... ]

REAL(dp), PARAMETER :: coeff(200,200) = RESHAPE( [  &
       column_1, column_2, ..., column_200 ],  &
     SHAPE=[200,200] )

用PARAMETER声明的事物称为常量。从概念上讲,它们仅在编译时存在-取决于您对命名常量所做的操作,编译器可能会或可能不会在可执行映像中为常量预留存储空间。

大的命名常量可能会导致编译器在编译文件时遇到问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在结构中初始化此数组数组?

来自分类Dev

如何在BCPL中初始化数组的数组?

来自分类Dev

如何在结构中初始化此数组数组?

来自分类Dev

如何在Ruby中初始化类数组

来自分类Dev

如何在Kotlin中初始化注释的数组属性

来自分类Dev

如何在Verilog中初始化参数数组

来自分类Dev

如何在Android中初始化位图数组?

来自分类Dev

如何在Swift中声明和初始化数组

来自分类Dev

如何在JavaScript中初始化布尔数组

来自分类Dev

如何在结构中初始化静态数组

来自分类Dev

如何在结构中初始化数组

来自分类Dev

如何在Kotlin中初始化按钮数组

来自分类Dev

如何在MIPS组件中初始化庞大的数组?

来自分类Dev

如何在Verilog中初始化参数数组?

来自分类Dev

如何在C中初始化未知大小的数组

来自分类Dev

如何在默认构造函数中初始化数组?

来自分类Dev

如何在Kotlin中初始化注释的数组属性

来自分类Dev

如何在Ruby中初始化类数组

来自分类Dev

如何在Eiffel中初始化数组

来自分类Dev

如何在 C 编程中初始化多维数组

来自分类Dev

如何在 Java 中静态初始化对象数组

来自分类Dev

Fortran中的随机数组/矩阵初始化

来自分类Dev

Cuda-大数组初始化

来自分类Dev

如何在引用数组之前初始化数组

来自分类Dev

如何在Swift中初始化包含枚举数组的结构数组?

来自分类Dev

在fortran 95中初始化向量

来自分类Dev

如何在C中的4维数组中声明和初始化

来自分类Dev

如何在React中的无状态函数组件中初始化类实例?

来自分类Dev

如何在header中声明数组并在cpp中初始化