Reputation: 123
I have the algorithm to order a Vector l(i)
with components in increasing order, and also I generated a vector order D(i)
, which tells me where each component comes from, so then I can go back to the original (disordered) vector.
The order and the order vector are fine, the problem occurs when I want to go back to the original. For some reason it doesn't work, it repeats components of the vector and not in a specific order. I don't realize what it is.
Here is the code:
program order
implicit none
integer i,j,k,q
integer l(7),D(7)
real x
do i=1,7
call random_number (x)
l(i)=1+FLOOR(13*x)
enddo
Write(*,*) "Without order"
do i=1,7
Write(*,*) l(i)
enddo
do i=1,7
D(i)=i
enddo
do i=1,6
do j=i+1,7
if(l(i).gt.l(j))then
k=l(i)
l(i)=l(j)
l(j)=k
q=D(i)
D(i)=D(j)
D(j)=q
endif
enddo
enddo
Write(*,*) "Ordered"
do i=1,7
Write(*,*) l(i)
enddo
Write(*,*) "Order vector"
do i=1,7
Write(*,*) D(i)
enddo
do i=1,7
l(D(i))=l(i)
enddo
Write(*,*) "The original vector is"
do i=1,7
Write(*,*) l(i)
enddo
endprogram order
Upvotes: 1
Views: 187
Reputation: 2981
As @albert points out, because your l(D(i))=l(i)
loop overwrites l
in-place, you are destroying information as you go. Consider the simple example
nmax = 2
l = [1,2]
D = [2,1]
Unrolling your loop gives
l(D(1))=l(1)
l(D(2))=l(2)
i.e.
l(2)=l(1)
l(1)=l(2)
and tracking the value of l
, we see
! l = [1,2]
l(2)=l(1)
! l = [1,1]
l(1)=l(2)
! l = [1,1]
So you either need to make a copy of l
before the loop, and work from that, or, as @steve points out, you need to do the whole thing in one operation, using a vector subscript, in which case the whole loop would become
l(D) = l
Indeed, it is possible to simplify most of your code using whole-array operations rather than loops, as e.g.
program order
implicit none
integer :: i,j,k,q
integer, parameter :: nmax=7
integer :: l(nmax),D(nmax)
real :: x(nmax)
! Set `l` to a random vector.
call random_number(x)
l = 1+floor(13*x)
write(*,*) "Without order"
write(*,'(I2)') l
! Set `D` to [1,2,3,4,5,6,7].
D = [(i, i=1, nmax)]
! Sort `l` and `D` together.
do i=1,nmax-1
do j=i+1,nmax
if (l(i) > l(j)) then
! Swap `l(i)` and `l(j)`.
l([i,j]) = l([j,i])
! Swap `D(i)` and `D(j)`.
D([i,j]) = D([j,i])
endif
enddo
enddo
write(*,*) "Ordered"
write(*,'(I2)') l
write(*,*) "Order vector"
write(*,'(I2)') D
! Unsort `l`.
l(D) = l
write(*,*) "The original vector is"
write(*,'(I2)') l
end program order
Upvotes: 3