Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
27087 Discussions

## reordering a vector

New Contributor I
148 Views

I have a vector, REAL(4)::V(1000). Say that the largest one happens to be V(123). I need to re-order the values so that V begins with the largest, i.e. Vnew(1) = Vold(123)
Vnew(2) = Vold(124)
​;
​Vnew(878) = Vold(1000)
​Vnew(879) = Vold(1)
Vnew(880) = Vold(2)
​:
Vnew(1000) = Vold(122)

That is, the sequence is to remain but the starting point must shift (it is NOT a matter of sorting in numerical order). Of course this can be done in an elementary straightforward manner by creating a copy, say Vaux, reassigning every element in a loop, and then copying Vaux back to V. I suspect there is a better way. Can anyone suggest an optimal algorithm, reducing both the memory required and the execution time?

6 Replies
Honored Contributor I
148 Views

You could mess with pointers maybe but it isn't that big I would do a couple of block copies and a move_alloc rather than copying everything twice.

```    subroutine order
implicit none
integer, parameter :: vsize = 1000
integer            :: ip1, isz, l1, istat
real, allocatable  :: V(:), Vtmp(:)

allocate(V(vsize), stat = istat)
if (istat /= 0) stop 'poo!'

do l1 = 1 , vsize  ! fill V
V(l1) = 1.0*l1
enddo

ip1 = 123             ! the pivot point in V
isz = vsize - ip1 + 1 ! size of the lower chunk

allocate (Vtmp(vsize), stat = istat)
if (istat /= 0) stop 'poo!'

vtmp(1:isz)       = V(ip1:vsize)
vtmp(isz+1:vsize) = V(1:ip1-1)
call move_alloc(Vtmp, V)
end subroutine order```

Honored Contributor II
148 Views

You can simply do the following using the intrinsic CSHIFT

```      V = cshift( V, shift=maxloc(V, dim=1)-1 )
```

Note though MAXLOC returns "a value equal to the first element of MAXLOC .."

CSHIFT is very efficient for rank-one arrays.

Honored Contributor I
148 Views

FortranFan wrote:

You can simply do the following using the intrinsic CSHIFT

```      V = cshift( V, shift=maxloc(V, dim=1)-1 )
```

Note though MAXLOC returns "a value equal to the first element of MAXLOC .."

CSHIFT is very efficient for rank-one arrays.

Certainly concise but that would surely create temporaries and data (2?) data copies?

Honored Contributor I
148 Views

cshift looks a useful function! Another bit of learning! I would guess that will copy into a temp and then copy the temp back to the original but that isn't really a penalty if the data size is not huge.

Honored Contributor II
148 Views

andrew_4619 wrote:

.. I would guess that will copy into a temp and then copy the temp back to the original but that isn't really a penalty if the data size is not huge.

With array transformations, one might as well as employ intrinsics as much as possible: if one can do better than Intel Fortran, then bring it up with Intel to improve their implementaton.

Honored Contributor I
148 Views

FortranFan wrote:
With array transformations, one might as well as employ intrinsics as much as possible: if one can do better than Intel Fortran, then bring it up with Intel to improve their implementaton.

Yes I agree with that, in a bored moment later in the week I might make some tests for my own amusement and report back if there is anything of interest.