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.