翻转矩阵 fortran
Flip a matrix fortran
我想将我的矩阵上下翻转。这样 T(1,1)=C(2,1)
我制作了这个程序,我发现了一个应该在线执行该程序的代码 C=T(2:1:-1, :)
但是当尝试获取应该为 3 的值 C(1,1) 时,我得到 1.3533635457363350 E-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
您正在分配 3 x 3 数组(索引范围 0 - 2,含)。您仅将值分配给数组 T
的九个元素中的四个,然后将该数组的 2 x 3 切片分配给 C
。这是无效的,因为赋值运算符右侧的数组表达式与左侧的形状不同。
此外,您选择要写入的数组元素掩盖了对所涉及数组维度的持续混淆。如果分配 T
维度为 0:2, 0:2 然后垂直翻转,则 T(2,2)
对应的结果元素将是 C(0,2)
.
有几种可能的方法来更正代码。其中比较有可能的是:
如果您想继续使用现在使用的维度,则翻转数组的表达式将为 T(2:0:-1, :)
.
如果您想要索引范围为 1 - 2(含)的 2 x 2 数组,这与 C=T(2:1:-1, :)
一致,则适当地分配数组(例如 allocate(T(2, 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 开始计数。为了安全起见,始终在 lbound
和 ubound
内在函数的帮助下遍历数组,而不是像上面那样使用显式边界:
do i = lbound(t, dim=1), ubound(t, dim=1)
write (*, *) t(i, :)
end do
我想将我的矩阵上下翻转。这样 T(1,1)=C(2,1)
我制作了这个程序,我发现了一个应该在线执行该程序的代码 C=T(2:1:-1, :)
但是当尝试获取应该为 3 的值 C(1,1) 时,我得到 1.3533635457363350 E-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
您正在分配 3 x 3 数组(索引范围 0 - 2,含)。您仅将值分配给数组 T
的九个元素中的四个,然后将该数组的 2 x 3 切片分配给 C
。这是无效的,因为赋值运算符右侧的数组表达式与左侧的形状不同。
此外,您选择要写入的数组元素掩盖了对所涉及数组维度的持续混淆。如果分配 T
维度为 0:2, 0:2 然后垂直翻转,则 T(2,2)
对应的结果元素将是 C(0,2)
.
有几种可能的方法来更正代码。其中比较有可能的是:
如果您想继续使用现在使用的维度,则翻转数组的表达式将为
T(2:0:-1, :)
.如果您想要索引范围为 1 - 2(含)的 2 x 2 数组,这与
C=T(2:1:-1, :)
一致,则适当地分配数组(例如allocate(T(2, 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 开始计数。为了安全起见,始终在 lbound
和 ubound
内在函数的帮助下遍历数组,而不是像上面那样使用显式边界:
do i = lbound(t, dim=1), ubound(t, dim=1)
write (*, *) t(i, :)
end do