definition example

A multiset is a set in which elements may occur more than once. Category Theory for Scientists makes this precise with a Surjection: a multiset is a triple of a set of element instances, a set of element names, and a surjective Function ; the multiplicity of a name is the cardinality of its Fiber . A mapping of multisets is a pair of functions , making the square commute, .

Sources: CTfS §2.7.6 (Definition 2.7.6.3, Exercises 2.7.6.2, 2.7.6.4–2.7.6.5, Definition 2.7.6.7, Exercises 2.7.6.8–2.7.6.9); Indexed Set for the fiberwise view.

Examples

  • is over with — the name has multiplicity 2. has with multiplicity 3.
  • Mappings (CTfS Exercise 2.7.6.5): a mapping must send the two instances of to instances of one and the same name. Sending , , is fine — the instances land among the three ‘s and the one . Counting: for each choice of the instances can be sent anywhere in the right fibers, giving mappings; without the commuting square there would be pairs of functions.
  • Data: a column of a database table, such as the surnames of all employees, is a multiset — rows are instances, distinct values are names, and repeated surnames have multiplicity .
  • The bag of words of a document, histograms, the prime factorization .

Relative sets and the slice category

Dropping the surjectivity requirement (allowing multiplicity 0 — CTfS’s pseudo-multisets, CTfS Exercise 2.7.6.4) and fixing the set of names gives CTfS’s relative sets over (Definition 2.7.6.7): a set with a function ; morphisms over are functions commuting with the maps to . These form the Slice Category (CTfS Exercise 2.7.6.8 checks that composites are again maps over ). Relative sets over are just sets; over there is only the empty set, with its identity (CTfS Exercise 2.7.6.9). Via fibers, a set over is the same as a -indexed family of sets, and a multiset is one in which every fiber is nonempty. Multisets of counts form the free commutative monoid, — the “commutative List”, a Monad on .

Docs: FinSets

using Catlab
# a multiset as a surjection π : E → B (CTfS Definition 2.7.6.3): X = (1,1,2,3), Y = (a,b,b,b)
πX = FinFunction([1, 1, 2, 3], 3)        # instances e₁…e₄ ↦ names 1,2,3
πY = FinFunction([1, 2, 2, 2], 2)        # names a = 1, b = 2
multiplicity(π) = [count(==(b), collect(π)) for b in codom(π)]
multiplicity(πX), multiplicity(πY)                       # ([2, 1, 1], [1, 3])
# a mapping (f, g) : X → Y must satisfy πY ∘ f = g ∘ πX
g = FinFunction([2, 1, 2], 3, 2)         # 1 ↦ b, 2 ↦ a, 3 ↦ b
f = FinFunction([2, 3, 1, 4], 4, 4)      # the two 1s ↦ two b's, the 2 ↦ the a, the 3 ↦ a b
force(compose(f, πY)) == force(compose(πX, g))           # true: the square commutes
import Mathlib
#check Multiset                 -- quotient of lists by permutation
#check @Multiset.count          -- multiplicity of an element
#eval Multiset.count 1 ({1, 1, 2, 3} : Multiset ℕ)   -- 2
-- the fibre view: a set over B
#check @CategoryTheory.Over     -- the slice category Over B of relative sets
import qualified Data.Map as Map
 
-- a multiset as element-name ↦ multiplicity: the free commutative monoid
type Multiset a = Map.Map a Int
 
fromList :: Ord a => [a] -> Multiset a
fromList xs = Map.fromListWith (+) [(x, 1) | x <- xs]
 
-- fromList [1,1,2,3] == Map.fromList [(1,2),(2,1),(3,1)]
-- the union of bags adds multiplicities: Map.unionWith (+)