- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I have the following problem. I want to cast a 1D array into column of 2D array in a loop. At 1st iteration the size of this 2D array is same as the 1D array. So. There should be no problem to cast it. At 2nd iteration, 1D array is going to have different elements. I want to cast it to 2nd column of 2D array.
This procedure continues till the norm of elements of 2D array is less than tolerance and it stops there. There, I can not guess the number of columns of 2D array to allocate it before starting calculation...
here are three codes I have tried. None of them work for me :
program ptrtest
real, pointer, CONTIGUOUS :: Mr(:)
real, pointer, CONTIGUOUS :: Mp(:,:)
real, DIMENSION(9) ::abc
integer :: n = 2
iter=3
Do i=1,iter
alpha2 = 2
allocate(Mr(n**2))
abc= 42
Mr(1:n**2) = 0.5 * abc(1:n**2)
write(*,*) 'Mr='
write(*,555) Mr
Mr(1:n**2) => Mp(1:n**2,1:1)
WRITE(*,*) 'Mp='
WRITE(*,555) Mp
end do
555 FORMAT(F12.4,1X)
end program ptrtest
----------------------------------------------------------------------------------------------------
program ptrtest
real, pointer, CONTIGUOUS :: Mr(:)
real, pointer, CONTIGUOUS :: Mp(:,:)
real, DIMENSION(9) ::abc
integer :: n = 2
iter=3
Do i=1,iter
alpha2 = 2
allocate(Mr(n**2))
abc= 42
Mr(1:n**2) = 0.5 * abc(1:n**2)
write(*,*) 'Mr='
write(*,555) Mr
do j = 1, iter
Mp(:, j) = Mr
end do
WRITE(*,*) 'Mp='
WRITE(*,555) Mp
end do
555 FORMAT(F12.4,1X)
end program ptrtest
program ptrtest
real :: start, finish
real, pointer :: Mr(:)
real, pointer,CONTIGUOUS :: Mp(:,:)
real, DIMENSION(4) ::abc
integer :: n = 2
call cpu_time(start)
iter=2
alpha2 = 2
Do i=1,iter
allocate(Mp(n**2,i))
allocate(Mr(n**2))
data abc/1,2,3,4/
Mr(1:n**2) = 0.5 * abc(1:4)
write(*,*) 'Mr='
write(*,555) Mr
Mp = TRANSFER (Mr,1.0)
WRITE(*,*) 'Mp='
WRITE(*,555) Mp
end do
555 FORMAT(F12.4,1X)
call cpu_time(finish)
print '("Time = ",f10.7," seconds.")', finish-start
end program ptrtest
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have just skimmed your code, and it occurred to me that you should look at the RESHAPE intrinsic, see https://software.intel.com/en-us/node/526713 . Your code makes heavy use of pointer variables; you may be better off with allocated variables instead, except in a few special cases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, reshape can be another alternative method. Thanks for reminding. However, the main issue still remains unsolved.
I mean, How should I tell Fortran to cast the 1D array into the 2nd column of 2D array when second iteration starts. I need to have preserve and save the 1D arrays which are calculated at each iteration in the columns of 2D array.
I have tried the following test program for reshape and I recieved segmentation error when 2nd iteration starts :
program ptrtest
real*8, DIMENSION(8) :: a
real*8, DIMENSION(:,:), Allocatable :: b
Do iter =1,3
a = (/1,2,3,4,5,6,7,8/)
b = reshape(a,(/iter,8/))
PRINT*, 'SHAPE(a)=', SHAPE(a)
PRINT*, 'SHAPE(b)=', SHAPE(b)
WRITE(*,*) 'a='
WRITE(*,100), a
100 FORMAT(1X,F5.2)
WRITE(*,*), 'b='
WRITE(*,200), b
end do
200 FORMAT (1X,F5.3)
end program ptrtest
RESULT:
SHAPE(a)= 8
SHAPE(b)= 1 8
a=
1.00
2.00
3.00
4.00
5.00
6.00
7.00
8.00
b=
1.000
2.000
3.000
4.000
5.000
6.000
7.000
8.000
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
2 [main] Reshape2 8200 cygwin_exception::open_stackdumpfile: Dumping stack trace to Reshape2.exe.stackdump
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What you seem to be trying to do is just infeasible. The issue is that you want an array to grow dynamically, but the Fortran processor can use up memory just ahead of where the array lies in memory if you don't reserve that space in advance. The next growth step can't occur without overwriting memory that the Fortran processor owns or copying all your data over to a new area of memory that has enough space for the bigger array size.
But this is the kind of thing that has to be handled all the time in practice, so what does everybody else do about it? The problem of handling potentially massive amounts of data without knowing the size or even shape in advance is the subject of any data structures text. Fortunately, you don't need to read a whole book to address your problem, because one of the simplest data structures, a linked list, seems to be adequate for your purposes. First you define the type of a linked list node:
INTEGER, PARAMETER :: dp = kind(1.0d0) TYPE Node REAL(dp), ALLOCATABLE :: Column(:) TYPE(Node), POINTER :: Next => NULL() END TYPE Node
Then a pointer to the start of the linked list and the current node:
TYPE(Node), POINTER :: Head => NULL(), Current => NULL()
Then you can allocate the first node of the linked list:
ALLOCATE(Head) Current => Head
Now you just work with the current node:
ALLOCATE(Current%Column(n)) Current%Column = [(i,i=1,n)]
And when you need another column, just allocate it and move on:
ALLOCATE(Current%Next) Current => Current%Next
When you are done, you still have a pointer to the start of your data, so you can use it as it stands if that mode of access is sufficient, or you could allocate an array of the now known size and walk through the linked list and fill it with your data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps you do not require using RESHAPE at all.
If you know the maximum number of iterations beforehand, simply declare B(1:8,IterMax), and within the loop set B(:,iter) = A.
If you do not, use an estimated upper bound of IterMax in the declaration and check for running into this limit in the loop.
If this is also impossible, you will need to rethink the goals and strategies. Note that RESHAPE does have optional arguments with which you can do padding.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page