【问题标题】:issues with Fortran function reshapeFortran 函数重塑的问题
【发布时间】:2021-03-08 19:51:05
【问题描述】:

我正在使用代码块和 gnu 编译器来运行 Fortran 代码,但我注意到一些非常奇怪的东西。 一旦我有一个数组(1,2,3,...,16),如果我想重塑为一个4x4矩阵,我会使用内置的reshape函数,理论上它应该对数字使用列优先顺序,所以给(1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16); 相反,我得到(1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16)。 这是一个主要的不一致,我想知道它是否与使用代码块或什么有关。 遇到此问题和/或知道原因和解决方案的任何其他人。

【问题讨论】:

  • Fortran 使用列优先排序。因此 reshape 会产生数组(1 5 9 13; ...。请向我们展示您的代码,然后我们可以更好地争论。
  • 请显示您的代码并使用代码格式以获得更好的可读性,
  • 非常感谢,我没有发布代码,因为它非常基础。下次我一定会做的。

标签: fortran codeblocks reshape


【解决方案1】:

我无法用Intel Fortran oneAPI HPC 复制问题

及参考代码

program FortranConsole1
use, intrinsic :: iso_fortran_env
implicit none

interface show
    procedure show_matrix_i, show_matrix_r, show_matrix_d
end interface

integer :: row(16), matrix(4,4)
real(real64) :: A(4,4)

row = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]    
matrix = reshape( row, [4, 4])
       
call show(matrix)

A = dble(matrix)

A = sqrt( matmul( transpose(A), A) )

call show(A, 8)
call show(A, 12)
call show(A, 16)

contains

subroutine show_matrix_i(A, w)
! Display the matrix 'A' in columns
!   A : the array of integers
!   w : the column width. Default = 5
    integer, intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    integer :: i,j,n,m, wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 5
    end if
    n = size(A,1)
    m = size(A,2)
    write( fmt, "(a,g0,a)") "(*(g",wt,".0))"        
    write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine

subroutine show_matrix_r(A, w)
! Display the matrix 'A' in columns
!   A : the array of real numbers
!   w : the column width. deafult = 12
!   s : sig. figures w-5 (calculated)
    real(real32), intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    integer :: i,j,n,m,dg,wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 12
    end if
    dg = wt-5
    n = size(A,1)
    m = size(A,2)
    write( fmt, "(a,g0,a,g0,a)") "(*(g",wt,".",dg,"))"
    write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine

subroutine show_matrix_d(A,w)
! Display the matrix 'A' in columns
!   A : the array of dble numbers
!   w : the column width. default = 12
! Converts 'A' into single precision and calls `show_matrix_r`
    real(real64), intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    call show_matrix_r(real(A),w)
end subroutine

end program FortranConsole1

有结果

【讨论】:

  • 非常感谢。我睡着了,又试了一次,现在一切正常,它应该是这样的,而且它一直是这样的。也许昨天我在暗示(我或代码块!我不知道该怎么想。非常感谢您提供并澄清解决方案。您是否碰巧知道一种更快的方法来打印矩阵而无需多次使用例如打印语句?
  • @DomenicoBianchi - 很高兴众神再次对齐。至于显示矩阵,可能有一种隐含的 do 循环的方法,但我真的不擅长使用 Fortran 进行文本格式化。通常,我在程序 contains 关键字下有几个函数,通用名称为 show,用于处理列中向量和矩阵的显示等。
  • @DomenicoBianchi - 我在答案中添加了一些格式代码,可以减轻您在显示整数、实数或双精度矩阵时的痛苦。
  • 谢谢!我阅读了您提供的链接并研究了您的代码,我喜欢它,我非常感谢您的努力。非常感谢。
猜你喜欢
  • 2021-01-08
  • 2013-11-30
  • 2017-01-13
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
  • 2016-01-08
相关资源
最近更新 更多