Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Arrays with parameters

krishnabc
Beginner
5,346 Views
How would wedeclare an array with constant parameters?
0 Kudos
1 Solution
John4
Valued Contributor I
5,346 Views

Since the initialization might be partial, the DATA statement is still your best choice.

Just put it in a module, change the continuation to F90+ style, and add the PROTECTED attribute to the declaration of L if you don't want it to be modified somewhere else, e.g.:

[bash]module mod1
    integer, protected :: L(4, 120)
    data ((L(I,J),I=1,3),J=6,12)/ 21*4/   
end module mod1
[/bash]

View solution in original post

0 Kudos
14 Replies
John4
Valued Contributor I
5,346 Views

I assume you meant an array with elements that will remain constant for the whole life of the given program. If that's the case, then the answer is part of your question ---i.e., use the PARAMETER attribute in the declaration, e.g.:

[fortran]integer, parameter :: something(5) = [1, 2, 3, 4, 5][/fortran]
Due to an oversight of a few decades in the standard, your declaration must explicitly state the number of array elements ---as of Fortran 2008, though, compilers seem to have learned how to count array elements at compile time.

If I misunderstood your question, please disregard this post.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
5,346 Views
You mean,

[fortran]!1-D parameter array
integer, parameter:: fibonacci(10) = [1,1,2,3,5,8,13,21,34,55]
!2-D parameter array
integer, parameter:: rotateMatrix(2,2) = reshape([1, -1, -1, 1], [2,2])[/fortran]
(Angle brackets are F2003 notation for array constructors. For Fortran-95 and older, use brace-slash pairs (/.../) )
0 Kudos
krishnabc
Beginner
5,346 Views
Thank you John and Jugoslav. I do appreciate your suggestions. However, I think the above declarations are good for onlysmall sized arrays. My array size is rather big with some sections are assigned the data using implied do loops. Hence, I found a bit confusing in the data assignment.

I found an another way. I declared the array with "PROTECTED" attribute and assigned the data in a subroutine of that module.This method served my purpose that I cannot change the values outside the module. However, in extra,I need to call that subroutine to access the values of the array, only USE association is not sufficient.

I am not sure if there is a better way. I am actually transporting the COMMON BLOCKs with BLOCK DATA structure of F77 tomodern Fortranmodule structure.

Thank you.
0 Kudos
krishnabc
Beginner
5,346 Views

Jugoslav,

Thanks a lot for pointing the angle brackets. I was also getting syntax errors due to copying the data from old code with brace-slash pairs.

0 Kudos
John4
Valued Contributor I
5,346 Views

Since you're converting code originally in Fortran 77, I suppose the original approach was no better than what you have now (or what most programming languages can offer). The Fortran standard allows the use of ELEMENTAL intrinsic functions (and a few non-ELEMENTAL ones) in the PARAMETER declaration, so that might help your case. Also, the PARAMETER declaration can incorporate other PARAMETERs previously declared, e.g.:

[fortran]integer, parameter :: negative(100) = [(i, i = -100, -1)]
integer, parameter :: zero(1) = [0]
integer, parameter :: positive(100) = [(i, i = 1, 100)]
integer, parameter :: natural(SIZE(positive)) =  positive
integer, parameter :: digit(101) = [zero, positive]
integer, parameter :: number(201) = [negative, digit]

end
[/fortran]
The PROTECTED approach is somewhat better, though, especially if generating the array requires invoking non-trivial functions. You can designate an initialization section at the beginning of your program to invoke the generation of such arrays.

0 Kudos
Steven_L_Intel1
Employee
5,346 Views
I want to point out that the Fortran 90 delimiters for array constructors are (/ /), that is, left parenthesis, slash and slash, right parenthesis. Fortran 2003 added square brackets [ ] - what Jugoslav called angle brackets (I would use that term for <>), but Intel Fortran has supported that for many years.

As for what I would call braces, {}, those are not part of Fortran syntax (yet).
0 Kudos
krishnabc
Beginner
5,346 Views
John,

Thank you very much for the additional inputs. My F77 code is Finite Element codes and the assignment is not that straightforward. I have to input each individual entry of the array manually. Would greatlyappreciate your suggestion for the example at the end.



Steve,

Sorry for the wrong terminologies used for the square brackets and slashes.I (and Jugoslav too)meant the same.
The slashes are fine for the 1-D array constructor, but gives syntax error for the assignment of data either for a row or column of a 2-D array (with XE 12.0.1.127). For example,


[bash]!1-D parameter array   
integer, parameter:: fibonacci(10) = [1,1,2,3,5,8,13,21,34,55]	! OK[/bash]

