Movatterモバイル変換
[0]ホーム
{-# LANGUAGE DeriveDataTypeable #-}{-# LANGUAGE Trustworthy #-}{-# LANGUAGE StandaloneDeriving #-}{-# LANGUAGE DeriveGeneric #-}{-# LANGUAGE DeriveTraversable #-}------------------------------------------------------------------------------- |-- Module : Data.Complex-- Copyright : (c) The University of Glasgow 2001-- License : BSD-style (see the file libraries/base/LICENSE)---- Maintainer : libraries@haskell.org-- Stability : provisional-- Portability : portable---- Complex numbers.-------------------------------------------------------------------------------moduleData.Complex(-- * Rectangular formComplex((:+)),realPart,imagPart-- * Polar form,mkPolar,cis,polar,magnitude,phase-- * Conjugate,conjugate)whereimportGHC.Base(Applicative(..))importGHC.Generics(Generic,Generic1)importGHC.Float(Floating(..))importData.Data(Data)importForeign(Storable,castPtr,peek,poke,pokeElemOff,peekElemOff,sizeOf,alignment)infix6:+-- ------------------------------------------------------------------------------- The Complex type-- | Complex numbers are an algebraic type.---- For a complex number @z@, @'abs' z@ is a number with the magnitude of @z@,-- but oriented in the positive real direction, whereas @'signum' z@-- has the phase of @z@, but unit magnitude.---- The 'Foldable' and 'Traversable' instances traverse the real part first.---- Note that `Complex`'s instances inherit the deficiencies from the type-- parameter's. For example, @Complex Float@'s 'Ord' instance has similar-- problems to `Float`'s.dataComplexa=!a:+!a-- ^ forms a complex number from its real and imaginary-- rectangular components.deriving(Eq-- ^ @since 2.01,Show-- ^ @since 2.01,Read-- ^ @since 2.01,Data-- ^ @since 2.01,Generic-- ^ @since 4.9.0.0,Generic1-- ^ @since 4.9.0.0,Functor-- ^ @since 4.9.0.0,Foldable-- ^ @since 4.9.0.0,Traversable-- ^ @since 4.9.0.0)-- ------------------------------------------------------------------------------- Functions over Complex-- | Extracts the real part of a complex number.realPart::Complexa->arealPart(x:+_)=x-- | Extracts the imaginary part of a complex number.imagPart::Complexa->aimagPart(_:+y)=y-- | The conjugate of a complex number.{-# SPECIALISEconjugate::ComplexDouble->ComplexDouble#-}conjugate::Numa=>Complexa->Complexaconjugate(x:+y)=x:+(-y)-- | Form a complex number from polar components of magnitude and phase.{-# SPECIALISEmkPolar::Double->Double->ComplexDouble#-}mkPolar::Floatinga=>a->a->ComplexamkPolarrtheta=r*costheta:+r*sintheta-- | @'cis' t@ is a complex value with magnitude @1@-- and phase @t@ (modulo @2*'pi'@).{-# SPECIALISEcis::Double->ComplexDouble#-}cis::Floatinga=>a->Complexacistheta=costheta:+sintheta-- | 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.{-# SPECIALISEpolar::ComplexDouble->(Double,Double)#-}polar::(RealFloata)=>Complexa->(a,a)polarz=(magnitudez,phasez)-- | The nonnegative magnitude of a complex number.{-# SPECIALISEmagnitude::ComplexDouble->Double#-}magnitude::(RealFloata)=>Complexa->amagnitude(x:+y)=scaleFloatk(sqrt(sqr(scaleFloatmkx)+sqr(scaleFloatmky)))wherek=max(exponentx)(exponenty)mk=-ksqrz=z*z-- | The phase of a complex number, in the range @(-'pi', 'pi']@.-- If the magnitude is zero, then so is the phase.{-# SPECIALISEphase::ComplexDouble->Double#-}phase::(RealFloata)=>Complexa->aphase(0:+0)=0-- SLPJ July 97 from John Petersonphase(x:+y)=atan2yx-- ------------------------------------------------------------------------------- Instances of Complex-- | @since 2.01instance(RealFloata)=>Num(Complexa)where{-# SPECIALISEinstanceNum(ComplexFloat)#-}{-# SPECIALISEinstanceNum(ComplexDouble)#-}(x:+y)+(x':+y')=(x+x'):+(y+y')(x:+y)-(x':+y')=(x-x'):+(y-y')(x:+y)*(x':+y')=(x*x'-y*y'):+(x*y'+y*x')negate(x:+y)=negatex:+negateyabsz=magnitudez:+0signum(0:+0)=0signumz@(x:+y)=x/r:+y/rwherer=magnitudezfromIntegern=fromIntegern:+0-- | @since 2.01instance(RealFloata)=>Fractional(Complexa)where{-# SPECIALISEinstanceFractional(ComplexFloat)#-}{-# SPECIALISEinstanceFractional(ComplexDouble)#-}(x:+y)/(x':+y')=(x*x''+y*y'')/d:+(y*x''-x*y'')/dwherex''=scaleFloatkx'y''=scaleFloatky'k=-max(exponentx')(exponenty')d=x'*x''+y'*y''fromRationala=fromRationala:+0-- | @since 2.01instance(RealFloata)=>Floating(Complexa)where{-# SPECIALISEinstanceFloating(ComplexFloat)#-}{-# SPECIALISEinstanceFloating(ComplexDouble)#-}pi=pi:+0exp(x:+y)=expx*cosy:+expx*sinywhereexpx=expxlogz=log(magnitudez):+phasezx**y=case(x,y)of(_,(0:+0))->1:+0((0:+0),(exp_re:+_))->casecompareexp_re0ofGT->0:+0LT->inf:+0EQ->nan:+nan((re:+im),(exp_re:+_))|(isInfinitere||isInfiniteim)->casecompareexp_re0ofGT->inf:+0LT->0:+0EQ->nan:+nan|otherwise->exp(logx*y)whereinf=1/0nan=0/0sqrt(0:+0)=0sqrtz@(x:+y)=u:+(ify<0then-velsev)where(u,v)=ifx<0then(v',u')else(u',v')v'=absy/(u'*2)u'=sqrt((magnitudez+absx)/2)sin(x:+y)=sinx*coshy:+cosx*sinhycos(x:+y)=cosx*coshy:+(-sinx*sinhy)tan(x:+y)=(sinx*coshy:+cosx*sinhy)/(cosx*coshy:+(-sinx*sinhy))wheresinx=sinxcosx=cosxsinhy=sinhycoshy=coshysinh(x:+y)=cosy*sinhx:+siny*coshxcosh(x:+y)=cosy*coshx:+siny*sinhxtanh(x:+y)=(cosy*sinhx:+siny*coshx)/(cosy*coshx:+siny*sinhx)wheresiny=sinycosy=cosysinhx=sinhxcoshx=coshxasinz@(x:+y)=y':+(-x')where(x':+y')=log(((-y):+x)+sqrt(1-z*z))acosz=y'':+(-x'')where(x'':+y'')=log(z+((-y'):+x'))(x':+y')=sqrt(1-z*z)atanz@(x:+y)=y':+(-x')where(x':+y')=log(((1-y):+x)/sqrt(1+z*z))asinhz=log(z+sqrt(1+z*z))-- Take care to allow (-1)::Complex, fixing #8532acoshz=log(z+(sqrt$z+1)*(sqrt$z-1))atanhz=0.5*log((1.0+z)/(1.0-z))log1px@(a:+b)|absa<0.5&&absb<0.5,u<-2*a+a*a+b*b=log1p(u/(1+sqrt(u+1))):+atan2(1+a)b|otherwise=log(1+x){-# INLINElog1p#-}expm1x@(a:+b)|a*a+b*b<1,u<-expm1a,v<-sin(b/2),w<--2*v*v=(u*w+u+w):+(u+1)*sinb|otherwise=expx-1{-# INLINEexpm1#-}-- | @since 4.8.0.0instanceStorablea=>Storable(Complexa)wheresizeOfa=2*sizeOf(realParta)alignmenta=alignment(realParta)peekp=doq<-return$castPtrpr<-peekqi<-peekElemOffq1return(r:+i)pokep(r:+i)=doq<-return$(castPtrp)pokeqrpokeElemOffq1i-- | @since 4.9.0.0instanceApplicativeComplexwherepurea=a:+af:+g<*>a:+b=fa:+gbliftA2f(x:+y)(a:+b)=fxa:+fyb-- | @since 4.9.0.0instanceMonadComplexwherea:+b>>=f=realPart(fa):+imagPart(fb)-- ------------------------------------------------------------------------------- Rules on Complex{-# RULES"realToFrac/a->Complex Double"realToFrac=\x->realToFracx:+(0::Double)"realToFrac/a->Complex Float"realToFrac=\x->realToFracx:+(0::Float)#-}
[8]ページ先頭