Quantcast
Channel: Intel® Fortran Compiler
Viewing all articles
Browse latest Browse all 3270

Bug Report: Incorrect application of elemental function on user defined type

$
0
0

 

 

I have an error with Intel Fortran incorrectly applying an elemental function to a user defined type.

module quart

  implicit none
  type quaternion
     ! q(4) = (w, x, y, z) where w is the scalar part
     real :: q(4)
     ! Flags to tell us if we want to keep the quaternion unitised, and
     ! also if the quaternion represents an improper rotation (rotation + inversion)
     logical :: unit
     logical :: improper
  end type quaternion
contains

  elemental subroutine pnormalise_quaternion(q)

    ! Normalise the quaternion by dividing the quaternion by it's
    ! 'reduced norm'

    type (quaternion), intent(inout) :: q

    q%q = q%q / (pnormq(q))

  end subroutine pnormalise_quaternion

  elemental subroutine enormalise_quaternion(q)

    ! Normalise the quaternion by dividing the quaternion by it's
    ! 'reduced norm'

    type (quaternion), intent(inout) :: q

    q%q = q%q / (enormq(q))

  end subroutine enormalise_quaternion

  pure real function pnormq(q)

    ! The 'reduced norm' of a quaternion is just the square root of the
    ! arithmetic sum of the squares of it's elements

    real :: normq
    type (quaternion), intent(in) :: q

    pnormq = sqrt(sum(q%q**2))

  end function pnormq

  elemental real function enormq(q)

    ! The 'reduced norm' of a quaternion is just the square root of the
    ! arithmetic sum of the squares of it's elements

    real :: normq
    type (quaternion), intent(in) :: q

    enormq = sqrt(sum(q%q**2))

  end function enormq
end module quart

program test
    use quart

    type(quaternion) :: q(2)

    q(1)%q = [1,2,2,4]
    q(2)%q = [1,0,0,0]

    call pnormalise_quaternion(q)

    write(*,*) q(1)%q
    write(*,*) q(2)%q

    q(1)%q = [1,2,2,4]
    q(2)%q = [1,0,0,0]

    call enormalise_quaternion(q)

    write(*,*) q(1)%q
    write(*,*) q(2)%q


end program

Compiled and run like so:

fort -o quaternion quaternion.f90​

./quaternion 
  0.2000000      0.4000000      0.4000000      0.8000000     

 1.000000      0.0000000E+00  0.0000000E+00  0.0000000E+00

  0.2000000      0.4079085      0.4449238      0.9875987     

 1.000000      0.0000000E+00  0.0000000E+00  0.0000000E+00

The top two lines are correct (from the pure routine), and the third line is erroneous.

Stepping through the code with gdb it seems that enormq is being 4 times for each quaternion q, once for each element of q%q.

 


Viewing all articles
Browse latest Browse all 3270

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>