How do I create a pointer to an element of an array with a variable index?

Click For Summary

Discussion Overview

The discussion revolves around creating a pointer to an element of an array in Fortran using a variable index. Participants explore the use of subroutines, pointer declarations, and built-in functions like maxloc and maxval, addressing both theoretical and practical aspects of the implementation.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested
  • Homework-related
  • Mathematical reasoning

Main Points Raised

  • One participant presents a Fortran program aiming to create a pointer to the largest element of an array using the maxloc function.
  • Another participant questions the intent declaration of the pointer parameter in the subroutine, suggesting it should be intent(out) or intent(inout) to modify its value.
  • Some participants clarify that Fortran subroutines can output values through parameters, unlike functions that return values directly.
  • There is a discussion about the behavior of the maxloc function, with some participants noting it returns an array of indices rather than a single index.
  • One participant suggests writing a custom function to find the largest value and its index instead of relying on built-in functions, while others argue for the efficiency of using built-in functions.
  • A participant expresses confusion about why a pointer cannot directly reference an array element using the maxloc function, leading to further clarification on syntax and pointer initialization.
  • Another participant points out that the syntax used with maxloc is incorrect, as it is a function and cannot be treated as a scalar directly.
  • Some participants share their experiences with different versions of Fortran, highlighting changes in syntax and functionality over time.

Areas of Agreement / Disagreement

Participants generally agree on the functionality of Fortran subroutines and the behavior of built-in functions like maxloc. However, there are competing views on whether to use built-in functions or write custom solutions, and the discussion remains unresolved regarding the best approach for the original problem.

Contextual Notes

There are limitations in understanding the behavior of maxloc and its return type, as well as the implications of pointer declarations in Fortran subroutines. The discussion also reflects varying familiarity with modern Fortran syntax and practices.

Who May Find This Useful

This discussion may be useful for students learning Fortran, particularly those working on exercises involving pointers and array manipulation, as well as practitioners interested in the nuances of Fortran subroutines and built-in functions.

Eclair_de_XII
Messages
1,082
Reaction score
91
TL;DR
In particular, I am having trouble creating a subroutine that takes an array and a pointer as arguments, and has the pointer reference the largest element of the array.
[CODE lang="fortran" title="1_point-to-biggest.f90"]program main
implicit none
real,dimension(3),target::x=[0,4,5]
real,pointer::y
call point_to_biggest(x,y)
!print *,y ! For testing purposes; to be unmuted only when y points to something
contains
subroutine point_to_biggest(array,ptr)
implicit none
real,dimension(:),intent(in),target::array
real,pointer,intent(in)::ptr
!ptr=>array(maxloc(array)) ! Results in gfortran thinking that array(maxloc(array)) is some sort of rank-1 object
end subroutine point_to_biggest
end program main[/CODE]
 
Last edited:
Technology news on Phys.org
Your variable ptr is declared in point_to_biggest as intent(in) but don't you want it to be an output of that subroutine?
 
Subroutines do not have outputs, though. They do not return anything. Are they not the Fortran-equivalent of void functions in C?
 
You are correct to say that a FORTRAN subroutine can not output a value through its name. It can output value(s) through one or more of its parameters. If you want your subroutine to modify the value of ptr, then you can not declare it intent(in). You can declare it intent(out) or intent(inout). See this.

A FORTRAN function can output a value through its name and that can be very handy for something, like sin(x), that would be used in formulas or equations. You might want to use that here.
 
Fortran:
program main
    implicit none
    real,dimension(3)::x=[1,3,77]
    real::y
    y=get_biggest(x)
    print *,y
contains
    real function get_biggest(x)
        implicit none
        real,dimension(:),intent(in)::x
        get_biggest=maxval(x)
    end function get_biggest
end program main

How do I do this with the pointer method, though? For some reason, array(maxloc(array)) is seen as an array and not as a scalar. I have no idea why this is.
 
Eclair_de_XII said:
Subroutines do not have outputs, though. They do not return anything. Are they not the Fortran-equivalent of void functions in C?
Fortran subroutines are similar to void functions in C, but the similarity is not exact. Parameters in Fortran subroutines/functions are passed by reference, while parameters in C functions are passed by value. C can simulate passing by reference by the use of pointer variable parameters.

The Fortran maxloc function returns the value of the largest element of an array, not its index. What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index. Working with pointers might be adding more complexity than is needed for what you're trying to do.
 
  • Like
Likes   Reactions: FactChecker
Mark44 said:
The Fortran maxloc function returns the value of the largest element of an array, not its index.
I think you mean MAXVAL, which he is calling in post #5, not MAXLOC, which he called in post #1.
Eclair_de_XII said:
How do I do this with the pointer method, though? For some reason, array(maxloc(array)) is seen as an array and not as a scalar. I have no idea why this is.
MAXLOC returns an array so that it will work with multidimensional arrays. If the input array has three dimensions, it will return an array of dimension 3 with the three indices of the largest value. In your case, it will return an array of dimension 1 with one index. It is instructive to study the documentation of MAXINT and look up any terminology or concepts that you are unfamiliar with.
.
Mark44 said:
What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index. Working with pointers might be adding more complexity than is needed for what you're trying to do.
Good advice. Although, in this case, there is a lot to learn about reading the FORTRAN documentation of MAXLOC which has terminology and concepts that may be new to the student. (It was new to an old-timer like me, who has not used modern FORTRAN versions.)
 
  • Like
