Joshua Moerman
4 years ago
commit
98472736c9
9 changed files with 143 additions and 0 deletions
@ -0,0 +1 @@ |
|||
dist-newstyle |
@ -0,0 +1,12 @@ |
|||
Counting |
|||
======== |
|||
|
|||
Some combinatorics in Haskell. Currently has Bell numbers, binomial |
|||
coefficients, and triangular numbers. And some number of orbits of |
|||
sets with atoms (nominal sets). |
|||
|
|||
Use `cabal` to build: |
|||
|
|||
``` |
|||
cabal run counting |
|||
``` |
@ -0,0 +1,2 @@ |
|||
import Distribution.Simple |
|||
main = defaultMain |
@ -0,0 +1,27 @@ |
|||
module Main where |
|||
|
|||
import Bell |
|||
import Matchings |
|||
import Stirling |
|||
import Control.Monad |
|||
|
|||
heightOfDistinctAtoms :: Int -> Integer |
|||
heightOfDistinctAtoms n = toInteger $ n + 1 |
|||
|
|||
heightOfAtoms :: Int -> Integer |
|||
heightOfAtoms n = sum [ norbits k * heightOfDistinctAtoms k | k <- [0 .. n] ] |
|||
+ sum [ matchings o1 o2 | (o1, o2) <- cross ] |
|||
where |
|||
norbits k = secondStirling n k |
|||
orbits k = replicate (fromIntegral (norbits k)) k |
|||
allOrbits = concat [ orbits k | k <- [0..n] ] |
|||
cross = [ (allOrbits !! i, allOrbits !! j) | let m = length allOrbits, i <- [0 .. m-1], j <- [i+1 .. m-1] ] |
|||
|
|||
orbitsOf :: Int -> [Int] |
|||
orbitsOf n = concat [ replicate (fromIntegral (secondStirling n k)) k | k <- [0..n] ] |
|||
|
|||
main :: IO () |
|||
main = do |
|||
let out = [ (i, heightOfAtoms i, bell (2*i)) | i <- [0..10] ] |
|||
forM_ out $ \(i, n, b) -> putStrLn ("h(A^" ++ show i ++ ") = " ++ show n ++ " < B_" ++ show (2*i) ++ " = " ++ show b) |
|||
|
@ -0,0 +1,28 @@ |
|||
cabal-version: 2.2 |
|||
name: counting |
|||
version: 0.1.0.0 |
|||
author: Joshua Moerman |
|||
maintainer: joshua@cs.rwth-aachen.de |
|||
build-type: Simple |
|||
|
|||
common stuff |
|||
default-language: Haskell2010 |
|||
build-depends: |
|||
base >=4.14 && <4.15, |
|||
containers, |
|||
MemoTrie |
|||
|
|||
library |
|||
import: stuff |
|||
hs-source-dirs: src |
|||
exposed-modules: |
|||
Bell, |
|||
Binomial, |
|||
Matchings, |
|||
Stirling |
|||
|
|||
executable counting |
|||
import: stuff |
|||
hs-source-dirs: app |
|||
main-is: Main.hs |
|||
build-depends: counting |
@ -0,0 +1,23 @@ |
|||
module Bell where |
|||
|
|||
import Data.MemoTrie |
|||
import Stirling |
|||
|
|||
-- A000110 |
|||
-- number of partitions of a set |
|||
-- also the number of n-types in the structure (N, =) |
|||
bell :: Int -> Integer |
|||
bell = memo bell0 where |
|||
bell0 n = if n <= 12 |
|||
then table !! n |
|||
else sum [ secondStirling n k | k <- [0 .. n] ] |
|||
table = [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597] |
|||
|
|||
-- number of n-types in the structure (N, <=) |
|||
orderedBell :: Int -> Integer |
|||
orderedBell = memo ob where |
|||
ob n = if n <= 10 |
|||
then table !! n |
|||
else sum [ fac k * secondStirling n k | k <- [0 .. n] ] |
|||
table = [1, 1, 3, 13, 75, 541, 4683, 47293, 545835, 7087261, 102247563] |
|||
fac k = product [1 .. fromIntegral k] |
@ -0,0 +1,18 @@ |
|||
module Binomial where |
|||
|
|||
import Data.MemoTrie |
|||
|
|||
-- binomial coefficients |
|||
binomial :: Int -> Int -> Integer |
|||
binomial = memo2 b where |
|||
b n k = if k > n |
|||
then 0 |
|||
else if n <= 5 |
|||
then table !! n !! k |
|||
else binomial (n-1) k + binomial (n-1) (k-1) |
|||
table = [ [1] |
|||
, [1, 1] |
|||
, [1, 2, 1] |
|||
, [1, 3, 3, 1] |
|||
, [1, 4, 6, 4, 1] |
|||
, [1, 5, 10, 10, 5, 1] ] |
@ -0,0 +1,12 @@ |
|||
module Matchings where |
|||
|
|||
import Data.MemoTrie |
|||
import Binomial |
|||
|
|||
-- number of ways to match up k elements with n elements |
|||
-- matchings may be partial |
|||
matchings :: Int -> Int -> Integer |
|||
matchings = memo2 m where |
|||
m n k = if n > k |
|||
then matchings k n |
|||
else sum [ binomial n i * product [fromIntegral (k-i+1) .. fromIntegral k] | i <- [0 .. n]] |
@ -0,0 +1,20 @@ |
|||
module Stirling where |
|||
|
|||
import Data.MemoTrie |
|||
|
|||
-- Number of ways to partition n into k subsets |
|||
secondStirling :: Int -> Int -> Integer |
|||
secondStirling = memo2 ss where |
|||
ss n k = if k > n |
|||
then 0 |
|||
else if n <= 6 |
|||
then table !! n !! k |
|||
else (fromIntegral k) * secondStirling (n - 1) k + secondStirling n (k - 1) |
|||
table = |
|||
[ [1] |
|||
, [0, 1] |
|||
, [0, 1, 1] |
|||
, [0, 1, 3, 1] |
|||
, [0, 1, 7, 6, 1] |
|||
, [0, 1, 15, 25, 10, 1] |
|||
, [0, 1, 31, 90, 65, 15, 1] ] |
Loading…
Reference in new issue