2012-03-19 6 views
1

В настоящее время я работаю над калькулятором матрицы fortran. У меня есть компиляция программы, и она работает, за исключением того, что я не получаю правильные результаты. Когда я выбираю функцию добавления, моя программа принимает в двух матрицах и заключается в их объединении. Мой результат кажется неправильным. Например, если я выберу две матрицы размером как 2x2, так и список 1 в качестве каждой записи, я получаю результат добавления 3,3,3. Я не могу понять, где я ошибся в алгоритме. Я еще не проверял другие алгоритмы, поскольку я пытаюсь исправить один алгоритм за раз. Ниже мой кодПомощь алгоритма Fortran - неправильные результаты

*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 
+0

Я изменил запись для СУММЫ (I, J), а также увеличил размер SUM, A, B. Еще не повезло – dtturner12

ответ

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).

+0

Спасибо. Я исправил эту проблему, но я все равно получаю неверный результат. Если я добавлю 1,1, 1,1 + 1,1, 1,1, я получаю ответ от 1; 2; 2; 3 – dtturner12

+0

. У вас точно такая же проблема и на ваших READ-строках, например: 'READ (*, *) A (M, N) '->' READ (*, *) A (J, I) '. Аналогично для чтения в B. – VolatileStorm

1

Вы объявляете SUM, A и B, чтобы быть массивами 1x1, а затем в программе вы ссылаетесь на них за пределами их объявленных границ. Все может случиться.

3

Основная проблема заключается в том, что при чтении матриц вы читаете их неверными индексами. вместо READ(*,*) A(M,N) и READ(*,*) B(M,N), вы должны иметь READ(*,*) A(J,I) и READ(*,*) B(J,I)

В дополнении к этому, вы должны иметь размещаемые массивы вместо декларирования суммы, A и B в качестве размерности (1,1). Я также думаю, что именование массива SUM - это плохая практика, поскольку это то же имя, что и встроенная функция Fortran, поэтому я назвал ее здесь. Объявить их так:

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

затем после того, как вы читаете размеры от пользователя, выполните следующие действия:

allocate(A(m, n)) 

С этими изменениями, я получаю (2,2; 2,2) при добавлении (1,1; 1,1) - (1,1; 1,1).

В общем, я бы также предложил отступывать ваши петли правильно и не использовать все кепки, это делает код намного сложнее читать.

4

Один из способов избежать некоторых ошибок, которые вы сделали, - использовать функции массива Fortran. Можно, например, сумма массивов А и В, если они имеют одинаковый размер, с единственным утверждением:

C = A + B 

Вы также можете использовать встроенные процедуры matmul и transpose для умножения матриц и транспозиции соответственно.

1

Некоторые ошибки, отмеченные в других ответах (например, подзаголовки вне границ), могут быть автоматически захвачены компиляторами, если вы выберете подходящие тесты времени выполнения. Выбор расширенных параметров предупреждения и проверки ошибок компилятора поможет быстрее найти ошибки. Какой компилятор вы используете?

+0

В настоящее время я использую компилятор VAX – dtturner12