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

Problem at IMSL's BINOM

Natalia_K_
Beginner
543 Views

Hi,

I am receiving an error at compiling the "test" code below,"error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands." The test code is a stripped down version of some bigger algorithm. The error occurs at IMSL BINOM routine. I believe I fulfilled the requirements on the input in BINOM, both inputs are integers, the output is real. I also have tried to compute integers b1=d-1 and b2=d+q-k, and use BINOM(b1,b2) instead, but it does not remove the problem. I would appreciate your help.

Best regards,

Natalia

PROGRAM test
INCLUDE 'link_fnl_shared.h'

    USE IMSL_LIBRARIES, ONLY: BINOM
    IMPLICIT NONE
    INTEGER(4)                :: d,k,q,minq,maxq      
    REAL(8)                    :: bq 
    
WRITE(*,*) 'Type 10'
READ(*,*) d
WRITE(*,*) 'Type 2'
READ(*,*) k

 minq = max(0,k-d)
 maxq = k-1
  DO q = minq,maxq
    bq = BINOM(d-1,d+q-k)
    bq=bq*(-1d0**(maxq-q))
  END DO
  
END PROGRAM test

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
543 Views

This indicates a bug in the module IMSL_LIBRARIES. If you replace the USE statement by USE BINOM_INT, the problem goes away.

A comment: rather than using bq=bq*(-1d0**(maxq-q)), which is probably incorrect (see R.O.'s response below) you could write the more efficient equivalent, if(mod(maxq-q,2) == 1)bq=-bq.

View solution in original post

0 Kudos
11 Replies
mecej4
Honored Contributor III
544 Views

This indicates a bug in the module IMSL_LIBRARIES. If you replace the USE statement by USE BINOM_INT, the problem goes away.

A comment: rather than using bq=bq*(-1d0**(maxq-q)), which is probably incorrect (see R.O.'s response below) you could write the more efficient equivalent, if(mod(maxq-q,2) == 1)bq=-bq.

0 Kudos
Natalia_K_
Beginner
543 Views

That helped. Thank you.

0 Kudos
JVanB
Valued Contributor II
543 Views

Actually -1d0**(maxq-q) should always be -1.0d0.

Since we are guaranteed that maxq >= q, mod is OK, but still I prefer modulo in contexts like that. Or maybe iand(maxq-q,1).

 

0 Kudos
mecej4
Honored Contributor III
543 Views

Natalia, please read R.O.'s comment -- he is pointing out that exponentiation has higher precedence than multiplication, so the statement in question does nothing useful beyond changing the sign of bq. I noted that you had provided a stripped down piece of code, and figured that in the larger application the -1.0d0 might actually be represented by a variable name. The stripped down DO loop is also superfluous since it is only the last set value of bq that would be used later in the program. It might be worthwhile to check the code in the larger program.

0 Kudos
Natalia_K_
Beginner
543 Views

Thank you for pointing to inefficiencies in the code. In the stripped down version I have leaved the features of the original code that I have suspected to be a problem: variable input in BINOM due to the loop (therefore I kept the loop), and modified value of bq (bq modification after BINOM).

The code is a direct translation of the algorithm written for MATLAB, it was important for me to stick to the original at the time it was written for fortran. I do occasional coding in fortran but cannot qualify to produce the most efficient code. However, I appreciate your comments, it is good to learn new things.

0 Kudos
Steven_L_Intel1
Employee
543 Views

There isn't a bug in IMSL_LIBRARIES. The problem is the "ONLY: BINOM". What this does is get you the function definition but NOT the defined assignment in module BINOM_INT. Removing the ONLY from the use of IMSL_LIBRARIES will also resolve the problem.

The problem is that BINOM is a function that returns a derived type FLOATING_POINT_NUMBER defined in the module. It then has defined assignment definitions to permit assignment to single and double precision reals. A (rather obscure) clue comes from this text in the documentation:

If the generic version of this function is used, the immediate result must be stored in a variable before use in an expression. For example: X = BINOM(9, 5) Y = SQRT(X) must be used rather than Y = SQRT(BINOM(9, 5)). If this is too much of a restriction on the programmer, then the specific name can be used without this restriction.

The use of "generic" here is a bit misleading - there is only one function BINOM which is not GENERIC, but it returns this FLOATING_POINT_NUMBER thing that, as the text says, can't be used in an expression. It relies on the defined assignment to allow you to assign the value to a variable.

By adding the ONLY, you prevent the compiler from accessing the defined assignment, and hence the error. My own preference is to use the individual interface modules such as BINOM_INT, which define just what you need, so no point in using ONLY.

0 Kudos
mecej4
Honored Contributor III
543 Views

Steve, I did see in the IMSL manual the item  that you quoted, and found it puzzling, since it says nothing about defined assignment there. I did wonder how the specific function was selected given that the single and double precision versions would have the same type arguments, therefore, the same "signature", except for the kind of the function value.

0 Kudos
Steven_L_Intel1
Employee
543 Views

Yeah, it would have been better if they had been up front about what is going on in the module.

0 Kudos
Natalia_K_
Beginner
543 Views

The large algorithm uses a couple of dozens IMSL routines. It make sense to keep USE IMSL_LIBRARIES, ONLY: option instead of just USE IMSL_LIBRARIES, my understanding is that it will make the algorithm more efficient. But I also had a similar problem with another IMSL function U4INF, again the solution was to use U4INF_INT instead of including it into the ONLY list of functions. However, I cannot recall now if the source of that problem was similar to the current case with BINOM.

0 Kudos
mecej4
Honored Contributor III
543 Views

Natalia K. wrote:
my understanding is that it will make the algorithm more efficient
. The only effect will be on compilation time, because the compiler will not have to sort through all the other unused module entities when compiling code using only a few entities from the module. There should be no effect at all on the run time.

The U4INF case would not have been similar, because U4INF is a subroutine rather than a function.

0 Kudos
Natalia_K_
Beginner
543 Views

Good to know. I guess if I write USE IMSL_LIBRARIES, that should be good enough for all IMSL routines.

0 Kudos
Reply