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 

Bug with maxloc, minloc
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Mon Aug 08, 2011 5:57 pm    Post subject: Bug with maxloc, minloc Reply with quote

Maxloc and minloc intrinsics should return a scalar when the array has rank of 1 and DIM=1 is used. In the following code, the call at (A) returns an integer scalar which is assigned to the value of max_index. At (B) the value of the array element max_index is printed out.

However, when the two operations are combined at (C) (using maxloc to get the index but without using an intermediate variable) I get a compiler error. The compiler thinks the RHS is an array.

I know this seems a rather convoluted way to get the maximum (I could just use maxval), but actually in my application I am using maxloc and minloc to get indices of doubly indexed array sections like.

ind = ix(maxloc(x(ix(lower:upper)),1)+lower-1)

which exhibits the same bug but is harder to follow.

The example below is simpler.


Code:

program maxim
   implicit none
   
   integer :: max_index
   real :: x(5), max_val

   x = (/1.0, 2.0, 5.0, 4.0, 3.0/)

   ! (A) Maximum index should be 3
   max_index = maxloc(x(1:5), 1)
   print *,'Maximum is at location ', max_index, ' (should be 3)'

   ! (B) Max value should be 5.0
   print *, 'Maximum value is ', x(max_index), ' (should be 5.0)'

   ! (C) This line should compile should also give 5.0, but the compiler
   ! thinks that the RHS is an array and issues an error 945.

   !*****************************
   max_val = x(maxloc(x(1:5), 1))
   !*****************************

   print *, 'Maximum value is ', max_val, ' (should be 5.0)'

end program maxim

_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl


Last edited by davidb on Fri Sep 09, 2011 4:54 pm; edited 2 times in total
Back to top
View user's profile Send private message
tk



Joined: 20 Jan 2007
Posts: 7
Location: Dublin, Ireland

PostPosted: Tue Aug 09, 2011 1:40 pm    Post subject: Reply with quote

I'm no wiser than you are in terms of what goes on within the compiler and machine during conversion from array to scalar data when the rank is specified to be 1.
But it is clear than when maxloc(x(1:5), 1) is used an an index to an array-typed variable, it is not "seen" by the compiler as a "normal" integer.

So you need a workaround.

INT function does not change the typing of the offending argument either.
It is still seen as an array . . .


Last edited by tk on Thu Aug 11, 2011 4:34 pm; edited 1 time in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Wed Aug 10, 2011 6:35 am    Post subject: Reply with quote

I have noted this issue and logged it for investigation.
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Tue Sep 06, 2011 4:06 pm    Post subject: Reply with quote

This turns out to be a programming error. i.e. the error report is correct.

maxloc always returns an array even when its size is one hence the type miss-match.

You can assign the result of maxloc to a scalar in order to generate the type conversion etc.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Sep 07, 2011 10:13 am    Post subject: Re: Reply with quote

PaulLaidler wrote:
This turns out to be a programming error. i.e. the error report is correct.

maxloc always returns an array even when its size is one hence the type miss-match.


Thanks for investigating. But I don't quite understand.

Do you mean

It's my programming error, and the compilers error report is correct?

Or.

Its a programming error in the compiler, and my report is correct?

If the latter, I hope it can be fixed.

David.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Wed Sep 07, 2011 3:46 pm    Post subject: Reply with quote

I meant to say that it is your programming error.
Back to top
View user's profile Send private message AIM Address
brucebowler
Guest





PostPosted: Wed Sep 07, 2011 4:02 pm    Post subject: Reply with quote

I'm not so sure... Looking at the draft standard (the only one I have),

If ARRAY has rank one, MAXLOC (ARRAY, DIM = DIM [, MASK = MASK]) is a
scalar whose value is equal to that of the first element of
MAXLOC (ARRAY [, MASK = MASK]).

and in the example code above,

max_val = x(maxloc(x(1:5), 1))

'x(1:5)' certainly looks like a rank one array, and DIM is specified. I think maxloc should be returning a scalar, not an array, in this case.

Bruce
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Wed Sep 07, 2011 8:59 pm    Post subject: Reply with quote

OK I think you are right. If you have DIM = 1 then the result is supposed to be a scalar.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Sep 07, 2011 10:05 pm    Post subject: Re: Reply with quote

PaulLaidler wrote:
I meant to say that it is your programming error.


OMG! It's not Razz . It should be an integer scalar for rank 1 arrays when DIM is supplied.

If it was supposed to return an array, the compiler should be complaining when I assign the result to a scalar in (A) in my code example above.

Thank's brucebowler for checking the draft standard.

It is also clearly stated by Jeanne Adams et.al in "The Fortran 2003 Handbook" :

"If DIM is absent it [the Result] is a rank-one array of size equal to the rank of n of ARRAY; if DIM is present and ARRAY is of rank-one, it is a scalar; otherwise, it is a rank one array of size n-1."

To my mind this is self consistent. It just says that when DIM is given the result is an integer array of size one less than the array argument; and one less than 1 is 0, and the closest thing to an "array of zero rank" in Fortran is a scalar.

