f1 :: Mesh -> Matrix Double
f1 me = knx where
hx :: Double
(hx , _) = h me
a, knx :: Matrix Double
a = fromLists [[1,2], [3,4]]
knx = hx * a
-- knx = 2 * a
I don't get why in the above function, mutliplying by 2 works whereas multiplying by hx = 0.5 doesn't. OTOH, multiplying a Matrix Double with a Double outside a function works as it should.
Couldn't match expected type ‘Matrix Double’
with actual type ‘Double’
In the first argument of ‘(*)’, namely ‘hx’
In the expression: hx * a
Failed, modules loaded: none.
I am seriously puzzled. Any pointers are welcome!
In HMatrix, scale :: Container c e => e -> c e -> c e does what it says on the label (multiplies the e in a c e by the first e). Here are some usage examples here: https://hackage.haskell.org/package/hmatrix-0.16.1.4/docs/src/Data-Packed-Internal-Numeric.html
It should be noted that scale x constructs a Container type by considering x a singleton list, via fromList.
It would be really handy if at least the common arithmetic operations would be overloaded, so that formulas may resemble their mathematical counterpart. I'm not sure whether defining function synonyms (e.g. (.*) = scale ) would be a good idea or it would just add a layer of complexity. Any thoughts?
Related
I'm implementing a notion of inner product that's general over the container and numerical types. The definition states that the return type of this operation is a (non-negative) real number.
One option (shown below) is to write all instances by hand, for each numerical type (Float, Double, Complex Float, Complex Double, Complex CFloat, Complex CDouble, etc.). The primitive types aren't many, but I dislike the repetition.
Another option, or so I thought, is to have a parametric instance with a constraint such as RealFloat (which represents Float and Double).
{-# language MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-}
module Test where
import Data.Complex
class Hilbert c e where
type HT e :: *
dot :: c e -> c e -> HT e
instance Hilbert [] Double where
type HT Double = Double
dot x y = sum $ zipWith (*) x y
instance Hilbert [] (Complex Double) where
type HT (Complex Double) = Double
a `dot` b = realPart $ sum $ zipWith (*) (conjugate <$> a) b
Question
Why does the instance below not work ("Couldn't match type e with Double.. expected type HT e, actual type e")?
instance RealFloat e => Hilbert [] e where
type HT e = Double
dot x y = sum $ zipWith (*) x y
Well, that particular instance doesn't work because the sum only yields an e, but you want the result to be Double. As e is constrained to RealFrac, this is easy to fix though, as any Real (questionable though is is mathematically) can be converted to a Fractional:
dot x y = realToFrac . sum $ zipWith (*) x y
However, that generic instance prevents you from also defining complex instances: with instance RealFloat e => Hilbert [] e where you cover all types, even if they aren't really real numbers. You could still instantiate Complex as an overlapping instance, but I'd rather stay away from those if I could help it.
It's also questionable if such vectorspace classes should be defined on * -> * at all. Yes, linear also does it this way, but IMO parametricity doesn't work in our favour in this application. Have you checked out the vector-space package? Mind, it isn't exactly complete for doing serious linear algebra; that's a gap I hope to fill with my linearmap-category package.
I just started learning Haskell and am having trouble with
using the hmatrix library. I want to write some simple code
to compute the eigenvalue using the power iteration method.
I start with:
c = fromList [4.0, 4.0, 4.0, 4.0]::Vector Double
n = norm2 c
Which creates a vector c and finds the 2-norm of the vector.
Multiplication with c:
c * 2 (Works)
c * 0.5 (Works)
c * pi (Works)
c * n (Error)
I checked that:
>:t pi
pi :: Floating a => a
>:t n
n :: Double
The problem is with the types but I do not know how to get
around it.
Would I need to define my own (/) function in this case?
Update:
The error I obtain from ghci:
Couldn't match expected type `Vector Double'
with actual type `Double'
In the second argument of `(*)', namely `n'
In the expression: c * n
In an equation for `it': it = c * n
You're doing the right thing by checking the types. If we're a bit more explicit, we can see what is going on.
Prelude Numeric.LinearAlgebra> :t let a = 2; b = c * a in a
let a = 2; b = c * a in a :: Vector Double
The problem is that the type of norm2 c is Double and thus cannot be made into a Vector Double
Let's see the value of that polymorphic 2 from earlier.
Prelude Numeric.LinearAlgebra> let a = 2; b = c * a in a
fromList [2.0]
So instead, n = fromList [norm2 c]
Edit: The very same library exposes functions scalar and scale which you should look into.
(*) assumes that both of its arguments have the same type:
(*) :: (Num a) => a -> a -> a
The reason that your first three multiplications worked was because in all three cases the right argument successfully type-checked as a Vector Double!
To see why, let's ask ghci what the types of those three arguments are:
> :t 2
2 :: Num a => a
> :t 0.5
0.5 :: Fractional a => a
> :t pi
pi :: Floating a => a
All three of those are valid Vector Doubles because hmatrix provides the following three instances:
instance Num (Vector Double) where ...
instance Fractional (Vector Double) where ...
instance Floating (Vector Double) where ...
In other words, Haskell will transform 2, 0.5, and pi into Vector Doubles automatically, thanks to those instances.
This explains why your last example does not type check. n has type Double, which means that there is no chance it can ever type-check also as a Vector Double.
How to numerically integrate complex, complex-valued functions in Haskell?
Are there any existing libraries for it? numeric-tools operates only on reals.
I am aware that on complex plane there's only line integrals, so the interface I am interested in is something like this:
i = integrate f x a b precision
to calculate integral along straight line from a to b of function f on point x.
i, x, a, b are all of Complex Double or better Num a => Complex a type.
Please... :)
You can make something like this yourself. Suppose you have a function realIntegrate of type (Double -> Double) -> (Double,Double) -> Double, taking a function and a tuple containing the lower and upper bounds, returning the result to some fixed precision. You could define realIntegrate f (lo,hi) = quadRomberg defQuad (lo,hi) f using numeric-tools, for example.
Then we can make your desired function as follows - I'm ignoring the precision for now (and I don't understand what your x parameter is for!):
integrate :: (Complex Double -> Complex Double) -> Complex Double -> Complex Double -> Complex Double
integrate f a b = r :+ i where
r = realIntegrate realF (0,1)
i = realIntegrate imagF (0,1)
realF t = realPart (f (interpolate t)) -- or realF = realPart . f . interpolate
imagF t = imagPart (f (interpolate t))
interpolate t = a + (t :+ 0) * (b - a)
So we express the path from a to b as a function on the real interval from 0 to 1 by linear interpolation, take the value of f along that path, integrate the real and imaginary parts separately (I don't know if this can give numerically badly behaving results, though) and reassemble them into the final answer.
I haven't tested this code as I don't have numeric-tools installed, but at least it typechecks :-)
(Apologies for the weird title, but I could not think of a better one.)
For a personal Haskell project I want to have the concepts of 'absolute values' (like a frequency) and relative values (like the ratio between two frequencies). In my context, it makes no sense to add two absolute values: one can add relative values to produce new relative values, and add a relative value to an absolute one to produce a new absolute value (and likewise for subtraction).
I've defined type classes for these: see below. However, note that the operators ##+ and #+ have a similar structure (and likewise for ##- and #-). Therefore I would prefer to merge these operators, so that I have a single addition operator, which adds a relative value (and likewise a single subtraction operator, which results in a relative value). UPDATE: To clarify, my goal is to unify my ##+ and #+ into a single operator. My goal is not to unify this with the existing (Num) + operator.
However, I don't see how to do this with type classes.
Question: Can this be done, and if so, how? Or should I not be trying?
The following is what I currently have:
{-# LANGUAGE MultiParamTypeClasses #-}
class Abs a where
nullPoint :: a
class Rel r where
zero :: r
(##+) :: r -> r -> r
neg :: r -> r
(##-) :: Rel r => r -> r -> r
r ##- s = r ##+ neg s
class (Abs a, Rel r) => AbsRel a r where
(#+) :: a -> r -> a
(#-) :: a -> a -> r
I think you're looking for a concept called a Torsor. A torsor consists of set of values, set of differences, and operator which adds a difference to a value. Additionally, the set of differences must form an additive group, so differences also can be added together.
Interestingly, torsors are everywhere. Common examples include
Points and Vectors
Dates and date-differences
Files and diffs
etc.
One possible Haskell definition is:
class Torsor a where
type TorsorOf a :: *
(.-) :: a -> a -> TorsorOf a
(.+) :: a -> TorsorOf a -> a
Here are few example instances:
instance Torsor UTCTime where
type TorsorOf UTCTime = NominalDiffTime
a .- b = diffUTCTime a b
a .+ b = addUTCTime b a
instance Torsor Double where
type TorsorOf Double = Double
a .- b = a - b
a .+ b = a + b
instance Torsor Int where
type TorsorOf Int = Int
a .- b = a - b
a .+ b = a + b
In the last case, notice that the two sets of the torsors don't need to be a different set, which makes adding your relative values together simple.
For more information, see a much nicer description in Roman Cheplyakas blog
I don't think you should be trying to unify these operators. Subtracting two vectors and subtracting two points are fundamentally different operations. The fact that it's difficult to represent them as the same thing in the type system is not the type system being awkward - it's because these two concepts really are different things!
The mathematical framework behind what you're working with is the affine space.
These are already available in Haskell in the vector-space package (do cabal install vector-space at the command prompt). Rather than using multi parameter type classes, they use type families to associate a vector (relative) type with each point (absolute) type.
Here's a minimal example showing how to define your own absolute and relative data types, and their interaction:
{-# LANGUAGE TypeFamilies #-}
import Data.VectorSpace
import Data.AffineSpace
data Point = Point { px :: Float, py :: Float }
data Vec = Vec { vx :: Float, vy :: Float }
instance AdditiveGroup Vec where
zeroV = Vec 0 0
negateV (Vec x y) = Vec (-x) (-y)
Vec x y ^+^ Vec x' y' = Vec (x+x') (y+y')
instance AffineSpace Point where
type Diff Point = Vec
Point x y .-. Point x' y' = Vec (x-x') (y-y')
Point x y .+^ Vec x' y' = Point (x+x') (y+y')
You have two answers telling you what you should do, here's another answer telling you how to do what you asked for (which might not be a good idea). :)
class Add a b c | a b -> c where
(#+) :: a -> b -> c
instance Add AbsTime RelTime AbsTime where
(#+) = ...
instance Add RelTime RelTime RelTime where
(#+) = ...
The overloading for (#+) makes it very flexible. Too flexible, IMO. The only restraint is that the result type is determined by the argument types (without this FD the operator becomes almost unusable because it constrains nothing).
I have the following Haskell code:
-- Problem 69
import ProjectEuler
phi :: Integer -> Integer
phi n = n * product [p - 1 | p <- primeDivisors n] `div` product [p | p <- primeDivisors n]
-- primeDivisors n is a list of the prime divisors of n
maxRatio :: (Int, Int, Double) -> (Int, Int, Double) -> (Int, Int, Double)
maxRatio t1#(_, _, x) t2#(_, _, y)
| x > y = t1
| otherwise = t2
main = print (foldl
maxRatio
(0, 0, 0.0)
[(n, phi n, ratio) | n <- [2..max], let ratio = fromIntegral n / (fromIntegral (phi n))]
)
where max = 1000
which gives the following error:
Couldn't match expected type `Int' with actual type `Integer'
In the expression: n
In the expression: (n, phi n, ratio)
In the third argument of `foldl', namely
`[(n, phi n, ratio) |
n <- [2 .. max],
let ratio = fromIntegral n / (fromIntegral (phi n))]'
I suspect that in the triple (0, 0, 0.0) the 0's are type Int. Is 0 always type Int or is ghci deducing the type as Int in this case? If the later, how do I force it to be type Integer instead? Or is there something else that causes this error?
Haskell can generally infer the type of numeric literals such as 0 as whatever appropriate type you need them to be. This is because it knows what functions you pass them to; if I have a function phi :: Integer -> Integer, and I call phi 0, Haskell knows that that particular 0 must have been an Integer. It's also fine if I call a function pho :: Int -> Int with pho 0; that particular 0 is inferred to be an Int.
However Int and Integer are different types, and there's no way one particular 0 can be passed to both phi and pho.
Your issue is simply that the tuples that maxRatio deals with are typed (by you) (Int, Int, Double), but that one such tuple is constructed as (n, phi n, ratio). Since phi takes and returns Integer, the n in that expression has to be an Integer. But then that doesn't work for maxRatio, so you get the error.
Depending on which type you actually wanted (Int or Integer), all you need to do is change the type signature of phi or maxRatio so that they're working with the same kind of number. Haskell will decide that your literally written 0s are whatever numeric type is necessary to make that work, provided there is one that can make it work!
Note that the error messaged specifically told you that it was n in (n, phi n, ratio) that was expected to be an Int and was actually an Integer. The (0, 0, 0.0) tuple is never mentioned. Often type errors originate somewhere other than where the compiler points you (since all the compiler can do is spot that different chains of inference produce inconsistent requirements on the type of something, with no way to know which part of the whole process is "wrong"), but in this case it did pretty well.
Haskell gets a (fairly justified) bad rep for inscrutable error messages, but it can help a lot to start from what the compiler is telling you is the problem and try to figure out why the facts it's complaining about arise from your code. This will be painful at first, but you'll quickly develop a basic literacy in Haskell's error messages (at least the more straightforward ones) that will help you spot these kinds of errors really quickly, which makes the compiler a very powerful error-detection system for you.
n is being inferred as Int due to the type of maxRatio, while the type of phi says it should be Integer. The simplest fix is to change the type of maxRatio to use Integer or even just a since it doesn't touch those values.
It's being inferred, so you can just change the type signature of maxRatio. Still, if you ever need to change an explicit Int to an Integer, use toInteger :: (Integral a) => a -> Integer
Your type signatures are inconsistent - replace Int with Integer throughout.