module E7 where import E8 (Vector,inp,e,showVector) import qualified E8 import Control.Applicative ((<$>),(<*>)) import Control.Arrow ((&&&)) import Control.Monad (msum) import qualified Data.Vector as V import Data.List (genericLength) import Data.Maybe (catMaybes) import qualified Number.Peano as Peano import Prelude hiding ((+)) import System.Environment (getArgs) import NumericPrelude ((+)) -- Main program main :: IO () main = do d : rest <- map read <$> getArgs putStr $ "d = " ++ show d ++ ": " if null rest then do let candidates = filter ((>= peano1) . snd) $ map (id &&& orthos) (gen d) special = filter ((<= peano8) . snd) candidates verySpecial = filter ((<= peano7) . snd) special case (map fst special,map fst verySpecial) of ([] ,_ ) -> putStrLn $ "No special vectors found." (x : _,[] ) -> putStrLn $ "No very special vectors, but found special vector:" ++ showVector x (_ ,x : _) -> putStrLn $ "Found very special vector:" ++ showVector x else putStrLn $ "Generated: " ++ show (length $ gen d) -- Compute the number of *positive* roots orthogonal to the given vector. orthos :: Vector -> Peano.T orthos = genericLength . filter (== 0) . flip map posRoots . inp peano1,peano7,peano8 :: Peano.T peano1 = 1 peano7 = 7 peano8 = 8 -- Let H be the group of permutations and even sign changes, a subgroup of -- the Weyl group of E_8. -- @E8.gen d@ intersects every H-orbit of E_8 (of vectors of length @d@). -- We want the intersection of every H-orbit with E_7 (or at least a -- representative of every W(E_7)-orbit of such). -- Now, since v \elem E_7 iff <v,e_7 + e_8> = 0 iff v_7 = -v_8, elements of -- this intersection occur precisely when the representative has two -- components that are equal up to sign change. -- This is made easier by the fact that 'E8.gen' gives vectors with -- nondecreasing successive coordinates. e7InOrbit :: Vector -> [Vector] e7InOrbit v = fmap V.fromList . concat . (zipWith3 f <$> id <*> tail <*> const [0 ..]) $ l where l = V.toList v f x y i = let (init,rest) = splitAt i l in case () of _ | x == y -> [negateFirst $ init ++ drop 2 rest ++ [x,negate y]] | x == negate y -> [ init ++ drop 2 rest ++ [x,y] ] | otherwise -> [] negateFirst (x : xs) = negate x : xs -- We want to generate elements of E_7, at least one out of every W(E_7)-orbit. -- This approach is not optimal: it may even give more than one element per -- $H `intersect` W(E_7)$-orbit. gen :: Int -> [Vector] gen = concatMap e7InOrbit . E8.gen -- test: -- *E7> mapM_ print . map (map numerator . V.toList) $ e7InOrbit v -- *E7> :m +Data.Ratio -- *E7 Data.Ratio> mapM_ print . map (map numerator . V.toList) $ e7InOrbit v e7 :: Vector -> Bool e7 = (== 0) . inp (e 7 + e 8) posRoots :: [Vector] posRoots = filter e7 E8.posRoots