What is the result for an array argument of rank 2 with DIM=1? Is it an array of rank 1 (as it should be) or an array of rank 2 (which would be incorrect)? Is there a more general bug here whereby the result is always one rank too many? (I haven't checked).
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Sep 08, 2011 1:13 am    Post subject: Reply with quote

My reading of this is that Paul was right the first time. I have extracted the description of MAXLOC from the Lahey fortran documentation, which indicates that the result is an array. Assuming the Lahey documentation is correct Fortran 95 syntax ( it always has been in the past)

Code:
MAXLOC Function

Description
Location of the first element in array having the maximum value of the elements identified
by mask.

Syntax
MAXLOC (array, dim, mask)

Required Arguments
array must be of type INTEGER or REAL.  It must not be scalar.

Optional Arguments
dim must be a scalar INTEGER in the range 1 ≤ dim ≤ n , where n is the rank of array.  The
corresponding dummy argument must not be an optional dummy argument.
mask must be of type LOGICAL and must be conformable with array.

Result
The result is of type default INTEGER. If dim is present, the result is an array of rank n-1
where n is the rank of array.  The result values are the locations having the maximum value
along dimension dim.
If dim is absent, the result is an array of rank one whose element values are the values of the
subscripts of the first element in array to have the maximum value of all of the elements of
array. 
If mask is present, the elements of array for which mask is false are not considered.

Example
integer, dimension(1) :: i
i = maxloc ((/3,0,4,4/)) ! i is assigned the value [3]


While "maxloc" is returned as an array, it is possible to declare i as a scaler for the statement i = maxloc (...).
It is not possible to use maxloc as an array subscript, which is the programing error.
It is not a very friendly definition, as David's expectation shows, although using a function as an array subscript is not something I would try.
David, you've deserted your F77 roots.

John

As a postscript, I find this definition a bit annoying. What does an array of dimension 1 and size 1 provide, apart from cleaning up a poor language definition. Indeed if "i" is an array and "j" is a scaler, what does j = i mean?

j = i(1) ! this would be correct
i = j ! array filled with a scaler is ok, but
j = i ! scaler filled with an array could only mean j = i(1)

If i was dimensioned as (2), and i(1) /= i(2), then how would we interpret j = i then. Somewhere along this line of thought something is wrong.
As I have observed in the past, the Fortran Standard has been taken over by non Fortranites.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Thu Sep 08, 2011 6:48 am    Post subject: Reply with quote

Sorry guys for this confusion. With the volume of work that I get through, I do occasionally make mistakes, hopefully not too often.

The result in this particular case needs to be a scalar and both FTN95 and Lahey have sliped up on this detail.

If I can fix the bug, I will and hopefully no ones existing code will be broken.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Thu Sep 08, 2011 8:52 am    Post subject: Reply with quote

Thank you Paul.

I checked a few other compilers, NAG, Gfortran, open64 all return a scalar if DIM=1 and the array has rank 1 and comply with the draft standard.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Thu Sep 08, 2011 8:59 am    Post subject: Re: Reply with quote

JohnCampbell wrote:

David, you've deserted your F77 roots.


Only temporarily . F77 was my first language (well I did a bit of F66).
Very Happy
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Sep 08, 2011 9:07 am    Post subject: Reply with quote

I have now looked in the latest standard that I have, and it shows 3 cases for MAXLOC, with case (iii) result being a scalar, as David has used and Bruce has indicated. However, if DIM is omitted (case (i)) then the result reverts to an array!

It's interesting to note that the standard shows the examples as
Case (i) is: The value of MAXLOC ((/ 2,6,4,6 /)) is [2], while for
Case(iii) is: The value of MAXLOC ((/ 5,-9,3 /), DIM=1) is 1

Can we take from this that "[2]" and "[2,1,2]" can be used as a valid alternative array syntax for "(/2/)" and "(/ 2,1,2 /)", as they are listed in the standard !!
If it was good enough for those who wrote the standard, why not for us users ?

John
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Fri Sep 09, 2011 4:52 pm    Post subject: Re: Reply with quote

JohnCampbell wrote:
I have now looked in the latest standard that I have, and it shows 3 cases for MAXLOC, with case (iii) result being a scalar, as David has used and Bruce has indicated. However, if DIM is omitted (case (i)) then the result reverts to an array!

It's interesting to note that the standard shows the examples as
Case (i) is: The value of MAXLOC ((/ 2,6,4,6 /)) is [2], while for
Case(iii) is: The value of MAXLOC ((/ 5,-9,3 /), DIM=1) is 1
John


Yes, this is the correct behaviour. The result is only a scalar in the special case of a rank 1 array when the DIM argument is provided and is 1. In all other valid cases you get an array.

JohnCampbell wrote:
Can we take from this that "[2]" and "[2,1,2]" can be used as a valid alternative array syntax for "(/2/)" and "(/ 2,1,2 /)", as they are listed in the standard !!
If it was good enough for those who wrote the standard, why not for us users ?

John


The array delimiters [ ] may be used instead of (/ and /) in Fortran 2003. But not in Fortran 95. (I am not sure if its an extension option in FTN95). It's certainly implemented in Gfortran, intel and NAG.

Edit: I just tried it and [ ] is in fact an allowed F2003 extension in FTN95. I just ticked the F2003 extensions option in Plato, which is the /F2K option on the command line.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
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