and
[fortran]!1-D parameter array   
integer, parameter:: fibonacci(10) = ( /1,1,2,3,5,8,13,21,34,55/)	! OK[/fortran]

Both are fine. However,

[fortran]L(1,1:5) = ( / ... / )	! gives syntax error
L(1,1:5) = ( [ ... ] )	! OK

[/fortran]


where my array L isof size (4, 120).

The array that I wanted to convert from F77 to F90 or F2003 is something like this:

[fxfortran]      DATA
    + ((L(I,J),I=1,3),J=6,12)/
    + ...
    + ...
+ ... / [/fxfortran]

I have many arrays like this. Would greatly appreciate any help.
Thank you.
0 Kudos
John4
Valued Contributor I
5,347 Views

Since the initialization might be partial, the DATA statement is still your best choice.

Just put it in a module, change the continuation to F90+ style, and add the PROTECTED attribute to the declaration of L if you don't want it to be modified somewhere else, e.g.:

[bash]module mod1
    integer, protected :: L(4, 120)
    data ((L(I,J),I=1,3),J=6,12)/ 21*4/   
end module mod1
[/bash]

0 Kudos
John_B__Walter
Beginner
5,346 Views
Quoting krishnabc
...
where my array L isof size (4, 120).

The array that I wanted to convert from F77 to F90 or F2003 is something like this:

DATA
+ ((L(I,J),I=1,3),J=6,12)/
+ ...
+ ...
+ ... /


I have many arrays like this. Would greatly appreciate any help.
Thank you.

When you say you have many arrays like this, what do you mean?
Are you saying you have many large arrays that you only want to assign some of the values such as L(1:2,6:12) in this example?

When you say you have them, yes I see your needing to yse them, but in what form do you have them? Are they in some text file that you could read in to initialize the array? Where are these values coming from?
Do you want to be typing these values into data statements, or parameter statements?
Can you help us to understand more clearly what it is you need?

0 Kudos
krishnabc
Beginner
5,346 Views
Thank you John. You are absolutely right.Then, is it correct to say that theDATA statement isa redundant feature?
0 Kudos
krishnabc
Beginner
5,346 Views

Dear John Walter,

Thank you very much. I would like to reply as follows:

"When you say you have many arrays like this, what do you mean? Are you saying you have many large arrays that you only want to assign some of the values such as L(1:2,6:12) in this example?"

-->
I mean to sayL (in the example)is only one array. L(1:3,6:12)is only a small segment of the code.Yes, I have some other multi-dimensional arrays storing some other types of values.


"When you say you have them, yes I see your needing to yse them, but in what form do you have them? Are they in some text file that you could read in to initialize the array? Where are these values coming from?"

--> I want to use them as modules than common blocks. The values are initialized in BLOCK DATA with DATA statements (not reading from files). But, I wanted to avoid DATA statements (because of declared reluctant feature). However, as another John said (reply #8), DATA statements are still useful in my case.

"Do you want to be typing these values into data statements, or parameter statements? Can you help us to understand more clearly what it is you need?"

--> Yes, the values are available to me as data statements. But, these values (e.g. gauss points, weights,and other elemental propertiesfor different types ofelements in the FE code) should not be changed in due course of running the program. Hence, I wanted to make them as parameter statements so that they would not be changed unnoticeably or unintentionally causing unintended outputs.

Hope I made it clear now. Thank you everyone for the continued interest.
Krishna

0 Kudos
John4
Valued Contributor I
5,346 Views

If you're doing full initialization of an array, then of course you can do it in the same declaration line, and the DATA statement is not necessary. Besides letting you do partial initialization, the DATA statement has the advantage of allowing for an arbitrary order ---say, initialize the array by row, instead of doing it by column---, so its usage is not redundant.

One thing that might be problematic, though, is to leave some of the elements of an array undefined, since that might be problematic in array-wise operations ---say, if you multiply the whole array by a certain number or things like that.

0 Kudos
Steven_L_Intel1
Employee
5,346 Views
The delimiters for array constructors are either (/ ... /) or [ ... ]. Not ([ ... ]).

For multidimensioned arrays, the intended method is to use RESHAPE to reshape a 1D array constructor to the desired shape.

DATA has its uses, though initialization expressions in declarations keep the initilaization and declaration together.
0 Kudos
krishnabc
Beginner
5,346 Views

Great. Thank you John, Steve, and all for many useful tips.
Partial assignments like L(1,1:5) = [1,2,3,4,5] can only appear in the executable part of the program unit and/or witha Subroutine orMain Program. Hence, I am going with DATA statements for the initialization together with declaration; however, I'll keep in mind the downside of DATA statements as John has highlighted.

Many thanks.

0 Kudos
Reply