{-# LANGUAGE RebindableSyntax #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Data.YAP.Complex
-- Copyright   :  (c) The University of Glasgow 2001
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  libraries@haskell.org
-- Stability   :  provisional
-- Portability :  portable
--
-- A version of "Data.Complex", using the same type, but with less
-- constrained operations.  In particular this version permits Gaussian
-- integers.
--
-----------------------------------------------------------------------------

module Data.YAP.Complex
        (
        -- * Rectangular form
          Complex((:+))

        , realPart
        , imagPart
        -- * Polar form
        , mkPolar
        , cis
        , polar
        , magnitude
        , phase
        -- * Conjugate
        , conjugate

        )  where

import Data.YAP.Algebra.Internal

import Prelude (Double)
import Data.Complex (Complex((:+)))

-- -----------------------------------------------------------------------------
-- Functions over Complex

-- | Extracts the real part of a complex number.
realPart :: Complex a -> a
realPart :: forall a. Complex a -> a
realPart (a
x :+ a
_) =  a
x

-- | Extracts the imaginary part of a complex number.
imagPart :: Complex a -> a
imagPart :: forall a. Complex a -> a
imagPart (a
_ :+ a
y) =  a
y

-- | The conjugate of a complex number.
{-# SPECIALISE conjugate :: Complex Double -> Complex Double #-}
conjugate        :: (AbelianGroup a) => Complex a -> Complex a
conjugate :: forall a. AbelianGroup a => Complex a -> Complex a
conjugate (a
x:+a
y) =  a
x a -> a -> Complex a
forall a. a -> a -> Complex a
:+ a -> a
forall a. AbelianGroup a => a -> a
negate a
y

-- | Form a complex number from polar components of magnitude and phase.
{-# SPECIALISE mkPolar :: Double -> Double -> Complex Double #-}
mkPolar          :: (Floating a) => a -> a -> Complex a
mkPolar :: forall a. Floating a => a -> a -> Complex a
mkPolar a
r a
theta  =  a
r a -> a -> a
forall a. Semiring a => a -> a -> a
* a -> a
forall a. Floating a => a -> a
cos a
theta a -> a -> Complex a
forall a. a -> a -> Complex a
:+ a
r a -> a -> a
forall a. Semiring a => a -> a -> a
* a -> a
forall a. Floating a => a -> a
sin a
theta

-- | @'cis' t@ is a complex value with magnitude @1@
-- and phase @t@ (modulo @2*'pi'@).
{-# SPECIALISE cis :: Double -> Complex Double #-}
cis              :: (Floating a) => a -> Complex a
cis :: forall a. Floating a => a -> Complex a
cis a
theta        =  a -> a
forall a. Floating a => a -> a
cos a
theta a -> a -> Complex a
forall a. a -> a -> Complex a
:+ a -> a
forall a. Floating a => a -> a
sin a
theta

-- | The function 'polar' takes a complex number and
-- returns a (magnitude, phase) pair in canonical form:
-- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@;
-- if the magnitude is zero, then so is the phase.
{-# SPECIALISE polar :: Complex Double -> (Double,Double) #-}
polar            :: (RealFloat a) => Complex a -> (a,a)
polar :: forall a. RealFloat a => Complex a -> (a, a)
polar Complex a
z          =  (Complex a -> a
forall a. Floating a => Complex a -> a
magnitude Complex a
z, Complex a -> a
forall a. RealFloat a => Complex a -> a
phase Complex a
z)