- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page