- 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