Fortran算法帮助 - 获得错误的结果

时间:2012-03-19 01:33:17

标签: algorithm matrix fortran fortran90 matrix-multiplication

我目前正在研究fortran矩阵计算器。我有程序编译,它似乎工作,但我没有收到正确的结果。当我选择添加功能时,我的程序接受两个矩阵,并将它们加在一起。我的结果似乎出错了。例如,如果我选择两个大小为2x2和列表1的矩阵作为每个条目,我会收到3,3,3的加法结果。我无法弄清楚算法在哪里出错了。我还没有检查其他算法,因为我试图一次修复一个算法。以下是我的代码

  *START PROGRAM
  PROGRAM MAIN

  *DECLARATIONS
  INTEGER SELECTION, DONE, VALID, J, I, K, M, N
  INTEGER, DIMENSION(10,10):: SUM, A, B

  *INTITIALIZE
  M = 0
  N = 0
  J = 0
  I = 0
  K = 0
  DONE = 1
  VALID = 1

  *LOOP UNTIL USER CHOOSES TO QUIT

  DO WHILE(DONE .GT. 0)

  *DISPLAY MENU UNTIL VALID ENTRY IS ENTERED

  DO WHILE (VALID .GT. 0)
  *PRINT MENU
  PRINT *,'MATRIX CALCULATOR'
  PRINT *,'PLEASE MAKE A SELECTION'
  PRINT *,'1) MATRIX ADDITION'
  PRINT *,'2) MATRIX SUBTRACTION'
  PRINT *,'3) MATRIX MULTIPLICATION'
  PRINT *,'4) MATRIX TRANSPOSE'
  PRINT *,'5) QUIT PROGRAM'
  READ (*,*) SELECTION

  *VALID ENTRY CHECK
  IF (SELECTION .GT. 5 .OR. SELECTION .LT. 1) THEN
  PRINT *,'PLEASE ENTER A VALID SELECTION'
  ELSE 
  VALID= -1
  END IF

  *END WHEN VALID ENTRY IS ENTERED
  END DO

  *QUIT?
  IF (SELECTION .EQ. 5) THEN
  DONE = -1
  ELSE
  *OTHERWISE CONTINUE
  *GET DIMENTIONS INPUT 
  PRINT *,'PLEASE ENTER THE DIMENTIONS'
  PRINT *,'ENTER IN M:'
  READ (*,*) M
  PRINT *,'ENTER IN N:'
  READ (*,*) N
  *GET IN MATRIX
  PRINT *, 'PLEASE ENTER IN MATRIX A'
  DO J=1, M
  DO I=1, N
  PRINT *, 'ENTER IN VALUE I, I', J, I
  READ(*,*) A(M,N)
  END DO
  END DO

  PRINT *, 'PLEASE ENTER IN MATRIX B'
  DO J=1, M
  DO I=1, N
  PRINT *, 'ENTER IN VALUE I, I', J,I
  READ(*,*) B(M,N)
  END DO
  END DO

  *PERFORM DESIRED CALCULATION
  SELECT CASE(SELECTION)
  *CASE 1
  CASE (1)
   PRINT *,'MATRIX ADDITION'
   DO J=1,M
   DO I=1,N
   SUM(J,I)=A(J,I)+B(J,I)
   END DO   
   END DO

  *PRINT ADDITION RESULT
   PRINT *,'ADDITION RESULT'
   DO J=1, M
   DO I=1, N
   WRITE (*,*) SUM(J,I)
   END DO
   END DO
  *CASE 2
  CASE (2)
   PRINT *,'MATRIX SUBTRACTION'
   DO J=1,M
   DO I=1,N
   SUM(J,I)=A(J,I)-B(J,I)
   END DO   
   END DO

  *PRINT SUBTRACTION RESULT
   PRINT *,'SUBTRACTION RESULT'
   DO J=1, M
   DO I=1, N
   WRITE (*,*) SUM(J,I)
   END DO
   END DO
  *CASE 3
  CASE (3)
   PRINT *,'MATRIX MULTIPLICATION'
   DO J=1, M
   DO I=1, N
   DO K=1, N
   SUM(J,I) = SUM(J,I)+A(J,K)*B(I,J)
   END DO
   END DO
   END DO

  *PRINT MULTIPLICATION RESULT
   DO J=1, M
   DO I=1, N
   WRITE (*,*) SUM(J,I)
   END DO
   END DO
  *CASE 4
  CASE (4)
   PRINT *,'MATRIX TRANSPOSE'
   DO J=1, M
   DO I=1, N
   B(I,J) = A(J,I)
   END DO
   END DO
  *PRINT TRANSPOSE RESULT
   PRINT *, 'MATRIX A RESULT'
   DO J=1, M
   DO I=1, N
   WRITE (*,*) A(J,I)
   END DO
   END DO
   PRINT *, 'MATRIX B RESULT'
   DO J=1, M
   DO I=1, N
   WRITE (*,*) B(J,I)
   END DO
   END DO
  CASE DEFAULT
   PRINT *,'SOMETHING HAS GONE WRONG'
  END SELECT

  *USER SELECTED TO QUIT
  END IF
  END DO
  PRINT *, 'PROGRAM HAS ENDED'
  *END PROGRAM
  STOP
  END

5 个答案:

答案 0 :(得分:4)

避免一些错误的一种方法是使用Fortran的数组函数。例如,您可以使用单个语句对数组A和B进行求和,如果它们具有相同的大小:

C = A + B

您也可以分别使用内在程序matmultranspose进行矩阵乘法和转置。

答案 1 :(得分:3)

主要问题是,在读取矩阵时,您正在读取错误的索引。而不是READ(*,*) A(M,N)READ(*,*) B(M,N),您应该READ(*,*) A(J,I)READ(*,*) B(J,I)

除此之外,您还需要具有可分配的数组,而不是将sum,A和B声明为dimension(1,1)。我也认为命名数组SUM是不好的做法,因为它与Fortran内部函数同名,所以我在这里称它为C.声明他们是这样的:

integer, allocatable, dimension(:,:) :: A, B, C

然后在您阅读用户的尺寸后,请执行以下操作:

allocate(A(m, n))

通过这些更改,我将(1,1; 1,1)添加到(1,1; 1,1)时得到(2,2; 2,2)。

一般来说,我还建议正确缩进你的循环而不是全部大写,这会使代码更难阅读。

答案 2 :(得分:1)

这是问题所在:

  *PRINT ADDITION RESULT
   PRINT *,'ADDITION RESULT'
   DO J=1, M
   DO I=1, N
   WRITE (*,*) SUM(N,M)
   END DO
   END DO

你应该有WRITE (*,*) SUM(J,I)

答案 3 :(得分:1)

您将SUMAB声明为1x1数组,然后在程序中将它们引用到声明的边界之外。任何事情都可能发生。

答案 4 :(得分:1)

如果选择适当的运行时测试,则其他答案中注明的一些错误(例如,越界下标)可以自动被编译器捕获。选择编译器的广泛警告和错误检查选项将帮助您更快地发现错误。你使用的是哪个编译器?