summaryrefslogtreecommitdiff
path: root/packages/base/src/Data/Packed
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2014-05-24 13:32:58 +0200
committerAlberto Ruiz <aruiz@um.es>2014-05-24 13:32:58 +0200
commit5b6de561f131d75049fdb999e98a07939ec2e8e7 (patch)
treeb662ce05f56e2c4aa67243b0030a4786dc1fef0b /packages/base/src/Data/Packed
parent0a9ef8f5b0088c1ac25175bffca4ed95d9e109a5 (diff)
backward compatibility
Diffstat (limited to 'packages/base/src/Data/Packed')
-rw-r--r--packages/base/src/Data/Packed/Development.hs3
-rw-r--r--packages/base/src/Data/Packed/IO.hs2
-rw-r--r--packages/base/src/Data/Packed/Internal/Numeric.hs39
-rw-r--r--packages/base/src/Data/Packed/Matrix.hs13
-rw-r--r--packages/base/src/Data/Packed/Numeric.hs288
-rw-r--r--packages/base/src/Data/Packed/Vector.hs16
6 files changed, 326 insertions, 35 deletions
diff --git a/packages/base/src/Data/Packed/Development.hs b/packages/base/src/Data/Packed/Development.hs
index 1efedc9..72eb16b 100644
--- a/packages/base/src/Data/Packed/Development.hs
+++ b/packages/base/src/Data/Packed/Development.hs
@@ -25,8 +25,7 @@ module Data.Packed.Development (
25 unsafeFromForeignPtr, 25 unsafeFromForeignPtr,
26 unsafeToForeignPtr, 26 unsafeToForeignPtr,
27 check, (//), 27 check, (//),
28 at', atM', fi, table, 28 at', atM', fi
29 conformMs, conformVs, shSize, splitEvery
30) where 29) where
31 30
32import Data.Packed.Internal 31import Data.Packed.Internal
diff --git a/packages/base/src/Data/Packed/IO.hs b/packages/base/src/Data/Packed/IO.hs
index 94fb30a..f7afa80 100644
--- a/packages/base/src/Data/Packed/IO.hs
+++ b/packages/base/src/Data/Packed/IO.hs
@@ -18,12 +18,12 @@ module Data.Packed.IO (
18) where 18) where
19 19
20import Data.Packed 20import Data.Packed
21import Data.Packed.Development
22import Text.Printf(printf) 21import Text.Printf(printf)
23import Data.List(intersperse) 22import Data.List(intersperse)
24import Data.Complex 23import Data.Complex
25import Numeric.Vectorized(vectorScan,saveMatrix) 24import Numeric.Vectorized(vectorScan,saveMatrix)
26import Control.Applicative((<$>)) 25import Control.Applicative((<$>))
26import Data.Packed.Internal
27 27
28{- | Creates a string from a matrix given a separator and a function to show each entry. Using 28{- | Creates a string from a matrix given a separator and a function to show each entry. Using
29this function the user can easily define any desired display function: 29this function the user can easily define any desired display function:
diff --git a/packages/base/src/Data/Packed/Internal/Numeric.hs b/packages/base/src/Data/Packed/Internal/Numeric.hs
index 9cd18df..3c1c1d0 100644
--- a/packages/base/src/Data/Packed/Internal/Numeric.hs
+++ b/packages/base/src/Data/Packed/Internal/Numeric.hs
@@ -49,6 +49,7 @@ import Data.Complex
49import Control.Applicative((<*>)) 49import Control.Applicative((<*>))
50 50
51import Numeric.LinearAlgebra.LAPACK(multiplyR,multiplyC,multiplyF,multiplyQ) 51import Numeric.LinearAlgebra.LAPACK(multiplyR,multiplyC,multiplyF,multiplyQ)
52import Data.Packed.Internal
52 53
53------------------------------------------------------------------- 54-------------------------------------------------------------------
54 55
@@ -65,7 +66,9 @@ type instance ArgOf Matrix a = a -> a -> a
65------------------------------------------------------------------- 66-------------------------------------------------------------------
66 67
67-- | Basic element-by-element functions for numeric containers 68-- | Basic element-by-element functions for numeric containers
68class (Complexable c, Fractional e, Element e) => Container c e where 69class (Complexable c, Fractional e, Element e) => Container c e
70 where
71 size' :: c e -> IndexOf c
69 scalar' :: e -> c e 72 scalar' :: e -> c e
70 conj' :: c e -> c e 73 conj' :: c e -> c e
71 scale' :: e -> c e -> c e 74 scale' :: e -> c e -> c e
@@ -114,7 +117,9 @@ class (Complexable c, Fractional e, Element e) => Container c e where
114 117
115-------------------------------------------------------------------------- 118--------------------------------------------------------------------------
116 119
117instance Container Vector Float where 120instance Container Vector Float
121 where
122 size' = dim
118 scale' = vectorMapValF Scale 123 scale' = vectorMapValF Scale
119 scaleRecip = vectorMapValF Recip 124 scaleRecip = vectorMapValF Recip
120 addConstant = vectorMapValF AddConstant 125 addConstant = vectorMapValF AddConstant
@@ -125,7 +130,7 @@ instance Container Vector Float where
125 equal u v = dim u == dim v && maxElement (vectorMapF Abs (sub u v)) == 0.0 130 equal u v = dim u == dim v && maxElement (vectorMapF Abs (sub u v)) == 0.0
126 arctan2' = vectorZipF ATan2 131 arctan2' = vectorZipF ATan2
127 scalar' x = fromList [x] 132 scalar' x = fromList [x]
128 konst' = constant 133 konst' = constantD
129 build' = buildV 134 build' = buildV
130 conj' = id 135 conj' = id
131 cmap' = mapVector 136 cmap' = mapVector
@@ -142,7 +147,9 @@ instance Container Vector Float where
142 accum' = accumV 147 accum' = accumV
143 cond' = condV condF 148 cond' = condV condF
144 149
145instance Container Vector Double where 150instance Container Vector Double
151 where
152 size' = dim
146 scale' = vectorMapValR Scale 153 scale' = vectorMapValR Scale
147 scaleRecip = vectorMapValR Recip 154 scaleRecip = vectorMapValR Recip
148 addConstant = vectorMapValR AddConstant 155 addConstant = vectorMapValR AddConstant
@@ -153,7 +160,7 @@ instance Container Vector Double where
153 equal u v = dim u == dim v && maxElement (vectorMapR Abs (sub u v)) == 0.0 160 equal u v = dim u == dim v && maxElement (vectorMapR Abs (sub u v)) == 0.0
154 arctan2' = vectorZipR ATan2 161 arctan2' = vectorZipR ATan2
155 scalar' x = fromList [x] 162 scalar' x = fromList [x]
156 konst' = constant 163 konst' = constantD
157 build' = buildV 164 build' = buildV
158 conj' = id 165 conj' = id
159 cmap' = mapVector 166 cmap' = mapVector
@@ -170,7 +177,9 @@ instance Container Vector Double where
170 accum' = accumV 177 accum' = accumV
171 cond' = condV condD 178 cond' = condV condD
172 179
173instance Container Vector (Complex Double) where 180instance Container Vector (Complex Double)
181 where
182 size' = dim
174 scale' = vectorMapValC Scale 183 scale' = vectorMapValC Scale
175 scaleRecip = vectorMapValC Recip 184 scaleRecip = vectorMapValC Recip
176 addConstant = vectorMapValC AddConstant 185 addConstant = vectorMapValC AddConstant
@@ -181,7 +190,7 @@ instance Container Vector (Complex Double) where
181 equal u v = dim u == dim v && maxElement (mapVector magnitude (sub u v)) == 0.0 190 equal u v = dim u == dim v && maxElement (mapVector magnitude (sub u v)) == 0.0
182 arctan2' = vectorZipC ATan2 191 arctan2' = vectorZipC ATan2
183 scalar' x = fromList [x] 192 scalar' x = fromList [x]
184 konst' = constant 193 konst' = constantD
185 build' = buildV 194 build' = buildV
186 conj' = conjugateC 195 conj' = conjugateC
187 cmap' = mapVector 196 cmap' = mapVector
@@ -198,7 +207,9 @@ instance Container Vector (Complex Double) where
198 accum' = accumV 207 accum' = accumV
199 cond' = undefined -- cannot match 208 cond' = undefined -- cannot match
200 209
201instance Container Vector (Complex Float) where 210instance Container Vector (Complex Float)
211 where
212 size' = dim
202 scale' = vectorMapValQ Scale 213 scale' = vectorMapValQ Scale
203 scaleRecip = vectorMapValQ Recip 214 scaleRecip = vectorMapValQ Recip
204 addConstant = vectorMapValQ AddConstant 215 addConstant = vectorMapValQ AddConstant
@@ -209,7 +220,7 @@ instance Container Vector (Complex Float) where
209 equal u v = dim u == dim v && maxElement (mapVector magnitude (sub u v)) == 0.0 220 equal u v = dim u == dim v && maxElement (mapVector magnitude (sub u v)) == 0.0
210 arctan2' = vectorZipQ ATan2 221 arctan2' = vectorZipQ ATan2
211 scalar' x = fromList [x] 222 scalar' x = fromList [x]
212 konst' = constant 223 konst' = constantD
213 build' = buildV 224 build' = buildV
214 conj' = conjugateQ 225 conj' = conjugateQ
215 cmap' = mapVector 226 cmap' = mapVector
@@ -228,7 +239,9 @@ instance Container Vector (Complex Float) where
228 239
229--------------------------------------------------------------- 240---------------------------------------------------------------
230 241
231instance (Container Vector a) => Container Matrix a where 242instance (Container Vector a) => Container Matrix a
243 where
244 size' = size
232 scale' x = liftMatrix (scale' x) 245 scale' x = liftMatrix (scale' x)
233 scaleRecip x = liftMatrix (scaleRecip x) 246 scaleRecip x = liftMatrix (scaleRecip x)
234 addConstant x = liftMatrix (addConstant x) 247 addConstant x = liftMatrix (addConstant x)
@@ -637,7 +650,7 @@ diag v = diagRect 0 v n n where n = dim v
637 650
638-- | creates the identity matrix of given dimension 651-- | creates the identity matrix of given dimension
639ident :: (Num a, Element a) => Int -> Matrix a 652ident :: (Num a, Element a) => Int -> Matrix a
640ident n = diag (constant 1 n) 653ident n = diag (constantD 1 n)
641 654
642-------------------------------------------------------- 655--------------------------------------------------------
643 656
@@ -681,8 +694,12 @@ condV f a b l e t = f a' b' l' e' t'
681 694
682class Transposable t 695class Transposable t
683 where 696 where
697 -- | (conjugate) transpose
684 tr :: t -> t 698 tr :: t -> t
685 699
700instance (Container Vector t) => Transposable (Matrix t)
701 where
702 tr = ctrans
686 703
687class Linear t v 704class Linear t v
688 where 705 where
diff --git a/packages/base/src/Data/Packed/Matrix.hs b/packages/base/src/Data/Packed/Matrix.hs
index b3be823..2acb31a 100644
--- a/packages/base/src/Data/Packed/Matrix.hs
+++ b/packages/base/src/Data/Packed/Matrix.hs
@@ -226,15 +226,12 @@ takeDiag m = fromList [flatten m `at` (k*cols m+k) | k <- [0 .. min (rows m) (co
226 226
227------------------------------------------------------------ 227------------------------------------------------------------
228 228
229{- | An easy way to create a matrix: 229{- | create a general matrix
230 230
231>>> (2><3)[2,4,7,-3,11,0] 231>>> (2><3) [2, 4, 7+2*𝑖, -3, 11, 0]
232(2><3) 232(2><3)
233 [ 2.0, 4.0, 7.0 233 [ 2.0 :+ 0.0, 4.0 :+ 0.0, 7.0 :+ 2.0
234 , -3.0, 11.0, 0.0 ] 234 , (-3.0) :+ (-0.0), 11.0 :+ 0.0, 0.0 :+ 0.0 ]
235
236This is the format produced by the instances of Show (Matrix a), which
237can also be used for input.
238 235
239The input list is explicitly truncated, so that it can 236The input list is explicitly truncated, so that it can
240safely be used with lists that are too long (like infinite lists). 237safely be used with lists that are too long (like infinite lists).
@@ -244,6 +241,8 @@ safely be used with lists that are too long (like infinite lists).
244 [ 1.0, 2.0, 3.0 241 [ 1.0, 2.0, 3.0
245 , 4.0, 5.0, 6.0 ] 242 , 4.0, 5.0, 6.0 ]
246 243
244This is the format produced by the instances of Show (Matrix a), which
245can also be used for input.
247 246
248-} 247-}
249(><) :: (Storable a) => Int -> Int -> [a] -> Matrix a 248(><) :: (Storable a) => Int -> Int -> [a] -> Matrix a
diff --git a/packages/base/src/Data/Packed/Numeric.hs b/packages/base/src/Data/Packed/Numeric.hs
new file mode 100644
index 0000000..01cf6c5
--- /dev/null
+++ b/packages/base/src/Data/Packed/Numeric.hs
@@ -0,0 +1,288 @@
1{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE FunctionalDependencies #-}
6{-# LANGUAGE UndecidableInstances #-}
7
8-----------------------------------------------------------------------------
9-- |
10-- Module : Data.Packed.Numeric
11-- Copyright : (c) Alberto Ruiz 2010-14
12-- License : BSD3
13-- Maintainer : Alberto Ruiz
14-- Stability : provisional
15--
16-- Basic numeric operations on 'Vector' and 'Matrix', including conversion routines.
17--
18-- The 'Container' class is used to define optimized generic functions which work
19-- on 'Vector' and 'Matrix' with real or complex elements.
20--
21-- Some of these functions are also available in the instances of the standard
22-- numeric Haskell classes provided by "Numeric.LinearAlgebra".
23--
24-----------------------------------------------------------------------------
25{-# OPTIONS_HADDOCK hide #-}
26
27module Data.Packed.Numeric (
28 -- * Basic functions
29 module Data.Packed,
30 Konst(..), Build(..),
31 linspace,
32 diag, ident,
33 ctrans,
34 -- * Generic operations
35 Container(..),
36 -- add, mul, sub, divide, equal, scaleRecip, addConstant,
37 scalar, conj, scale, arctan2, cmap,
38 atIndex, minIndex, maxIndex, minElement, maxElement,
39 sumElements, prodElements,
40 step, cond, find, assoc, accum,
41 Transposable(..), Linear(..),
42 -- * Matrix product
43 Product(..), udot, dot, (◇),
44 Mul(..),
45 Contraction(..),(<.>),
46 optimiseMult,
47 mXm,mXv,vXm,LSDiv,(<\>),
48 outer, kronecker,
49 -- * Random numbers
50 RandDist(..),
51 randomVector,
52 gaussianSample,
53 uniformSample,
54 meanCov,
55 -- * Element conversion
56 Convert(..),
57 Complexable(),
58 RealElement(),
59
60 RealOf, ComplexOf, SingleOf, DoubleOf,
61
62 IndexOf,
63 module Data.Complex,
64 -- * IO
65 module Data.Packed.IO,
66 -- * Misc
67 Testable(..)
68) where
69
70import Data.Packed
71import Data.Packed.Internal.Numeric
72import Data.Complex
73import Numeric.LinearAlgebra.Algorithms(Field,linearSolveSVD)
74import Data.Monoid(Monoid(mconcat))
75import Data.Packed.IO
76import Numeric.LinearAlgebra.Random
77
78------------------------------------------------------------------
79
80{- | Creates a real vector containing a range of values:
81
82>>> linspace 5 (-3,7::Double)
83fromList [-3.0,-0.5,2.0,4.5,7.0]@
84
85>>> linspace 5 (8,2+i) :: Vector (Complex Double)
86fromList [8.0 :+ 0.0,6.5 :+ 0.25,5.0 :+ 0.5,3.5 :+ 0.75,2.0 :+ 1.0]
87
88Logarithmic spacing can be defined as follows:
89
90@logspace n (a,b) = 10 ** linspace n (a,b)@
91-}
92linspace :: (Container Vector e) => Int -> (e, e) -> Vector e
93linspace 0 (a,b) = fromList[(a+b)/2]
94linspace n (a,b) = addConstant a $ scale s $ fromList $ map fromIntegral [0 .. n-1]
95 where s = (b-a)/fromIntegral (n-1)
96
97--------------------------------------------------------
98
99{- | Matrix product, matrix - vector product, and dot product (equivalent to 'contraction')
100
101(This operator can also be written using the unicode symbol ◇ (25c7).)
102
103Examples:
104
105>>> let a = (3><4) [1..] :: Matrix Double
106>>> let v = fromList [1,0,2,-1] :: Vector Double
107>>> let u = fromList [1,2,3] :: Vector Double
108
109>>> a
110(3><4)
111 [ 1.0, 2.0, 3.0, 4.0
112 , 5.0, 6.0, 7.0, 8.0
113 , 9.0, 10.0, 11.0, 12.0 ]
114
115matrix × matrix:
116
117>>> disp 2 (a <.> trans a)
1183x3
119 30 70 110
120 70 174 278
121110 278 446
122
123matrix × vector:
124
125>>> a <.> v
126fromList [3.0,11.0,19.0]
127
128dot product:
129
130>>> u <.> fromList[3,2,1::Double]
13110
132
133For complex vectors the first argument is conjugated:
134
135>>> fromList [1,i] <.> fromList[2*i+1,3]
1361.0 :+ (-1.0)
137
138>>> fromList [1,i,1-i] <.> complex a
139fromList [10.0 :+ 4.0,12.0 :+ 4.0,14.0 :+ 4.0,16.0 :+ 4.0]
140-}
141infixl 7 <.>
142(<.>) :: Contraction a b c => a -> b -> c
143(<.>) = contraction
144
145
146class Contraction a b c | a b -> c
147 where
148 -- | Matrix product, matrix - vector product, and dot product
149 contraction :: a -> b -> c
150
151instance (Product t, Container Vector t) => Contraction (Vector t) (Vector t) t where
152 u `contraction` v = conj u `udot` v
153
154instance Product t => Contraction (Matrix t) (Vector t) (Vector t) where
155 contraction = mXv
156
157instance (Container Vector t, Product t) => Contraction (Vector t) (Matrix t) (Vector t) where
158 contraction v m = (conj v) `vXm` m
159
160instance Product t => Contraction (Matrix t) (Matrix t) (Matrix t) where
161 contraction = mXm
162
163
164--------------------------------------------------------------------------------
165
166class Mul a b c | a b -> c where
167 infixl 7 <>
168 -- | Matrix-matrix, matrix-vector, and vector-matrix products.
169 (<>) :: Product t => a t -> b t -> c t
170
171instance Mul Matrix Matrix Matrix where
172 (<>) = mXm
173
174instance Mul Matrix Vector Vector where
175 (<>) m v = flatten $ m <> asColumn v
176
177instance Mul Vector Matrix Vector where
178 (<>) v m = flatten $ asRow v <> m
179
180--------------------------------------------------------------------------------
181
182-- | least squares solution of a linear system, similar to the \\ operator of Matlab\/Octave (based on linearSolveSVD)
183infixl 7 <\>
184(<\>) :: (LSDiv c, Field t) => Matrix t -> c t -> c t
185(<\>) = linSolve
186
187class LSDiv c
188 where
189 linSolve :: Field t => Matrix t -> c t -> c t
190
191instance LSDiv Vector
192 where
193 linSolve m v = flatten (linearSolveSVD m (reshape 1 v))
194
195instance LSDiv Matrix
196 where
197 linSolve = linearSolveSVD
198
199--------------------------------------------------------------------------------
200
201class Konst e d c | d -> c, c -> d
202 where
203 -- |
204 -- >>> konst 7 3 :: Vector Float
205 -- fromList [7.0,7.0,7.0]
206 --
207 -- >>> konst i (3::Int,4::Int)
208 -- (3><4)
209 -- [ 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0
210 -- , 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0
211 -- , 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0, 0.0 :+ 1.0 ]
212 --
213 konst :: e -> d -> c e
214
215instance Container Vector e => Konst e Int Vector
216 where
217 konst = konst'
218
219instance Container Vector e => Konst e (Int,Int) Matrix
220 where
221 konst = konst'
222
223--------------------------------------------------------------------------------
224
225class Build d f c e | d -> c, c -> d, f -> e, f -> d, f -> c, c e -> f, d e -> f
226 where
227 -- |
228 -- >>> build 5 (**2) :: Vector Double
229 -- fromList [0.0,1.0,4.0,9.0,16.0]
230 --
231 -- Hilbert matrix of order N:
232 --
233 -- >>> let hilb n = build (n,n) (\i j -> 1/(i+j+1)) :: Matrix Double
234 -- >>> putStr . dispf 2 $ hilb 3
235 -- 3x3
236 -- 1.00 0.50 0.33
237 -- 0.50 0.33 0.25
238 -- 0.33 0.25 0.20
239 --
240 build :: d -> f -> c e
241
242instance Container Vector e => Build Int (e -> e) Vector e
243 where
244 build = build'
245
246instance Container Matrix e => Build (Int,Int) (e -> e -> e) Matrix e
247 where
248 build = build'
249
250--------------------------------------------------------------------------------
251
252-- | alternative unicode symbol (25c7) for 'contraction'
253(◇) :: Contraction a b c => a -> b -> c
254infixl 7 ◇
255(◇) = contraction
256
257-- | dot product: @cdot u v = 'udot' ('conj' u) v@
258dot :: (Container Vector t, Product t) => Vector t -> Vector t -> t
259dot u v = udot (conj u) v
260
261--------------------------------------------------------------------------------
262
263optimiseMult :: Monoid (Matrix t) => [Matrix t] -> Matrix t
264optimiseMult = mconcat
265
266--------------------------------------------------------------------------------
267
268
269{- | Compute mean vector and covariance matrix of the rows of a matrix.
270
271>>> meanCov $ gaussianSample 666 1000 (fromList[4,5]) (diagl[2,3])
272(fromList [4.010341078059521,5.0197204699640405],
273(2><2)
274 [ 1.9862461923890056, -1.0127225830525157e-2
275 , -1.0127225830525157e-2, 3.0373954915729318 ])
276
277-}
278meanCov :: Matrix Double -> (Vector Double, Matrix Double)
279meanCov x = (med,cov) where
280 r = rows x
281 k = 1 / fromIntegral r
282 med = konst k r `vXm` x
283 meds = konst 1 r `outer` med
284 xc = x `sub` meds
285 cov = scale (recip (fromIntegral (r-1))) (trans xc `mXm` xc)
286
287--------------------------------------------------------------------------------
288
diff --git a/packages/base/src/Data/Packed/Vector.hs b/packages/base/src/Data/Packed/Vector.hs
index 53fe563..31dcf47 100644
--- a/packages/base/src/Data/Packed/Vector.hs
+++ b/packages/base/src/Data/Packed/Vector.hs
@@ -17,17 +17,15 @@
17 17
18module Data.Packed.Vector ( 18module Data.Packed.Vector (
19 Vector, 19 Vector,
20 fromList, (|>), toList, buildVector, constant, 20 fromList, (|>), toList, buildVector,
21 dim, (@>), 21 dim, (@>),
22 subVector, takesV, vjoin, join, 22 subVector, takesV, vjoin, join,
23 mapVector, mapVectorWithIndex, zipVector, zipVectorWith, unzipVector, unzipVectorWith, 23 mapVector, mapVectorWithIndex, zipVector, zipVectorWith, unzipVector, unzipVectorWith,
24 mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, 24 mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_,
25 foldLoop, foldVector, foldVectorG, foldVectorWithIndex, 25 foldLoop, foldVector, foldVectorG, foldVectorWithIndex
26 stepD, stepF, condD, condF, conjugateC, conjugateQ
27) where 26) where
28 27
29import Data.Packed.Internal.Vector 28import Data.Packed.Internal.Vector
30import Data.Packed.Internal.Matrix
31import Foreign.Storable 29import Foreign.Storable
32 30
33------------------------------------------------------------------- 31-------------------------------------------------------------------
@@ -95,13 +93,3 @@ unzipVector = unzipVectorWith id
95join :: Storable t => [Vector t] -> Vector t 93join :: Storable t => [Vector t] -> Vector t
96join = vjoin 94join = vjoin
97 95
98{- | creates a vector with a given number of equal components:
99
100@> constant 2 7
1017 |> [2.0,2.0,2.0,2.0,2.0,2.0,2.0]@
102-}
103constant :: Element a => a -> Int -> Vector a
104-- constant x n = runSTVector (newVector x n)
105constant = constantD-- about 2x faster
106
107