Questions from New-Old User

Glynn Clements glynn.clements@virgin.net
Fri, 3 Jan 2003 06:04:15 +0000


Matthew Donadio wrote:

> First, I cannot get a function to type.  The basic definition is:
> 
> rxx x k | k >= 0 = sum [ (conjugate (x!k)) * x!(n+k) | k <- [0..(n-1-k)]
> ] / n
> 	| k < 0  = conjugate (rxx x (-k))
> 	where n = snd (bounds x) + 1
> 
> This function performs autocorrelation for a complex array, and returns
> a complex value.  The array indexes are integral in the general sense,
> but could be safely Int.  I have tried various combinations of explicit
> types and numeric type coersion functions without any success.  Any help
> would be appreciated.

My guess is that you didn't intend n to be complex, but it's being
inferred as such (the numerator of the division is determined to be
complex from the return type of conjugate, hence the denominator must
also be complex).

If this is the case, then you probably want something like:

        rxx x k | k >= 0 = sum [ ... ] / fromIntegral n
                                         ^^^^^^^^^^^^

This works for both ghc (5.04.2) and hugs (Dec 2001).

> The second question has to do with the numeric class system.  In signal
> processing and spectral estimation, there are a lot of algorithms that
> can operate on real and complex data.  In most cases, the only
> difference is the complex versions have conjugates in various places. 
> In the function above, the equivalent real valued version is the same if
> you either get rid of the conjugate applications, or assume that the
> conjugate function for real numbers is the identity function.
> 
> What is the best way to handle this?  I don't want to have separate
> functions for real and complex data, but I'm not sure of the proper way
> to add conjugate=I to to the class system for non-complex numbers.

I don't know about "best", but off the top of my head:

	class (Num a) => MaybeComplex a where
		conj :: a -> a
	
	instance (RealFloat a) => MaybeComplex (Complex a) where
		conj = conjugate
	
	instance MaybeComplex Float where
		conj = id
	
	instance MaybeComplex Double where
		conj = id

-- 
Glynn Clements <glynn.clements@virgin.net>