|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sat Mar 06, 2021 12:49 pm Post subject: PACK function |
|
|
Hello,
I have a large one-dimensional array consisting of about 2000 elements, most of them has ZERO values and only small part of them contains NON-zero value: I need to extract from it the NON-zero values only.
So, I used the PACK function with mask as follows:
Code: |
...
INTEGER, ALLOCATABLE :: D(:)
...
IF (.not. ALLOCATED (D)) ALLOCATE (D(en))
d=pack(up,mask=up.ne.0)
....
|
The number of non-zero elements (en) is found in a procedure preceding the call to the PACK function.
Basically, the PACK function works fine and I get the array D(en) with non-zero values only, which becomes then an one-dimensional array with 20 non-zero values only.
If I create a release EXE version - it runs (apart from a problem with DRAW_POLYLINED@ which does not join the lines).
However, when I check the /UNDEF option for debugging and run the debug process - the debugger says:
RUN-TIME error 112. Reference to undefined variable, array element or function result (/UNDEF) and points to the newly created one-dimensional array with 20 elements (array named UP in the code above).
My question is: when I use the PACK function, it creates a new array of the same dimension (one dimension with 20 non-zero elements in my case) and the rest zero elements are disregarded (I suppose so) or not
and still keeps the information about the original input array (in my case - one-dimensional array named UP with 2000 elements)?
Thanks!
Martin |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sat Mar 06, 2021 1:21 pm Post subject: |
|
|
Martin
Can you demonstrate the runtime error in a short program and post it here? |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sat Mar 06, 2021 8:45 pm Post subject: |
|
|
Paul,
here is the link to download main program and the module along with the input data file:
https://www.dropbox.com/h?preview=TEST_PACK_FUNCTION.zip
I also included two JPG screen shots, one with RUN-TIME error message and the other one with a look in compiler options in my PLATO test project
for this purpose.
I repeat once again, when I uncheck the option CHECK FOR UNDEFINED VARIABLES, the program runs problem free both in RELEASE/X64 and DEBUG/X64 (the results are output to the screen and are correct).
As soon as I check the above mentioned option, the program crashes in both variants (release and debug).
I think, when this will be explained, where I am wrong, it could have the connection to my problem with DRAW_POLYLINED@.
DO not forget to setup the option UNICODE UTF8 without signature, when you load in both files into a PLATO project. The OC_points.TXT file with the input data is also attached to test the problem on real data. |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Sun Mar 07, 2021 6:02 am Post subject: |
|
|
The use of PACK in Fortran 90/95 has some limitations, as there is no report of the extent of D that has been used.
for your statement:
d=pack(up,mask=up.ne.0)
What part of D has been initialised ?
Also, was UP initialised ?
It is probably easier not to use PACK and just keep a list of active points as they are reviewed.
In F03, using PACK with auto-allocate, it works much better using:
INTEGER, ALLOCATABLE :: D(:)
D=pack(up,mask=up.ne.0) ; num = size (D)
Imagine the problems if UP was real !! |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sun Mar 07, 2021 10:25 am Post subject: |
|
|
Thanks John.
I initialised neither D nor UP. Now, I did so (all elements of both arrays are
after initialising equal zero), but the symptoms
are the same (when CHECK FOR UNDEFINED VARIABLE is active,
program crashes, without this checking, program runs fine). |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Sun Mar 07, 2021 1:22 pm Post subject: |
|
|
Paul,
I think there may be an issue with allocate on assignment for logical arrays. The following code does not behave as expected:
Code: | program t
implicit none
integer, parameter :: dp=kind(1.d0)
integer, parameter :: n = 20
real(kind=dp) a(1:n)
logical, allocatable :: mask(:)
real(kind=dp), allocatable :: copy_a(:)
integer i, counter
a = 0.d0
do i = 1, n, 5
call random_number(a(i))
end do
do i = 1, n ; print*, i, a(i) ; end do
counter = 0
do i = 1, n
if ( a(i) .ne. 0.d0) counter = counter + 1
end do
print*
print*, 'No of non-zero entries ', counter
mask = (a .ne. 0.d0) !Allocate mask on assignment
print*
print*, 'Size of auto-allocated mask array', size(mask)
copy_a = a
print*
print*, 'Size of auto-allocated copy of a', size(copy_a)
end program t
!Size(mask):-
!Checkmate + Win32 returns 0
!Release + Win32 fails on access violation
!Checkmate + x64 returns 0
!Release + x64 fails on access violation
!
!Alternative compiler returns 20 as expected.
|
This may be relevant to the issue that Martin is experiencing.
PS Curiosity got the better of me. It appears there are issues with allocate on assignment for complex arrays:-
Code: | program t
implicit none
integer, parameter :: dp=kind(1.d0)
complex(kind=dp) :: mat(1:3,1:3)
complex(kind=dp), allocatable :: mat_c(:,:)
integer i
!Create matrix with j on main diagonal, zero otherwise
mat = 0.d0
do i = 1, 3, 1
mat(i,i) = cmplx(0.d0,1.d0,kind=dp)
end do
print*, mat
mat_c = mat
print*
print*, mat_c
end program t
! Checkmate + Win32 "Nonconformant arrays"
! Release + Win32 Process hangs
! Checkmate + X64 "Nonconformant arrays"
! Release + X64 OK |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Mar 07, 2021 3:09 pm Post subject: |
|
|
Martin
John has pointed out that the arrays must be initialised. Also D must have the right number of elements.
en has the correct value which is COUNT(up.ne.0) but this must be the current size of D. So you could write...
Code: |
IF(ALLOCATED(D)) DEALLOCATE(D)
ALLOCATE (D(en))
D = 0
|
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Mar 07, 2021 3:27 pm Post subject: |
|
|
Ken
Thank you for the feedback. I have made a note of that allocate on assignment does not work in these cases. |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sun Mar 07, 2021 4:22 pm Post subject: |
|
|
Thanks guys for your comments.
Paul,
I did exactly what John said:
Code: |
IF (.not. ALLOCATED (D)) ALLOCATE (D(en))
D(en)=0
print*,d
pause
d=pack(up,mask=up.ne.0)
|
The same I did for the UP(K).
The result can be seen here (in yellow are the D(en) values after initialisation. Their number is correct and also - after executing
the PACK commad (last three lines in the picture below), the number
of D(en) values is correct and filled up with correct values.
Nevertheless, it does not help, the symptoms remain
the same (program crashes when using /UNDEF option).
An additional observation: Originally, I used for initialisation
the commands UP = 0 and D = 0.
When I run the program after such initialisation, when I want to print the values UP(k) and D(en), it displays only the UP values and exits automatically, although after every initialisation I use the PAUSE command. It also should display D values. It displays them
(the initialised D values) for a second and program ends automattically,
although I also used the PAUSE command after the PACK function, when
it is executed.
Therefore I used UP(K) = 0 and D(en) = 0, instead of UP = 0 and D = 0. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Mar 07, 2021 5:07 pm Post subject: |
|
|
Martin
It works for me but with the changes that I have recommended.
UP(K) = 0 sets just one element to zero whilst UP = 0 sets all the array values to zero.
Also the array D must be the right size which is why I have suggested that you you deallocate D and re-allocate to the current size. |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sun Mar 07, 2021 5:08 pm Post subject: |
|
|
I forgot to mention that I also used the Paulīs alternative:
Code: |
IF (ALLOCATED (D)) DEALLOCATE (D)
ALLOCATE (D(en))
D(en)=0
|
All results and behaviour are exactly the same as in my alternative:
Code: |
IF (.not. ALLOCATED (D)) ALLOCATE (D(en))
D(en)=0
|
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Mar 07, 2021 5:11 pm Post subject: |
|
|
Martin
Our posts may have crossed.
D(en) = 0 is not the same as D = 0. |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Sun Mar 07, 2021 5:53 pm Post subject: |
|
|
Paul,
here are two 20s videos that demonstrate what I wrote
about D = 0 and D(en) =0:
https://www.dropbox.com/s/d4bdgz81hd9by5f/videos.zip?dl=0
Simply, when I use D=0, program ignores the PAUSE command located immediately after initialisation
D=0 and PRINT*,D command
Code: |
IF (ALLOCATED (D)) DEALLOCATE (D)
ALLOCATE (D(en))
D=0
print*,d
pause
d=pack(up,mask=up.ne.0) ! to select ONLY the points with NON-ZERO values
print*,'Now - below - follows D(en) array correctly filled up with correct NON-ZERO values:'
print*,d
pause
|
and neither displays the PACK results, nor wait for pressing END, simply ends automatically without any intervention.
When I use (D(en) = 0 because D=0 does not work well with me, you say that only one element (which one of 20 elements?) has assigned the ZERO value. But as can be seen in one of my video, after such assignment (D(en) = 0) all 20 elements have assigned ZERO values. Or am I wrong?
Moreover, even when I use your alternative method for allocation with /UNDEF option, program always crashes. Both things are mystery for me. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Mar 07, 2021 9:19 pm Post subject: |
|
|
Martin
Try running the debugger SDBG or SDBG64. Set a break point at the point you talk about and then look at the array elements. |
|
Back to top |
|
|
|
|
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
|