1

行列計算プログラムを持っていますが、内積乗数の答えが間違っています。

これが私の乗算サブルーチンです。

subroutine multiply(m1,m2,res,row1,row2,col1,col2)
    integer, intent(in) :: row1,row2,col1,col2
    real, intent(in), dimension(row1,col1) :: m1
    real, intent(in), dimension(row2,col2) :: m2
    real, intent(out), dimension(row1,col2) :: res

    integer :: i,j,k

    do i = 1, col2
        do j = 1, col1
            res(j, i) = 0
        enddo
        do j = 1, col1
            do k = 1, row1
                res(k, i) = res(k, i) + m1(k, j)*m2(j, i)
            enddo
        enddo
    enddo

そして、これが問題の場合に備えて、私の出力です。

        subroutine output(r,c,matrix,name)
            integer, intent(in) :: r
            integer, intent(in):: c
            character(len=10) :: name
            real, intent(out), dimension(3,3) :: matrix


            integer i,j

            print *,name
            do i = 1, r
                    write(*,"(100F6.1)") ( matrix(i,j), j=1,c )
            enddo
        end subroutine

それが役立つ場合、3x3 マトリックスではうまく機能しますが、2 つの長方形マトリックスでは機能しません。2x3 * 3x2 行列を実行すると、次のようになります。この時点で、私は助けを切望しています。あなたが提案できるものは何でも素晴らしいでしょう。ありがとう!

ここに画像の説明を入力

編集:これが、現在の状態の私のコードとあなたの提案のすべてです。

        PROGRAM G6P5
        integer :: r1,r2,c1,c2,i,j,k,s
        real :: input
        real, dimension (3,3) :: mat1, mat2, rmat
        write (*,*) 'Please make a selection:'
        write (*,*) 'Enter 1 to add matrices'
        write (*,*) 'Enter 2 to subtract matrices'
        write (*,*) 'Enter 3 to multiply matrices'
        write (*,*) 'Enter 4 to transpose a matrix'
        write (*,*) 'Enter 5 to quit'
        read *, s
        select case (s)
            case (1)
                print *, 'Enter # of rows & columns (1-10) (ex. 3 3 = 3x3)'
                read *, r1,c1
              print *, 'Matrix 1:'
                call fillmatrix(r1,c1,mat1)
                r2 = r1
                c2 = c1
                print *, 'Matrix 2:'
                call fillmatrix(r2,c2,mat2)
                call output(r1,c1,mat1,'Matrix 1: ')
                call output(r2,c2,mat2,'Matrix 2: ')
                rmat = mat1+mat2
                call output(r1,c1,rmat,'Sum:      ')
            case (2)
                print *, 'Enter # of rows & columns (1-10) (ex. 3 3 = 3x3)'
                read *, r1,c1
              print *, 'Matrix 1:'
                call fillmatrix(r1,c1,mat1)
                r2 = r1
                c2 = c1
                print *, 'Matrix 2:'
                call fillmatrix(r2,c2,mat2)
                rmat = mat1-mat2
                call output(r1,c1,mat1,'Matrix 1: ')
                call output(r2,c2,mat2,'Matrix 2: ')
                call output(r1,c1,rmat,'Sum:      ')
            case (3)
                print *, 'Enter # of rows & columns for matrix 1'
                print *, '(1 through 10, ex: 3 3 = 3x3)'
                read *, r1,c1
              print *, 'Matrix 1:'
                call fillmatrix(r1,c1,mat1)
                print *, 'Enter # of rows & columns for matrix 2'
                print *, '(1 through 10, ex: 3 3 = 3x3)'
                read *, r2,c2
              print *, 'Matrix 2:'
                call fillmatrix(r2,c2,mat2)
                if (c1.eq.r2) then
                    call multiply(mat1,mat2,rmat,r1,r2,c1,c2)
                    call output(r1,c1,mat1,'Matrix 1: ')
                    call output(r2,c2,mat2,'Matrix 2: ')
                    call output(r1,c2,rmat,'Product:  ')
                end if
            case (4)
                print *, 'Enter # of rows & columns for matrix 1'
                print *, '(1 through 10, ex: 3 3 = 3x3)'
                read *, r1,c1
              print *, 'Matrix 1:'
                call fillmatrix(r1,c1,mat1)
                call transpose(mat1,rmat,r1,c1)
                call output(r1,c1,rmat,'Transpose:')
            case (5)
                print *,'5'
            case default
                print *,'default'
        end select
        !       call fillmatrix(rows,columns,mat1)
        !       write (*,*) matrix1
        END PROGRAM




        subroutine fillmatrix(r,c,matrix)
            integer, intent(in) :: r
            integer, intent(in):: c
            real, intent(out), dimension(3,3) :: matrix

            integer i,j

            do i=1,r
                do j = 1,c
                    write (*,'(A,I2,A,I2,A)') 'Enter value (',i,',',j,').'
                    read*, matrix(i,j)
                enddo
            enddo
        end subroutine


        subroutine multiply(m1,m2,res,row1,row2,col1,col2)
            integer, intent(in) :: row1,row2,col1,col2
            real, intent(in), dimension(row1,col1) :: m1
            real, intent(in), dimension(row2,col2) :: m2
            real, intent(out), dimension(row1,col2) :: res

            integer :: i,j,k

            res = 0
            do i = 1, row1
                 do j = 1, col2
                      do k = 1, col1   ! col1 must equal row2
                         res(i, j) = res(i, j) + m1(i, k)*m2(k, j)
                      enddo   ! k
                    enddo  ! j
            enddo  ! i


        end subroutine


        subroutine transpose(m1,res,row,col)
            integer, intent(in) :: row,col
            real, intent(in), dimension(row,col) :: m1
            real, intent(out), dimension(row,col) :: res

            integer :: i,j,k
            do i = 1,col
                do j = 1,row
                    res(i,j) = m1(j,i)
                enddo
            enddo
        end subroutine



        subroutine output(r,c,matrix,name)
            integer, intent(in) :: r
            integer, intent(in):: c
            character(len=10) :: name
            real, intent(in), dimension(r,c) :: matrix


            integer i,j

            print *,name
            do i = 1, r
                    write(*,"(100F6.1)") ( matrix(i,j), j=1,c )
            enddo
        end subroutine
4

1 に答える 1

2

索引付けが少し混乱しているようです。これを試して。

res = 0
do i = 1, col2
    do j = 1, row1
        do k = 1, col1
            res(j, i) = res(j, i) + m1(j, k)*m2(k, i)
        enddo
    enddo
enddo

outputまた、あなたのルーチンには次の行があることに気付きました

real, intent(out), dimension(3,3) :: matrix

matrixこのルーチンに送信する場合は、 intent(in). また、2x2 マトリックスを印刷している場合は、これdimension(3,3)も正しくありません。この行を次のように変更する必要があります

real, intent(in) :: matrix(r,c)

あなたが考えるかもしれない最後の1つのこと。マトリックスは常に 3x3 ですが、常にすべての要素を使用しているわけではありません。そのため、行数と列数をサブルーチンに渡します。ここでの問題は、行列の実際のサイズがこれらの数値と一致する必要があることです。これを行うには、スライス表記を使用する必要があります。

それ以外の

call sub(2,2,mat)

使用する

call sub(2,2,mat(1:2,1:2))

これは、最初の方法が本質的に同等であるためです。

call sub(2,2,mat(1:3,1:3))

これにより、サブルーチンに渡すものとサブルーチンが期待するものとの間に不一致が生じます。ご覧のとおり、これによりおかしなことが起こる可能性があります。

于 2013-10-10T01:16:41.687 に答える