翻转矩阵fortran

时间:2016-10-28 20:45:31

标签: matrix fortran fortran90 gfortran

我想将我的矩阵向上翻转。这样T(1,1)= C(2,1)

我已经制作了这个程序,我找到了一个应该在线进行的代码C=T(2:1:-1, :)但是当试图获得应该为3的值C(1,1)时,我得到1.3533635457363350E- 306。你怎么翻转一个矩阵使得向上变暗?

program main


implicit none
  integer iMax, jMax
  double precision, dimension(:,:), allocatable :: T,C

double precision x, dx,f,L2old,L2norm

integer i, j,n


 allocate(T(0:2, 0:2))
 allocate(C(0:2, 0:2))


T(1,1)=1
T(1,2)=2
T(2,1)=3
T(2,2)=4

write(*,*) T(2,2)

C=T(2:1:-1, :)

Write(*,*) C(1,2)


end program main

2 个答案:

答案 0 :(得分:2)

您正在分配3 x 3阵列(索引范围0 - 2,包括0和2)。您只将值分配给数组T的九个元素中的四个,然后将该数组的2 x 3切片分配给C。这是无效的,因为赋值运算符右侧的数组表达式与左侧的数组表达式不同。

此外,您选择要编写的数组元素仍然会引起对所涉及数组维度的混淆。如果您将T分配为维度0:2,0:2然后垂直翻转,则与T(2,2)对应的结果元素将为C(0,2)

有几种方法可以纠正代码。其中更有可能:

  • 如果您想继续使用当前使用的尺寸,则翻转数组的表达式为T(2:0:-1, :)

  • 如果您希望2 x 2数组的索引范围为1 - 2(包括1和2),与C=T(2:1:-1, :)一致,则适当地分配数组(例如allocate(T(2, 2)))。

答案 1 :(得分:2)

如果您分配了正确大小的矩阵,那么一切都应该按预期工作。

例如,这个程序

program main
  implicit none

  double precision, dimension(:, :), allocatable :: t, c
  integer :: i

  allocate (t(1:2, 1:2))
  allocate (c(1:2, 1:2))

  t = reshape([1, 3, 2, 4], shape(t))
  do i = 1, 2
    write (*, *) t(i, :)
  end do
  write (*, *) ""

  c = t(2:1:-1, :)
  do i = 1, 2
    write (*, *) c(i, :)
  end do
end program main

产生以下输出

   1.0000000000000000        2.0000000000000000
   3.0000000000000000        4.0000000000000000

   3.0000000000000000        4.0000000000000000
   1.0000000000000000        2.0000000000000000

或者,如果你确实想使用3x3矩阵,那么错误就在行C=T(2:1:-1, :)中。它应该是C=T(2:0:-1, :)

program main
  implicit none

  double precision, dimension(:, :), allocatable :: t, c
  integer :: i

  allocate (t(0:2, 0:2))
  allocate (c(0:2, 0:2))

  t = reshape([1, 4, 7, 2, 5, 8, 3, 6, 9], shape(t))
  do i = 0, 2
    write (*, *) t(i, :)
  end do
  write (*, *) ""

  c = t(2:0:-1, :)
  do i = 0, 2
    write (*, *) c(i, :)
  end do
end program main

输出:

   1.0000000000000000        2.0000000000000000        3.0000000000000000
   4.0000000000000000        5.0000000000000000        6.0000000000000000
   7.0000000000000000        8.0000000000000000        9.0000000000000000

   7.0000000000000000        8.0000000000000000        9.0000000000000000
   4.0000000000000000        5.0000000000000000        6.0000000000000000
   1.0000000000000000        2.0000000000000000        3.0000000000000000

小心计算数组的元素。 Off-by-one errors可能很难调试,因此最好始终从0开始计数或始终从1开始计数。为了安全起见,总是在lboundubound内在函数的帮助下遍历数组,而不是像上面那样使用显式边界:

  do i = lbound(t, dim=1), ubound(t, dim=1)
    write (*, *) t(i, :)
  end do