module Math.RootLoci.CSM.Projective
(
delta_star
, pi_star
, tangentChernClass
, smallestOrbitCSM
, upperCSM , lowerCSM
, openCSM , closedCSM
, highestCoeff_ , lowestCoeff_
, highestCoeff , lowestCoeff
)
where
import Data.List
import Data.Maybe
import Math.Combinat.Numbers
import Math.Combinat.Sign
import Math.Combinat.Partitions.Integer
import Math.Combinat.Partitions.Set
import Math.Combinat.Sets
import qualified Data.Map as Map ; import Data.Map (Map)
import qualified Data.Set as Set ; import Data.Set (Set)
import Data.Array.IArray
import Data.Array (Array)
import Math.RootLoci.Algebra
import Math.RootLoci.Geometry
import Math.RootLoci.Misc
import qualified Math.RootLoci.Algebra.FreeMod as ZMod
pi_star_1 :: Int -> HS -> (G,Integer)
pi_star_1 n (HS hs) = (gk,c) where
c = factorial (n length hs)
gk = G (length hs)
pi_star
:: Int
-> ZMod HS
-> ZMod G
pi_star n = ZMod.flatMap (sing . pi_star_1 n) where
sing (b,c) = ZMod.singleton b c
delta_star_1 :: Partition -> US -> ZMod HS
delta_star_1 part@(Partition ps) (US us) = ZMod.histogram almost where
n = sum ps
d = length ps
idxtable = linearIndices part
stuff :: [[[H]]]
stuff = (map . map . map) H (go 1 idxtable)
almost :: [HS]
almost = map (HS . concat) $ listTensor stuff
uis = [ i | U i <- us ]
go :: Int -> [[Int]] -> [[[Int]]]
go _ [] = []
go k (is:iss) = this : go (k+1) iss where
this = if k `elem` uis
then [is]
else chooseN1 is
delta_star :: Partition -> ZMod US -> ZMod HS
delta_star part = ZMod.flatMap (delta_star_1 part)
tangentChernClass :: Int -> ZMod US
tangentChernClass d = ZMod.fromList $ concatMap worker [0..d] where
worker k = map (\xs -> (US (map U xs) , 2^k)) (choose_ k d)
smallestOrbitCSM :: Int -> ZMod G
smallestOrbitCSM n = ZMod.fromList
[ (G (n1) , fromIntegral n)
, (G n , 2 * fromIntegral n)
]
upperCSM :: Partition -> ZMod HS
upperCSM = pcache calc where
calc part@(Partition ps) = (delta_star part) (tangentChernClass d) where
d = length ps
lowerCSM :: Partition -> ZMod G
lowerCSM = pcache calc where
calc part@(Partition ps) = zmod where
d = length ps
n = sum ps
zmod = ZMod.fromList
[ ( G (nd+r) , coeff )
| r<-[0..d]
, let coeff = factorial (dr) * 2^r * symPolyNum (dr) (map fi ps)
]
fi :: Int -> Integer
fi = fromIntegral
check_lower_upper :: Int -> Bool
check_lower_upper n = and [ pi_star n (upperCSM p) == lowerCSM p | p <- partitions n ]
openCSM :: Partition -> ZMod G
openCSM = pcache calcOpenCSM where
calcOpenCSM :: Partition -> ZMod G
calcOpenCSM part = ZMod.invScale thisCoeff (pushdown smaller) where
n = partitionWeight part
pushdown = lowerCSM part
smaller = ZMod.linComb [ (c , openCSM q) | (q,c) <- Map.assocs theClosure ]
(thisCoeff,theClosure) = preimageView part
closedCSM :: Partition -> ZMod G
closedCSM = pcache calcClosedCSM where
calcClosedCSM :: Partition -> ZMod G
calcClosedCSM part = ZMod.sum [ openCSM q | q <- Set.toList (closureSet part) ]
lowestCoeff_ :: ZMod G -> Integer
lowestCoeff_ = snd . lowestCoeff
highestCoeff_ :: ZMod G -> Integer
highestCoeff_ = snd . highestCoeff
lowestCoeff :: ZMod G -> (G,Integer)
lowestCoeff = fromJust . ZMod.findMinTerm
highestCoeff :: ZMod G -> (G,Integer)
highestCoeff = fromJust . ZMod.findMaxTerm