{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- | -- Module : Numeric.Conversion -- Copyright : (c) Alberto Ruiz 2010 -- License : GPL-style -- -- Maintainer : Alberto Ruiz -- Stability : provisional -- Portability : portable -- -- Conversion routines -- ----------------------------------------------------------------------------- module Numeric.Conversion ( Complexable(..), RealElement, module Data.Complex ) where import Data.Packed.Internal.Vector import Data.Packed.Internal.Matrix import Data.Complex import Control.Arrow((***)) ------------------------------------------------------------------- -- | Supported single-double precision type pairs class (Element s, Element d) => Precision s d | s -> d, d -> s where double2FloatG :: Vector d -> Vector s float2DoubleG :: Vector s -> Vector d instance Precision Float Double where double2FloatG = double2FloatV float2DoubleG = float2DoubleV instance Precision (Complex Float) (Complex Double) where double2FloatG = asComplex . double2FloatV . asReal float2DoubleG = asComplex . float2DoubleV . asReal -- | Supported real types class (Element t, Element (Complex t), RealFloat t -- , RealOf t ~ t, RealOf (Complex t) ~ t ) => RealElement t instance RealElement Double instance RealElement Float -- | Structures that may contain complex numbers class Complexable c where toComplex' :: (RealElement e) => (c e, c e) -> c (Complex e) fromComplex' :: (RealElement e) => c (Complex e) -> (c e, c e) comp' :: (RealElement e) => c e -> c (Complex e) single' :: Precision a b => c b -> c a double' :: Precision a b => c a -> c b instance Complexable Vector where toComplex' = toComplexV fromComplex' = fromComplexV comp' v = toComplex' (v,constantD 0 (dim v)) single' = double2FloatG double' = float2DoubleG -- | creates a complex vector from vectors with real and imaginary parts toComplexV :: (RealElement a) => (Vector a, Vector a) -> Vector (Complex a) toComplexV (r,i) = asComplex $ flatten $ fromColumns [r,i] -- | the inverse of 'toComplex' fromComplexV :: (RealElement a) => Vector (Complex a) -> (Vector a, Vector a) fromComplexV z = (r,i) where [r,i] = toColumns $ reshape 2 $ asReal z instance Complexable Matrix where toComplex' = uncurry $ liftMatrix2 $ curry toComplex' fromComplex' z = (reshape c *** reshape c) . fromComplex' . flatten $ z where c = cols z comp' = liftMatrix comp' single' = liftMatrix single' double' = liftMatrix double'