我有一个矩阵计算器程序,但我的点积乘数得到了错误的答案。
这是我的乘法子程序:
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矩阵,但不适用于两个矩形矩阵。这是我做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
答案 0 :(得分: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)
你可能会考虑的最后一件事。您的矩阵总是3x3,但您并不总是使用所有元素。这就是您将行数和列数传递给子例程的原因。这里的问题是矩阵的实际大小需要匹配这些数字。为此,您需要使用切片表示法。
而不是
call sub(2,2,mat)
使用
call sub(2,2,mat(1:2,1:2))
这是因为第一种方法基本上等同于
call sub(2,2,mat(1:3,1:3))
这将导致您传递给子例程的内容与子例程所期望的内容不匹配。正如你所看到的,这可能会导致有趣的事情发生。