haskell-numerics / hmatrix

Linear algebra and numerical computation
381 stars 104 forks source link

Scale a vector with a complex scale factor #203

Closed fedeinthemix closed 8 years ago

fedeinthemix commented 8 years ago

One can scale a vector, where the scale factor is a complex number, with scale. However, the (*) operator appears not to work with a complex scalar:

ghci> let w = build 5 (\k -> iC*k)
ghci> scale iC w
[0.0 :+ 0.0,(-1.0) :+ 0.0,(-2.0) :+ 0.0,(-3.0) :+ 0.0,(-4.0) :+ 0.0]
ghci> iC * w

<interactive>:18:6:
    Couldn't match type ‘Vector C’ with ‘Complex Double’
    Expected type: C
      Actual type: Vector C
    In the second argument of ‘(*)’, namely ‘w’
    In the expression: iC * w

With real vectors and scalar factors both scale, and (*) work as I would expect:

ghci> let v = vector [0..4]
ghci> scale 2 v
[0.0,2.0,4.0,6.0,8.0]
ghci> 2 * v
[0.0,2.0,4.0,6.0,8.0]

Is this intended? Am I doing something wrong?

albertoruiz commented 8 years ago

You did nothing wrong. (*) is element-by-element multiplication of two vectors or two matrices. Both arguments in the standard (*) operator must be of the same type. For convenience, the instance of (*) in hmatrix automatically expands arrays of one single element:

λ> let v = vector [1,2,3]
λ> let w = vector [5,10,15]

λ> v * w
fromList [5.0,20.0,45.0]

λ> vector [3] * v
fromList [3.0,6.0,9.0]

λ> 3 * v
fromList [3.0,6.0,9.0]

In the last case the polymorphic literal 3 is interpreted as vector [3]

The problem is that iC is just a complex number, not a polymorphic numeric literal, and then it cannot be combined with a vector. We can use scale or scalar:

λ> scalar 3 :: Vector R
fromList [3.0]

λ> scalar 3 * v
fromList [3.0,6.0,9.0]

λ> scale iC (fromList [1,2,3])
fromList [0.0 :+ 1.0,0.0 :+ 2.0,0.0 :+ 3.0]

λ> scalar iC * fromList [1,2,3]
fromList [0.0 :+ 1.0,0.0 :+ 2.0,0.0 :+ 3.0]
fedeinthemix commented 8 years ago

Makes a lot of sense. Thanks for the explanation!