Hi,
i am a beginner in F90 and I do not know how to select some array
elements according to its values.
That is to say what is the equivalent of the "where" function (in IDL)
in fortran.
a = [ 2,5,9,-7,4,-8]
b = [ 100,200,300,400,500,600]
I want to know the index of the positive values of the array a ( here
the index are 1, 2, 3 and 5) and pass them to my b array to keep only
the b items for which a is positive...I would do
b = b(where(a ge 0)) in IDL and it would give: b = 100, 200, 300, 500
but no idea how to do it in fortran...
Does anyone know??
Thanks
|
|
0
|
|
|
|
Reply
|
thibaultgarel (44)
|
3/26/2010 2:53:46 PM |
|
On 26 mrt, 15:53, bing999 <thibaultga...@gmail.com> wrote:
> Hi,
>
> i am a beginner in F90 and I do not know how to select some array
> elements according to its values.
>
> That is to say what is the equivalent of the "where" function (in IDL)
> in fortran.
>
> a =3D [ 2,5,9,-7,4,-8]
> b =3D [ 100,200,300,400,500,600]
>
> I want to know the index of the positive values of the array a ( here
> the index are 1, 2, 3 and 5) and pass them to my b array to keep only
> the b items for which a is positive...I would do
>
> b =3D b(where(a ge 0)) in IDL =A0and it would give: b =3D 100, 200, 300, =
500
>
> but no idea how to do it in fortran...
> Does anyone know??
>
> Thanks
You can do that with the pack() function:
pack( b, a >=3D 0 )
but there is a caveat:
The result is an array whose length you do not know in advance. That
means that you can not simply say:
b =3D pack( b, a >=3D 0 )
The array b is not automatically resized (in Fortran 2003 that does
happen)
What you can do instead is pass the result to a subroutine:
integer, dimension(:), allocatable :: b
call resize( b, pack( b, a >=3D 0 ) )
....
subroutine resize( b, fill )
integer, dimension(:), allocatable, intent(inout) :: b
integer, dimension(:), intent(in) :: fill
deallocate( b )
allocate( b(1:size(fill) )
b =3D fill
end subroutine
Or you can simply pass the result of pack() to a subroutine and
work with the dummy argument:
call examine( pack( b, a >=3D 0 ) )
subroutine examine( r )
integer, dimension(:) :: r ! Ordinary array, but you should not
change the
! elements' values
...
end subroutine
Yet another way is:
b =3D (/ pack( b, a>=3D 0 ), pack( b, a < 0 ) /)
With the array constructor (/ .. /) you simply shift the negative
elements to the back. The contructed array on the right has the same
size as b (because of the complementary conditions)
A lengthy expose, but I hope this helps you understand the
possibilities.
Regards,
Arjen
|
|
0
|
|
|
|
Reply
|
Arjen
|
3/26/2010 3:07:00 PM
|
|
bing999 wrote:
> Hi,
>
> i am a beginner in F90 and I do not know how to select some array
> elements according to its values.
>
> That is to say what is the equivalent of the "where" function (in IDL)
> in fortran.
>
> a = [ 2,5,9,-7,4,-8]
> b = [ 100,200,300,400,500,600]
>
> I want to know the index of the positive values of the array a ( here
> the index are 1, 2, 3 and 5) and pass them to my b array to keep only
> the b items for which a is positive...I would do
>
> b = b(where(a ge 0)) in IDL and it would give: b = 100, 200, 300, 500
>
> but no idea how to do it in fortran...
> Does anyone know??
seems like you want to PACK:
b2 = PACK(b, mask=a>0) ! using a new var b2 (with size(b2)=count(a>0))
|
|
0
|
|
|
|
Reply
|
Tom
|
3/26/2010 3:21:58 PM
|
|
Thanks but PACK does not return the index of the array, right? i need
the index since my 2 arrays have same dimensions (and by the way my
problem is more complicated than just grab the positive values...)
|
|
0
|
|
|
|
Reply
|
bing999
|
3/26/2010 3:23:13 PM
|
|
bing999 wrote:
> Thanks but PACK does not return the index of the array, right? i need
> the index since my 2 arrays have same dimensions (and by the way my
> problem is more complicated than just grab the positive values...)
>
i still think pack is what you want. if your required mask if quite
complicated, then just precalculate it (the mask array is just an array
of logicals) and use it with pack. eg.
fancy_mask = (a>0 .and. mod(a,2)==0)
allocate (b2(count(fancy_mask))) ! must allocate b2 to correct size
b2 = PACK(b, mask=fancy_mask) ! extracts elements of b where
! fancy_mask=.TRUE.
|
|
0
|
|
|
|
Reply
|
Tom
|
3/26/2010 3:43:03 PM
|
|
bing999 <thibaultgarel@gmail.com> wrote:
> Thanks but PACK does not return the index of the array, right? i need
> the index since my 2 arrays have same dimensions (and by the way my
> problem is more complicated than just grab the positive values...)
Ok. Pack does what your example shows, but apparently the example isn't
adequately representative. Another possibility is the Fortran WHERE
construct. It also doesn't return index values. In fact, it doesn't
return anything at all, being a construct instead of a procedure. But it
does allow you to do some things on the selected elements of multiple
arrays having the same dimensions. Admitedly, the things you can do are
very limitted.
Otherwise, if you really do want an array of the index values as you
say, then I'll give an answer much like that I gave to another recent
inquiry. Broaden your focus to realize that there are ways to operate on
arrays other than whole array expressions. It is pretty simple to do
this one with a DO loop. The only thing that makes it non-trivial is
that you don't know the size of the needed array of index values until
after the fact. You can address this either by determining the size as a
separate first step or by dimensioning the array to the maximum possible
size (which is the size of the original array).
As in
allocate (indices(count(condition-involving-array-a)))
n = 0
do i = 1 , size(a)
if (condition-involving-a(i)) then
n = n + 1
indices(n) = i
end if
end do
or
allocate(indices(size(a)))
... the same loop as above
! Optionally followed by
a = a(1:n) !-- Assuming f2003 allocatable assignment.
As an aside, note that an array of index values is not a particularly
handy form in Fortran in general. In particular, you can't directly use
such a thing for the multi-dimensional case; you'd have to break it
appart, probably in a loop. You can use it in the one-dimensional case,
but there are restrictions on the usage and, depending on details, you
might find it inefficient.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam
|
3/26/2010 4:07:43 PM
|
|
Richard Maine wrote:
....
> Otherwise, if you really do want an array of the index values as you
> say, then I'll give an answer much like that I gave to another recent
> inquiry. Broaden your focus to realize that there are ways to operate on
> arrays other than whole array expressions. It is pretty simple to do
> this one with a DO loop. The only thing that makes it non-trivial is
> that you don't know the size of the needed array of index values until
> after the fact. You can address this either by determining the size as a
> separate first step or by dimensioning the array to the maximum possible
> size (which is the size of the original array).
....
And, I'll note for OP that while in environments such as IDL or Matlab
where there may be a significant performance penalty in looping
constructs as compared to figuring out how to vectorize the code, since
Fortran is compiled there will not be such a penalty at run time to
worry about. The offsetting condition is it may take a little more
coding effort in Fortran than in one of these languages.
Also, there's a distinct possibility that the concise Fortran constructs
may not compile/optimize as well as the straightahead DO construct;
whether that's true or not will, of course, depend on the actual
construct as well as the specifics of a given compiler.
--
|
|
0
|
|
|
|
Reply
|
dpb
|
3/26/2010 4:42:22 PM
|
|
dpb <none@non.net> wrote:
(snip)
> And, I'll note for OP that while in environments such as IDL or Matlab
> where there may be a significant performance penalty in looping
> constructs as compared to figuring out how to vectorize the code, since
> Fortran is compiled there will not be such a penalty at run time to
> worry about. The offsetting condition is it may take a little more
> coding effort in Fortran than in one of these languages.
and R and Mathematica. After the question a few days ago, and then
this one, I was about to write the same thing. The key to fast
code in such interpreted languages is using the array operations,
or even more specialized built-in operators.
> Also, there's a distinct possibility that the concise Fortran constructs
> may not compile/optimize as well as the straightahead DO construct;
> whether that's true or not will, of course, depend on the actual
> construct as well as the specifics of a given compiler.
The array operations can easily require temporary arrays that are
not needed in the DO loop case. Using array operators tends to
require more passes through the array. Also, like in the one a few
days ago, the DO case can often exit early without processing the
whole array. The array operation case usually can't do that.
While compilers are getting better, I believe the statement that
I made years ago is still true: Array operations are likely
at least as fast for simple operations, but often slower
(and also less readable) for more complicated operations.
They do make nice entries for Obfuscated Code contests, though.
-- glen
|
|
0
|
|
|
|
Reply
|
glen
|
3/26/2010 7:15:15 PM
|
|
|
7 Replies
332 Views
(page loaded in 0.086 seconds)
Similiar Articles: IDL books for beginners - comp.lang.idl-pvwave... string and integer in F90 - comp.lang.fortran ..... list to number list - comp.soft-sys.math ..... and a few books ... equivalent in fortran of the IDL "where" function ... To combine string and integer in F90 - comp.lang.fortran ...... to number list - comp.soft-sys.math ..... and a few books ... equivalent in fortran of the IDL ... comp.soft-sys.matlab convert string to ascii ... mean the function that ... Fortran 95 equivalent of read(..., POS=...) - comp.lang.fortran ...I would have expected it to work , soI just ran a trivial test with ... problem reading Fortran binary file - comp.lang.idl-pvwave ... Fortran 95 equivalent of read(..., POS ... Preferred way to get multiple returns from a function - comp.lang ...I am writing a function that fits an ... question: what is the preferred IDL way to return > multiple values from a function ... dealing with the same issue in Fortran ... Windows API programming with gfortran or g95 - comp.lang.fortran ...function CreateWindow(lpClassName, lpWindowName, dwStyle,& > ! x, y ... Fortran 95 equivalent of read(..., POS=...) - comp.lang.fortran ... Windows API programming ... IDL routine to read MATLAB MAT-files - comp.lang.idl-pvwave ...I don't have a huge amount of time to work on this routine, but I'll ... Fortran binary file - comp.lang.idl-pvwave ... IDL reading ... read labview files in matlab. - comp ... Least Cost Path using Dijkstra's Algorithm - comp.lang.idl-pvwave ...... if this sounds interesting to you, I can send you the C code and the IDL wrapper function. ... Where did Fortran go? - comp.lang.fortran At least that's my impression based ... Trying to implement dynamic arrays, but... - comp.lang.fortran ...Hello, I'm not a Fortran expert, but I think I can help: The WRITE() function will put ... What I wrote is 100% equivalent to what ... Maxima of 2D array - comp.lang.idl ... Fortran 77/90/95 free compiler - comp.lang.fortran> > > /* at work, so I'm posting via google */ > > I should download each compiler ... Fortran 95 equivalent of read(..., POS=...) - comp.lang.fortran ... Windows API programming ... Smoothing Spline -- any existing efficient routines? - comp.lang ...It's not very nicely coded - I wrote it as an exercise in my early IDL days - but it might work. ... The () brackets were, at least in my case, an atavism from FORTRAN ... Introduction to IDL - University of Virginia Department of Astronomy... of basic operation of the Interactive Data Language (IDL) for ... little as one fifth the time of the equivalent FORTRAN ... [Refer to the definition of the SIZE function in the IDL ... School Computer System InformationIt should be noted that while in some situations IDL can be slower than the C or Fortran equivalent ... wrapper for vecadd.f called vecadd_wrapc.c; and an IDL function ... 7/17/2012 2:03:14 PM
|