fix typos, remove unused imports
[variable-precision:variable-precision.git] / Numeric / VariablePrecision / Complex.hs
1 {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, StandaloneDeriving, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, Rank2Types, UndecidableInstances #-}
2 {- |
3 Module      :  Numeric.VariablePrecision.Complex
4 Copyright   :  (c) Claude Heiland-Allen 2012
5 License     :  BSD3
6
7 Maintainer  :  claudiusmaximus@goto10.org
8 Stability   :  unstable
9 Portability :  DeriveDataTypeable, GeneralizedNewtypeDeriving, StandaloneDeriving, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, Rank2Types, UndecidableInstances
10
11 Newtype wrapper using 'Data.Complex.Generic'.
12
13 -}
14 module Numeric.VariablePrecision.Complex
15   ( module Data.Complex.Generic
16   , VComplex()
17   , toComplex
18   , fromComplex
19   , withComplex
20   , recodeComplex
21   , scaleComplex
22   , scaleVComplex
23   , toComplexDFloat
24   , toComplexDFixed
25   , fromComplexDFloat
26   , fromComplexDFixed
27   , withComplexDFloat
28   , withComplexDFixed
29   ) where
30
31 import Data.Complex.Generic
32 import Data.Complex.Generic.Default
33
34 import Numeric.VariablePrecision.Fixed
35 import Numeric.VariablePrecision.Float
36 import Numeric.VariablePrecision.Precision
37 import Numeric.VariablePrecision.Algorithms (recodeFloat)
38
39 -- | Newtype wrapper around 'Complex' so that instances can be written
40 --   for 'HasPrecision' and 'VariablePrecision'.
41 newtype VComplex t p = FromComplex
42   { -- | Convert 'VComplex' to 'Complex'.
43     toComplex :: Complex (t p)
44   }
45   deriving (Eq)
46
47 deriving instance Num (Complex (t p)) => Num (VComplex t p)
48 deriving instance Fractional (Complex (t p)) => Fractional (VComplex t p)
49 deriving instance Floating (Complex (t p)) => Floating (VComplex t p)
50
51 -- | Convert 'Complex' to 'VComplex'.
52 fromComplex :: Complex (t p) -> VComplex t p
53 fromComplex = FromComplex
54
55 instance NaturalNumber p => Num (Complex (VFloat p)) where
56   (+) = addDefault
57   (-) = subDefault
58   (*) = mulDefault
59   negate = negateDefault
60   fromInteger = fromIntegerDefault
61   abs = absDefault
62   signum = signumDefault
63
64 instance NaturalNumber p => Num (Complex (VFixed p)) where
65   (+) = addDefault
66   (-) = subDefault
67   (*) = mulDefault
68   negate = negateDefault
69   fromInteger = fromIntegerDefault
70   abs = error "Num.abs: unimplemented for Complex VFixed"
71   signum = error "Num.signum: unimplemented for Complex VFixed"
72
73 instance NaturalNumber p => Fractional (Complex (VFloat p)) where
74   (/) = divDefaultRF
75   fromRational = fromRationalDefault
76
77 instance NaturalNumber p => Fractional (Complex (VFixed p)) where
78   (/) = divDefault
79   fromRational = fromRationalDefault
80
81 instance NaturalNumber p => Floating (Complex (VFloat p)) where
82   pi = piDefault
83   exp = expDefault
84   log = logDefault
85   sqrt = sqrtDefault
86   sin = sinDefault
87   cos = cosDefault
88   tan = tanDefault
89   sinh = sinhDefault
90   cosh = coshDefault
91   tanh = tanhDefault
92   asin = asinDefault
93   acos = acosDefault
94   atan = atanDefault
95   asinh = asinhDefault
96   acosh = acoshDefault
97   atanh = atanhDefault
98
99 instance NaturalNumber p => ComplexRect (Complex (VFloat p)) (VFloat p) where
100   mkRect x y = (x :+ y)
101   rect (x :+ y) = (x, y)
102   real = realDefault
103   imag = imagDefault
104   realPart = realPartDefault
105   imagPart = imagPartDefault
106   conjugate = conjugateDefault
107   magnitudeSquared = magnitudeSquaredDefault
108   sqr = sqrDefaultRF
109   (.*) = rmulDefault
110   (*.) = mulrDefault
111
112 instance NaturalNumber p => ComplexRect (Complex (VFixed p)) (VFixed p) where
113   mkRect x y = (x :+ y)
114   rect (x :+ y) = (x, y)
115   real = realDefault
116   imag = imagDefault
117   realPart = realPartDefault
118   imagPart = imagPartDefault
119   conjugate = conjugateDefault
120   magnitudeSquared = magnitudeSquaredDefault
121   sqr = sqrDefault -- FIXME
122   (.*) = rmulDefault
123   (*.) = mulrDefault
124
125 instance NaturalNumber p => ComplexPolar (Complex (VFloat p)) (VFloat p) where
126   mkPolar = mkPolarDefault
127   cis = cisDefault
128   polar = polarDefault
129   magnitude = magnitudeDefaultRF
130   phase = phaseDefaultRF
131
132 instance NaturalNumber p => ComplexRect (VComplex VFloat p) (VFloat p) where
133   mkRect x y = FromComplex (x :+ y)
134   rect = rect . toComplex
135   real = realDefault
136   imag = imagDefault
137   realPart = realPartDefault
138   imagPart = imagPartDefault
139   conjugate = conjugateDefault
140   magnitudeSquared = magnitudeSquaredDefault
141   sqr = sqrDefaultRF
142   (.*) = rmulDefault
143   (*.) = mulrDefault
144
145 instance NaturalNumber p => ComplexRect (VComplex VFixed p) (VFixed p) where
146   mkRect x y = FromComplex (x :+ y)
147   rect = rect . toComplex
148   real = realDefault
149   imag = imagDefault
150   realPart = realPartDefault
151   imagPart = imagPartDefault
152   conjugate = conjugateDefault
153   magnitudeSquared = magnitudeSquaredDefault
154   sqr = sqrDefault -- FIXME
155   (.*) = rmulDefault
156   (*.) = mulrDefault
157
158 instance NaturalNumber p => ComplexPolar (VComplex VFloat p) (VFloat p) where
159   mkPolar = mkPolarDefault
160   cis = cisDefault
161   polar = polarDefault
162   magnitude = magnitudeDefaultRF
163   phase = phaseDefaultRF
164
165 instance HasPrecision (VComplex VFloat)
166
167 instance HasPrecision (VComplex VFixed)
168
169 instance VariablePrecision (VComplex VFloat) where
170   adjustPrecision = withComplex (fmap adjustPrecision)
171
172 instance VariablePrecision (VComplex VFixed) where
173   adjustPrecision = withComplex (fmap adjustPrecision)
174
175 instance Normed (VComplex VFloat) where
176   norm1 z = abs (realPart z) + abs (imagPart z)
177   norm2 = magnitude
178   norm2Squared = magnitudeSquared
179   normInfinity z = abs (realPart z) `max` abs (imagPart z)
180
181 instance NaturalNumber p => Show (VComplex VFloat p) where
182   showsPrec p = showsPrec p . toComplex
183
184 instance NaturalNumber p => Show (VComplex VFixed p) where
185   showsPrec p = showsPrec p . toComplex
186
187 instance NaturalNumber p => Read (VComplex VFloat p) where
188   readsPrec p = map (first fromComplex) . readsPrec p
189     where first f (a, b) = (f a, b)
190
191 instance NaturalNumber p => Read (VComplex VFixed p) where
192   readsPrec p = map (first fromComplex) . readsPrec p
193     where first f (a, b) = (f a, b)
194
195 -- | Lift an operation on 'X.Complex' to one on 'VComplex'.
196 withComplex :: (Complex (t p) -> Complex (t q)) -> (VComplex t p -> VComplex t q)
197 withComplex f = fromComplex . f . toComplex
198
199 -- | Much like 'mapComplex' 'recodeFloat'.
200 recodeComplex :: (RealFloat a, RealFloat b) => Complex a -> Complex b
201 recodeComplex = fmap recodeFloat
202
203 -- | Much like 'withComplex' 'scaleComplex''.
204 scaleVComplex :: NaturalNumber p => Int -> VComplex VFloat p -> VComplex VFloat p
205 scaleVComplex = withComplex . scaleComplex
206
207 -- | Much like 'mapComplex' 'scaleFloat'.
208 scaleComplex :: RealFloat r => Int -> Complex r -> Complex r
209 scaleComplex = fmap . scaleFloat
210
211 -- | Freeze a 'VComplex VFloat'.
212 toComplexDFloat :: NaturalNumber p => VComplex VFloat p -> Complex DFloat
213 toComplexDFloat = fmap toDFloat . toComplex
214
215 -- | Freeze a 'VComplex VFixed'.
216 toComplexDFixed :: NaturalNumber p => VComplex VFixed p -> Complex DFixed
217 toComplexDFixed = fmap toDFixed . toComplex
218
219 -- | Thaw a 'Complex DFloat'.  Results in 'Nothing' on precision mismatch.
220 fromComplexDFloat :: NaturalNumber p => Complex DFloat -> Maybe (VComplex VFloat p)
221 fromComplexDFloat (x :+ y) = do
222   r <- fromDFloat x
223   i <- fromDFloat y
224   return (r .+ i)
225
226 -- | Thaw a 'Complex DFixed'.  Results in 'Nothing' on precision mismatch.
227 fromComplexDFixed :: NaturalNumber p => Complex DFixed -> Maybe (VComplex VFixed p)
228 fromComplexDFixed (x :+ y) = do
229   r <- fromDFixed x
230   i <- fromDFixed y
231   return (r .+ i)
232
233 -- | Thaw a 'Complex DFloat' to its natural precision.  'Nothing' is passed on
234 --   precision mismatch between real and imaginary parts.
235 withComplexDFloat :: Complex DFloat -> (forall p . NaturalNumber p => Maybe (VComplex VFloat p) -> r) -> r
236 withComplexDFloat (x :+ y) f = withDFloat x $ \r -> f $ do
237   i <- fromDFloat y
238   return (r .+ i)
239
240 -- | Thaw a 'Complex DFixed' to its natural precision.  'Nothing' is passed on
241 --   precision mismatch between real and imaginary parts.
242 withComplexDFixed :: Complex DFixed -> (forall p . NaturalNumber p => Maybe (VComplex VFixed p) -> r) -> r
243 withComplexDFixed (x :+ y) f = withDFixed x $ \r -> f $ do
244   i <- fromDFixed y
245   return (r .+ i)