Metadata-Version: 2.3
Name: posets
Version: 1.0.0
Summary: A package for working with finite partial orders
Project-URL: Homepage, https://github.com/WilliamGustafson/posets
Author-email: William Gustafson <williamlgustafson@gmail.com>
License-File: LICENSE
Keywords: Hasse diagram,ab-index,cd-index,flag vectors,lattices,order complex,partial orders,partially ordered,partially ordered sets,posets
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.8
Requires-Dist: decorator
Requires-Dist: numpy
Requires-Dist: wand
Description-Content-Type: text/markdown


This module provides a class `Poset` that encodes a finite partially
ordered set (poset). Most notably, this module can efficiently compute
flag vectors, the
<span class="upright">**a**</span><span class="upright">**b**</span>-index
and the
<span class="upright">**c**</span><span class="upright">**d**</span>-index.
Quasigraded posets, in the sense of [\[2\]](#references), can be encoded and the
<span class="upright">**a**</span><span class="upright">**b**</span>-index
and
<span class="upright">**c**</span><span class="upright">**d**</span>-index
of quasigraded posets can be computed. Latex code for Hasse diagrams can
be produced with a very flexible interface. There are methods for common
operations and constructions such as Cartesian products, disjoint
unions, interval lattices, lattice of ideals, etc. Various examples of
posets are provided such as Boolean algebras, the face lattice of the
$n$-dimensional cube, (noncrossing) partition lattices, the type $A_n$
Bruhat and weak orders, uncrossing orders etc. General subposets can be
selected as well as particular ones of interest such as intervals and
rank selections. Posets from this module can also be converted to and
from posets from [sagemath](https://www.sagemath.org) and
[Macaulay2](https://www.macaulay2.com/).

Terminology and notation on posets generally follows [\[3\]](#references) and [\[1\]](#references).

## Installation

Download the whl file
[here](https://www.github.com/WilliamGustafson/posets/releases) and
install it with pip via `python -m pip posets-*-py3-none-any.whl`.

## Building

Building the package requires [hatch](https://hatch.pypa.io) to be
installed. Running `make` will build the package with a timestamp in the
version, to build without the timestamp in the version run
`make RELEASE=0` (the value of 0 is arbitrary, you just need to set
`RELEASE` to any nonemtpy value). This will make a whl file at
`dist/posets-<version>-py3-none-any.whl` that you can install with pip.

The documentation can be built in pdf form by running `make docs` from
the base directory, this will also use a timestamp in the version unless
you use `RELEASE=0`. Compilation requires LaTeXto be installed with the
packages pgf/tikz, graphicx, fancyvrb, amsmath, amsssymb, scrextend,
mdframed and hyperref as well as the python module `pydox`. `pydox` can
be obtained from <a href="github.com/WilliamGustafson/pydox.git"
class="uri">github.com/WilliamGustafson/pydox.git</a>. You must either
place the script `pydox.py` somewhere in your path named `pydox` or call
make with `make PYDOX=[path to pydox] docs`.

## Testing

You can run the tests via `make test`, this requires
[pytest](https://pytest.org) to be installed. You can create an html
coverage report, output to `tests/htmlcov/index.html`, with
`make coverage`. Making the coverage report requires
[pytest](https://pytest.org),
[coverage](https://coverage.readthedocs.io) and the
[pytest-cov](https://pytest-cov.readthedocs.io) plugin. Note, coverage
on `hasseDiagram.py` is very low because testing drawing functions
cannot be easily automated.

## Publishing

After building the package it can be published to PyPi by running
`make publish RELEASE=0`, running `make publish` will publish to
TestPyPi. This requires `twine` and `gpg` to be installed. Additionally,
the publishing command expects there to be an encrypted api token named
`pypi.token.gpg` (or `test.pypi.token.gpg` for TestPyPi) at the project
root. This will also build the package if it is not built already. If
you have an unencrypted api token from PyPi named `pypi.token` you can
encrypt it via:

    gpg --encrypt --symmetric --output pypi.token.gpg pypi.token

## Usage

Here we give an introduction to using the posets module.

In the code snippets below we assume the module is imported via

`from posets import *`

Constructing a poset:

    P = Poset(relations={'':['a','b'],'a':['ab'],'b':['ab']})
    Q = Poset(relations=[['','a','b'],['a','ab'],['b','ab']])
    R = Poset(elements=['ab','a','b',''], less=lambda x,y: return x in y)
    S = Poset(zeta = [[0,1,1,1],[0,0,0,1],[0,0,0,1],[0,0,0,0]], elements=['','a','b','ab'])

Built in examples (see page ):

    Boolean(3) #Boolean algebra of rank 3
    Cube(3) #Face lattice of the 3-dimensional cube
    Bruhat(3) #Bruhat order on symmetric group of order 3!
    Bnq(n=3,q=2) #Lattice of subspaces of F_2^3
    DistributiveLattice(P) #lattice of ideals of P
    Intervals(P) #meet semilattice of intervals of P

These examples come with default drawing methods, for example, when
making latex code by calling `DistributiveLattice(P).latex()` the
resulting figure depicts elements of the lattice as Hasse diagrams of
$P$ with elements of the ideal highlighted (again, see page ). Note, you
will have to set the `height`, `width` and possibly `nodescale`
parameters in order to get sensible output.

Two posets compare equal when they have the same set of elements and the
same zeta values (i.e. the same order relation with the same weights):

    P == Q and Q == R and R == S #True
    P == Poset(relations={'':['a','b']}) #False
    P == Poset(relations={'':['ab'],'a':['ab'],'b':['ab']}) #False
    P == Poset(zeta=[[0,1,1,2],[0,0,0,3],[0,0,0,4],[0,0,0,0]],
        elements=['','a','b','ab']) #False

Use `is_isomorphic` or `PosetIsoClass` to check whether posets are
isomorphic:

    P.is_isomorphic(Boolean(2)) #True
    P.isoClass()==Boolean(2).isoClass() #True
    P.is_isomorphic(Poset(relations={'':['a','b']})) #False

Viewing and creating Hasse diagrams:

    P.show() #displays a Hasse diagram in a new window
    P.latex() #returns latex code: \begin{tikzpicture}...
    P.latex(standalone=True) #latex code for a
    #standalone document: \documentclass{preview}...
    display(P.img()) #Display a poset when in a Jupyter notebook
    #this uses the output of latex()

Computing invariants:

    Cube(2).fVector() #{(): 1, (1,): 4, (2,): 4, (1, 2): 8}
    Cube(2).hVector() #{(): 1, (1,): 3, (2,): 3, (1, 2): 1}
    Boolean(5).sparseKVector() #{(3,): 8, (2,): 8, (1, 3): 4, (1,): 3, (): 1}
    Boolean(5).cdIndex() #Polynomial({'ccd': 3, 'cdc': 5, 'dd': 4, 'dcc': 3, 'cccc': 1})
    print(Boolean(5).cdIndex()) #c^{4}+3c^{2}d+5cdc+3dc^{2}+4d^{2}

Polynomial operations:

    #Create noncommutative polynomials from dictionaries,
    #keys are monomials, values are coefficients
    p=Polynomial({'ab':1})
    q=Polynomial({'a':1,'b':1})

    #get and set coefficients like a dictionary
    q['a'] #1
    q['x'] #0
    p['ba'] = 1

    #print latex
    str(p) #ab+ba

    #basic arithmetic, polynomials form a real algebra
    p+q #ab+ba+a+b
    p*q #aba+ab^{2}+ba^{2}+bab
    q*p #a^{2}b+aba+bab+b^{2}a
    2*p #2ab+2ba
    p**2 #abab+ab^{2}a+ba^{2}b+baba
    p**(-1) #raises NotImplementedError
    p**q #raises NotImplementedError

    #substitutions and conversions
    p.sub(q,'a') #ab+ba+2b^{2} substitute q for a in p
    p.abToCd() #d rewrite a's and b's
    #in terms of c=a+b and d=ab+ba when possible
    Polynomial({'c':1,'d':1}).cdToAb() #a+b+ab+ba rewrite c's and d's
    #in terms of a's and b's

Converting posets to and from SageMath:

    P.toSage() #Returns a SageMath class, must be run under sage
    Poset.fromSage(Q) #Take a poset Q made with SageMath and return an instance of Poset

Converting to and from Macaulay2:

    -- In M2
    load "convertPosets.m2" --Also loads Python and Posets packages
    import "posets" --This module must be installed to system version of python
    P = posets\@\@Boolean(3) --Calling python functions
    pythonPosetToMac(P) --Returns an instance of the M2 class Posets
    macPosetToPython(Q) --Take a poset made with M2 and return an
    --instance of the python class Poset

Quasigraded posets:

    #Provide the zeta and rank functions explicitly
    #To construct a 2-chain with top two elements rank 2 and 3
    #and with zeta value -1 between minimum and the element covering it:
    T = Poset([[1,-1,1],[1,1],[1]], ranks=[[0],[],[1],[2]])

The poset `T` above is from \[2, Example 6.14\] with $M$ taken to be the
3-dimensional solid torus.

You can calculate the flag vectors and the
<span class="upright">**c**</span><span class="upright">**d**</span>-index
just as you would for a classical poset, for example, `T.cdIndex()`
returns the polynomial $\textup{\textbf{c}}^2-2\textup{\textbf{d}}$.

When plotting a quasigraded poset by default only the underlying poset
is shown with element heights based on rank, the zeta values are not
shown. If you wish to display the zeta values you can use the class
`ZetaHasseDiagram` to draw a Hasse diagram of your poset with an element
$p$ depicted as the associated filter, namely the subposet
$\\{q:q\ge p\\}$, and with elements of the filters labeled by the
corresponding zeta value. To do so, either construct the poset with
`hasse_class=ZetaHasseDiagram` such as in
`Poset([[1,-1,1],[1,1],[1]], ranks=[[0],[],[1],[2]],hasse_class=ZetaHasseDiagram)`
or set the Hasse diagram attribute on the poset as below:

    T = Poset([[1,-1,1],[1,1],[1]], ranks=[[0],[],[1],[2]])
    T.hasseDiagram = ZetaHasseDiagram(T)

You can also represent elements with ideals instead of filters by
passing `filters=False`. See `ZetaHasseDiagram` and
`SubposetsHasseDiagram` for a thorough explanation of the options.

# References
<div id="refs" class="references csl-bib-body">

<div id="ref-birkhoff-67" class="csl-entry">

<span class="csl-left-margin">1.
</span><span class="csl-right-inline">Garrett Birkhoff. 1967. *Lattice
theory*. American Mathematical Society, Providence, R.I.</span>

</div>

<div id="ref-ehrenborg-goresky-readdy-15" class="csl-entry">

<span class="csl-left-margin">2.
</span><span class="csl-right-inline">Richard Ehrenborg, Mark Goresky,
and Margaret Readdy. 2015. Euler flag enumeration of whitney stratified
spaces. *Adv. Math. (N. Y.)* 268: 85–128.</span>

</div>

<div id="ref-stanley-12" class="csl-entry">

<span class="csl-left-margin">3.
</span><span class="csl-right-inline">Richard P Stanley. 2012.
*Enumerative combinatorics. Volume 1*. Cambridge University Press,
Cambridge.</span>

</div>

</div>
