Computes the roots of a quadratic polynomial of the form
a(1) + a(2)*z + a(3)*z**2 = 0
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in), | dimension(3) | :: | a |
coefficients |
|
real(kind=wp), | intent(out), | dimension(2) | :: | zr |
real components of roots |
|
real(kind=wp), | intent(out), | dimension(2) | :: | zi |
imaginary components of roots |
pure subroutine dqdcrt(a, zr, zi) implicit none real(wp), dimension(3), intent(in) :: a !! coefficients real(wp), dimension(2), intent(out) :: zr !! real components of roots real(wp), dimension(2), intent(out) :: zi !! imaginary components of roots real(wp) :: d, r, w if (a(3) == 0.0_wp) then !it is really a linear equation: if (a(2) == 0.0_wp) then !degenerate case, just return zeros zr = 0.0_wp zi = 0.0_wp else !there is only one root (real), so just duplicate it: zr(1) = -a(1)/a(2) zr(2) = zr(1) zi = 0.0_wp end if else if (a(1) == 0.0_wp) then zr(1) = 0.0_wp zi(1) = 0.0_wp zr(2) = -a(2)/a(3) zi(2) = 0.0_wp else d = a(2)*a(2) - 4.0_wp*a(1)*a(3) if (abs(d) <= 2.0_wp*eps*a(2)*a(2)) then !equal real roots zr(1) = -0.5_wp*a(2)/a(3) zr(2) = zr(1) zi(1) = 0.0_wp zi(2) = 0.0_wp else r = sqrt(abs(d)) if (d < 0.0_wp) then !complex roots zr(1) = -0.5_wp*a(2)/a(3) zr(2) = zr(1) zi(1) = abs(0.5_wp*r/a(3)) zi(2) = -zi(1) else !distinct real roots zi(1) = 0.0_wp zi(2) = 0.0_wp if (a(2) /= 0.0_wp) then w = -(a(2) + sign(r, a(2))) zr(1) = 2.0_wp*a(1)/w zr(2) = 0.5_wp*w/a(3) else zr(1) = abs(0.5_wp*r/a(3)) zr(2) = -zr(1) end if end if end if end if end if end subroutine dqdcrt