{-# LANGUAGE BangPatterns, TypeSynonymInstances, FlexibleInstances #-}
module Math.RootLoci.CSM.Aluffi where
import Data.List
import Control.Monad
import Math.Combinat.Classes
import Math.Combinat.Numbers
import Math.Combinat.Sign
import Math.Combinat.Partitions.Integer
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 (Array)
import Data.Array.IArray
import Math.RootLoci.Algebra
import Math.RootLoci.Geometry
import Math.RootLoci.Classic
import Math.RootLoci.Misc
import qualified Math.Algebra.Polynomial.FreeModule as ZMod
aluffiOpenCSM :: Partition -> ZMod G
aluffiOpenCSM :: Partition -> ZMod G
aluffiOpenCSM part :: Partition
part@(Partition [Int]
ps) = Integer -> ZMod G -> ZMod G
forall b c.
(Ord b, Eq c, Integral c, Show c) =>
c -> FreeMod c b -> FreeMod c b
ZMod.divideByConst (Partition -> Integer
aut Partition
part) ZMod G
xsum where
n :: Int
n = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
ps
d :: Int
d = [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ps
xsum :: ZMod G
xsum = [(G, Integer)] -> ZMod G
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList [ ( Int -> G
G (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
k) , Int -> Integer
coeff Int
k ) | Int
k<-[Int
0..Int
d] ]
coeff :: Int -> Integer
coeff Int
k = Int -> Integer -> Integer
forall a b. (Integral a, Num b) => a -> b -> b
negateIfOdd Int
k
(Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Integer
signedBinomial (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
3) Int
k Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Integral a => a -> Integer
factorial Int
k Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Integral a => a -> Integer
factorial (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> [Integer] -> Integer
forall a. Num a => Int -> [a] -> a
symPolyNum (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k) ((Int -> Integer) -> [Int] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
ps)
aluffiClosedCSM :: Partition -> ZMod G
aluffiClosedCSM :: Partition -> ZMod G
aluffiClosedCSM part :: Partition
part@(Partition [Int]
ps) = [ZMod G] -> ZMod G
forall b c. (Ord b, Eq c, Num c) => [FreeMod c b] -> FreeMod c b
ZMod.sum [ZMod G]
opens where
opens :: [ZMod G]
opens = [ Partition -> ZMod G
aluffiOpenCSM Partition
q | Partition
q <- Set Partition -> [Partition]
forall a. Set a -> [a]
Set.toList (Partition -> Set Partition
closureSet Partition
part) ]
aluffiOpenEuler :: Partition -> Integer
aluffiOpenEuler :: Partition -> Integer
aluffiOpenEuler Partition
p = G -> ZMod G -> Integer
forall b c. (Ord b, Num c) => b -> FreeMod c b -> c
ZMod.coeffOf (Int -> G
G Int
n) (Partition -> ZMod G
aluffiOpenCSM Partition
p) where
n :: Int
n = Partition -> Int
partitionWeight Partition
p
aluffiClosedEuler :: Partition -> Integer
aluffiClosedEuler :: Partition -> Integer
aluffiClosedEuler Partition
p = G -> ZMod G -> Integer
forall b c. (Ord b, Num c) => b -> FreeMod c b -> c
ZMod.coeffOf (Int -> G
G Int
n) (Partition -> ZMod G
aluffiClosedCSM Partition
p) where
n :: Int
n = Partition -> Int
partitionWeight Partition
p
openEulerChar :: Partition -> Integer
openEulerChar :: Partition -> Integer
openEulerChar (Partition [Int]
ps) = case [Int]
ps of
[Int
n] -> Integer
2
[Int
a,Int
b] -> if Int
aInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
b then Integer
1 else Integer
2
[Int]
_ -> Integer
0
csmToEulerOfLinearSections
:: Int
-> ZMod G
-> [Integer]
csmToEulerOfLinearSections :: Int -> ZMod G -> [Integer]
csmToEulerOfLinearSections Int
n ZMod G
csm = [ Int -> Integer
euler Int
i | Int
i<-[Int
0..Int
n] ] where
csmArr :: Array Int Integer
csmArr = (Integer -> Integer -> Integer)
-> Integer -> (Int, Int) -> [(Int, Integer)] -> Array Int Integer
forall (a :: * -> * -> *) e i e'.
(IArray a e, Ix i) =>
(e -> e' -> e) -> e -> (i, i) -> [(i, e')] -> a i e
accumArray ((Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Integer -> Integer
forall a b. a -> b -> a
const) Integer
0 (Int
0,Int
n) [ (Int
i,Integer
c) | (G Int
i, Integer
c) <- ZMod G -> [(G, Integer)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList ZMod G
csm ] :: Array Int Integer
euler :: Int -> Integer
euler Int
k = (Integer -> Integer -> Integer) -> Integer -> [Integer] -> Integer
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) Integer
0 [ Int -> Int -> Integer
signedBinomial (-Int
k) Int
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Array Int Integer
csmArr Array Int Integer -> Int -> Integer
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) | Int
i<-[Int
0..Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k] ]
aluffiDegree :: Partition -> Integer
aluffiDegree :: Partition -> Integer
aluffiDegree Partition
part = [Integer]
list [Integer] -> Int -> Integer
forall a. [a] -> Int -> a
!! Partition -> Int
dimension Partition
part where
list :: [Integer]
list = Int -> ZMod G -> [Integer]
csmToEulerOfLinearSections (Partition -> Int
forall a. HasWeight a => a -> Int
weight Partition
part) (Partition -> ZMod G
aluffiClosedCSM Partition
part)