import Data.Array.Repa as R
import Data.Array.Repa.Algorithms.Randomish
import System.CPUTime
import Data.Vector.Unboxed			(Vector)
import qualified Data.Vector.Unboxed		as V

len :: Int
len = 30000000
a :: Float
a = 1
b :: Float
b = 2
c :: Float
c = 3

ws = getVectorFloat len
xs = getVectorFloat len
ys = getVectorFloat len

main = do
	ws `deepSeqArray` xs `deepSeqArray` ys `deepSeqArray` return()
	do
		start <- getCPUTime
		print (norm a b c ws xs ys)
		stop <- getCPUTime
		print ((stop - start))
	

norm a b c ws xs ys = R.sum (R.map (\x->x*x) (R.map (a*) ws +^ R.map (b*) xs +^ R.map (c*) ys))

getVectorFloat len = randomishFloatArray (Z :. len) (-100) 100 12345



-- | Generate some randomish floats with terrible statistical properties.
--   This just takes randomish ints then scales them, so there's not much randomness in low-order bits.
randomishFloatArray
	:: Shape sh
	=> sh 			-- ^ Shape of array
	-> Float		-- ^ Minumum value in output.
	-> Float		-- ^ Maximum value in output.
	-> Int 			-- ^ Random seed.	
	-> Array sh Float	-- ^ Array of randomish numbers.

randomishFloatArray !sh !valMin !valMax !seed
	= fromVector sh $ randomishFloatVector (R.size sh) valMin valMax seed


-- | Generate some randomish floats with terrible statistical properties.
--   This just takes randmish ints then scales them, so there's not much randomness in low-order bits.
randomishFloatVector
	:: Int			-- ^ Length of vector
	-> Float		-- ^ Minimum value in output
	-> Float		-- ^ Maximum value in output
	-> Int			-- ^ Random seed.
	-> Vector Float	-- ^ Vector of randomish doubles.

randomishFloatVector !len !valMin !valMax !seed
 = let	range	= valMax - valMin

	mx	= 2^(30 :: Integer) - 1
	mxf	= fromIntegral mx
	ints	= randomishIntVector len 0 mx seed
	
   in	V.map (\n -> valMin + (fromIntegral n / mxf) * range) ints
