HaskellForMaths 0.4.1 → 0.4.2
raw patch · 52 files changed
+761/−265 lines, 52 files
Files
- HaskellForMaths.cabal +6/−2
- Math/Algebra/Field/Base.hs +7/−3
- Math/Algebra/Field/Extension.hs +8/−1
- Math/Algebra/Group/CayleyGraph.hs +2/−3
- Math/Algebra/Group/PermutationGroup.hs +46/−25
- Math/Algebra/Group/RandomSchreierSims.hs +1/−0
- Math/Algebra/Group/SchreierSims.hs +1/−0
- Math/Algebra/LinearAlgebra.hs +17/−5
- Math/Algebras/Commutative.hs +4/−4
- Math/Algebras/GroupAlgebra.hs +78/−12
- Math/Algebras/LaurentPoly.hs +2/−2
- Math/Algebras/Matrix.hs +4/−4
- Math/Algebras/NonCommutative.hs +1/−1
- Math/Algebras/Octonions.hs +3/−3
- Math/Algebras/Quaternions.hs +7/−7
- Math/Algebras/Structures.hs +15/−15
- Math/Algebras/TensorAlgebra.hs +28/−28
- Math/Algebras/TensorProduct.hs +12/−12
- Math/Algebras/VectorSpace.hs +13/−13
- Math/Combinatorics/Design.hs +2/−0
- Math/Combinatorics/FiniteGeometry.hs +13/−15
- Math/Combinatorics/Graph.hs +2/−9
- Math/Combinatorics/GraphAuts.hs +79/−24
- Math/Combinatorics/Hypergraph.hs +1/−0
- Math/Combinatorics/IncidenceAlgebra.hs +8/−8
- Math/Combinatorics/LatinSquares.hs +1/−0
- Math/Combinatorics/Matroid.hs +16/−14
- Math/Combinatorics/Poset.hs +1/−1
- Math/Combinatorics/StronglyRegularGraph.hs +1/−0
- Math/Common/IntegerAsType.hs +1/−1
- Math/CommutativeAlgebra/GroebnerBasis.hs +2/−2
- Math/CommutativeAlgebra/Polynomial.hs +9/−9
- Math/Core/Field.hs +30/−1
- Math/Core/Utils.hs +26/−0
- Math/NumberTheory/Factor.hs +4/−2
- Math/NumberTheory/Prime.hs +3/−3
- Math/Projects/KnotTheory/Braid.hs +1/−1
- Math/Projects/KnotTheory/IwahoriHecke.hs +1/−1
- Math/Projects/KnotTheory/TemperleyLieb.hs +1/−1
- Math/Projects/MiniquaternionGeometry.hs +2/−1
- Math/Projects/RootSystem.hs +0/−2
- Math/QuantumAlgebra/Tangle.hs +1/−1
- Math/Test/TAlgebras/TGroupAlgebra.hs +28/−16
- Math/Test/TAlgebras/TOctonions.hs +39/−0
- Math/Test/TAlgebras/TTensorProduct.hs +7/−0
- Math/Test/TAlgebras/TVectorSpace.hs +3/−2
- Math/Test/TCombinatorics/TFiniteGeometry.hs +67/−0
- Math/Test/TCombinatorics/TGraphAuts.hs +127/−0
- Math/Test/TCore/TField.hs +2/−1
- Math/Test/TFiniteGeometry.hs +9/−8
- Math/Test/TPermutationGroup.hs +2/−0
- Math/Test/TestAll.hs +17/−2
HaskellForMaths.cabal view
@@ -1,13 +1,14 @@ Name: HaskellForMaths - Version: 0.4.1 + Version: 0.4.2 Category: Math - Description: A library of maths code in the areas of combinatorics, group theory, commutative algebra, and non-commutative algebra. The library is mainly intended for educational purposes, but does have efficient implementations of several fundamental algorithms. + Description: A library of maths code in the areas of combinatorics, group theory, commutative algebra, and non-commutative algebra. The library is mainly intended as an educational resource, but does have efficient implementations of several fundamental algorithms. Synopsis: Combinatorics, group theory, commutative algebra, non-commutative algebra License: BSD3 License-file: license.txt Author: David Amos Maintainer: haskellformaths-at-gmail-dot-com Homepage: http://haskellformaths.blogspot.com/ + Stability: experimental Build-Type: Simple Cabal-Version: >=1.2 @@ -25,10 +26,13 @@ Math/Test/TAlgebras/TTensorProduct.hs Math/Test/TAlgebras/TStructures.hs Math/Test/TAlgebras/TQuaternions.hs + Math/Test/TAlgebras/TOctonions.hs Math/Test/TAlgebras/TMatrix.hs Math/Test/TAlgebras/TGroupAlgebra.hs Math/Test/TCombinatorics/TPoset.hs Math/Test/TCombinatorics/TDigraph.hs + Math/Test/TCombinatorics/TFiniteGeometry.hs + Math/Test/TCombinatorics/TGraphAuts.hs Math/Test/TCombinatorics/TIncidenceAlgebra.hs Math/Test/TCombinatorics/TMatroid.hs Math/Test/TCommutativeAlgebra/TPolynomial.hs
Math/Algebra/Field/Base.hs view
@@ -1,12 +1,12 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -fglasgow-exts #-} +{-# LANGUAGE GeneralizedNewtypeDeriving, ScopedTypeVariables #-} module Math.Algebra.Field.Base where import Data.Ratio import Math.Common.IntegerAsType - +import Math.Core.Utils -- RATIONALS @@ -55,13 +55,17 @@ in Fp $ u `mod` p where p = value (undefined :: n) -class Fractional fq => FiniteField fq where +-- Not sure if Eq fq is required, need to try with ghc >= 7.4.1 +class (Eq fq, Fractional fq) => FiniteField fq where eltsFq :: fq -> [fq] -- return all elts of the field basisFq :: fq -> [fq] -- return an additive basis for the field (as Z-module) instance IntegerAsType p => FiniteField (Fp p) where eltsFq _ = map fromInteger [0..p'-1] where p' = value (undefined :: p) basisFq _ = [fromInteger 1] + +instance IntegerAsType p => FinSet (Fp p) where + elts = map fromInteger [0..p'-1] where p' = value (undefined :: p) primitiveElt fq = head [x | x <- tail fq, length (powers x) == q-1] where q = length fq
Math/Algebra/Field/Extension.hs view
@@ -1,6 +1,6 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -fglasgow-exts #-} +{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, ScopedTypeVariables, EmptyDataDecls #-} module Math.Algebra.Field.Extension where @@ -8,6 +8,7 @@ import Data.List as L (elemIndex) import Math.Common.IntegerAsType +import Math.Core.Utils import Math.Algebra.Field.Base @@ -136,6 +137,12 @@ d = deg $ pvalue (undefined :: (k,poly)) basisFq _ = map embed $ take (d-1) $ iterate (*x) 1 where d = deg $ pvalue (undefined :: (k,poly)) + +-- Not sure if Eq fp is required, need to check with ghc >= 7.4.1 +instance (FinSet fp, Eq fp, Num fp, PolynomialAsType fp poly) => FinSet (ExtensionField fp poly) where + elts = map Ext (polys (d-1) fp') where + fp' = elts + d = deg $ pvalue (undefined :: (fp,poly)) embed f = Ext (convert f)
Math/Algebra/Group/CayleyGraph.hs view
@@ -4,6 +4,8 @@ module Math.Algebra.Group.CayleyGraph where +import Math.Core.Utils hiding (elts)+ import Math.Algebra.Group.StringRewriting as SR import Math.Combinatorics.Graph -- import Math.Combinatorics.GraphAuts@@ -11,9 +13,6 @@ import Math.Algebra.Group.PermutationGroup as P import qualified Data.List as L-import qualified Data.Set as S--toSet = S.toList . S.fromList data Digraph a = DG [a] [(a,a)] deriving (Eq,Ord,Show)
Math/Algebra/Group/PermutationGroup.hs view
@@ -1,5 +1,15 @@--- Copyright (c) David Amos, 2008-2009. All rights reserved. +-- Copyright (c) David Amos, 2008-2012. All rights reserved. +{-# LANGUAGE NoMonomorphismRestriction #-} + +-- |A module for doing arithmetic in permutation groups. +-- +-- Group elements are represented as permutations of underlying sets, and are entered and displayed +-- using a Haskell-friendly version of cycle notation. For example, the permutation (1 2 3)(4 5) +-- would be entered as @p [[1,2,3],[4,5]]@, and displayed as [[1,2,3],[4,5]]. Permutations can be defined +-- over arbitrary underlying sets (types), not just the integers. +-- +-- If @g@ and @h@ are group elements, then the expressions @g*h@ and @g^-1@ calculate product and inverse respectively. module Math.Algebra.Group.PermutationGroup where import qualified Data.List as L @@ -8,8 +18,11 @@ import Math.Common.ListSet (toListSet, union, (\\) ) -- a version of union which assumes the arguments are ascending sets (no repeated elements) -infix 8 ^-, ~^ +import Math.Core.Utils hiding (elts) +import Math.Algebra.LinearAlgebra hiding (inverse) -- only needed for use in ghci +infix 8 ~^ + rotateL (x:xs) = xs ++ [x] @@ -18,6 +31,11 @@ -- |A type for permutations, considered as functions or actions which can be performed on an underlying set. newtype Permutation a = P (M.Map a a) deriving (Eq,Ord) +-- |Construct a permutation from a list of cycles. +-- For example, @p [[1,2,3],[4,5]]@ returns the permutation that sends 1 to 2, 2 to 3, 3 to 1, 4 to 5, 5 to 4. +p :: (Ord a) => [[a]] -> Permutation a +p = fromCycles + fromPairs xys | isValid = fromPairs' xys | otherwise = error "Not a permutation" where (xs,ys) = unzip xys @@ -37,27 +55,23 @@ -- (This is guaranteed not to contain fixed points provided the permutations have been constructed using the supplied constructors) -- |x .^ g returns the image of a vertex or point x under the action of the permutation g. +-- For example, @1 .^ p [[1,2,3]]@ returns 2. -- The dot is meant to be a mnemonic for point or vertex. -(.^) :: (Ord k) => k -> Permutation k -> k +(.^) :: (Ord a) => a -> Permutation a -> a x .^ P g = case M.lookup x g of Just y -> y Nothing -> x -- if x `notElem` supp (P g), then x is not moved -- |b -^ g returns the image of an edge or block b under the action of the permutation g. +-- For example, @[1,2] -^ p [[1,4],[2,3]]@ returns [3,4]. -- The dash is meant to be a mnemonic for edge or line or block. -(-^) :: (Ord t) => [t] -> Permutation t -> [t] +(-^) :: (Ord a) => [a] -> Permutation a -> [a] xs -^ g = L.sort [x .^ g | x <- xs] -- construct a permutation from cycles fromCycles cs = fromPairs $ concatMap fromCycle cs where fromCycle xs = zip xs (rotateL xs) --- |Construct a permutation from a list of cycles. --- For example, p [[1,2,3],[4,5]] returns the permutation that sends 1 to 2, 2 to 3, 3 to 1, 4 to 5, 5 to 4 -p :: (Ord a) => [[a]] -> Permutation a -p cs = fromCycles cs --- can't specify in pointfree style because of monomorphism restriction - -- convert a permutation to cycles toCycles g = toCycles' $ supp g where toCycles' ys@(y:_) = let c = cycleOf g y in c : toCycles' (ys L.\\ c) @@ -77,23 +91,25 @@ orderElt g = foldl lcm 1 $ map length $ toCycles g -- == order [g] +-- |The Num instance is what enables us to write @g*h@ for the product of group elements and @1@ for the group identity. +-- Unfortunately we can't of course give sensible definitions for the other functions declared in the Num typeclass. instance (Ord a, Show a) => Num (Permutation a) where g * h = fromPairs' [(x, x .^ g .^ h) | x <- supp g `union` supp h] -- signum = sign -- doesn't work, complains about no (+) instance fromInteger 1 = P $ M.empty + _ + _ = error "(Permutation a).+: not applicable" + negate _ = error "(Permutation a).negate: not applicable" + abs _ = error "(Permutation a).abs: not applicable" + signum _ = error "(Permutation a).signum: not applicable" -inverse (P g) = P $ M.fromList $ map (\(x,y)->(y,x)) $ M.toList g +-- |The HasInverses instance is what enables us to write @g^-1@ for the inverse of a group element. +instance (Ord a, Show a) => HasInverses (Permutation a) where + inverse (P g) = P $ M.fromList $ map (\(x,y)->(y,x)) $ M.toList g --- |A trick: g^-1 returns the inverse of g -(^-) :: (Ord k, Show k) => Permutation k -> Int -> Permutation k -g ^- n = inverse g ^ n -instance (Ord a, Show a) => Fractional (Permutation a) where - recip = inverse - --- |g ~^ h returns the conjugate of g by h. +-- |g ~^ h returns the conjugate of g by h, that is, h^-1*g*h. -- The tilde is meant to a mnemonic, because conjugacy is an equivalence relation. -(~^) :: (Ord t, Show t) => Permutation t -> Permutation t -> Permutation t +(~^) :: (Ord a, Show a) => Permutation a -> Permutation a -> Permutation a g ~^ h = h^-1 * g * h -- commutator @@ -122,7 +138,7 @@ orbitV gs x = orbit (.^) x gs -- |b -^^ gs returns the orbit of the block or edge b under the action of the gs -(-^^) :: (Ord t) => [t] -> [Permutation t] -> [[t]] +(-^^) :: (Ord a) => [a] -> [Permutation a] -> [[a]] b -^^ gs = orbit (-^) b gs orbitB gs b = orbit (-^) b gs @@ -174,9 +190,9 @@ t = p [[1,2,3]] --- Direct product of groups --- Given generators for H and K, acting on sets X and Y respectively, --- return generators for H*K, acting on the disjoint union X+Y (== Either X Y) +-- |Given generators for groups H and K, acting on sets A and B respectively, +-- return generators for the direct product H*K, acting on the disjoint union A+B (= Either A B) +dp :: (Ord a, Ord b) => [Permutation a] -> [Permutation b] -> [Permutation (Either a b)] dp hs ks = [P $ M.fromList $ map (\(x,x') -> (Left x,Left x')) $ M.toList h' | P h' <- hs] ++ [P $ M.fromList $ map (\(y,y') -> (Right y,Right y')) $ M.toList k' | P k' <- ks] @@ -300,9 +316,9 @@ conjClass gs h = closure [h] [ (~^ g) | g <- gs] -- conjClass gs h = h ~^^ gs --- |conjClassReps gs returns a conjugacy class representatives and sizes for the group generated by gs. +-- |conjClassReps gs returns conjugacy class representatives and sizes for the group generated by gs. -- This implementation is only suitable for use with small groups (|G| < 10000). -conjClassReps :: (Ord t, Show t) => [Permutation t] -> [(Permutation t, Int)] +conjClassReps :: (Ord a, Show a) => [Permutation a] -> [(Permutation a, Int)] conjClassReps gs = conjClassReps' (elts gs) where conjClassReps' (h:hs) = let cc = conjClass gs h in (h, length cc) : conjClassReps' (hs \\ cc) @@ -440,4 +456,9 @@ -- in cube gp, the subgps all appear to correspond to stabilisers of subsets, or of blocks +-- right regular permutation representation +rrpr gs h = rrpr' (elts gs) h +rrpr' gs h = fromPairs [(g, g*h) | g <- gs] + +permutationMatrix xs g = [ [if x .^ g == y then 1 else 0 | y <- xs] | x <- xs ]
Math/Algebra/Group/RandomSchreierSims.hs view
@@ -13,6 +13,7 @@ import System.IO.Unsafe import Math.Common.ListSet (toListSet)+import Math.Core.Utils hiding (elts) import Math.Algebra.Group.PermutationGroup import Math.Algebra.Group.SchreierSims (sift, cosetRepsGx, ss')
Math/Algebra/Group/SchreierSims.hs view
@@ -8,6 +8,7 @@ import qualified Data.Map as M import Math.Algebra.Group.PermutationGroup hiding (elts, order, gens, isMember, isSubgp, isNormal, reduceGens, normalClosure, commutatorGp, derivedSubgp) import Math.Common.ListSet (toListSet) +import Math.Core.Utils hiding (elts) -- COSET REPRESENTATIVES FOR STABILISER OF A POINT
Math/Algebra/LinearAlgebra.hs view
@@ -1,6 +1,4 @@--- Copyright (c) David Amos, 2008. All rights reserved. - -{-# OPTIONS_GHC -fglasgow-exts #-} +-- Copyright (c) 2008-2012, David Amos. All rights reserved. -- |A module providing elementary operations involving scalars, vectors, and matrices -- over a ring or field. Vectors are represented as [a], matrices as [[a]]. @@ -165,7 +163,6 @@ inverse2 ((1:r):rs) = inverse2' r rs : inverse2 rs where inverse2' xs [] = xs inverse2' (x:xs) ((1:r):rs) = inverse2' (xs <-> x *> r) rs --- This is basically reduced row echelon form xs ! i = xs !! (i-1) -- ie, a 1-based list lookup instead of 0-based @@ -187,6 +184,21 @@ reduceStep rs@((0:_):_) = zipWith (:) (map head rs) (reduceStep $ map tail rs) reduceStep rs = rs +-- Given a matrix m and (column) vector b, either find (column vector) x such that m x == b, +-- or indicate that there is none +solveLinearSystem m b = + let augmented = zipWith (\r x -> r ++ [x]) m b -- augmented matrix + trisystem = inverse1 augmented -- upper triangular form + solution = reverse $ solveTriSystem $ reverse $ map reverse trisystem + in if length solution == length b then Just solution else Nothing + where solveTriSystem ([v,c]:rs) = + let x = v/c -- the first row tells us that cx == v + rs' = map (\(v':c':r) -> (v'-c'*x):r) rs + in x : solveTriSystem rs' + solveTriSystem [] = [] + solveTriSystem _ = [] -- abnormal termination - m wasn't invertible + + isZero v = all (==0) v -- inSpanRE m v returns whether the vector v is in the span of the matrix m, where m is required to be in row echelon form @@ -213,7 +225,7 @@ findLeadingCols i (c@(0:_):cs) = findLeadingCols (i+1) cs findLeadingCols _ _ = [] -m ^- n = recip m ^ n +-- m ^- n = recip m ^ n -- t (M m) = M (L.transpose m)
Math/Algebras/Commutative.hs view
@@ -47,7 +47,7 @@ -} -- This is the monoid algebra for commutative monomials (which are the free commutative monoid)-instance (Num k, Ord v) => Algebra k (GlexMonomial v) where+instance (Eq k, Num k, Ord v) => Algebra k (GlexMonomial v) where unit x = x *> return munit where munit = Glex 0 [] mult xy = nf $ fmap (\(a,b) -> a `mmult` b) xy@@ -55,7 +55,7 @@ -- GlexPoly can be given the set coalgebra structure, which is compatible with the monoid algebra structure-instance Num k => Coalgebra k (GlexMonomial v) where+instance (Eq k, Num k) => Coalgebra k (GlexMonomial v) where counit = unwrap . nf . fmap (\m -> () ) -- trace -- counit (V ts) = sum [x | (m,x) <- ts] -- trace comult = fmap (\m -> (m,m) ) -- diagonal@@ -78,7 +78,7 @@ -- |In effect, we have (Num k, Monomial m) => Monad (\v -> Vect k (m v)), with return = var, and (>>=) = bind. -- However, we can't express this directly in Haskell, firstly because of the Ord b constraint, -- secondly because Haskell doesn't support type functions.-bind :: (Monomial m, Num k, Ord b, Show b, Algebra k b) =>+bind :: (Monomial m, Eq k, Num k, Ord b, Show b, Algebra k b) => Vect k (m v) -> (v -> Vect k b) -> Vect k b V ts `bind` f = sum [c *> product [f x ^ i | (x,i) <- powers m] | (m, c) <- ts] -- flipbind f = linear (\m -> product [f x ^ i | (x,i) <- powers m])@@ -120,7 +120,7 @@ infixl 7 %% -- |(%%) reduces a polynomial with respect to a list of polynomials.-(%%) :: (Fractional k, Ord b, Show b, Algebra k b, DivisionBasis b)+(%%) :: (Eq k, Fractional k, Ord b, Show b, Algebra k b, DivisionBasis b) => Vect k b -> [Vect k b] -> Vect k b f %% gs = r where (_,r) = quotRemMP f gs
Math/Algebras/GroupAlgebra.hs view
@@ -1,18 +1,35 @@--- Copyright (c) 2010, David Amos. All rights reserved.+-- Copyright (c) 2010-2012, David Amos. All rights reserved. -{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances #-}+-- ScopedTypeVariables +-- |A module for doing arithmetic in the group algebra.+--+-- Group elements are represented as permutations of the integers, and are entered and displayed+-- using a Haskell-friendly version of cycle notation. For example, the permutation (1 2 3)(4 5)+-- would be entered as @p [[1,2,3],[4,5]]@, and displayed as [[1,2,3],[4,5]].+--+-- Given a field K and group G, the group algebra KG is the free K-vector space over the elements of G.+-- Elements of the group algebra consists of arbitrary K-linear combinations of elements of G.+-- For example, @p [[1,2,3]] + 2 * p [[1,2],[3,4]]@ module Math.Algebras.GroupAlgebra where +import Math.Core.Field+import Math.Core.Utils+ import Math.Algebras.VectorSpace import Math.Algebras.TensorProduct import Math.Algebras.Structures -import Math.Algebra.Group.PermutationGroup hiding (action)+import Math.Algebra.Group.PermutationGroup hiding (p, action)+import qualified Math.Algebra.Group.PermutationGroup as P -import Math.Algebra.Field.Base+import Math.Algebra.LinearAlgebra hiding (inverse, (*>) ) +import Math.CommutativeAlgebra.Polynomial+import Math.CommutativeAlgebra.GroebnerBasis + instance Mon (Permutation Int) where munit = 1 mmult = (*)@@ -20,7 +37,7 @@ type GroupAlgebra k = Vect k (Permutation Int) -- Monoid Algebra instance-instance Num k => Algebra k (Permutation Int) where+instance (Eq k, Num k) => Algebra k (Permutation Int) where unit 0 = zero -- V [] unit x = V [(munit,x)] mult = nf . fmap (\(a,b) -> a `mmult` b)@@ -28,27 +45,76 @@ -- Set Coalgebra instance -- instance SetCoalgebra (Permutation Int) where {} -instance Num k => Coalgebra k (Permutation Int) where+instance (Eq k, Num k) => Coalgebra k (Permutation Int) where counit (V ts) = sum [x | (m,x) <- ts] -- trace comult = fmap (\m -> (m,m)) -- diagonal -instance Num k => Bialgebra k (Permutation Int) where {}+instance (Eq k, Num k) => Bialgebra k (Permutation Int) where {} -- should check that the algebra and coalgebra structures are compatible -instance (Num k) => HopfAlgebra k (Permutation Int) where+instance (Eq k, Num k) => HopfAlgebra k (Permutation Int) where antipode (V ts) = nf $ V [(g^-1,x) | (g,x) <- ts] --- inject permutation into group algebra-ip :: [[Int]] -> GroupAlgebra Q-ip cs = return $ p cs+-- |Construct a permutation, as an element of the group algebra, from a list of cycles.+-- For example, @p [[1,2],[3,4,5]]@ constructs the permutation (1 2)(3 4 5), which is displayed+-- as [[1,2],[3,4,5]].+p :: [[Int]] -> GroupAlgebra Q+p cs = return $ P.p cs -instance Num k => Module k (Permutation Int) Int where+instance (Eq k, Num k) => Module k (Permutation Int) Int where action = nf . fmap (\(g,x) -> x .^ g) -- use *. instead -- r *> m = action (r `te` m) +newtype X a = X a deriving (Eq,Ord,Show) +-- Find the inverse of a group algebra element using Groebner basis techniques+-- This is overkill, but it was what I had to hand at first+inv x@(V ts) =+ let gs = P.elts $ map fst $ terms x -- all elements in the group generated by the terms+ cs = map (glexvar . X) gs+ x' = V $ map (\(g,c) -> (g, unit c)) ts+ one = x' * (V $ zip gs cs)+ oneEquations = (coeff 1 one - 1) : [coeff g one - 0 | g <- tail gs]+ zeroEquations = [coeff g one - 0 | g <- gs]+ solution = gb oneEquations+ in if solution == [1]+ then Left (gb zeroEquations) -- it's a zero divisor+ else Right solution+ -- sum [-c *> p g | V [ (Glex (M 1 [(X g, 1)]), 1), (Glex (M 0 []), c) ] <- solution]+ -- should extract the solution into a group algebra element, but having trouble getting types right +-- The following code can be made to work over an arbitrary field by uncommenting the commented code+-- However, we should then probably also change the signature of p to p :: Fractional k => [[Int]] -> GroupAlgebra k+-- instance Fractional k => HasInverses (GroupAlgebra k) where +-- |Note that the inverse of a group algebra element can only be efficiently calculated+-- if the group generated by the non-zero terms is very small (eg \<100 elements).+instance HasInverses (GroupAlgebra Q) where+ inverse x@(V ts) =+ let gs = P.elts $ map fst $ terms x -- all elements in the group generated by the terms+ -- cs = map (var . X) gs :: [Vect k (Glex (X (Permutation Int)))]+ cs = map (glexvar . X) gs+ x' = V $ map (\(g,c) -> (g, unit c)) ts+ one = x' * (V $ zip gs cs)+ m = [ [coeff (mvar (X j)) c | j <- gs] | i <- gs, let c = coeff i one]+ b = 1 : replicate (length gs - 1) 0+ in case solveLinearSystem m b of+ Just v -> nf $ V $ zip gs v+ Nothing -> error "GroupAlgebra.inverse: not invertible"++maybeInverse x@(V ts) =+ let gs = P.elts $ map fst $ terms x -- all elements in the group generated by the terms+ cs = map (glexvar . X) gs+ x' = V $ map (\(g,c) -> (g, unit c)) ts+ one = x' * (V $ zip gs cs)+ m = [ [coeff (mvar (X j)) c | j <- gs] | i <- gs, let c = coeff i one]+ b = 1 : replicate (length gs - 1) 0+ in fmap (\v -> nf $ V $ zip gs v) (solveLinearSystem m b)+{-+ in case solveLinearSystem m b of+ Just v -> Just $ nf $ V $ zip gs v+ Nothing -> Nothing+-}
Math/Algebras/LaurentPoly.hs view
@@ -31,7 +31,7 @@ munit = LM 0 [] mmult (LM si xis) (LM sj yjs) = LM (si+sj) $ addmerge xis yjs -instance Num k => Algebra k LaurentMonomial where+instance (Eq k, Num k) => Algebra k LaurentMonomial where unit 0 = zero -- V [] unit x = V [(munit,x)] mult (V ts) = nf $ fmap (\(a,b) -> a `mmult` b) (V ts)@@ -49,7 +49,7 @@ lvar v = V [(LM 1 [(v,1)], 1)] :: LaurentPoly Q -instance Fractional k => Fractional (LaurentPoly k) where+instance (Eq k, Fractional k) => Fractional (LaurentPoly k) where recip (V [(LM si xis,c)]) = V [(LM (-si) $ map (\(x,i)->(x,-i)) xis, recip c)] recip _ = error "LaurentPoly.recip: only defined for single terms"
Math/Algebras/Matrix.hs view
@@ -22,7 +22,7 @@ data Mat2 = E2 Int Int deriving (Eq,Ord,Show) -- E i j represents the elementary matrix with a 1 at the (i,j) position, and 0s elsewhere -instance Num k => Algebra k Mat2 where+instance (Eq k, Num k) => Algebra k Mat2 where unit x = x *> V [(E2 i i, 1) | i <- [1..2] ] mult = linear mult' where mult' (E2 i j, E2 k l) = delta j k *> return (E2 i l)@@ -33,7 +33,7 @@ -- mult (a1 b1) `te` (a2 b2) = (a1 b1) * (a2 b2) = (a b) -- (c1 d1) (c2 d2) (c1 d1) (c2 d2) (c d) -instance Num k => Module k Mat2 EBasis where+instance (Eq k, Num k) => Module k Mat2 EBasis where -- action ax = nf $ ax >>= action' where action = linear action' where action' (E2 i j, E k) = delta j k `smultL` return (E i)@@ -55,7 +55,7 @@ -- E2' i j represents the dual basis element corresponding to E i j -- Kassel p42-instance Num k => Coalgebra k Mat2' where+instance (Eq k, Num k) => Coalgebra k Mat2' where counit (V ts) = sum [xij * delta i j | (E2' i j, xij) <- ts] -- comult (V ts) = V $ concatMap (\(E2' i j,xij) -> [(T (E2' i k) (E2' k j), xij) | k <- [1..2]]) ts comult = linear (\(E2' i j) -> foldl (<+>) zero [return (E2' i k, E2' k j) | k <- [1..2]])@@ -73,7 +73,7 @@ data M3 = E3 Int Int deriving (Eq,Ord,Show) -- E i j represents the elementary matrix with a 1 at the (i,j) position, and 0s elsewhere -instance Num k => Algebra k M3 where+instance (Eq k, Num k) => Algebra k M3 where unit 0 = zero -- V [] unit x = V [(E3 i i, x) | i <- [1..3] ] -- mult (V ts) = nf $ V $ map (\((E3 i j, E3 k l), x) -> (E3 i l, delta j k * x)) ts
Math/Algebras/NonCommutative.hs view
@@ -29,7 +29,7 @@ munit = NCM 0 [] mmult (NCM i xs) (NCM j ys) = NCM (i+j) (xs++ys) -instance (Num k, Ord v) => Algebra k (NonComMonomial v) where+instance (Eq k, Num k, Ord v) => Algebra k (NonComMonomial v) where unit 0 = zero -- V [] unit x = V [(munit,x)] mult = nf . fmap (\(a,b) -> a `mmult` b)
Math/Algebras/Octonions.hs view
@@ -5,7 +5,7 @@ -- |A module defining the (non-associative) algebra of octonions over an arbitrary field. -- -- The octonions are the algebra defined by the basis {1,i0,i1,i2,i3,i4,i5,i6},--- where each i_n^2 = -1, and i_n+1*i_n+2 = i_n+4 (where the indices are modulo 7).+-- where each i_n * i_n = -1, and i_n+1 * i_n+2 = i_n+4 (where the indices are modulo 7). module Math.Algebras.Octonions where import Math.Core.Field@@ -43,7 +43,7 @@ i_ :: Num k => Int -> Octonion k i_ n = return (O n) -instance (Num k) => Algebra k OBasis where+instance (Eq k, Num k) => Algebra k OBasis where unit x = x *> return (O (-1)) mult = linear m where m (O (-1), O n) = return (O n)@@ -57,7 +57,7 @@ 5 -> -1 *> i_ ((a+4) `mod` 7) -- i_n+4 * i_n+2 == -i_n+1 6 -> -1 *> i_ ((a+2) `mod` 7) -- i_n+2 * i_n+1 == -i_n+4 -instance Num k => HasConjugation k OBasis where+instance (Eq k, Num k) => HasConjugation k OBasis where conj = (>>= conj') where conj' (O n) = (if n == -1 then 1 else -1) *> return (O n) -- ie conj = linear conj', but avoiding unnecessary nf call
Math/Algebras/Quaternions.hs view
@@ -27,7 +27,7 @@ show J = "j" show K = "k" -instance (Num k) => Algebra k HBasis where+instance (Eq k, Num k) => Algebra k HBasis where unit x = x *> return One mult = linear mult' where mult' (One,b) = return b@@ -69,7 +69,7 @@ -- |If an algebra has a conjugation operation, then it has multiplicative inverses, -- via 1/x = conj x / sqnorm x-instance (Fractional k, Ord a, Show a, HasConjugation k a) => Fractional (Vect k a) where+instance (Eq k, Fractional k, Ord a, Show a, HasConjugation k a) => Fractional (Vect k a) where recip 0 = error "recip 0" recip x = (1 / sqnorm x) *> conj x fromRational q = fromRational q *> 1@@ -79,10 +79,10 @@ scalarPart = coeff One -- |The vector part of the quaternion w+xi+yj+zk is xi+yj+zk. Also called the pure part.-vectorPart :: (Num k) => Quaternion k -> Quaternion k+vectorPart :: (Eq k, Num k) => Quaternion k -> Quaternion k vectorPart q = q - scalarPart q *> 1 -instance Num k => HasConjugation k HBasis where+instance (Eq k, Num k) => HasConjugation k HBasis where conj = (>>= conj') where conj' One = return One conj' imag = -1 *> return imag@@ -126,7 +126,7 @@ -- This shows that the multiplicative group of unit quaternions is isomorphic to Spin3, the double cover of SO3. -- -- @reprSO3 q@ returns the 3*3 matrix representing this map.-reprSO3 :: (Fractional k) => Quaternion k -> [[k]]+reprSO3 :: (Eq k, Fractional k) => Quaternion k -> [[k]] reprSO3 q = reprSO3' q `asMatrix` [i,j,k] -- It's clear from the definition that repr3' q leaves scalars invariant @@ -145,7 +145,7 @@ -- is isomorphic to Spin4, the double cover of SO4. -- -- @reprSO4 (l,r)@ returns the 4*4 matrix representing this map.-reprSO4 :: (Fractional k) => (Quaternion k, Quaternion k) -> [[k]]+reprSO4 :: (Eq k, Fractional k) => (Quaternion k, Quaternion k) -> [[k]] reprSO4 (l,r) = reprSO4' (l,r) `asMatrix` [1,i,j,k] -- could consider checking that l,r are unit length - except that this is hard to achieve working over Q @@ -164,7 +164,7 @@ -- Coalgebra structure on the dual vector space to the quaternions -- The comult is the transpose of mult-instance Num k => Coalgebra k (Dual HBasis) where+instance (Eq k, Num k) => Coalgebra k (Dual HBasis) where counit = unwrap . linear counit' where counit' (Dual One) = return () counit' _ = zero
Math/Algebras/Structures.hs view
@@ -43,7 +43,7 @@ antipode :: Vect k b -> Vect k b -instance (Num k, Eq b, Ord b, Show b, Algebra k b) => Num (Vect k b) where+instance (Eq k, Num k, Eq b, Ord b, Show b, Algebra k b) => Num (Vect k b) where x+y = x <+> y negate x = neg x -- negate (V ts) = V $ map (\(b,x) -> (b, negate x)) ts@@ -66,7 +66,7 @@ -} -instance Num k => Algebra k () where+instance (Eq k, Num k) => Algebra k () where unit = wrap -- unit 0 = zero -- V [] -- unit x = V [( (),x)]@@ -74,7 +74,7 @@ -- mult (V [( ((),()), x)]) = V [( (),x)] -- mult (V []) = zerov -instance Num k => Coalgebra k () where+instance (Eq k, Num k) => Coalgebra k () where counit = unwrap -- counit (V []) = 0 -- counit (V [( (),x)]) = x@@ -82,10 +82,10 @@ -- comult (V [( (),x)]) = V [( ((),()), x)] -- comult (V []) = zerov -unit' :: (Num k, Algebra k b) => Trivial k -> Vect k b+unit' :: (Eq k, Num k, Algebra k b) => Trivial k -> Vect k b unit' = unit . unwrap -- where unwrap = counit :: Num k => Trivial k -> k -counit' :: (Num k, Coalgebra k b) => Vect k b -> Trivial k+counit' :: (Eq k, Num k, Coalgebra k b) => Vect k b -> Trivial k counit' = wrap . counit -- where wrap = unit :: Num k => k -> Trivial k -- unit' and counit' enable us to form tensors of these functions@@ -94,7 +94,7 @@ -- Kassel p4 -- |The direct sum of k-algebras can itself be given the structure of a k-algebra. -- This is the product object in the category of k-algebras.-instance (Num k, Ord a, Ord b, Algebra k a, Algebra k b) => Algebra k (DSum a b) where+instance (Eq k, Num k, Ord a, Ord b, Algebra k a, Algebra k b) => Algebra k (DSum a b) where unit k = i1 (unit k) <+> i2 (unit k) -- unit == (i1 . unit) <<+>> (i2 . unit) mult = linear mult'@@ -108,7 +108,7 @@ -- |The direct sum of k-coalgebras can itself be given the structure of a k-coalgebra. -- This is the coproduct object in the category of k-coalgebras.-instance (Num k, Ord a, Ord b, Coalgebra k a, Coalgebra k b) => Coalgebra k (DSum a b) where+instance (Eq k, Num k, Ord a, Ord b, Coalgebra k a, Coalgebra k b) => Coalgebra k (DSum a b) where counit = unwrap . linear counit' where counit' (Left a) = (wrap . counit) (return a) counit' (Right b) = (wrap . counit) (return b)@@ -123,7 +123,7 @@ -- Kassel p32 -- |The tensor product of k-algebras can itself be given the structure of a k-algebra-instance (Num k, Ord a, Ord b, Algebra k a, Algebra k b) => Algebra k (Tensor a b) where+instance (Eq k, Num k, Ord a, Ord b, Algebra k a, Algebra k b) => Algebra k (Tensor a b) where -- unit 0 = V [] unit x = x *> (unit 1 `te` unit 1) mult = linear m where@@ -131,7 +131,7 @@ -- Kassel p42 -- |The tensor product of k-coalgebras can itself be given the structure of a k-coalgebra-instance (Num k, Ord a, Ord b, Coalgebra k a, Coalgebra k b) => Coalgebra k (Tensor a b) where+instance (Eq k, Num k, Ord a, Ord b, Coalgebra k a, Coalgebra k b) => Coalgebra k (Tensor a b) where counit = counit . (counit' `tf` counit') -- counit = counit . linear (\(T x y) -> counit' (return x) * counit' (return y)) comult = assocL . (id `tf` assocR) . (id `tf` (twist `tf` id))@@ -139,20 +139,20 @@ -- The set coalgebra - can be defined on any set-instance Num k => Coalgebra k EBasis where+instance (Eq k, Num k) => Coalgebra k EBasis where counit (V ts) = sum [x | (ei,x) <- ts] -- trace comult = fmap ( \ei -> (ei,ei) ) -- diagonal newtype SetCoalgebra b = SC b deriving (Eq,Ord,Show) -instance Num k => Coalgebra k (SetCoalgebra b) where+instance (Eq k, Num k) => Coalgebra k (SetCoalgebra b) where counit (V ts) = sum [x | (m,x) <- ts] -- trace comult = fmap ( \m -> (m,m) ) -- diagonal newtype MonoidCoalgebra m = MC m deriving (Eq,Ord,Show) -instance (Num k, Ord m, Mon m) => Coalgebra k (MonoidCoalgebra m) where+instance (Eq k, Num k, Ord m, Mon m) => Coalgebra k (MonoidCoalgebra m) where counit (V ts) = sum [if m == MC munit then x else 0 | (m,x) <- ts] comult = linear cm where cm m = if m == MC munit then return (m,m) else return (m, MC munit) <+> return (MC munit, m)@@ -184,13 +184,13 @@ -- Kassel p57-8 -instance (Num k, Ord a, Ord u, Ord v, Algebra k a, Module k a u, Module k a v)+instance (Eq k, Num k, Ord a, Ord u, Ord v, Algebra k a, Module k a u, Module k a v) => Module k (Tensor a a) (Tensor u v) where -- action x = nf $ x >>= action' action = linear action' where action' ((a,a'), (u,v)) = (action $ return (a,u)) `te` (action $ return (a',v)) -instance (Num k, Ord a, Ord u, Ord v, Bialgebra k a, Module k a u, Module k a v)+instance (Eq k, Num k, Ord a, Ord u, Ord v, Bialgebra k a, Module k a u, Module k a v) => Module k a (Tensor u v) where -- action x = nf $ x >>= action' action = linear action'@@ -200,7 +200,7 @@ -- On the other hand, if a == Tensor u v, then we have overlapping instance with the earlier instance -- Kassel p63-instance (Num k, Ord a, Ord m, Ord n, Bialgebra k a, Comodule k a m, Comodule k a n)+instance (Eq k, Num k, Ord a, Ord m, Ord n, Bialgebra k a, Comodule k a m, Comodule k a n) => Comodule k a (Tensor m n) where coaction = (mult `tf` id) . twistm . (coaction `tf` coaction) where twistm x = nf $ fmap ( \((h,m), (h',n)) -> ((h,h'), (m,n)) ) x
Math/Algebras/TensorAlgebra.hs view
@@ -34,7 +34,7 @@ munit = TA 0 [] mmult (TA i xs) (TA j ys) = TA (i+j) (xs++ys) -instance (Num k, Ord a) => Algebra k (TensorAlgebra a) where+instance (Eq k, Num k, Ord a) => Algebra k (TensorAlgebra a) where unit x = x *> return munit mult = nf . fmap (\(a,b) -> a `mmult` b) @@ -50,7 +50,7 @@ -- The Num k context is not strictly necessary -- |Inject an element of the set\/type A\/a into the tensor algebra T(A) = Vect k (TensorAlgebra a).-injectTA' :: Num k => a -> Vect k (TensorAlgebra a)+injectTA' :: (Eq k, Num k) => a -> Vect k (TensorAlgebra a) injectTA' = injectTA . return -- injectTA' a = return (TA 1 [a]) @@ -59,7 +59,7 @@ -- where T(A) is the tensor algebra Vect k (TensorAlgebra a). -- f' will agree with f on A itself (considered as a subspace of T(A)). -- In other words, f = f' . injectTA-liftTA :: (Num k, Ord b, Show b, Algebra k b) =>+liftTA :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (Vect k a -> Vect k b) -> Vect k (TensorAlgebra a) -> Vect k b liftTA f = linear (\(TA _ xs) -> product [f (return x) | x <- xs]) -- The Show b constraint is required because we use product (and Num requires Show)!!@@ -67,7 +67,7 @@ -- |Given a set\/type A\/a, and a vector space B = Vect k b, where B is also an algebra, -- lift a function f: A -> B to an algebra morphism f': T(A) -> B. -- f' will agree with f on A itself. In other words, f = f' . injectTA'-liftTA' :: (Num k, Ord b, Show b, Algebra k b) =>+liftTA' :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (a -> Vect k b) -> Vect k (TensorAlgebra a) -> Vect k b liftTA' = liftTA . linear -- liftTA' f = linear (\(TA _ xs) -> product [f x | x <- xs])@@ -77,7 +77,7 @@ -- |Tensor algebra is a functor from k-Vect to k-Alg. -- The action on objects is Vect k a -> Vect k (TensorAlgebra a). -- The action on arrows is f -> fmapTA f.-fmapTA :: (Num k, Ord b, Show b) =>+fmapTA :: (Eq k, Num k, Ord b, Show b) => (Vect k a -> Vect k b) -> Vect k (TensorAlgebra a) -> Vect k (TensorAlgebra b) fmapTA f = liftTA (injectTA . f) -- fmapTA f = linear (\(TA _ xs) -> product [injectTA (f (return x)) | x <- xs])@@ -86,18 +86,18 @@ -- we obtain a functor Set -> k-Alg, the free algebra functor. -- The action on objects is a -> Vect k (TensorAlgebra a). -- The action on arrows is f -> fmapTA' f.-fmapTA' :: (Num k, Ord b, Show b) =>+fmapTA' :: (Eq k, Num k, Ord b, Show b) => (a -> b) -> Vect k (TensorAlgebra a) -> Vect k (TensorAlgebra b) fmapTA' = fmapTA . fmap -- fmapTA' f = liftTA' (injectTA' . f) -- fmapTA' f = linear (\(TA _ xs) -> product [injectTA' (f x) | x <- xs]) -bindTA :: (Num k, Ord b, Show b) =>+bindTA :: (Eq k, Num k, Ord b, Show b) => Vect k (TensorAlgebra a) -> (Vect k a -> Vect k (TensorAlgebra b)) -> Vect k (TensorAlgebra b) bindTA = flip liftTA -bindTA' :: (Num k, Ord b, Show b) =>+bindTA' :: (Eq k, Num k, Ord b, Show b) => Vect k (TensorAlgebra a) -> (a -> Vect k (TensorAlgebra b)) -> Vect k (TensorAlgebra b) bindTA' = flip liftTA' -- Another way to think about this is variable substitution@@ -121,14 +121,14 @@ munit = Sym 0 [] mmult (Sym i xs) (Sym j ys) = Sym (i+j) $ L.sort (xs++ys) -instance (Num k, Ord a) => Algebra k (SymmetricAlgebra a) where+instance (Eq k, Num k, Ord a) => Algebra k (SymmetricAlgebra a) where unit x = x *> return munit mult = nf . fmap (\(a,b) -> a `mmult` b) -- |Algebra morphism from tensor algebra to symmetric algebra. -- The kernel of the morphism is the ideal generated by all -- differences of products u⊗v - v⊗u.-toSym :: (Num k, Ord a) =>+toSym :: (Eq k, Num k, Ord a) => Vect k (TensorAlgebra a) -> Vect k (SymmetricAlgebra a) toSym = linear toSym' where toSym' (TA i xs) = return $ Sym i (L.sort xs) @@ -147,31 +147,31 @@ injectSym' = injectSym . return -- injectSym' a = return (Sym 1 [a]) -liftSym :: (Num k, Ord b, Show b, Algebra k b) =>+liftSym :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (Vect k a -> Vect k b) -> Vect k (SymmetricAlgebra a) -> Vect k b liftSym f = linear (\(Sym _ xs) -> product [f (return x) | x <- xs]) -liftSym' :: (Num k, Ord b, Show b, Algebra k b) =>+liftSym' :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (a -> Vect k b) -> Vect k (SymmetricAlgebra a) -> Vect k b liftSym' = liftSym . linear -- liftSym' f = linear (\(Sym _ xs) -> product [f x | x <- xs]) -fmapSym :: (Num k, Ord b, Show b) =>+fmapSym :: (Eq k, Num k, Ord b, Show b) => (Vect k a -> Vect k b) -> Vect k (SymmetricAlgebra a) -> Vect k (SymmetricAlgebra b) fmapSym f = liftSym (injectSym . f) -- fmapSym f = linear (\(Sym _ xs) -> product [injectSym (f (return x)) | x <- xs]) -fmapSym' :: (Num k, Ord b, Show b) =>+fmapSym' :: (Eq k, Num k, Ord b, Show b) => (a -> b) -> Vect k (SymmetricAlgebra a) -> Vect k (SymmetricAlgebra b) fmapSym' = fmapSym . fmap -- fmapSym' f = liftSym' (injectSym' . f) -- fmapSym' f = linear (\(Sym _ xs) -> product [injectSym' (f x) | x <- xs]) -bindSym :: (Num k, Ord b, Show b) =>+bindSym :: (Eq k, Num k, Ord b, Show b) => Vect k (SymmetricAlgebra a) -> (Vect k a -> Vect k (SymmetricAlgebra b)) -> Vect k (SymmetricAlgebra b) bindSym = flip liftSym -bindSym' :: (Num k, Ord b, Show b) =>+bindSym' :: (Eq k, Num k, Ord b, Show b) => Vect k (SymmetricAlgebra a) -> (a -> Vect k (SymmetricAlgebra b)) -> Vect k (SymmetricAlgebra b) bindSym' = flip liftSym' -- Another way to think about this is variable substitution@@ -190,7 +190,7 @@ show (Ext _ xs) = filter (/= '"') $ concat $ L.intersperse "^" $ map show xs -instance (Num k, Ord a) => Algebra k (ExteriorAlgebra a) where+instance (Eq k, Num k, Ord a) => Algebra k (ExteriorAlgebra a) where unit x = x *> return (Ext 0 []) mult xy = nf $ xy >>= (\(Ext i xs, Ext j ys) -> signedMerge 1 (0,[]) (i,xs) (j,ys)) where signedMerge s (k,zs) (i,x:xs) (j,y:ys) =@@ -206,7 +206,7 @@ -- |Algebra morphism from tensor algebra to exterior algebra. -- The kernel of the morphism is the ideal generated by all -- self-products u⊗u and sums of products u⊗v + v⊗u-toExt :: (Num k, Ord a) =>+toExt :: (Eq k, Num k, Ord a) => Vect k (TensorAlgebra a) -> Vect k (ExteriorAlgebra a) toExt = linear toExt' where toExt' (TA i xs) = let (sign,xs') = signedSort 1 True [] xs@@ -230,31 +230,31 @@ injectExt' = injectExt . return -- injectExt' a = return (Ext 1 [a]) -liftExt :: (Num k, Ord b, Show b, Algebra k b) =>+liftExt :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (Vect k a -> Vect k b) -> Vect k (ExteriorAlgebra a) -> Vect k b liftExt f = linear (\(Ext _ xs) -> product [f (return x) | x <- xs]) -liftExt' :: (Num k, Ord b, Show b, Algebra k b) =>+liftExt' :: (Eq k, Num k, Ord b, Show b, Algebra k b) => (a -> Vect k b) -> Vect k (ExteriorAlgebra a) -> Vect k b liftExt' = liftExt . linear -- liftExt' f = linear (\(Ext _ xs) -> product [f x | x <- xs]) -fmapExt :: (Num k, Ord b, Show b) =>+fmapExt :: (Eq k, Num k, Ord b, Show b) => (Vect k a -> Vect k b) -> Vect k (ExteriorAlgebra a) -> Vect k (ExteriorAlgebra b) fmapExt f = liftExt (injectExt . f) -- fmapExt f = linear (\(Ext _ xs) -> product [injectExt (f (return x)) | x <- xs]) -fmapExt' :: (Num k, Ord b, Show b) =>+fmapExt' :: (Eq k, Num k, Ord b, Show b) => (a -> b) -> Vect k (ExteriorAlgebra a) -> Vect k (ExteriorAlgebra b) fmapExt' = fmapExt . fmap -- fmapExt' f = liftExt' (injectExt' . f) -- fmapExt' f = linear (\(Ext _ xs) -> product [injectExt' (f x) | x <- xs]) -bindExt :: (Num k, Ord b, Show b) =>+bindExt :: (Eq k, Num k, Ord b, Show b) => Vect k (ExteriorAlgebra a) -> (Vect k a -> Vect k (ExteriorAlgebra b)) -> Vect k (ExteriorAlgebra b) bindExt = flip liftExt -bindExt' :: (Num k, Ord b, Show b) =>+bindExt' :: (Eq k, Num k, Ord b, Show b) => Vect k (ExteriorAlgebra a) -> (a -> Vect k (ExteriorAlgebra b)) -> Vect k (ExteriorAlgebra b) bindExt' = flip liftExt' -- Another way to think about this is variable substitution@@ -265,7 +265,7 @@ -- Kassel p67 data TensorCoalgebra c = TC Int [c] deriving (Eq,Ord,Show) -instance (Num k, Ord c) => Coalgebra k (TensorCoalgebra c) where+instance (Eq k, Num k, Ord c) => Coalgebra k (TensorCoalgebra c) where counit = unwrap . linear counit' where counit' (TC 0 []) = return () -- 1 counit' _ = zerov@@ -278,14 +278,14 @@ -- coliftTC f is a coalgebra morphism, and f == projectTC . coliftTC f -- projection onto the underlying vector space-projectTC :: (Num k, Ord b) => Vect k (TensorCoalgebra b) -> Vect k b+projectTC :: (Eq k, Num k, Ord b) => Vect k (TensorCoalgebra b) -> Vect k b projectTC = linear projectTC' where projectTC' (TC 1 [b]) = return b; projectTC' _ = zerov -- projectTC t = V [(b,c) | (TC 1 [b], c) <- terms t] -- lift a vector space morphism C -> D to a coalgebra morphism C -> T'(D) -- this function returns an approximation, valid only up to second order terms-coliftTC :: (Num k, Coalgebra k c, Ord d) =>+coliftTC :: (Eq k, Num k, Coalgebra k c, Ord d) => (Vect k c -> Vect k d) -> Vect k c -> Vect k (TensorCoalgebra d) coliftTC f = sumf [coliftTC' i f | i <- [0..2] ] @@ -299,7 +299,7 @@ fn' c = fmap (\(TC 1 [x], TC _ xs) -> TC n (x:xs)) $ ( (f1' `tf` fn1') . comult) (return c) -cobindTC :: (Num k, Ord c, Ord d) =>+cobindTC :: (Eq k, Num k, Ord c, Ord d) => (Vect k (TensorCoalgebra c) -> Vect k d) -> Vect k (TensorCoalgebra c) -> Vect k (TensorCoalgebra d) cobindTC = coliftTC
Math/Algebras/TensorProduct.hs view
@@ -27,7 +27,7 @@ -- |The coproduct of two linear functions (with the same target). -- Satisfies the universal property that f == coprodf f g . i1 and g == coprodf f g . i2-coprodf :: (Num k, Ord t) =>+coprodf :: (Eq k, Num k, Ord t) => (Vect k a -> Vect k t) -> (Vect k b -> Vect k t) -> Vect k (DSum a b) -> Vect k t coprodf f g = linear fg' where fg' (Left a) = f (return a)@@ -35,33 +35,33 @@ -- |Projection onto left summand from direct sum-p1 :: (Num k, Ord a) => Vect k (DSum a b) -> Vect k a+p1 :: (Eq k, Num k, Ord a) => Vect k (DSum a b) -> Vect k a p1 = linear p1' where p1' (Left a) = return a p1' (Right b) = zero -- |Projection onto right summand from direct sum-p2 :: (Num k, Ord b) => Vect k (DSum a b) -> Vect k b+p2 :: (Eq k, Num k, Ord b) => Vect k (DSum a b) -> Vect k b p2 = linear p2' where p2' (Left a) = zero p2' (Right b) = return b -- |The product of two linear functions (with the same source). -- Satisfies the universal property that f == p1 . prodf f g and g == p2 . prodf f g-prodf :: (Num k, Ord a, Ord b) =>+prodf :: (Eq k, Num k, Ord a, Ord b) => (Vect k s -> Vect k a) -> (Vect k s -> Vect k b) -> Vect k s -> Vect k (DSum a b) prodf f g = linear fg' where fg' b = fmap Left (f $ return b) <+> fmap Right (g $ return b) -- |The direct sum of two vector space elements-dsume :: (Num k, Ord a, Ord b) => Vect k a -> Vect k b -> Vect k (DSum a b)+dsume :: (Eq k, Num k, Ord a, Ord b) => Vect k a -> Vect k b -> Vect k (DSum a b) -- dsume x y = fmap Left x <+> fmap Right y dsume x y = i1 x <+> i2 y -- |The direct sum of two linear functions. -- Satisfies the universal property that f == p1 . dsumf f g . i1 and g == p2 . dsumf f g . i2-dsumf :: (Num k, Ord a, Ord b, Ord a', Ord b') => +dsumf :: (Eq k, Num k, Ord a, Ord b, Ord a', Ord b') => (Vect k a -> Vect k a') -> (Vect k b -> Vect k b') -> Vect k (DSum a b) -> Vect k (DSum a' b') dsumf f g ab = (i1 . f . p1) ab <+> (i2 . g . p2) ab @@ -80,7 +80,7 @@ -- Implicit assumption - f and g are linear -- |The tensor product of two linear functions-tf :: (Num k, Ord a', Ord b') => (Vect k a -> Vect k a') -> (Vect k b -> Vect k b')+tf :: (Eq k, Num k, Ord a', Ord b') => (Vect k a -> Vect k a') -> (Vect k b -> Vect k b') -> Vect k (Tensor a b) -> Vect k (Tensor a' b') tf f g (V ts) = sum [x *> te (f $ return a) (g $ return b) | ((a,b), x) <- ts] where sum = foldl add zero -- (V [])@@ -107,16 +107,16 @@ unitOutR :: Vect k (Tensor a ()) -> Vect k a unitOutR = fmap ( \(a,()) -> a ) -twist :: (Num k, Ord a, Ord b) => Vect k (Tensor a b) -> Vect k (Tensor b a)+twist :: (Eq k, Num k, Ord a, Ord b) => Vect k (Tensor a b) -> Vect k (Tensor b a) twist v = nf $ fmap ( \(a,b) -> (b,a) ) v -- note the nf call, as f is not order-preserving -distrL :: (Num k, Ord a, Ord b, Ord c)+distrL :: (Eq k, Num k, Ord a, Ord b, Ord c) => Vect k (Tensor a (DSum b c)) -> Vect k (DSum (Tensor a b) (Tensor a c)) distrL v = nf $ fmap (\(a,bc) -> case bc of Left b -> Left (a,b); Right c -> Right (a,c)) v -undistrL :: (Num k, Ord a, Ord b, Ord c)+undistrL :: (Eq k, Num k, Ord a, Ord b, Ord c) => Vect k (DSum (Tensor a b) (Tensor a c)) -> Vect k (Tensor a (DSum b c)) undistrL v = nf $ fmap ( \abc -> case abc of Left (a,b) -> (a,Left b); Right (a,c) -> (a,Right c) ) v @@ -132,11 +132,11 @@ -- Left (e1,e2) -ev :: (Num k, Ord b) => Vect k (Tensor (Dual b) b) -> k+ev :: (Eq k, Num k, Ord b) => Vect k (Tensor (Dual b) b) -> k ev = unwrap . linear (\(Dual bi, bj) -> delta bi bj *> return ()) -- slightly cheating, as delta i j is meant to compare indices, not the basis elements themselves delta i j = if i == j then 1 else 0 -reify :: (Num k, Ord b) => Vect k (Dual b) -> (Vect k b -> k)+reify :: (Eq k, Num k, Ord b) => Vect k (Dual b) -> (Vect k b -> k) reify f x = ev (f `te` x)
Math/Algebras/VectorSpace.hs view
@@ -19,7 +19,7 @@ -- Elements of Vect k b consist of k-linear combinations of elements of b. newtype Vect k b = V [(b,k)] deriving (Eq,Ord) -instance (Num k, Show b) => Show (Vect k b) where+instance (Show k, Eq k, Num k, Show b) => Show (Vect k b) where show (V []) = "0" show (V ts) = concatWithPlus $ map showTerm ts where showTerm (b,x) | show b == "1" = show x@@ -52,11 +52,11 @@ zerov = V [] -- |Addition of vectors-add :: (Ord b, Num k) => Vect k b -> Vect k b -> Vect k b+add :: (Ord b, Eq k, Num k) => Vect k b -> Vect k b -> Vect k b add (V ts) (V us) = V $ addmerge ts us -- |Addition of vectors (same as add)-(<+>) :: (Ord b, Num k) => Vect k b -> Vect k b -> Vect k b+(<+>) :: (Ord b, Eq k, Num k) => Vect k b -> Vect k b -> Vect k b (<+>) = add addmerge ((a,x):ts) ((b,y):us) =@@ -68,33 +68,33 @@ addmerge [] us = us -- |Sum of a list of vectors-sumv :: (Ord b, Num k) => [Vect k b] -> Vect k b+sumv :: (Ord b, Eq k, Num k) => [Vect k b] -> Vect k b sumv = foldl (<+>) zerov -- |Negation of vector-neg :: (Num k) => Vect k b -> Vect k b+neg :: (Eq k, Num k) => Vect k b -> Vect k b neg (V ts) = V $ map (\(b,x) -> (b,-x)) ts -- |Subtraction of vectors-(<->) :: (Ord b, Num k) => Vect k b -> Vect k b -> Vect k b+(<->) :: (Ord b, Eq k, Num k) => Vect k b -> Vect k b -> Vect k b (<->) u v = u <+> neg v -- |Scalar multiplication (on the left)-smultL :: (Num k) => k -> Vect k b -> Vect k b+smultL :: (Eq k, Num k) => k -> Vect k b -> Vect k b smultL 0 _ = zero -- V [] smultL k (V ts) = V [(ei,k*xi) | (ei,xi) <- ts] -- |Same as smultL. Mnemonic is \"multiply through (from the left)\"-(*>) :: (Num k) => k -> Vect k b -> Vect k b+(*>) :: (Eq k, Num k) => k -> Vect k b -> Vect k b (*>) = smultL -- |Scalar multiplication on the right-smultR :: (Num k) => Vect k b -> k -> Vect k b+smultR :: (Eq k, Num k) => Vect k b -> k -> Vect k b smultR _ 0 = zero -- V [] smultR (V ts) k = V [(ei,xi*k) | (ei,xi) <- ts] -- |Same as smultR. Mnemonic is \"multiply through (from the right)\"-(<*) :: (Num k) => Vect k b -> k -> Vect k b+(<*) :: (Eq k, Num k) => Vect k b -> k -> Vect k b (<*) = smultR -- same as return@@ -107,7 +107,7 @@ -- |Convert an element of Vect k b into normal form. Normal form consists in having the basis elements in ascending order, -- with no duplicates, and all coefficients non-zero-nf :: (Ord b, Num k) => Vect k b -> Vect k b+nf :: (Ord b, Eq k, Num k) => Vect k b -> Vect k b nf (V ts) = V $ nf' $ L.sortBy compareFst ts where nf' ((b1,x1):(b2,x2):ts) = case compare b1 b2 of@@ -135,7 +135,7 @@ -- -- If we have A = Vect k a, B = Vect k b, and f :: a -> Vect k b is a function from the basis elements of A into B, -- then @linear f@ is the linear map that this defines by linearity.-linear :: (Ord b, Num k) => (a -> Vect k b) -> Vect k a -> Vect k b+linear :: (Ord b, Eq k, Num k) => (a -> Vect k b) -> Vect k a -> Vect k b linear f v = nf $ v >>= f newtype EBasis = E Int deriving (Eq,Ord)@@ -154,7 +154,7 @@ -- but in the code, we need this if we want to be able to put k as one side of a tensor product. type Trivial k = Vect k () -wrap :: Num k => k -> Vect k ()+wrap :: (Eq k, Num k) => k -> Vect k () wrap 0 = zero wrap x = V [( (),x)]
Math/Combinatorics/Design.hs view
@@ -8,6 +8,8 @@ import qualified Data.Set as S import Math.Common.ListSet (intersect, symDiff) +import Math.Core.Utils (combinationsOf) + import Math.Algebra.Field.Base import Math.Algebra.Field.Extension import Math.Algebra.Group.PermutationGroup hiding (elts, order, isMember)
Math/Combinatorics/FiniteGeometry.hs view
@@ -1,4 +1,4 @@--- Copyright (c) David Amos, 2008-2009. All rights reserved. +-- Copyright (c) David Amos, 2008-2011. All rights reserved. -- |Constructions of the finite geometries AG(n,Fq) and PG(n,Fq), their points, lines and flats, -- together with the incidence graphs between points and lines. @@ -8,15 +8,15 @@ import qualified Data.Set as S import Math.Common.ListSet (toListSet) +import Math.Core.Utils -import Math.Algebra.Field.Base -import Math.Algebra.Field.Extension hiding ( (<+>) ) -- , (*>) ) +import Math.Core.Field import Math.Algebra.LinearAlgebra -- hiding ( det ) import Math.Combinatorics.Graph import Math.Combinatorics.GraphAuts -- for use in GHCi -import Math.Algebra.Group.PermutationGroup -- for use in GHCi -import Math.Algebra.Group.SchreierSims as SS -- for use in GHCi +import Math.Algebra.Group.PermutationGroup hiding (elts) -- for use in GHCi +import Math.Algebra.Group.SchreierSims as SS hiding (elts) -- for use in GHCi -- !! The following two functions previously required (FiniteField a) as context -- but this has been temporarily removed to enable them to work with Math.Core.Field @@ -47,13 +47,13 @@ -- then this is the same as [v <*>> m | v <- vs] == [m' <<*> v | v <- vs] -- |Given a list of points in AG(n,Fq), return their closure, the smallest flat containing them -closureAG :: (Ord a, FiniteField a) => [[a]] -> [[a]] +closureAG :: (Num a, Ord a, FinSet a) => [[a]] -> [[a]] closureAG ps = let vs = [ (1 - sum xs) : xs | xs <- ptsAG (k-1) fq ] -- k-vectors over fq whose sum is 1 in toListSet [m' <<*> v | v <- vs] where k = length ps -- the dimension of the flat (assuming ps are independent) m' = L.transpose ps - fq = eltsFq undefined + fq = elts -- toListSet call sorts the result, and also removes duplicates in case the points weren't independent {- @@ -66,21 +66,21 @@ lineAG [p1,p2] = L.sort [ p1 <+> (c *> dp) | c <- fq ] where dp = p2 <-> p1 - fq = eltsFq undefined + fq = elts -- closure of points in PG(n,Fq) -- take all linear combinations of the points (ie the subspace generated by the points, considered as points in Fq ^(n+1) ) -- then discard all which aren't in PNF (thus dropping back into PG(n,Fq)) -- |Given a set of points in PG(n,Fq), return their closure, the smallest flat containing them -closurePG :: (Ord a, FiniteField a) => [[a]] -> [[a]] +closurePG :: (Num a, Ord a, FinSet a) => [[a]] -> [[a]] closurePG ps = toListSet $ filter ispnf $ map (<*>> ps) $ ptsAG k fq where k = length ps - fq = eltsFq undefined + fq = elts -- toListSet call sorts the result, and also removes duplicates in case the points weren't independent linePG [p1,p2] = toListSet $ filter ispnf [(a *> p1) <+> (b *> p2) | a <- fq, b <- fq] - where fq = eltsFq undefined + where fq = elts -- van Lint & Wilson, p325, 332 qtorial n q | n >= 0 = product [(q^i - 1) `div` (q-1) | i <- [1..n]] @@ -105,11 +105,9 @@ -- Cameron, Combinatorics, p126 - -- FLATS VIA REDUCED ROW ECHELON FORMS -- Suggested by Cameron p125 - data ZeroOneStar = Zero | One | Star deriving (Eq) instance Show ZeroOneStar where @@ -183,7 +181,7 @@ -- INCIDENCE GRAPH -- |Incidence graph of PG(n,fq), considered as an incidence structure between points and lines -incidenceGraphPG :: (Ord a, FiniteField a) => Int -> [a] -> Graph (Either [a] [[a]]) +incidenceGraphPG :: (Num a, Ord a, FinSet a) => Int -> [a] -> Graph (Either [a] [[a]]) incidenceGraphPG n fq = G vs es where points = ptsPG n fq lines = linesPG n fq @@ -200,7 +198,7 @@ -- |Incidence graph of AG(n,fq), considered as an incidence structure between points and lines -incidenceGraphAG :: (Ord a, FiniteField a) => Int -> [a] -> Graph (Either [a] [[a]]) +incidenceGraphAG :: (Num a, Ord a, FinSet a) => Int -> [a] -> Graph (Either [a] [[a]]) incidenceGraphAG n fq = G vs es where points = ptsAG n fq lines = linesAG n fq
Math/Combinatorics/Graph.hs view
@@ -12,6 +12,7 @@ import Control.Arrow ( (&&&) ) import Math.Common.ListSet as LS +import Math.Core.Utils import Math.Algebra.Group.PermutationGroup hiding (fromDigits, fromBinary) import Math.Algebra.Group.SchreierSims as SS @@ -27,14 +28,6 @@ powerset [] = [[]] powerset (x:xs) = let p = powerset xs in p ++ map (x:) p --- |combinationsOf k xs returns the subsets of xs of size k. --- If xs is in ascending order, then the returned list is in ascending order -combinationsOf :: (Integral t) => t -> [a] -> [[a]] -combinationsOf 0 _ = [[]] -combinationsOf _ [] = [] -combinationsOf k (x:xs) | k > 0 = map (x:) (combinationsOf (k-1) xs) ++ combinationsOf k xs - - -- GRAPH -- |Datatype for graphs, represented as a list of vertices and a list of edges. @@ -338,7 +331,7 @@ -- kneser v k | v >= 2*k = j v k 0 -- |kneser n k returns the kneser graph KG n,k - -- whose vertices are the k-element subsets of [1..n], with edges joining disjoint subsets -kneser :: (Integral t) => t -> t -> Graph [t] +kneser :: Int -> Int -> Graph [Int] kneser n k | 2*k <= n = graph (vs,es) where vs = combinationsOf k [1..n] es = [ [v1,v2] | [v1,v2] <- combinationsOf 2 vs, disjoint v1 v2]
Math/Combinatorics/GraphAuts.hs view
@@ -2,12 +2,14 @@ module Math.Combinatorics.GraphAuts where +import Data.Either (lefts) import qualified Data.List as L import qualified Data.Map as M import qualified Data.Set as S import Data.Maybe import Math.Common.ListSet +import Math.Core.Utils (combinationsOf, pairs) import Math.Combinatorics.Graph -- import Math.Combinatorics.StronglyRegularGraph -- import Math.Combinatorics.Hypergraph -- can't import this, creates circular dependency @@ -281,13 +283,27 @@ -- else error (show (src_split, trg_split)) -- for debugging -- Now, every time we intersect two partitions, refine to an equitable partition --- |Given a graph g, @graphAuts g@ returns a strong generating set for the automorphism group of g. --- --- Note that the implementation is currently only valid for connected graphs + +-- |Given a graph g, @graphAuts g@ returns generators for the automorphism group of g. +-- If g is connected, then the generators will be a strong generating set. graphAuts :: (Ord a) => Graph a -> [Permutation a] -graphAuts g@(G vs es) +graphAuts g = autsWithinComponents ++ isosBetweenComponents + where cs = map (inducedSubgraph g) (components g) + -- autsWithinComponents = concatMap graphAutsCon cs + autsWithinComponents = concatMap graphAuts4 cs + isosBetweenComponents = map swapFromIso $ concat [take 1 (graphIsos ci cj) | (ci,cj) <- pairs cs] + swapFromIso xys = fromPairs (xys ++ map swap xys) + swap (x,y) = (y,x) +-- Using graphAuts4 instead of graphAutsCon as latter appears to have a bug, eg +-- > graphAuts4 $ G [1..3] [[1,2],[2,3]] +-- [[[1,3]]] +-- > graphAutsCon $ G [1..3] [[1,2],[2,3]] +-- [] + +-- Automorphisms of a connected graph +graphAutsCon g@(G vs es) | isConnected g = graphAuts' [] (toEquitable g $ valencyPartition g) - | otherwise = error "graphAuts: only implemented for connected graphs" + | otherwise = error "graphAutsCon: graph is not connected" where graphAuts' us p@((x:ys):pt) = let p' = L.sort $ filter (not . null) $ refine' (ys:pt) (dps M.! x) in level us p x ys [] @@ -305,8 +321,6 @@ dps = M.fromList [(v, distancePartition g v) | v <- vs] es' = S.fromList es nbrs_g = M.fromList [(v, nbrs g v) | v <- vs] --- To handle disconnected graphs, you not only need to find auts of each component, --- you also need to find auts that swap components dfsEquitable (dps,es',nbrs_g) xys p1 p2 = dfs xys p1 p2 where dfs xys p1 p2 @@ -333,17 +347,24 @@ -- AUTS OF INCIDENCE STRUCTURE VIA INCIDENCE GRAPH -- based on graphAuts as applied to the incidence graph, but modified to avoid point-block crossover auts + -- |Given the incidence graph of an incidence structure between points and blocks -- (for example, a set system), --- @incidenceAuts g@ returns a strong generating set for the automorphism group of the incidence structure. +-- @incidenceAuts g@ returns generators for the automorphism group of the incidence structure. -- The generators are represented as permutations of the points. -- The incidence graph should be represented with the points on the left and the blocks on the right. --- --- Note that the implementation is currently only valid for connected incidence graphs +-- If the incidence graph is connected, then the generators will be a strong generating set. incidenceAuts :: (Ord p, Ord b) => Graph (Either p b) -> [Permutation p] -incidenceAuts g@(G vs es) +incidenceAuts g = autsWithinComponents ++ isosBetweenComponents + where cs = map (inducedSubgraph g) (components g) + autsWithinComponents = concatMap incidenceAutsCon cs + isosBetweenComponents = map swapFromIso $ concat [take 1 (incidenceIsos ci cj) | (ci,cj) <- pairs cs] + swapFromIso xys = fromPairs (xys ++ map swap xys) + swap (x,y) = (y,x) + +incidenceAutsCon g@(G vs es) | isConnected g = map points (incidenceAuts' [] [vs]) - | otherwise = error "incidenceAuts: only implemented for connected incidence graphs" + | otherwise = error "incidenceAutsCon: graph is not connected" where points h = fromPairs [(x,y) | (Left x, Left y) <- toPairs h] -- filtering out the action on blocks incidenceAuts' us p@((x@(Left _):ys):pt) = -- let p' = L.sort $ filter (not . null) $ refine' (ys:pt) (dps M.! x) @@ -351,8 +372,8 @@ in level us p x ys [] ++ incidenceAuts' (x:us) p' incidenceAuts' us ([]:pt) = incidenceAuts' us pt - incidenceAuts' _ (((Right _):_):_) = [] -- if we fix all the points, then the blocks must be fixed too - -- incidenceAuts' _ [] = [] + incidenceAuts' _ (((Right _):_):_) = [] -- if we fix all the points, then the blocks must be fixed too + incidenceAuts' _ [] = [] level us p@(ph:pt) x (y@(Left _):ys) hs = let px = refine' (L.delete x ph : pt) (dps M.! x) py = refine' (L.delete y ph : pt) (dps M.! y) @@ -370,13 +391,28 @@ -- !! not yet using equitable partitions, so could probably be more efficient + -- graphIsos :: (Ord a, Ord b) => Graph a -> Graph b -> [[(a,b)]] -graphIsos g1 g2 +graphIsos g1 g2 + | length cs1 /= length cs2 = [] + | otherwise = graphIsos' cs1 cs2 + where cs1 = map (inducedSubgraph g1) (components g1) + cs2 = map (inducedSubgraph g2) (components g2) + graphIsos' (ci:cis) cjs = + [iso ++ iso' | cj <- cjs, + iso <- graphIsosCon ci cj, + let cjs' = L.delete cj cjs, + iso' <- graphIsos' cis cjs'] + graphIsos' [] [] = [[]] + +-- isos between connected graphs +graphIsosCon g1 g2 | isConnected g1 && isConnected g2 - = concat [dfs [] (distancePartition g1 v1) (distancePartition g2 v2) | v2 <- vertices g2] - | otherwise = error "graphIsos: only implemented for connected graphs" - where v1 = head $ vertices g1 - dfs xys p1 p2 + = concat [dfs [] (distancePartition g1 v1) (distancePartition g2 v2) + | v1 <- take 1 (vertices g1), v2 <- vertices g2] + -- the take 1 handles the case where g1 is the null graph + | otherwise = error "graphIsosCon: either or both graphs are not connected" + where dfs xys p1 p2 | map length p1 /= map length p2 = [] | otherwise = let p1' = filter (not . null) p1 @@ -397,10 +433,12 @@ es2 = S.fromList $ edges g2 +-- |Are the two graphs isomorphic? +isGraphIso :: (Ord a, Ord b) => Graph a -> Graph b -> Bool +isGraphIso g1 g2 = (not . null) (graphIsos g1 g2) -- !! If we're only interested in seeing whether or not two graphs are iso, -- !! then the cost of calculating distancePartitions may not be warranted -- !! (see Math.Combinatorics.Poset: orderIsos01 versus orderIsos) -isGraphIso g1 g2 = (not . null) (graphIsos g1 g2) -- !! deprecate isIso g1 g2 = (not . null) (graphIsos g1 g2) @@ -411,12 +449,26 @@ -- we return only the action on the Lefts, and unLeft it -- incidenceIsos :: (Ord p1, Ord b1, Ord p2, Ord b2) => -- Graph (Either p1 b1) -> Graph (Either p2 b2) -> [[(p1,p2)]] + incidenceIsos g1 g2 + | length cs1 /= length cs2 = [] + | otherwise = incidenceIsos' cs1 cs2 + where cs1 = map (inducedSubgraph g1) (filter (not . null . lefts) $ components g1) + cs2 = map (inducedSubgraph g2) (filter (not . null . lefts) $ components g2) + incidenceIsos' (ci:cis) cjs = + [iso ++ iso' | cj <- cjs, + iso <- incidenceIsosCon ci cj, + let cjs' = L.delete cj cjs, + iso' <- incidenceIsos' cis cjs'] + incidenceIsos' [] [] = [[]] + +incidenceIsosCon g1 g2 | isConnected g1 && isConnected g2 - = concat [dfs [] (distancePartition g1 v1) (distancePartition g2 v2) | v2@(Left _) <- vertices g2] - | otherwise = error "incidenceIsos: only implemented for connected graphs" - where v1@(Left _) = head $ vertices g1 - dfs xys p1 p2 + = concat [dfs [] (distancePartition g1 v1) (distancePartition g2 v2) + | v1@(Left _) <- take 1 (vertices g1), v2@(Left _) <- vertices g2] + -- g1 may have no vertices + | otherwise = error "incidenceIsos: one or both graphs not connected" + where dfs xys p1 p2 | map length p1 /= map length p2 = [] | otherwise = let p1' = filter (not . null) p1 @@ -436,6 +488,9 @@ es1 = S.fromList $ edges g1 es2 = S.fromList $ edges g2 +-- |Are the two incidence structures represented by these incidence graphs isomorphic? +isIncidenceIso :: (Ord p1, Ord b1, Ord p2, Ord b2) => + Graph (Either p1 b1) -> Graph (Either p2 b2) -> Bool isIncidenceIso g1 g2 = (not . null) (incidenceIsos g1 g2) {-
Math/Combinatorics/Hypergraph.hs view
@@ -5,6 +5,7 @@ import qualified Data.List as L import Math.Common.ListSet +import Math.Core.Utils (combinationsOf) import Math.Combinatorics.Graph hiding (incidenceMatrix) import Math.Algebra.Group.PermutationGroup (orbitB, p) -- needed for construction of Coxeter group
Math/Combinatorics/IncidenceAlgebra.hs view
@@ -97,7 +97,7 @@ -- with multiplication defined by concatenation of intervals. -- The incidence algebra can also be thought of as the vector space of functions from intervals to k, with multiplication -- defined by the convolution (f*g)(x,y) = sum [ f(x,z) g(z,y) | x <= z <= y ].-instance (Num k, Ord a) => Algebra k (Interval a) where+instance (Eq k, Num k, Ord a) => Algebra k (Interval a) where -- |Note that we are not able to give a generic definition of unit for the incidence algebra, -- because it depends on which poset we are working in, -- and that information is encoded at the value level rather than the type level. See unitIA.@@ -111,14 +111,14 @@ -- |The unit of the incidence algebra of a poset-unitIA :: (Num k, Ord t) => Poset t -> Vect k (Interval t)+unitIA :: (Eq k, Num k, Ord t) => Poset t -> Vect k (Interval t) unitIA poset@(Poset (set,_)) = sumv [return (Iv poset (x,x)) | x <- set] basisIA :: Num k => Poset t -> [Vect k (Interval t)] basisIA poset = [return (Iv poset xy) | xy <- intervals poset] -- |The zeta function of a poset-zetaIA :: (Num k, Ord t) => Poset t -> Vect k (Interval t)+zetaIA :: (Eq k, Num k, Ord t) => Poset t -> Vect k (Interval t) zetaIA poset = sumv $ basisIA poset -- Then for example, zeta^2 counts the number of points in each interval@@ -132,7 +132,7 @@ -- calculate the mobius function of a poset, with memoization -- |The Mobius function of a poset-muIA :: (Num k, Ord t) => Poset t -> Vect k (Interval t)+muIA :: (Eq k, Num k, Ord t) => Poset t -> Vect k (Interval t) muIA poset@(Poset (set,po)) = sumv [mus M.! (x,y) *> return (Iv poset (x,y)) | x <- set, y <- set] where mu (x,y) | x == y = 1 | po x y = negate $ sum [mus M.! (x,z) | z <- set, po x z, po z y, z /= y]@@ -152,7 +152,7 @@ -- Stanley, Enumerative Combinatorics I, p144 -- |The inverse of an element in the incidence algebra of a poset. -- This is only defined for elements which are non-zero on all intervals (x,x)-invIA :: (Fractional k, Ord t) => Vect k (Interval t) -> Maybe (Vect k (Interval t))+invIA :: (Eq k, Fractional k, Ord t) => Vect k (Interval t) -> Maybe (Vect k (Interval t)) invIA f | f == zerov = Nothing -- error "invIA 0" | any (==0) [f' (x,x) | x <- set] = Nothing -- error "invIA: not invertible" | otherwise = Just g@@ -210,7 +210,7 @@ -- INCIDENCE COALGEBRA -- Schmitt, Incidence Hopf Algebras -instance (Num k, Ord a) => Coalgebra k (Interval a) where+instance (Eq k, Num k, Ord a) => Coalgebra k (Interval a) where counit = unwrap . linear counit' where counit' (Iv _ (x,y)) = (if x == y then 1 else 0) *> return () comult = linear comult'@@ -228,7 +228,7 @@ -- rather than of intervals themselves. -- Note that if this operation is to be performed repeatedly for the same poset, -- then it is more efficient to use @toIsoClasses' poset@, which memoizes the isomorphism class lookup table.-toIsoClasses :: (Num k, Ord a) => Vect k (Interval a) -> Vect k (Interval a)+toIsoClasses :: (Eq k, Num k, Ord a) => Vect k (Interval a) -> Vect k (Interval a) toIsoClasses v | v == zerov = zerov | otherwise = toIsoClasses' poset v@@ -236,7 +236,7 @@ -- |Given a poset, @toIsoClasses' poset@ is the linear map from the incidence Hopf algebra of the poset to itself, -- in which each interval is mapped to (the minimal representative of) its isomorphism class.-toIsoClasses' :: (Num k, Ord a) => Poset a -> Vect k (Interval a) -> Vect k (Interval a)+toIsoClasses' :: (Eq k, Num k, Ord a) => Poset a -> Vect k (Interval a) -> Vect k (Interval a) toIsoClasses' poset = linear isoRep where isoRep iv = case isoMap M.! iv of Nothing -> return iv
Math/Combinatorics/LatinSquares.hs view
@@ -14,6 +14,7 @@ import Math.Combinatorics.Graph import Math.Combinatorics.GraphAuts import Math.Combinatorics.StronglyRegularGraph+import Math.Core.Utils (combinationsOf) -- LATIN SQUARES
Math/Combinatorics/Matroid.hs view
@@ -171,13 +171,13 @@ -- |Given a matrix, represented as a list of rows, number the columns [1..], -- and construct the matroid whose independent sets correspond to those sets of columns which are linearly independent -- (or in case there are repetitions, those multisets of columns which are sets, and which are linearly independent).-vectorMatroid :: (Fractional k) => [[k]] -> Matroid Int+vectorMatroid :: (Eq k, Fractional k) => [[k]] -> Matroid Int vectorMatroid = vectorMatroid' . L.transpose -- |Given a list of vectors (or rows of a matrix), number the vectors (rows) [1..], and construct the matroid whose independent sets -- correspond to those sets of vectors (rows) which are linearly independent -- (or in case there are repetitions, those multisets which are sets, and which are linearly independent).-vectorMatroid' :: (Fractional k) => [[k]] -> Matroid Int+vectorMatroid' :: (Eq k, Fractional k) => [[k]] -> Matroid Int vectorMatroid' vs = fromBases (map fst vs') bs where vs' = zip [1..] vs bs = dfs [] [([],[],vs')]@@ -247,6 +247,13 @@ es' = L.sort [ [Left e, Right b] | b <- bs, e <- b ] -- incidence graph for the matroid considered as an incidence structure between elements and bases +incidenceGraphC m = G.G vs' es'+ where es = elements m+ cs = L.sort $ circuits m+ vs' = map Left es ++ map Right cs+ es' = L.sort [ [Left e, Right c] | c <- cs, e <- c ]+-- incidence graph for the matroid considered as an incidence structure between elements and circuits+ incidenceGraphH m = G.G vs' es' where es = elements m hs = L.sort $ hyperplanes m@@ -266,12 +273,7 @@ -- |Return the automorphisms of the matroid. matroidAuts :: (Ord a) => Matroid a -> [Permutation a]-matroidAuts m- | G.isConnected hgraph = incidenceAuts hgraph- | G.isConnected bgraph = incidenceAuts bgraph- | otherwise = error "matroidAuts: incidence graph is not connected"- where hgraph = incidenceGraphH m- bgraph = incidenceGraphB m+matroidAuts m = incidenceAuts $ incidenceGraphH m -- Note that the results aren't always what one intuitively expects from the geometric representation. -- This is because geometric representations suggest additional structure beyond matroid structure. -- For example, for the Vamos matroid v8,@@ -613,7 +615,7 @@ -- -- A multiset of points in k^n is said to be affinely dependent if it contains two identical points, -- or three collinear points, or four coplanar points, or ... - and affinely independent otherwise.-affineMatroid :: (Fractional k) => [[k]] -> Matroid Int+affineMatroid :: (Eq k, Fractional k) => [[k]] -> Matroid Int affineMatroid vs = vectorMatroid' $ map (1:) vs -- |fromGeoRep returns a matroid from a geometric representation consisting of dependent flats of various ranks.@@ -790,11 +792,11 @@ -- REPRESENTABILITY -- |@matroidPG n fq@ returns the projective geometry PG(n,Fq), where fq is a list of the elements of Fq-matroidPG :: (Fractional a) => Int -> [a] -> Matroid Int+matroidPG :: (Eq a, Fractional a) => Int -> [a] -> Matroid Int matroidPG n fq = vectorMatroid' $ ptsPG n fq -- |@matroidAG n fq@ returns the affine geometry AG(n,Fq), where fq is a list of the elements of Fq-matroidAG :: (Fractional a) => Int -> [a] -> Matroid Int+matroidAG :: (Eq a, Fractional a) => Int -> [a] -> Matroid Int matroidAG n fq = vectorMatroid' $ ptsAG n fq @@ -889,7 +891,7 @@ -- |Find representations of the matroid m over fq. Specifically, this function will find one representative -- of each projective equivalence class of representation.-representations :: (Fractional fq, Ord a) => [fq] -> Matroid a -> [[[fq]]]+representations :: (Eq fq, Fractional fq, Ord a) => [fq] -> Matroid a -> [[[fq]]] representations fq m = map L.transpose $ representations' (reverse $ zip b ir) (zip b' dhash') where fq' = tail fq -- fq \ {0} b = head $ bases m@@ -905,7 +907,7 @@ representations' ls [] = [map snd $ reverse ls] -- |Is the matroid representable over Fq? For example, to find out whether a matroid m is binary, evaluate @isRepresentable f2 m@.-isRepresentable :: (Fractional fq, Ord a) => [fq] -> Matroid a -> Bool+isRepresentable :: (Eq fq, Fractional fq, Ord a) => [fq] -> Matroid a -> Bool isRepresentable fq m = (not . null) (representations fq m) -- |A binary matroid is a matroid which is representable over F2@@ -1137,7 +1139,7 @@ -- TODO --- 1. Sort out the isomorphism / automorphism code in the case where the incidence graph isn't connected+-- 1. Sort out the isomorphism code in the case where the incidence graph isn't connected -- 2. We could generate the geometric representation from a matroid (provided its rank <= 4) -- geoRep m = filter (isDependent m) (flats m)
Math/Combinatorics/Poset.hs view
@@ -146,7 +146,7 @@ -- This is the projective geometry PG(n,q) -- |posetL n fq is the lattice of subspaces of the vector space Fq^n, ordered by inclusion. -- Subspaces are represented by their reduced row echelon form.-posetL :: FiniteField fq => Int -> [fq] -> Poset [[fq]]+posetL :: (Eq fq, FiniteField fq) => Int -> [fq] -> Poset [[fq]] posetL n fq = Poset ( subspaces fq n, isSubspace )
Math/Combinatorics/StronglyRegularGraph.hs view
@@ -9,6 +9,7 @@ import qualified Data.Set as S import Math.Common.ListSet +import Math.Core.Utils (combinationsOf) import Math.Algebra.Group.PermutationGroup hiding (P) import Math.Algebra.Group.SchreierSims as SS import Math.Combinatorics.Graph as G hiding (G)
Math/Common/IntegerAsType.hs view
@@ -1,6 +1,6 @@ -- Copyright (c) David Amos, 2009. All rights reserved. -{-# OPTIONS_GHC -fglasgow-exts #-} +{-# LANGUAGE EmptyDataDecls, ScopedTypeVariables #-} module Math.Common.IntegerAsType where
Math/CommutativeAlgebra/GroebnerBasis.hs view
@@ -281,10 +281,10 @@ where h // g = let ([u],_) = quotRemMP h [g] in u -- |@eliminate vs gs@ returns the elimination ideal obtained from the ideal generated by gs by eliminating the variables vs.-eliminate :: (Fractional k, Ord k, MonomialConstructor m, Monomial (m v), Ord (m v)) =>+eliminate :: (Eq k, Fractional k, Ord k, MonomialConstructor m, Monomial (m v), Ord (m v)) => [Vect k (m v)] -> [Vect k (m v)] -> [Vect k (m v)] eliminate vs gs = let subs = subFst vs in eliminateFst [g `bind` subs | g <- gs]- where subFst :: (Num k, MonomialConstructor m, Eq (m v), Mon (m v)) =>+ where subFst :: (Eq k, Num k, MonomialConstructor m, Eq (m v), Mon (m v)) => [Vect k (m v)] -> v -> Vect k (Elim2 (m v) (m v)) subFst vs = (\v -> let v' = var v in if v' `elem` vs then toElimFst v' else toElimSnd v')
Math/CommutativeAlgebra/Polynomial.hs view
@@ -157,7 +157,7 @@ lexvar v = return $ Lex $ M 1 [(v,1)] -- lexvar = var -instance (Num k, Ord v, Show v) => Algebra k (Lex v) where+instance (Eq k, Num k, Ord v, Show v) => Algebra k (Lex v) where unit x = x *> return munit mult xy = nf $ fmap (\(a,b) -> a `mmult` b) xy @@ -191,7 +191,7 @@ glexvar v = return $ Glex $ M 1 [(v,1)] -- glexvar = var -instance (Num k, Ord v, Show v) => Algebra k (Glex v) where+instance (Eq k, Num k, Ord v, Show v) => Algebra k (Glex v) where unit x = x *> return munit mult xy = nf $ fmap (\(a,b) -> a `mmult` b) xy @@ -227,7 +227,7 @@ grevlexvar v = return $ Grevlex $ M 1 [(v,1)] -- grevlexvar = var -instance (Num k, Ord v, Show v) => Algebra k (Grevlex v) where+instance (Eq k, Num k, Ord v, Show v) => Algebra k (Grevlex v) where unit x = x *> return munit mult xy = nf $ fmap (\(a,b) -> a `mmult` b) xy @@ -258,7 +258,7 @@ mcoprime (Elim2 a1 b1) (Elim2 a2 b2) = mcoprime a1 a2 && mcoprime b1 b2 mdeg (Elim2 a b) = mdeg a + mdeg b -instance (Num k, Ord a, Mon a, Ord b, Mon b) => Algebra k (Elim2 a b) where+instance (Eq k, Num k, Ord a, Mon a, Ord b, Mon b) => Algebra k (Elim2 a b) where unit x = x *> return munit mult xy = nf $ fmap (\(a,b) -> a `mmult` b) xy @@ -286,7 +286,7 @@ -- This is occasionally useful. -- |bind performs variable substitution-bind :: (Num k, MonomialConstructor m, Ord a, Show a, Algebra k a) =>+bind :: (Eq k, Num k, MonomialConstructor m, Ord a, Show a, Algebra k a) => Vect k (m v) -> (v -> Vect k a) -> Vect k a v `bind` f = linear (\m -> product [f x ^ i | (x,i) <- mindices m]) v -- V ts `bind` f = sum [c *> product [f x ^ i | (x,i) <- mindices m] | (m, c) <- ts] @@ -298,7 +298,7 @@ -- |Evaluate a polynomial at a point. -- For example @eval (x^2+y^2) [(x,1),(y,2)]@ evaluates x^2+y^2 at the point (x,y)=(1,2).-eval :: (Num k, MonomialConstructor m, Eq (m v), Show v) =>+eval :: (Eq k, Num k, MonomialConstructor m, Eq (m v), Show v) => Vect k (m v) -> [(Vect k (m v), k)] -> k eval f vs = unwrap $ f `bind` sub where sub x = case lookup (var x) vs of@@ -307,7 +307,7 @@ -- |Perform variable substitution on a polynomial. -- For example @subst (x*z-y^2) [(x,u^2),(y,u*v),(z,v^2)]@ performs the substitution x -> u^2, y -> u*v, z -> v^2.-subst :: (Num k, MonomialConstructor m, Eq (m u), Show u, Ord (m v), Show (m v), Algebra k (m v)) =>+subst :: (Eq k, Num k, MonomialConstructor m, Eq (m u), Show u, Ord (m v), Show (m v), Algebra k (m v)) => Vect k (m u) -> [(Vect k (m u), Vect k (m v))] -> Vect k (m v) subst f vs = f `bind` sub where sub x = case lookup (var x) vs of@@ -392,7 +392,7 @@ -- In the case where the gs are a Groebner basis for an ideal I, -- then @f %% gs@ is the equivalence class representative of f in R/I, -- and is zero if and only if f is in I.-(%%) :: (Fractional k, Monomial m, Ord m, Algebra k m) =>+(%%) :: (Eq k, Fractional k, Monomial m, Ord m, Algebra k m) => Vect k m -> [Vect k m] -> Vect k m f %% gs = rewrite f gs -- f %% gs = r where (_,r) = quotRemMP f gs@@ -402,7 +402,7 @@ -- The instance is well-defined only for scalars, and gives an error if used on other values. -- The purpose of this is to allow entry of fractional scalars, in expressions such as @x/2@. -- On the other hand, an expression such as @2/x@ will return an error.-instance (Fractional k, Monomial m, Ord m, Algebra k m) => Fractional (Vect k m) where+instance (Eq k, Fractional k, Monomial m, Ord m, Algebra k m) => Fractional (Vect k m) where recip (V [(m,c)]) | m == munit = V [(m,1/c)] | otherwise = error "Polynomial recip: only defined for scalars" fromRational x = V [(munit, fromRational x)]
Math/Core/Field.hs view
@@ -17,6 +17,8 @@ import Data.Bits import Data.List as L +import Math.Core.Utils (FinSet, elts)+ -- |Q is just the rationals, but with a better show function than the Prelude version newtype Q = Q Rational deriving (Eq,Ord,Num,Fractional) @@ -52,6 +54,8 @@ recip (F2 1) = F2 1 fromRational _ = error "F2.fromRational: not well defined" +instance FinSet F2 where elts = f2+ -- |f2 is a list of the elements of F2 f2 :: [F2] f2 = map fromInteger [0..1] -- :: [F2]@@ -77,6 +81,8 @@ recip (F3 x) = F3 x fromRational _ = error "F3.fromRational: not well defined" +instance FinSet F3 where elts = f3+ -- |f3 is a list of the elements of F3 f3 :: [F3] f3 = map fromInteger [0..2] -- :: [F3]@@ -102,6 +108,8 @@ recip (F5 x) = F5 $ (x^3) `mod` 5 fromRational _ = error "F5.fromRational: not well defined" +instance FinSet F5 where elts = f5+ -- |f5 is a list of the elements of F5 f5 :: [F5] f5 = map fromInteger [0..4]@@ -127,6 +135,8 @@ recip (F7 x) = F7 $ (x^5) `mod` 7 fromRational _ = error "F7.fromRational: not well defined" +instance FinSet F7 where elts = f7+ -- |f7 is a list of the elements of F7 f7 :: [F7] f7 = map fromInteger [0..6]@@ -152,6 +162,8 @@ recip (F11 x) = F11 $ (x^9) `mod` 11 fromRational _ = error "F11.fromRational: not well defined" +instance FinSet F11 where elts = f11+ -- |f11 is a list of the elements of F11 f11 :: [F11] f11 = map fromInteger [0..10]@@ -177,6 +189,8 @@ recip (F13 x) = F13 $ (x5*x5*x) `mod` 13 where x5 = x^5 `mod` 13 -- 12^11 would overflow Int fromRational _ = error "F13.fromRational: not well defined" +instance FinSet F13 where elts = f13+ -- |f13 is a list of the elements of F13 f13 :: [F13] f13 = map fromInteger [0..12]@@ -202,6 +216,8 @@ recip (F17 x) = F17 $ (x5^3) `mod` 17 where x5 = x^5 `mod` 17 -- 16^15 would overflow Int fromRational _ = error "F17.fromRational: not well defined" +instance FinSet F17 where elts = f17+ -- |f17 is a list of the elements of F17 f17 :: [F17] f17 = map fromInteger [0..16]@@ -227,6 +243,8 @@ recip (F19 x) = F19 $ (x4^4*x) `mod` 19 where x4 = x^4 `mod` 19 -- 18^17 would overflow Int fromRational _ = error "F19.fromRational: not well defined" +instance FinSet F19 where elts = f19+ -- |f19 is a list of the elements of F19 f19 :: [F19] f19 = map fromInteger [0..18]@@ -252,6 +270,8 @@ recip (F23 x) = F23 $ (x5^4*x) `mod` 23 where x5 = x^5 `mod` 23 -- 22^21 would overflow Int fromRational _ = error "F23.fromRational: not well defined" +instance FinSet F23 where elts = f23+ -- |f23 is a list of the elements of F23 f23 :: [F23] f23 = map fromInteger [0..22]@@ -290,6 +310,8 @@ recip (F4 x) = F4 (x `xor` 1) fromRational _ = error "F4.fromRational: not well defined" +instance FinSet F4 where elts = f4+ -- |f4 is a list of the elements of F4 f4 :: [F4] f4 = L.sort $ 0 : powers a4@@ -330,6 +352,8 @@ recip x = x^6 fromRational _ = error "F8.fromRational: not well defined" +instance FinSet F8 where elts = f8+ -- |f8 is a list of the elements of F8 f8 :: [F8] f8 = L.sort $ 0 : powers a8@@ -373,6 +397,8 @@ recip x = x^7 fromRational _ = error "F9.fromRational: not well defined" +instance FinSet F9 where elts = f9+ -- |f9 is a list of the elements of F9 f9 :: [F9] f9 = L.sort $ 0 : powers a9@@ -419,6 +445,8 @@ recip x = x^14 fromRational _ = error "F16.fromRational: not well defined" +instance FinSet F16 where elts = f16+ -- |f16 is a list of the elements of F16 f16 :: [F16] f16 = L.sort $ 0 : powers a16@@ -459,8 +487,9 @@ recip x = x^23 fromRational _ = error "F25.fromRational: not well defined" +instance FinSet F25 where elts = f25+ -- |f25 is a list of the elements of F25 f25 :: [F25] f25 = L.sort $ 0 : powers a25-
Math/Core/Utils.hs view
@@ -11,6 +11,14 @@ toSet = S.toList . S.fromList +-- Merge two ordered listsets. Elements appearing in both inputs appear only once in the output+mergeSet (x:xs) (y:ys) =+ case compare x y of+ LT -> x : mergeSet xs (y:ys)+ EQ -> x : mergeSet xs ys+ GT -> y : mergeSet (x:xs) ys+mergeSet xs ys = xs ++ ys+ pairs (x:xs) = map (x,) xs ++ pairs xs pairs [] = [] @@ -62,3 +70,21 @@ -- |@choose n k@ is the number of ways of choosing k distinct elements from an n-set choose :: (Integral a) => a -> a -> a choose n k = product [n-k+1..n] `div` product [1..k]+++-- |The class of finite sets+class FinSet x where+ elts :: [x]++-- |A class representing algebraic structures having an inverse operation.+-- Although strictly speaking the Num precondition means that we are requiring the structure+-- also to be a ring, we do sometimes bend the rules (eg permutation groups).+-- Note also that we don't insist that every element has an inverse.+class Num a => HasInverses a where+ inverse :: a -> a++infix 8 ^-++-- |A trick: x^-1 returns the inverse of x+(^-) :: (HasInverses a, Integral b) => a -> b -> a+x ^- n = inverse x ^ n
Math/NumberTheory/Factor.hs view
@@ -1,6 +1,7 @@ -- Copyright (c) 2006-2011, David Amos. All rights reserved. -module Math.NumberTheory.Factor where+-- |A module for finding prime factors.+module Math.NumberTheory.Factor (pfactors) where import Math.NumberTheory.Prime import Data.Either (lefts)@@ -105,7 +106,8 @@ -- |List the prime factors of n (with multiplicity).--- The algorithm uses trial division, followed by the elliptic curve method if necessary.+-- The algorithm uses trial division to find small factors,+-- followed if necessary by the elliptic curve method to find larger factors. -- The running time increases with the size of the second largest prime factor of n. -- It can find 10-digit prime factors in seconds, but can struggle with 20-digit prime factors. pfactors :: Integer -> [Integer]
Math/NumberTheory/Prime.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE NoMonomorphismRestriction #-} -+-- |A module providing functions to test for primality, and find next and previous primes. module Math.NumberTheory.Prime where import System.Random@@ -13,7 +13,7 @@ | n > 1 = isNotDivisibleBy primes | otherwise = False where isNotDivisibleBy (d:ds) | d*d > n = True- | n `mod` d == 0 = False+ | n `rem` d == 0 = False | otherwise = isNotDivisibleBy ds -- |A (lazy) list of the primes@@ -58,7 +58,7 @@ -- power_mod b t n == b^t mod n power_mod b t n = powerMod' b 1 t where powerMod' x y 0 = y- powerMod' x y t = powerMod' (x*x `mod` n) (if even t then y else x*y `mod` n) (t `div` 2)+ powerMod' x y t = powerMod' (x*x `rem` n) (if even t then y else x*y `rem` n) (t `div` 2) isMillerRabinPrime' n | n >= 4 =
Math/Projects/KnotTheory/Braid.hs view
@@ -1,6 +1,6 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -XFlexibleInstances -XTypeSynonymInstances #-} +{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-} module Math.Projects.KnotTheory.Braid where
Math/Projects/KnotTheory/IwahoriHecke.hs view
@@ -1,6 +1,6 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -XFlexibleInstances #-} +{-# LANGUAGE FlexibleInstances #-} module Math.Projects.KnotTheory.IwahoriHecke where
Math/Projects/KnotTheory/TemperleyLieb.hs view
@@ -1,6 +1,6 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -XFlexibleInstances #-} +{-# LANGUAGE FlexibleInstances #-} module Math.Projects.KnotTheory.TemperleyLieb where
Math/Projects/MiniquaternionGeometry.hs view
@@ -5,10 +5,11 @@ import qualified Data.List as L import Math.Common.ListSet as LS+import Math.Core.Utils (combinationsOf) import Math.Algebra.Field.Base import Math.Combinatorics.FiniteGeometry (pnf, ispnf, orderPGL)-import Math.Combinatorics.Graph (combinationsOf)+-- import Math.Combinatorics.Graph import Math.Combinatorics.GraphAuts import Math.Algebra.Group.PermutationGroup hiding (order) import qualified Math.Algebra.Group.SchreierSims as SS
Math/Projects/RootSystem.hs view
@@ -1,7 +1,5 @@ -- Copyright (c) David Amos, 2008. All rights reserved. -{-# OPTIONS_GHC -fglasgow-exts #-} - module Math.Projects.RootSystem where import Data.Ratio
Math/QuantumAlgebra/Tangle.hs view
@@ -24,7 +24,7 @@ -- type TensorAlgebra k a = Vect k [a] -instance (Num k, Ord a) => Algebra k [a] where+instance (Eq k, Num k, Ord a) => Algebra k [a] where unit 0 = zero -- V [] unit x = V [(munit,x)] mult = nf . fmap (\(a,b) -> a `mmult` b)
Math/Test/TAlgebras/TGroupAlgebra.hs view
@@ -4,35 +4,23 @@ module Math.Test.TAlgebras.TGroupAlgebra where +import Test.HUnit import Test.QuickCheck -import Math.Algebra.Group.PermutationGroup+import Math.Algebra.Group.PermutationGroup hiding (p) import Math.Test.TPermutationGroup -- for instance Arbitrary (Permutation Int) import Math.Algebras.VectorSpace import Math.Algebras.TensorProduct import Math.Algebras.Structures import Math.Algebras.GroupAlgebra+import Math.Core.Utils import Math.Test.TAlgebras.TStructures -{--instance Arbitrary (TensorAlgebra Integer) where- arbitrary = do ts <- arbitrary :: Gen [([Int], Integer)]- return $ nf $ V ts--} instance Arbitrary (GroupAlgebra Integer) where arbitrary = do ts <- arbitrary :: Gen [(Permutation Int, Integer)]- return $ nf $ V ts---{--prop_Algebra_TensorAlgebra (k,x,y,z) = prop_Algebra (k,x,y,z)- where types = (k,x,y,z) :: (Integer, TensorAlgebra Integer, TensorAlgebra Integer, TensorAlgebra Integer)--prop_Coalgebra_TensorAlgebra x = prop_Coalgebra x- where types = x :: TensorAlgebra Integer--}+ return $ nf $ V $ take 10 ts prop_Algebra_GroupAlgebra (k,x,y,z) = prop_Algebra (k,x,y,z) where types = (k,x,y,z) :: (Integer, GroupAlgebra Integer, GroupAlgebra Integer, GroupAlgebra Integer)@@ -53,3 +41,27 @@ prop_HopfAlgebra_GroupAlgebra x = prop_HopfAlgebra x where types = x :: GroupAlgebra Integer+++quickCheckGroupAlgebra = do+ putStrLn "Checking that group algebra is an algebra, coalgebra, bialgebra, and Hopf algebra..."+ quickCheck prop_Algebra_GroupAlgebra+ quickCheck prop_Coalgebra_GroupAlgebra+ quickCheck prop_Bialgebra_GroupAlgebra+ quickCheck prop_HopfAlgebra_GroupAlgebra+++testlistGroupAlgebra = TestList [+ testlistLeftInverse,+ testlistRightInverse+ ]++groupAlgebraElts = [ 1+p[[1,2,3]], 1+p[[1,2,3]]+p[[1,2],[3,4]], 1+2*p[[1,2,3]]+p[[1,2],[3,4]] ]++testcaseLeftInverse x = TestCase $ assertEqual ("inverse " ++ show x) 1 (x^-1 * x)++testlistLeftInverse = TestList $ map testcaseLeftInverse groupAlgebraElts ++testcaseRightInverse x = TestCase $ assertEqual ("inverse " ++ show x) 1 (x * x^-1)++testlistRightInverse = TestList $ map testcaseRightInverse groupAlgebraElts
+ Math/Test/TAlgebras/TOctonions.hs view
@@ -0,0 +1,39 @@+-- Copyright (c) 2011, David Amos. All rights reserved.++module Math.Test.TAlgebras.TOctonions where++import Test.QuickCheck++import Math.Algebra.Field.Base+import Math.Algebras.VectorSpace+import Math.Algebras.TensorProduct+import Math.Algebras.Quaternions+import Math.Algebras.Octonions++import Math.Test.TAlgebras.TVectorSpace+import Math.Test.TAlgebras.TStructures++import Math.Algebras.Structures -- not really needed++instance Arbitrary OBasis where+ arbitrary = elements $ map O [-1..6]++-- TVectorSpace defines an Arbitrary instance for Vect k b, given Arbitrary instances for k and b++-- same as prop_Algebra, but missing associativity axiom+prop_AlgebraNonAssociative (k,x) =+ unitOutL (k' `te` x) == (mult . (unit' `tf` id)) (k' `te` x) && -- left unit+ unitOutR (x `te` k') == (mult . (id `tf` unit')) (x `te` k') -- right unit+ where k' = k *> return ()++prop_AlgebraNonAssociative_Octonions (k,x) = prop_AlgebraNonAssociative (k,x)+ where types = (k,x) :: (Q, Octonion Q)++prop_InverseLoop (x,y) =+ x*1 == x && x == 1*x &&+ (x == 0 ||+ (x^-1 * (x*y) == y && y == (y*x) * x^-1 &&+ (x^-1)^-1 == x) )++prop_InverseLoop_Octonions (x,y) = prop_InverseLoop (x,y)+ where types = (x,y) :: (Octonion Q, Octonion Q)
Math/Test/TAlgebras/TTensorProduct.hs view
@@ -15,6 +15,13 @@ import Control.Category as C import Control.Arrow ++quickCheckTensorProduct = do+ putStrLn "Testing that tf is linear, and tensor product is a functor"+ quickCheck prop_Linear_tf+ quickCheck prop_TensorFunctor++ type DirectSum k u v = (u ~ Vect k a, v ~ Vect k b) => Vect k (DSum a b)
Math/Test/TAlgebras/TVectorSpace.hs view
@@ -28,7 +28,7 @@ instance Arbitrary EBasis where arbitrary = do n <- arbitrary :: Gen Int- return (E n)+ return (E $ abs n) instance Arbitrary b => Arbitrary (Dual b) where arbitrary = fmap Dual arbitrary@@ -42,7 +42,8 @@ instance (Num k, Ord b, Arbitrary k, Arbitrary b) => Arbitrary (Vect k b) where arbitrary = do ts <- arbitrary :: Gen [(b, k)] -- ScopedTypeVariables- return $ nf $ V ts+ return $ nf $ V $ take 10 ts+ -- we impose complexity bound of 10 terms, to avoid unbounded running time. prop_VecSpQn (a,b,x,y,z) = prop_VecSp (a,b,x,y,z) where types = (a,b,x,y,z) :: (Q, Q, Vect Q EBasis, Vect Q EBasis, Vect Q EBasis)
+ Math/Test/TCombinatorics/TFiniteGeometry.hs view
@@ -0,0 +1,67 @@+-- Copyright (c) 2011, David Amos. All rights reserved++module Math.Test.TCombinatorics.TFiniteGeometry where++import Test.HUnit++import Math.Combinatorics.FiniteGeometry+import Math.Core.Field+import Math.Combinatorics.GraphAuts (incidenceAuts)+import Math.Algebra.Group.PermutationGroup (orderSGS)+import Math.NumberTheory.Factor (pfactors)++testlistFiniteGeometry = TestList [+ testlistFlatsAG,+ testlistFlatsPG,+ testlistAutsAG,+ testlistAutsPG+ ]+++-- !! can't make list [f2,f3,f4], because they're different types+testcaseFlatsAG n fq k = TestCase $+ assertEqual (show "flatsAG " ++ show n ++ " " ++ show q ++ " " ++ show k)+ (numFlatsAG n q k) (length (flatsAG n fq k))+ where q = length fq++testlistFlatsAG = TestList $+ [testcaseFlatsAG n f2 k | n <- [2,3], k <- [0..n]] +++ [testcaseFlatsAG n f3 k | n <- [2,3], k <- [0..n]] +++ [testcaseFlatsAG n f4 k | n <- [2,3], k <- [0..n]]+++testcaseFlatsPG n fq k = TestCase $+ assertEqual (show "flatsPG " ++ show n ++ " " ++ show q ++ " " ++ show k)+ (numFlatsPG n q k) (length (flatsPG n fq k))+ where q = length fq++testlistFlatsPG = TestList $+ [testcaseFlatsPG n f2 k | n <- [2,3], k <- [0..n]] +++ [testcaseFlatsPG n f3 k | n <- [2,3], k <- [0..n]] +++ [testcaseFlatsPG n f4 k | n <- [2,3], k <- [0..n]]+++testcaseAutsAG n fq = TestCase $+ assertEqual ("autsAG " ++ show n ++ " " ++ show q)+ (orderAff n q * degree)+ (orderSGS $ incidenceAuts $ incidenceGraphAG n fq)+ where q = toInteger $ length fq+ degree = toInteger $ length $ pfactors $ toInteger q++testlistAutsAG = TestList $ + -- [testcaseAutsAG n f2 | n <- [2,3] ] ++ -- this is the complete graph, so has more auts than expected+ [testcaseAutsAG n f3 | n <- [2] ] -- +++ -- [testcaseAutsAG n f4 | n <- [2,3] ] -- these take too long+++testcaseAutsPG n fq = TestCase $+ assertEqual ("autsPG " ++ show n ++ " " ++ show q)+ (orderPGL (n+1) q * degree)+ (orderSGS $ incidenceAuts $ incidenceGraphPG n fq)+ where q = toInteger $ length fq+ degree = toInteger $ length $ pfactors $ toInteger q++testlistAutsPG = TestList $ + [testcaseAutsPG n f2 | n <- [2,3] ] +++ [testcaseAutsPG n f3 | n <- [2] ] -- +++ -- [testcaseAutsPG n f4 | n <- [2,3] ] -- these take too long
+ Math/Test/TCombinatorics/TGraphAuts.hs view
@@ -0,0 +1,127 @@+-- Copyright (c) 2011, David Amos. All rights reserved.++module Math.Test.TCombinatorics.TGraphAuts where++import Data.List as L+import Math.Core.Field hiding (f7)+import Math.Core.Utils (combinationsOf)+import Math.Algebra.Group.PermutationGroup as P+import Math.Combinatorics.Graph as G+import Math.Combinatorics.GraphAuts+import Math.Combinatorics.Matroid as M++import Test.HUnit+++testlistGraphAuts = TestList [+ testlistGraphAutsOrder,+ testlistGraphAutsGroup,+ testlistGraphAutsComplement,+ testlistIncidenceAutsOrder,+ testlistGraphIsos,+ testlistIsGraphIso,+ testlistIncidenceIsos+ ]+++-- We know the expected order of the graph automorphism group+testcaseGraphAutsOrder desc g n = TestCase $+ assertEqual ("order " ++ desc) n (orderSGS $ graphAuts g)++testlistGraphAutsOrder = TestList [+ let g = G [1..6] [[1,2],[3,4],[5,6]] in+ testcaseGraphAutsOrder (show g) g 48, -- 2*2*2*3!+ testcaseGraphAutsOrder "cube" cube 48,+ testcaseGraphAutsOrder "dodecahedron" dodecahedron 120+ ]+++induced bs g = fromPairs [(b, b -^ g) | b <- bs]++-- We know the expected group of graph automorphisms+testcaseGraphAutsGroup desc graph group = TestCase $+ assertEqual ("group " ++ desc) (elts $ graphAuts graph) (elts $ group)++testlistGraphAutsGroup = TestList [+ testcaseGraphAutsGroup "nullGraph 0" (nullGraph 0) [],+ testcaseGraphAutsGroup "nullGraph 1" (nullGraph 1) (_S 1),+ testcaseGraphAutsGroup "nullGraph 2" (nullGraph 2) (_S 2),+ testcaseGraphAutsGroup "nullGraph 3" (nullGraph 3) (_S 3),+ testcaseGraphAutsGroup "k 3" (k 3) (_S 3),+ testcaseGraphAutsGroup "k 4" (k 4) (_S 4),+ testcaseGraphAutsGroup "k 5" (k 5) (_S 5),+ testcaseGraphAutsGroup "c 4" (c 4) (_D 8),+ testcaseGraphAutsGroup "c 5" (c 5) (_D 10),+ let graph = G [1..3] [[1,2],[2,3]] in+ testcaseGraphAutsGroup (show graph) graph [p [[1,3]]], -- regression test+ let graph = G [1..6] [[2,3],[4,5],[5,6]] in+ testcaseGraphAutsGroup (show graph) graph [p [[2,3]], p [[4,6]]],+ testcaseGraphAutsGroup "petersen" petersen (map (induced $ combinationsOf 2 [1..5]) $ _S 5)+ ]+++-- The automorphisms of the graph should be the same as the auts of its complement+testcaseGraphAutsComplement desc g = TestCase $+ assertEqual ("complement " ++ desc) (elts $ graphAuts g) (elts $ graphAuts $ complement g)+-- the algorithm may not find the same set of generators, so we have to compare the elements++testlistGraphAutsComplement = TestList [+ testcaseGraphAutsComplement "k 3" (k 3),+ testcaseGraphAutsComplement "kb 2 3" (kb 2 3), -- complement is not connected+ testcaseGraphAutsComplement "kb 3 3" (kb 3 3), -- complement is not connected, but components can be swapped+ testcaseGraphAutsComplement "kt 2 3 3" (kt 2 3 3),+ testcaseGraphAutsComplement "kt 2 3 4" (kt 2 3 4),+ testcaseGraphAutsComplement "kt 3 3 3" (kt 3 3 3)+ ]++kt a b c = graph (vs,es)+ where vs = [1..a+b+c]+ es = L.sort $ [[i,j] | i <- [1..a], j <- [a+1..a+b] ]+ ++ [[i,k] | i <- [1..a], k <- [a+b+1..a+b+c] ]+ ++ [[j,k] | j <- [a+1..a+b], k <- [a+b+1..a+b+c] ]++-- We know the expected order of the incidence structure automorphism group+testcaseIncidenceAutsOrder desc g n = TestCase $+ assertEqual ("incidence order " ++ desc) n (P.order $ incidenceAuts g)++-- We use matroids as our incidence structure just because we have a powerful library for constructing them+testlistIncidenceAutsOrder = TestList [+ testcaseIncidenceAutsOrder "pg2 f2 (B)" (incidenceGraphB $ matroidPG 2 f2) 168,+ testcaseIncidenceAutsOrder "pg2 f2 (C)" (incidenceGraphC $ matroidPG 2 f2) 168,+ testcaseIncidenceAutsOrder "pg2 f2 (H)" (incidenceGraphH $ matroidPG 2 f2) 168,+ testcaseIncidenceAutsOrder "u 1 3 (B)" (incidenceGraphB $ u 1 3) 6, -- not connected+ testcaseIncidenceAutsOrder "u 1 3 (C)" (incidenceGraphC $ u 1 3) 6,+ testcaseIncidenceAutsOrder "u 1 3 (H)" (incidenceGraphH $ u 1 3) 6, -- not connected+ testcaseIncidenceAutsOrder "u 2 3 `dsum` u 2 3 (H)" (incidenceGraphH $ u 2 3 `dsum` u 2 3) 72, -- 6*6*2+ testcaseIncidenceAutsOrder "u 2 3 `dsum` u 2 3 (C)" (incidenceGraphC $ u 2 3 `dsum` u 2 3) 72, -- not connected+ testcaseIncidenceAutsOrder "u 2 3 `dsum` u 3 4 (H)" (incidenceGraphH $ u 2 3 `dsum` u 3 4) 144, -- 6*24+ testcaseIncidenceAutsOrder "u 2 3 `dsum` u 3 4 (C)" (incidenceGraphC $ u 2 3 `dsum` u 3 4) 144 -- not connected+ ]+++testcaseGraphIsos g1 g2 isos = TestCase $+ assertEqual (show (g1,g2)) isos (graphIsos g1 g2)++testlistGraphIsos = TestList [+ testcaseGraphIsos (G [1,2] []) (G [3,4] []) [[(1,3),(2,4)],[(1,4),(2,3)]],+ testcaseGraphIsos (G [1,2,3] [[1,2]]) (G [4,5,6] [[5,6]]) [[(1,5),(2,6),(3,4)],[(1,6),(2,5),(3,4)]]+ ]+++testcaseIsGraphIso g1 g2 = TestCase $+ assertBool (show (g1,g2)) $ isGraphIso g1 g2++testlistIsGraphIso = TestList [+ testcaseIsGraphIso (nullGraph') (nullGraph')+ ]+++testcaseIncidenceIsos g1 g2 isos = TestCase $+ assertEqual (show (g1,g2)) isos (incidenceIsos g1 g2)++testlistIncidenceIsos = TestList [+ testcaseIncidenceIsos (G [Left 1, Right 2] []) (G [Left 3, Right 4] []) [[(1,3)]],+ testcaseIncidenceIsos (G [Left 1, Left 2, Right 1] [[Left 1, Right 1]])+ (G [Left 3, Left 4, Right 4] [[Left 4, Right 4]])+ [[(1,4),(2,3)]]+ ]
Math/Test/TCore/TField.hs view
@@ -60,7 +60,8 @@ quickCheckField =- do putStrLn "Testing F2..."+ do putStrLn "Testing finite fields"+ putStrLn "Testing F2..." quickCheck (prop_Field :: (F2,F2,F2) -> Bool) putStrLn "Testing F3..." quickCheck (prop_Field :: (F3,F3,F3) -> Bool)
Math/Test/TFiniteGeometry.hs view
@@ -1,8 +1,9 @@ module Math.Test.TFiniteGeometry where import Math.Combinatorics.FiniteGeometry -import Math.Algebra.Field.Base -import Math.Algebra.Field.Extension +import Math.Core.Field +-- import Math.Algebra.Field.Base +-- import Math.Algebra.Field.Extension import Math.Combinatorics.GraphAuts import Math.Algebra.Group.PermutationGroup @@ -23,10 +24,10 @@ ,numFlatsPG 3 4 1 == length (flatsPG 3 f4 1) ,numFlatsPG 3 4 2 == length (flatsPG 3 f4 2) ,numFlatsPG 3 4 3 == length (flatsPG 3 f4 3) - ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f2) == orderAff 2 2 * toInteger (degree f2) - ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f3) == orderAff 2 3 * toInteger (degree f3) - ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f4) == orderAff 2 4 * toInteger (degree f4) - ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f2) == orderPGL 3 2 * toInteger (degree f2) - ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f3) == orderPGL 3 3 * toInteger (degree f3) - ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f4) == orderPGL 3 4 * toInteger (degree f4) + ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f2) == orderAff 2 2 -- * toInteger (degree f2) + ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f3) == orderAff 2 3 -- * toInteger (degree f3) + ,(orderSGS $ incidenceAuts $ incidenceGraphAG 2 f4) == orderAff 2 4 * 2 -- * toInteger (degree f4) + ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f2) == orderPGL 3 2 -- * toInteger (degree f2) + ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f3) == orderPGL 3 3 -- * toInteger (degree f3) + ,(orderSGS $ incidenceAuts $ incidenceGraphPG 2 f4) == orderPGL 3 4 * 2 -- * toInteger (degree f4) ]
Math/Test/TPermutationGroup.hs view
@@ -6,6 +6,8 @@ import qualified Data.List as L +import Math.Core.Utils hiding (elts) + import Math.Algebra.Group.PermutationGroup as P import Math.Algebra.Group.SchreierSims as SS import Math.Algebra.Group.RandomSchreierSims as RSS
Math/Test/TestAll.hs view
@@ -11,7 +11,13 @@ import Math.Test.TCore.TField +import Math.Test.TAlgebras.TGroupAlgebra +import Math.Test.TAlgebras.TOctonions +import Math.Test.TAlgebras.TTensorAlgebra +import Math.Test.TAlgebras.TTensorProduct import Math.Test.TCombinatorics.TDigraph +import Math.Test.TCombinatorics.TFiniteGeometry +import Math.Test.TCombinatorics.TGraphAuts import Math.Test.TCombinatorics.TIncidenceAlgebra import Math.Test.TCombinatorics.TMatroid import Math.Test.TCombinatorics.TPoset @@ -21,7 +27,6 @@ import Math.Test.TProjects.TMiniquaternionGeometry - import Test.QuickCheck import Test.HUnit @@ -37,14 +42,24 @@ quickCheckAll = do - quickCheck prop_NonCommRingNPoly + -- quickCheck prop_NonCommRingNPoly quickCheck prop_GroupPerm quickCheckField + quickCheckTensorProduct + quickCheckGroupAlgebra + quickCheckTensorAlgebra + putStrLn "Testing Octonions..." + quickCheck prop_AlgebraNonAssociative_Octonions + quickCheck prop_InverseLoop_Octonions + putStrLn "Testing miniquaternion geometries..." quickCheck prop_NearFieldF9 quickCheck prop_NearFieldJ9 hunitAll = runTestTT $ TestList [ + testlistGroupAlgebra, testlistDigraph, + testlistFiniteGeometry, + testlistGraphAuts, testlistIncidenceAlgebra, testlistMatroid, testlistPoset,