forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Using PACK

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
wahorger



Joined: 13 Oct 2014
Posts: 1214
Location: Morrison, CO, USA

PostPosted: Tue Apr 27, 2021 6:44 pm    Post subject: Using PACK Reply with quote

First off, this is NOT a bug report or a request for action!

I like using PACK(). It is an easy, understandable way to select data from arrays and reorganize the data.

It is an easy way, in well-defined lists, to select an item and move it to the top of the list. I was doing that with file extents (for get_filtered_file@() usage. Since I cannot select a specific file specification to match an already defined file, I am re-organizing the list, matching the file extent of the file to the list of potential file extents.

As an example, if my file choices are *.txt, *.dat, and *.*, and the file ends in .dat, I will reorder the sequence to be *.dat, *.txt, and *.*.

There are two methods shown in the sample code below. Method 1 just PACK()'s the data using what I term as a "direct memory move". The second method generates a vector of indices, then moves the data. Method 1 yields different results from Method 2 (Method 2 is correct). I am posting this to give a "heads up". As always, moving data onto itself is risky, regardless of the technique used. It is especially problematic when you cannot control the moves (i.e. relying on the compiler writer to do it the way you might want).

Code:
        program main
        character*5:: fspec(3)
        integer:: i

       
        fspec(1) = '*.txt'; fspec(2)= '*.dat'; fspec(3) = '*.*'
        call reorder1(fspec,3,'*.dat')
        do i=1,3 ; print *,'Spec=',fspec(i) ; end do

       
        fspec(1) = '*.txt'; fspec(2)= '*.dat'; fspec(3) = '*.*'
        call reorder2(fspec,3,'*.dat')
        do i=1,3 ; print *,'Spec=',fspec(i) ; end do
        end
        subroutine reorder1(fspec,nf,first)
        integer:: nf
        character*(*):: fspec(nf),first
        character*(len(fspec(1))):: spec(1)
        integer :: i, n_index(nf)
! make sure the integer array is properly built
        do i=1,nf ; n_index(i) = i ; end do
        print *,'Reorder 1: Move the data directly'
        print *,'Index to move to the top =',pack(n_index,fspec.eq.first)
        print *,'   Indices to keep below =',pack(n_index,fspec.ne.first)
! this does not compile unless you specify spec as a vector
        spec(1:1)   = fspec(pack(n_index,fspec.eq.first))
        fspec(2:nf) = pack(fspec,fspec.ne.first)
        fspec(1)    = spec(1)
        return
        end
        subroutine reorder2(fspec,nf,first)
        integer:: nf
        character*(*):: fspec(nf),first
        character*(len(fspec(1))):: spec(1)
        integer :: i, n_index(nf)
! make sure the integer array is properly built
        do i=1,nf ; n_index(i) = i ; end do
        print *,'Reorder 2: Use integer vector to move data'
        print *,'Index to move to the top =',pack(n_index,fspec.eq.first)
        print *,'   Indices to keep below =',pack(n_index,fspec.ne.first)
! this does not compile unless you specify spec as a vector
        spec(1:1)   = fspec(pack(n_index,fspec.eq.first))
        fspec(2:nf) = fspec(pack(n_index,fspec.ne.first))
        fspec(1)    = spec(1)
        return
        end


Results:
Quote:

Reorder 1: Move the data directly
Index to move to the top = 2
Indices to keep below = 1 3
Spec=*.dat
Spec=*.dat
Spec=*.*
Reorder 2: Use integer vector to move data
Index to move to the top = 2
Indices to keep below = 1 3
Spec=*.dat
Spec=*.txt
Spec=*.*
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group