【问题标题】:Print lower triangular packed matrix in Fortran 77在 Fortran 77 中打印下三角压缩矩阵
【发布时间】:2017-12-07 05:12:30
【问题描述】:

我有一个实数*8 数字矩阵作为压缩下三角矩阵保存在一个数组中:

|1  *   *   *   *   *|
|2  7   *   *   *   *| 
|3  8  12   *   *   *|
|4  9  13  16   *   *| => [1,2,3,4,5,6,7,8,9...21]
|5 10  14  17  19   *|
|6 11  15  18  20  21|

我希望能够以以下格式打印:

 [row|col]   1  2   3   4   5   
     1       1  *   *   *   *   
     2       2  7   *   *   *   
     3       3  8  12   *   *   
     4       4  9  13  16   *   
     5       5  10 14  17  19   
     6       6  11 15  18  20  

 [row|col]   6  
     1       *  
     2       *  
     3       * 
     4       *  
     5       *   
     6       6  

我的问题是我不知道如何循环进入矩阵元素,而无需创建额外的数组来按列保存元素然后打印它们。这是我迄今为止尝试过的

      Implicit Real*8 (A-H,O-Z)


      INTEGER      ARRAY(21)



      10 Format(5X,'[Row|Col]',5(8X,I6))
      Icol=6
      Num1=1
C     Test array
      DO  K=1,21
      Array(K)=K*1.0d0
      ENDO

C     Print the elements row-by-row.      
44    Num2=Icol-Num1 
      Num=Num2  
      If ((Num2).gt.5) Num=5 
      Write(*,10) (I,I=Num1,Num1+Num)
      INum1=INum1+Num
      if (Inum1.ne.Icol) goto 44       
      STOP 
      END

【问题讨论】:

  • 第 6 列应该与前 5 列分开吗?
  • 是的,我想一次打印 5 列,这样它们就可以毫无问题地适合我的输出。
  • 所有 Fortran 问题请使用fortran 以获得更多关注。还要在你的代码中使用一些缩进以使其可读,并考虑在 2017 年使用一些史前版本的 Fortran。不是 yu 显示的代码有语法错误,如ENDO。您应该显示真实代码 minimal reproducible example.
  • 首先开发一个公式来计算要在矩阵中给定坐标处打印的值在数组中的索引。
  • 我怀疑你真的需要 fortran 77,更有可能你只是使用固定格式的输入。答案(对我来说很好)是 not fortran 77.

标签: matrix printing fortran fortran77 triangular


【解决方案1】:

关键是确定指定下三角矩阵非零元素的公式。如果 i 和 j 分别是行和列的运行索引,则 (j

PROGRAM print_low_tri_matrix
IMPLICIT NONE
INTEGER :: i,j,n,m,p
REAL ,ALLOCATABLE, DIMENSION(:,:) :: a
REAL, ALLOCATABLE, DIMENSION(:) :: r

n = 6
p = n*(n+1)/2   ! Number of non-zero elements in a lower triangular matrix of size n by n

ALLOCATE(a(n,n),r(p))

DO i = 1, p
        r(i) = i*1.0    ! Array containing the non-zero elements
END DO

m = 1          ! Index tracking the non-zero elements array r 
DO j = 1,n
        DO i = 1,n
                IF(j .LE. i) THEN       ! Non-zero indices of the matrix
                        a(i,j) = r(m)
                        m = m + 1
                ELSE
                        a(i,j) = 0.
                END IF
        END DO 
END DO


!       Printing the full matrix a - uncomment for checking 
!         DO i = 1,n
!                         WRITE(*,*) (a(i,j),j=1,n)
!         END DO


!       Printing the matrix a as needed
DO i = 1,n
        DO j = 1,n
                IF(j .LE. i) THEN
                        WRITE(*,'(F12.4)',ADVANCE="NO") a(i,j)
                ELSE
                        WRITE(*,'(A12)',ADVANCE="NO") '*'
                END IF

                IF (j .EQ. n ) WRITE(*,*) 
        END DO
END DO

END PROGRAM print_low_tri_matrix

输出将是:

1.0000           *           *           *           *           *
2.0000      7.0000           *           *           *           *
3.0000      8.0000     12.0000           *           *           *
4.0000      9.0000     13.0000     16.0000           *           *
5.0000     10.0000     14.0000     17.0000     19.0000           *
6.0000     11.0000     15.0000     18.0000     20.0000     21.0000

当然,如果需要,您可以将矩阵更改为整数数组。

P.S :- 要在 f77 中进行这项工作,您可以将格式说明符从 WRITE(*,'(F12.4)',ADVANCE="NO") a(i,j) 更改为 WRITE(*,'(F12.4,$)') a(i,j)。应该直接删除和定义数组的分配。

【讨论】:

  • OP 要求 fortran 77,我怀疑他们是否真的需要。但可能值得注意的是,您的代码不符合 F77。
  • @Ross,是的,你是对的。我忘了把它设为 f77 标准。但我希望OP可以适当地修改它。我将在答案中添加注释。
  • 除了更改write 语句和动态分配以使其(不必要地)与 F77 兼容外,还需要做很多事情。请注意,$ 编辑无论如何都不是 F77。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
相关资源
最近更新 更多