Likes   Reactions: DrClaude
FactChecker said:
I think you mean MAXVAL
Yes, I looked up the docs for MAXVAL but miswrote it as maxloc.
FactChecker said:
(It was new to an old-timer like me, who has not used modern FORTRAN versions.)
Nor have I. Last Fortran compiler I had was an F95 implementation by Fahey, IIRC. It was a lot different from the F77 compiler I used in a class I took back in '80 -- which ran on machines (IBM?) that were programming with punch cards.
 
  • Like
Likes   Reactions: FactChecker
Fortran:
program main
    implicit none
    real,dimension(3),target::x=[0,5,5]
    real,pointer::y
    call point_to_biggest(x,y)
    print *,x(2)
contains
    subroutine point_to_biggest(array,ptr)
        implicit none
        real,dimension(:),intent(in),target::array
        real,pointer::ptr
        integer,dimension(1)::array_maxlocs
        array_maxlocs=maxloc(array)
        ptr=>array(array_maxlocs(1))
        ! ptr=>array(maxloc(array)(1)) ! Compiler tells me this is an invalid form of array reference.
        ptr=66 ! To verify that ptr does indeed point to x(2)
    end subroutine point_to_biggest
end program main

Okay, I solved the problem. Thanks, to everyone who replied. I had initially thought that the maxloc function returned an integer scalar; but reading the gnu documentation provided by FactChecker tells me that it returns an integer 1-array that stores the index I had initially thought the maxloc function returned. I had to create an integer 1-array variable to store the result of the maxloc function. What troubles me now, is why I cannot simply have a pointer point to the specific array element directly, as I have done in line 15.
 
  • #10
Eclair_de_XII said:
What troubles me now, is why I cannot simply have a pointer point to the specific array element directly, as I have done in line 15.
Here's your line 15, uncommented:
Fortran:
ptr=>array(maxloc(array)(1)) ! Compiler tells me this is an invalid form of array reference.

My Fortran is pretty rusty, but it seems to me that what you have is an expression, but what I think you need is an assignment statement. In the expression above, ptr is a declared, but uninitialized, pointer.

Edit: My rustiness with relatively recent Fortran syntax led me to think the above was an expression. On review, the problem is more likely the (1) that @DrClaude pointed out.
 
Last edited:
  • #11
The problem is that
Fortran:
maxloc(array)(1)
doesn't make sense syntactically. maxloc is a function, so appending (1) to it makes no sense.
 
  • #12
Mark44 said:
What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index.
I must disagree with this. The point of all these built-in functions in modern FORTRAN is to allow for more efficient code. I think they should be used as much as possible.
 
  • #13
DrClaude said:
I must disagree with this. The point of all these built-in functions in modern FORTRAN is to allow for more efficient code. I think they should be used as much as possible.
That's a fair point, but I think the OP just wants to get something done. I don't believe this is any production code that has to be super efficient.
 
  • #14
DrClaude said:
The problem is that
Fortran:
maxloc(array)(1)
doesn't make sense syntactically. maxloc is a function, so appending (1) to it makes no sense.
Oh, I see. So I cannot treat it like the value that it returns, then.

Mark44 said:
OP just wants to get something done
You are mistaken. I created this topic in order to address an exercise I found in an online textbook. It is on page 379 of this book.
 
  • #15
Eclair_de_XII said:
You are mistaken. I created this topic in order to address an exercise I found in an online textbook.
So that is what you wanted to "getting something done," as I put it. My point was that this is not some production code that has to be very efficient.
 
  • #16
Mark44 said:
So that is what you wanted to "getting something done," as I put it. My point was that this is not some production code that has to be very efficient.
That is correct. However, in the context of learning modern FORTRAN, I think it is good to try and master the built-in functions.

(Note: I think that the only point of programming in modern FORTRAN (≥90) is for high-performance computing applications, and therefore using the most efficient approaches.)
 
  • #17
DrClaude said:
That is correct. However, in the context of learning modern FORTRAN, I think it is good to try and master the built-in functions.
I agree. There is the efficiency of execution and also the efficiency of creating reliable code. Using established library functions achieves both.
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
 
  • Like
Likes   Reactions: berkeman and DrClaude
  • #18
FactChecker said:
I agree. There is the efficiency of execution and also the efficiency of creating reliable code. Using established library functions achieves both.
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it? That would provide an even better reason to use them.

For example, the same user program may be used to process 101 elements, or 1010 elements. But huge data sets might make good use of different strategies. They could look for example at the cache size and availability of GPU processors. It would make more sense to me to embed such intelligence in libraries rather than in end user written programs.
 
  • Like
Likes   Reactions: FactChecker
  • #19
anorlunda said:
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it?
Good question.
 
  • #20
FactChecker said:
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
I agree.
 
  • #21
anorlunda said:
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it? That would provide an even better reason to use them.
Yes. Modern HPC compilers can do automatic parallelization. In addition to library functions, you have constructs such as DO CONCURRENT, where the compiler can execute the different iterations of the loop in any order.
 
  • Informative
Likes   Reactions: FactChecker

Similar threads

  • · Replies 5 ·
Replies
5
Views
8K
Replies
235
Views
14K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 5 ·
Replies
5
Views
5K
  • · Replies 4 ·
Replies
4
Views
3K
Replies
11
Views
2K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 5 ·
Replies
5
Views
13K