For instant, lets say I have an array A = (/ 2,5,6,11 /). I want to get the combinations (2,5), (5,6), (6,11), (11,2) for a calculation. Basically, it is (A(i),A(i+1)), but must loop with the first element in the array. How do I set up this in FORTRAN?
Appreciate your help.
Chin
-
1What have you got so far ?High Performance Mark– High Performance Mark2014-01-23 21:22:41 +00:00Commented Jan 23, 2014 at 21:22
-
I'd append rotated (starting from 2nd element, then first one or CSHIFT) copy and reshaped it to 2D. Perhaps combined with transposition. Or something along these lines.mlt– mlt2014-01-23 21:28:22 +00:00Commented Jan 23, 2014 at 21:28
-
Well I am new to programing. I know i, i+1 will get combinations until the array. But how can I cycle last element with 1st element.Chinthaka Nadun Ratnaweera– Chinthaka Nadun Ratnaweera2014-01-23 21:28:31 +00:00Commented Jan 23, 2014 at 21:28
-
Perhaps something with MOD?mlt– mlt2014-01-23 21:29:54 +00:00Commented Jan 23, 2014 at 21:29
-
3Of course you could use a mod operation as well in Fortran, aside from letting your array start from 0 or any other integer, you can always shift your indices into the mod space you'd like and shift it back afterwards. Thus, no problem at all using a mod based solution in Fortran...haraldkl– haraldkl2014-01-23 23:12:52 +00:00Commented Jan 23, 2014 at 23:12
|
Show 1 more comment
2 Answers
Given an integer array such as yours
A = (/ 2,5,6,11 /)
you could declare another array for the combinations
integer, dimension(:,:), allocatable :: b
allocate it
allocate(b(size(a),2))
and then populate it
b(:,1) = a
b(:,2) = cshift(a,1)
you will find that the rows of b are the combinations you seek.
I have used, of course, the approach suggested by @mlt in a comment. As you can see, I have not explicitly used any loops, nor have I bothered with the indices of the elements of any arrays.
I make no claims about the performance of this approach which a compiler is very likely to implement by making a temporary copy of a behind the scenes.
Comments
Try these:
program simple
implicit none
integer,parameter :: A(4) = (/ 2,5,6,11 /)
integer :: i, next
! Version 1
do i=1,size(A)
next = i + 1
if (next > size(A)) next = 1
print *, A(i), A(next)
enddo ! i
! Version 2
do i=1,size(A)
print *, A(i), A( merge( 1, i+1, ( i==size(A) ) ) )
enddo ! i
! Version 3
do i=1,size(A)
print *, A(i), A( mod( i, size(A) ) + 1 )
enddo ! i
end program