{-# OPTIONS_GHC -fglasgow-exts #-}
module Main where

import Foreign.C.Types
import Random

----------------------------------------------------------------

import Prepose
import Domain
import Sparse
import Base

type V e a = Sparse CInt Double e a

-- 52
type Foo = (Plus (X5 (X2 (X_))))
-- 17
type Bar = (Plus (X1 (X7 (X_))))

main :: IO ()
main = do
    -- v is a pair-indexed vector; i.e. a matrix. v has 52 "rows" and 17 "columns"
    (v::V Double (L Foo, L Bar)) <-
    -- this fills it with 300 randomly-placed 1's
        getStdRandom $ randomFill 300

    -- dot product of v with itself; result is a scalar
    putStrLn $ "dot v v = "++(show $ dot v v)

    {- this defines v', a vector of vectors:

    v' :: V (V Double (L Bar)) (L Foo)

    the elements of v' are the "rows" of v; note the similarity
    between "vcurry" and "curry" -}
    let v' = vcurry v

    {- the result of a dot product is always of same type as the
    vector element, in this case the result has type 'V Double (L
    Bar)', i.e. it is a vector of 17 elements. this is the same as
    taking the dot product of each column of v with itself, and
    arranging the results in a vector -}
    putStrLn $ "dot v' v' = "++(show $ elems (dot v' v'))

-- example output:
-- dot v v = 434.0
-- dot v' v' = [13.0,40.0,21.0,23.0,16.0,29.0,23.0,24.0,28.0,20.0,24.0,40.0,31.0,37.0,19.0,18.0,28.0]

