Input 用FORTRAN90从TXT文件中读取复数数组和向量
我试图在一个模块中编写一个子程序,我可以将它包含在各种代码中,以便从给定的文件中读取数据。我有几个代码(数值算法)将从文件中读取数据 该文件具有以下格式: 第一项:我的数据数组的行数和列数(例如720) 前n(=720)个条目:矩阵A的整个第一行 第二个n(=720)项:矩阵A的整个第二行 等等 最后n(=720)个条目:向量b的所有n个条目 每个条目有两列,一列表示数字的真实部分,另一列表示复杂部分 总之,一个示例基本输入文件:Input 用FORTRAN90从TXT文件中读取复数数组和向量,input,text-files,fortran90,complex-numbers,Input,Text Files,Fortran90,Complex Numbers,我试图在一个模块中编写一个子程序,我可以将它包含在各种代码中,以便从给定的文件中读取数据。我有几个代码(数值算法)将从文件中读取数据 该文件具有以下格式: 第一项:我的数据数组的行数和列数(例如720) 前n(=720)个条目:矩阵A的整个第一行 第二个n(=720)项:矩阵A的整个第二行 等等 最后n(=720)个条目:向量b的所有n个条目 每个条目有两列,一列表示数字的真实部分,另一列表示复杂部分 总之,一个示例基本输入文件: 2 -0.734192049E+00 0.7114
2
-0.734192049E+00 0.711486186E+01
0.274492957E+00 0.378855374E+01
0.248391205E-01 0.412154039E+01
-0.632557864E+00 0.195397735E+01
0.289619736E+00 0.895562183E+00
-0.284756160E+00 -0.892163111E+00
其中第一个条目表示它是2x2矩阵和2x1向量
前4行是矩阵A的四个条目(左列实数,右列Imag.)
最后两行是向量b的两个条目(左列实数,右列Imag。)
我编写了以下代码来尝试实现这一点,但它只是输出了错误的结果:
n= 2
A= ( 0.0000000 , 1.08420217E-19) (-9.15983229E-16, 3.69024734E+19) ( 1.26116862E-43, 0.0000000 ) ( 0.0000000 , 0.0000000 )
b= ( 0.0000000 , 1.08420217E-19) ( 0.0000000 , 1.08420217E-19)
使用代码:
SUBROUTINE matrix_input(n,A,b)
IMPLICIT NONE
!
INTEGER, INTENT(OUT) ::n !size of matrix to be read
COMPLEX, DIMENSION(:,:), INTENT(OUT), ALLOCATABLE ::A !system matrix to be read
COMPLEX, DIMENSION(:), INTENT(OUT), ALLOCATABLE ::b !RHS b vector to be read
DOUBLE PRECISION ::A_Re,A_Im,b_Re,b_Im !
INTEGER ::i,j
!----------------------------------------------------------
! Subroutine outputs 'n'=size of matrix, 'A'=system matrix
! 'b'= RHS vector
!matrix194.txt
OPEN (UNIT = 24, FILE = "matrix_input_test.txt", STATUS="OLD", FORM="FORMATTED", ACTION="READ")
!Read in size of matrix
READ(24,*) n
ALLOCATE(A(n,n))
ALLOCATE(b(n))
!Read matrix A:
DO i=1,n
DO j=1,n
READ(24,*) A_Re, A_Im
A(i,j)=CMPLX(A_Re,A_Im)
END DO
END DO
!Read RHS vector b:
DO i=((n*n)+1),((n*n)+n)
READ(24,*) b_Re, b_Im
b(i)=CMPLX(b_Re,b_Im)
END DO
CLOSE(UNIT=24)
DEALLOCATE(A,b)
END SUBROUTINE matrix_input
编辑:根据HPC Mark的见解,我编辑了我的代码,这产生了正确的结果,但是,如果有任何命令可能导致以后的问题(例如,我将使用非常大的阵列),我将非常感谢听到这些命令
SUBROUTINE matrix_input(n,A,b)
IMPLICIT NONE
!
INTEGER, INTENT(OUT) ::n !size of matrix to be read
COMPLEX, DIMENSION(:,:), INTENT(OUT), ALLOCATABLE ::A !system matrix to be read
COMPLEX, DIMENSION(:), INTENT(OUT), ALLOCATABLE ::b !RHS b vector to be read
!
COMPLEX, DIMENSION(:), ALLOCATABLE ::temp,A_temp !temp vector of matrix A
DOUBLE PRECISION ::A_Re,A_Im,b_Re,b_Im
INTEGER ::i,j,k
!----------------------------------------------------------
! Subroutine outputs 'n'=size of matrix, 'A'=system matrix
! 'b'= RHS vector
!matrix194.txt
OPEN (UNIT = 24, FILE = "matrix_input_test.txt", STATUS="OLD", FORM="FORMATTED", ACTION="READ")
!Read in size of matrix
READ(24,*) n
!Allocate arrays/vectors
ALLOCATE(A(n,n))
ALLOCATE(b(n))
ALLOCATE(temp(n*n+n))
ALLOCATE(A_temp(n*n))
!Read matrix A & vector b:
!16 characters, 9 decimal places, exponent notation, 2 spaces
DO i=1,(n*n)+n
READ(24, FMT="(E16.9, 2X, E16.9)") A_Re, A_Im
temp(i)=CMPLX(A_Re,A_Im)
END DO
!Select A:
DO i=1,n*n
A_temp(i)=temp(i)
END DO
!Reshape
A=RESHAPE(A_temp, (/n,n/))
!Select b:
k=0
DO i=n*n+1,n*n+n
k=k+1
b(k)=temp(i)
END DO
CLOSE(UNIT=24)
!Do not deallocate A & b otherwise won't return anything properly
DEALLOCATE(temp, A_temp)
END SUBROUTINE matrix_input
编辑代码的结果:
n= 2
A= (-0.73419207 , 7.1148620 ) ( 0.27449295 , 3.7885537 ) ( 0.24839121 , 4.1215405 ) (-0.63255787 , 1.9539773 )
b= ( 0.28961974 , 0.89556217 ) (-0.28475615 ,-0.89216310 )
你的密码把我弄糊涂了<代码>子程序矩阵\u输入声明数组
A
和b
可分配
,具有意图(out)
。就在END子例程
语句之前,您直接执行并取消分配它们。您希望子程序返回调用例程的是什么?您的代码让我感到困惑<代码>子程序矩阵\u输入声明数组A
和b
可分配
,具有意图(out)
。就在END子例程
语句之前,您直接执行并取消分配它们。您希望子程序返回调用例程的是什么?高性能标记已经确定了重要问题,其他一些注意事项
- 更新代码中的格式规范建议数字之间有两个空格。您的示例输入提示一-请注意第二个数字上的(可选)前导符号
和A
是可分配的伪参数。这是一个受广泛支持且非常有用的Fortran 2003特性。你远远超过了Fortran 90!如果这是无意的,那么你需要认真重新设计,否则b
- 超越Fortran 90是件好事-Fortran 95(这是所有当前主流Fortran编译器提供的最低标准支持级别-Fortran 90实际上已经过时)Fortran 2003通过扩展修复了Fortran 90中的一个严重缺陷—自Fortran 95以来,当执行过程的return或end语句时,本地可分配对象将自动解除分配。因此,末尾的deallocate语句是无害的,但却是多余的
- 将每个复数的组成部分读入双精度(注意,现代Fortran使用的一种常见源代码样式倾向于避免使用
类型说明符-它只是双精度
的同义词。然后将它们存储到默认(单精度)复合体中。这是故意的吗?如果是这样,它是无害的,但有点毫无意义/不一致,否则,如果您希望以更高的精度存储输出数组中的实部和虚部,则需要适当地更改复杂数组的声明。可用于实数(种类(0.0D0))
的所有类型必须可用于REAL
,因此您的声明可以是COMPLEX
(通常您将该种类作为命名常量)COMPLEX(种类(0.0D0))
- 在输入输出列表中,复数标量变量表示两个有效项—实部后跟虚部。因此,双精度变量
和A_Re
等有些多余<代码>读取(24,FMT=“(E16.9,2X,E16.9)”)温度(i)是所需的全部A_Im
- 就我个人而言,我不会为其他临时数组操心——一旦知道输入数据的大小(第一行),就将
和A
数组分配到必要的大小,并直接读取它们。在io列表中,数组按数组元素顺序展开为其元素(第一个下标变化最快)-这似乎就是文件的排列方式。您可以将其与所谓的格式反转相结合,以消除循环的需要B
- 从您的子例程返回时,可分配数组“知道”它们的形状-不需要单独返回该信息。同样,无害但多余
! Read A and B in from a file that has... etc, etc...
! Assuming a module procedure, where the module already has IMPLICIT NONE.
SUBROUTINE matrix_input(A, b)
! Number of rows and columns of A, elements of B.
INTEGER :: n
! Our output data.
COMPLEX(KIND(0.0D0)), INTENT(OUT), ALLOCATABLE :: A(:,:), b(:)
! Number of the logical unit for IO. In F2008 this becomes a variable
! and you use the NEWUNIT specifier.
INTEGER, PARAMETER :: unit = 24
! The name of the file to read the data from.
CHARACTER(*), PARAMETER :: filename = "matrix_input_test.txt"
! Format for the array and vector component of the data.
CHARACTER(*), PARAMETER :: fmt = "(E16.9, 1X, E16.9)"
!*****************************************************************************
! Connect to the file for sequential formatted reading.
OPEN(unit, FILE=filename, STATUS='OLD', ACTION='READ')
READ (unit, *) n ! Get array dimension.
ALLOCATE(A(n,n), b(n)) ! Allocate result arrays.
READ (unit, fmt) A ! Read in A.
READ (unit, fmt) b ! Read in B.
CLOSE (unit) ! Clean up.
END SUBROUTINE matrix_input
High Performance Mark已经确定了重要问题,其他一些注意事项
- 更新代码中的格式规范建议数字之间有两个空格。您的示例输入提示一-请注意第二个数字上的(可选)前导符号
和A
是可分配的伪参数。这是一个受广泛支持且非常有用的Fortran 2003特性。你远远超过了Fortran 90!如果这是无意的,那么你需要认真重新设计,否则b
- 超越Fortran 90是一件好事-Fortran 95(这是所有当前主流Fortran编译器提供的最低标准支持级别-Fortran 90实际上已经过时),而Fortran 2003通过扩展修复了Fortran 90中的一个严重缺陷-从Fortran 95 local Allocate开始