|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Mon Aug 08, 2011 5:57 pm Post subject: Bug with maxloc, minloc |
|
|
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 |
|
|
tk
Joined: 20 Jan 2007 Posts: 7 Location: Dublin, Ireland
|
Posted: Tue Aug 09, 2011 1:40 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Wed Aug 10, 2011 6:35 am Post subject: |
|
|
I have noted this issue and logged it for investigation. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Tue Sep 06, 2011 4:06 pm Post subject: |
|
|
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 |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Sep 07, 2011 10:13 am Post subject: Re: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Wed Sep 07, 2011 3:46 pm Post subject: |
|
|
I meant to say that it is your programming error. |
|
Back to top |
|
|
brucebowler Guest
|
Posted: Wed Sep 07, 2011 4:02 pm Post subject: |
|
|
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
|
Posted: Wed Sep 07, 2011 8:59 pm Post subject: |
|
|
OK I think you are right. If you have DIM = 1 then the result is supposed to be a scalar. |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Sep 07, 2011 10:05 pm Post subject: Re: |
|
|
PaulLaidler wrote: | I meant to say that it is your programming error. |
OMG! It's not . 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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Sep 08, 2011 1:13 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Thu Sep 08, 2011 6:48 am Post subject: |
|
|
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 |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Sep 08, 2011 8:52 am Post subject: |
|
|
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 |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Sep 08, 2011 8:59 am Post subject: Re: |
|
|
JohnCampbell wrote: |
David, you've deserted your F77 roots.
|
Only temporarily . F77 was my first language (well I did a bit of F66).
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Sep 08, 2011 9:07 am Post subject: |
|
|
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 |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Fri Sep 09, 2011 4:52 pm Post subject: Re: |
|
|
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 |
|
|
|
|
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
|