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

sum intrinsic in constant expressions

tracyx
New Contributor I
1,414 Views

i want to define a parameter that is equal to the sum of a parameter array. in the code below covmatrix is a variance matrix, and i have 1's and 0's depending upon whether they are restricted or not. i want to define a parameter that tells me the number of unrestricted parameters:

[cpp]integer, parameter :: covmatrix(4,4) = reshape( &
& (/1, 0, 0, 0, &
& 1, 1, 0, 0, &
& 1, 1, 1, 0, &
& 1, 0, 1, 1/),(/4,4/))

integer, parameter :: numcov = sum(covmatrix)[/cpp]

however, this gives an error that "This intrinsic function is invalid in constant expressions". Is there an elegant way of calculating the number of ones in covmatrix? something like, integer, parameter :: numcov = covmatrix(1,1) + covmatrix(1,2) + ... works but it is tedious (especially if the dimension of covmatrix were to change). thanks

0 Kudos
7 Replies
Les_Neilson
Valued Contributor II
1,414 Views
Sorry. No
In the help, under "Initialization Expressions", SUM is shown as an example of an invalid initialization expression - though I can see how it could be useful.
Off the top of my head I can't think of an easy way to do it either.
Les

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,414 Views
Quoting - Les Neilson
Off the top of my head I can't think of an easy way to do it either.

...me neither, other than the obvious workaround of not making it a parameter, and calculating the SUM (or COUNT) somewhere in the initialization stage.

0 Kudos
ender01
New Contributor I
1,414 Views
Quoting - Jugoslav Dujic

...me neither, other than the obvious workaround of not making it a parameter, and calculating the SUM (or COUNT) somewhere in the initialization stage.

Another idea is to use a wrapper. If you want to protect is as a parameter, have a wrapper calling function pass it with intent(in) and have your main consist of computing the sum and invoking the wrapper which effectively serves as your main.

Cheers,

Rich

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,414 Views
Quoting - tracyx

i want to define a parameter that is equal to the sum of a parameter array. in the code below covmatrix is a variance matrix, and i have 1's and 0's depending upon whether they are restricted or not. i want to define a parameter that tells me the number of unrestricted parameters:

[cpp]integer, parameter :: covmatrix(4,4) = reshape( &
& (/1, 0, 0, 0, &
& 1, 1, 0, 0, &
& 1, 1, 1, 0, &
& 1, 0, 1, 1/),(/4,4/))

integer, parameter :: numcov = sum(covmatrix)[/cpp]

however, this gives an error that "This intrinsic function is invalid in constant expressions". Is there an elegant way of calculating the number of ones in covmatrix? something like, integer, parameter :: numcov = covmatrix(1,1) + covmatrix(1,2) + ... works but it is tedious (especially if the dimension of covmatrix were to change). thanks

Tracy,

You might try using the Fortran Preprocessor

[cpp]#define parms 
 1,0,0,0, 
 1,1,0,0, 
 1,1,1,0, 
 1,0,1,1

#define parmsSum (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) 
 a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p

integer, parameter :: covmatrix(4,4) = reshape( (/ parms /),(/4,4/))

integer, parameter :: numcov = parmsSum

Jim Dempsey
[/cpp]

0 Kudos
JVanB
Valued Contributor II
1,414 Views
/stand:f03
0 Kudos
tracyx
New Contributor I
1,414 Views
Quoting - Repeat Offender
/stand:f03

This doesn't work for me. I'm using 11.0.69.

To be clear: is the sum intrinsic in constant expressions part of F2003, but it just hasn't been implemented in Intel Fortran yet?

Thanks for all the suggestions, etc. I'm about to give up hope that this is easily doable in a parameter expression as some of the suggestions (e.g. wrapper function) do not work either.

0 Kudos
ender01
New Contributor I
1,414 Views
Quoting - tracyx

This doesn't work for me. I'm using 11.0.69.

To be clear: is the sum intrinsic in constant expressions part of F2003, but it just hasn't been implemented in Intel Fortran yet?

Thanks for all the suggestions, etc. I'm about to give up hope that this is easily doable in a parameter expression as some of the suggestions (e.g. wrapper function) do not work either.

Using the wrapper won't let you declare it as a parameter. However, if you pass the argument with the intent(in) attribute the compiler won't let you inadvertently change the value and you can use it in the scope of the called function as if it were a parameter (i.e., a named constant whose value cannot be changed). For instance:

[cpp]program main
   implicit none
   integer, dimension(4,4) :: covmatrix
   integer :: numcov

   covmatrix = reshape( (/1, 0, 0, 0, & 
                      &   1, 1, 0, 0, & 
                      &   1, 1, 1, 0, & 
                      &   1, 0, 1, 1/),(/4,4/)) 
      
    numcov = sum(covmatrix)  

    call pseudo_main(numcov)


contains
    subroutine pseudo_main(constant)
        implicit none

        integer, intent(in) :: constant

        !  Put main here, use constant like a parameter (can't appear
! on LHS of an expression)
.... end subroutine pseudo_main end program main[/cpp]

The use of an intrinsic in an initialization expression is part of Fortran 2003 (subject to some limitations on the primaries of the expression (e.g., each primary is a constant or subobject of a constant)).

Cheers,

Rich

0 Kudos
Reply