# Using Polymake.jl

In this section, the main functionality of Polymake.jl is covered: how to access polymake's powerful abilities. For this cause one needs to know how to call polymake methods and how to handle the supported types.

## Executing Polymake Methods

### Directly calling a polymake method

One of the simplest yet most useful possibilities Polymake.jl offers is to directly use a polymake method via the following macro:

Polymake.@pmMacro
@pm polymakeapp.function_name{Template, parameters}(args)

This macro can be used to

• create polymake Big Objects (such as polytopes)
• call polymake functions with specific template parameters.

The expression passed to the macro has to be:

• a fully qualified name of a polymake object (i.e. starting with the

lowercase name of a polymake application), or

• a function with template parameters enclosed in { ... }.

Examples

julia> P = @pm polytope.Polytope{QuadraticExtension}(POINTS=[1 0 0; 0 1 0])

POINTS
1 0 0
0 1 0

julia> @pm common.convert_to{Float}(P)
type: Polytope<Float>

POINTS
1 0 0
0 1 0

CONE_AMBIENT_DIM
3

julia> @pm tropical.Polytope{Max}(POINTS=[1 0 0; 0 1 0])
type: Polytope<Max, Rational>

POINTS
0 -1 -1
0 1 0



!!! Note the expression in @pm macro is parsed syntactically, so it has to be a valid julia expression. However template parameters need not to be defined in julia, but must be valid names of polymake property types. Nested types (such as {QuadraticExtension{Rational}}) are allowed.

source

The @pm macro can be used to issue more complicated calls to polymake from julia. If You need to pass templates to BigObjects, some limited support is provided in costructors. For example one can construct polytope.Polytope{Float64}(...). However for this to work templates need to be valid julia types/object, hence it is not possible to construct a Polytope<QuadraticExtension> through such call. For this (and in general: for passing more complicated templates) one needs the @pm macro:

$obj = new BigObject<Template,Parameters>(args) becomes obj = @pm appname.BigObject{Template, Parameters}(args) Examples: tropical.Polytope{max, Polymake.Rational}(POINTS=[1 0 0; 1 1 0; 1 1 1]) # call to constructor, note that max is a julia function, hence a valid object @pm tropical.Polytope{Max, QuadraticExtension}(POINTS=[1 0 0; 1 1 0; 1 1 1]) # macro call: none of the types in templates need to exist in julia As a rule of thumb any template passed to @pm macro needs to be translatable on syntax level to a C++ one. E.g. Matrix{Integer} works, as it translates to pm::Matrix<pm::Integer>. Such templates can be passed to functions as well. A very useful example is the common.convert_to: julia> c = polytope.cube(3); julia> f = c.FACETS; julia> f[1,1] # f is an opaque pm::perl::PropertyValue to julia ERROR: MethodError: no method matching getindex(::Polymake.PropertyValueAllocated, ::Int64, ::Int64) Stacktrace: [...] julia> m = @pm common.convert_to{Matrix{Integer}}(f) # the template must consist of C++ names pm::Matrix<pm::Integer> 1 1 0 0 1 -1 0 0 1 0 1 0 1 0 -1 0 1 0 0 1 1 0 0 -1 julia> m[1,1] 1 Since the combination of the @pm macro and common.convert_to is quite common there is a specialized @convert_to macro for this:  julia> m = @convert_to Matrix{Integer} f # the template must consist of C++ names pm::Matrix<pm::Integer> 1 1 0 0 1 -1 0 0 1 0 1 0 1 0 -1 0 1 0 0 1 1 0 0 -1 ### Wrapped methods As the @pm macro allows to access polymake's library, there is no need for every method to be wrapped. In general, the wrapped methods restrict to simpler ones in the context of small types, guaranteeing compatibility with julia or allowing easy modification/operations of/with instances of these types. This results in a handling of these types which is equivalent to julia's syntax, e.g. arrays can be accessed with the brackets operator [] or addition can be applied by using +: julia> m = Polymake.Matrix{Polymake.Rational}(4,6) pm::Matrix<pm::Rational> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 julia> m[2,1] = 9 9 julia> m pm::Matrix<pm::Rational> 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 julia> a = Polymake.TropicalNumber{Polymake.Min}(7) pm::TropicalNumber<pm::Min, pm::Rational> 7 julia> b = Polymake.TropicalNumber{Polymake.Min}(10) pm::TropicalNumber<pm::Min, pm::Rational> 10 julia> a + b pm::TropicalNumber<pm::Min, pm::Rational> 7 ### Function Arguments Functions in Polymake.jl accept the following types for their arguments: • simple data types (bools, machine integers, floats) • wrapped native types (Polymake.Integer, Polymake.Rational, Polymake.Vector, Polymake.Matrix, Polymake.Set etc.) • other objects returned by polymake: • Polymake.BigObject, • Polymake.PropertyValue (containers opaque to Julia) If an object passed to Polymake.jl function is of a different type the software will try its best to convert it to a known one. However, if the conversion doesn't work an ArgumentError will be thrown: ERROR: ArgumentError: Unrecognized argument type: SomeType. You need to convert to polymake compatible type first. You can tell Polymake.jl how to convert it by definig Base.convert(::Type{Polymake.PolymakeType}, x::SomeType) The returned value must be of one of the types as above. For example to use AbstractAlgebra.jl matrices as input to Polymake.jl one may define Base.convert(::Type{Polymake.PolymakeType}, M::Generic.MatSpaceElem) = Polymake.Matrix(M.entries) and the following should run smoothly. julia> using AbstractAlgebra, Polymake polymake version 4.0 Copyright (c) 1997-2020 Ewgenij Gawrilow, Michael Joswig (TU Berlin) https://polymake.org This is free software licensed under GPL; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. julia> mm = AbstractAlgebra.matrix(ZZ, [1 2 3; 4 5 6]) [1 2 3] [4 5 6] julia> polytope.Polytope(POINTS=mm) ERROR: ArgumentError: Unrecognized argument type: AbstractAlgebra.Generic.MatSpaceElem{Int64}. You need to convert to polymake compatible type first. [...] julia> Base.convert(::Type{Polymake.PolymakeType}, M::Generic.MatSpaceElem) = Polymake.Matrix(M.entries) julia> polytope.Polytope(POINTS=mm) type: Polytope<Rational> POINTS 1 2 3 1 5/4 3/2  ## Accessing the polyDB Polymake.jl allows the user to access the objects stored within the polyDB via the Mongoc.jl package; this functionality can be found in another sub-module, Polymake.Polydb, which requires no additional interaction to be loaded. It offers two different ways for querying, as well as some methods for information. For demonstration purposes, there also is a Jupyter notebook in the examples/ folder. ### General tools There are three types one needs to know when working with Polymake.Polydb: Polymake.Polydb.CollectionType  Collection{T} Type for referencing a specific collection. T<:Union{Polymake.BigObject, Mongoc.BSON} defines the template and/or element types returned by operations applied on objects of this type. source Polymake.Polydb.CursorType  Cursor{T} Type containing the results of a query. Can be iterated, but the iterator can not be reset. For this cause, one has to query again. T<:Union{Polymake.BigObject, Mongoc.BSON} defines the element types. source To receive the Database object referencing to the polyDB, there is the get_db() method: Polymake.Polydb.get_dbMethod  get_db() Connect to the polyDB and return Database instance. The uri of the server can be set in advance by writing its String representation into ENV["POLYDBTESTURI"]. (used to connect to the github services container for testing) Examples julia> db = Polymake.Polydb.get_db(); julia> typeof(db) Polymake.Polydb.Database source A specific Collection object can then be obtained with the brackets operator: Base.getindexMethod  getindex(db::Database, name::AbstractString) Return a Polymake.Polydb.Collection{Polymake.BigObject} instance from db with the given name. Sections and collections in the name are connected with the '.' sign. Examples julia> db = Polymake.Polydb.get_db(); julia> collection = getindex(db, "Polytopes.Lattice.SmoothReflexive") Polymake.Polydb.Collection{Polymake.BigObject}: Polytopes.Lattice.SmoothReflexive julia> collection = db["Matroids.Small"] Polymake.Polydb.Collection{Polymake.BigObject}: Matroids.Small source By default, the results are parsed to Polymake.BigObjects when accessed, but one may choose to change this behaviour by adjusting the typing template of Collection or Cursor using the following method: Polymake.Polydb.CollectionMethod  Collection{T}(c::Collection) Create another Collection object with a specific template parameter referencing the same collection as c. T can be chosen from Polymake.BigObject and Mongoc.BSON. Examples julia> db = Polymake.Polydb.get_db(); julia> collection = db["Polytopes.Lattice.SmoothReflexive"] Polymake.Polydb.Collection{Polymake.BigObject}: Polytopes.Lattice.SmoothReflexive julia> collection_bson = Polymake.Polydb.Collection{Mongoc.BSON}(collection) Polymake.Polydb.Collection{Mongoc.BSON}: Polytopes.Lattice.SmoothReflexive julia> collection_bo = Polymake.Polydb.Collection{Polymake.BigObject}(collection_bson) Polymake.Polydb.Collection{Polymake.BigObject}: Polytopes.Lattice.SmoothReflexive source ### Information Polymake.Polydb.infoFunction  info(db::Database, level::Base.Integer=1) Print a structured list of the sections and collections of the Polydb together with information about each of these (if existent). Detail of the output determined by value of level: • 1: short description, • 2: description, • 3: description, authors, maintainers, • 4: full info, • 5: full info and list of recommended search fields. source  info(c::Collection, level::Base.Integer=1) Print information about collection c (if existent). Detail of the output determined by value of level: • 1: short description, • 2: description, • 3: description, authors, maintainers, • 4: full info, • 5: full info and list of recommended search fields. source Polymake.Polydb.get_collection_namesFunction  get_collection_names(db::Database) Return a Vector{String} containing the names of all collections in the Polydb, excluding meta collections. Examples julia> db = Polymake.Polydb.get_db(); julia> Polymake.Polydb.get_collection_names(db) 16-element Vector{String}: "Polytopes.Combinatorial.FacesBirkhoffPolytope" "Polytopes.Combinatorial.SmallSpheresDim4" "Polytopes.Geometric.01Polytopes" "Polytopes.Lattice.SmoothReflexive" "Polytopes.Lattice.ExceptionalMaximalHollow" "Tropical.TOM" ⋮ "Polytopes.Lattice.Panoptigons" "Tropical.Cubics" "Tropical.SchlaefliFan" "Polytopes.Lattice.Reflexive" "Polytopes.Combinatorial.CombinatorialTypes" source Polymake.Polydb.get_fieldsFunction  get_fields(c::Collection) Return a Vector{String} containing the names of the fields of c. Examples julia> db = Polymake.Polydb.get_db(); julia> collection = db["Matroids.Small"] Polymake.Polydb.Collection{Polymake.BigObject}: Matroids.Small julia> Polymake.Polydb.get_fields(collection) 27-element Vector{String}: "DUAL" "N_BASES" "TUTTE_POLYNOMIAL" "SERIES_PARALLEL" "N_FLATS" "SPLIT_FLACETS" ⋮ "TERNARY" "REGULAR" "TRANSVERSAL" "IDENTICALLY_SELF_DUAL" "BETA_INVARIANT" source ### Querying There are two ways for querying within Polymake.jl. #### Methods Mongoc.findFunction find(collection::Collection, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) :: Cursor Executes a query on collection and returns an iterable Cursor. Example function find_contract_codes(collection, criteria::Dict=Dict()) :: Vector{String} result = Vector{String}() let bson_filter = Mongoc.BSON(criteria) bson_options = Mongoc.BSON("""{ "projection" : { "_id" : true }, "sort" : { "_id" : 1 } }""") for bson_document in Mongoc.find(collection, bson_filter, options=bson_options) push!(result, bson_document["_id"]) end end return result end Check the libmongoc documentation for more information. find(bucket::Bucket, bson_filter::BSON=BSON(); options::BSON=BSON()) :: Cursor Looks for files in GridFS bucket.  find(c::Collection{T}, d::Dict=Dict(); opts::Union{Nothing, Dict}) Search a collection c for documents matching the criteria given by d. Apply search options opts. Examples julia> db = Polymake.Polydb.get_db(); julia> collection = db["Polytopes.Lattice.SmoothReflexive"]; julia> query = Dict("DIM"=>3, "N_FACETS"=>5); julia> results = Polymake.Polydb.find(collection, query); julia> typeof(results) Polymake.Polydb.Cursor{Polymake.BigObject} source  find(c::Collection{T}, d::Pair...) Search a collection c for documents matching the criteria given by d. Examples julia> db = Polymake.Polydb.get_db(); julia> collection = db["Polytopes.Lattice.SmoothReflexive"]; julia> results = Polymake.Polydb.find(collection, "DIM"=>3, "N_FACETS"=>5); julia> typeof(results) Polymake.Polydb.Cursor{Polymake.BigObject} source #### Macros Polymake.Polydb.@selectMacro Polymake.Polydb.@select collectionName This macro can be used as part of a chain for easy (i.e. human readable) querying. Generate a method asking a container for the entry with key collectionName. See also: @filter, @map Examples julia> db = Polymake.Polydb.get_db(); julia> collection = db |> Polymake.Polydb.@select("Polytopes.Lattice.SmoothReflexive") Polymake.Polydb.Collection{Polymake.BigObject}: Polytopes.Lattice.SmoothReflexive source Polymake.Polydb.@filterMacro Polymake.Polydb.@filter conditions... This macro can be used as part of a chain for easy (i.e. human readable) querying. Convert conditions into the corresponding Dict and generate a method expanding its input by this Dict. Multiple conditions can be passed in the same line and/or in different lines. See also: @select, @map Examples julia> db = Polymake.Polydb.get_db(); julia> query_tuple = db |> Polymake.Polydb.@select("Polytopes.Lattice.SmoothReflexive") |> Polymake.Polydb.@filter("DIM" <= 3) |> Polymake.Polydb.@filter("N_VERTICES" == 8) (Polymake.Polydb.Collection{Polymake.BigObject} COLLECTION: Polytopes.Lattice.SmoothReflexive Smooth reflexive lattice polytopes in dimensions up to 9, up to lattice equivalence. The lists were computed with the algorithm of Mikkel Oebro (see [[http://arxiv.org/abs/0704.0049|arxiv: 0704.0049]]) and are taken from the [[http://polymake.org/polytopes/paffenholz/www/fano.html|website of Andreas Paffenholz]]. They also contain splitting data according to [[https://arxiv.org/abs/1711.02936| arxiv: 1711.02936]]. Authored by Andreas Paffenholz, paffenholz@opt.tu-darmstadt.de, TU Darmstadt Benjamin Lorenz, paffenholz@opt.tu-darmstadt.de, TU Berlin Mikkel Oebro Fields: AFFINE_HULL, CONE_DIM, DIM, EHRHART_POLYNOMIAL, F_VECTOR, FACET_SIZES, FACET_WIDTHS, FACETS, H_STAR_VECTOR, LATTICE_DEGREE, LATTICE_VOLUME, LINEALITY_SPACE, N_BOUNDARY_LATTICE_POINTS, N_EDGES, N_FACETS, N_INTERIOR_LATTICE_POINTS, N_LATTICE_POINTS, N_RIDGES, N_VERTICES, REFLEXIVE, SMOOTH, SELF_DUAL, SIMPLE, TERMINAL, VERTEX_SIZES, VERTICES, VERTICES_IN_FACETS, VERY_AMPLE, ALTSHULER_DET, BALANCED, CENTROID, DIAMETER, NORMAL, N_HILBERT_BASIS, IS_PRISM, IS_PRODUCT, IS_SKEW_PRISM, IS_SIMPLEX_SUM, PRISM_BASE, PRODUCT_FACTORS, SIMPLEX_SUM_BASES, SKEW_PRISM_BASES, Dict{String,Any}("DIM" => Dict{String,Any}("$lte" => 3),"N_VERTICES" => Dict{String,Any}("$eq" => 8))) julia> query_tuple = db |> Polymake.Polydb.@select("Polytopes.Lattice.SmoothReflexive") |> Polymake.Polydb.@filter("DIM" <= 3, "N_VERTICES" == 8) (Polymake.Polydb.Collection{Polymake.BigObject} COLLECTION: Polytopes.Lattice.SmoothReflexive Smooth reflexive lattice polytopes in dimensions up to 9, up to lattice equivalence. The lists were computed with the algorithm of Mikkel Oebro (see [[http://arxiv.org/abs/0704.0049|arxiv: 0704.0049]]) and are taken from the [[http://polymake.org/polytopes/paffenholz/www/fano.html|website of Andreas Paffenholz]]. They also contain splitting data according to [[https://arxiv.org/abs/1711.02936| arxiv: 1711.02936]]. Authored by Andreas Paffenholz, paffenholz@opt.tu-darmstadt.de, TU Darmstadt Benjamin Lorenz, paffenholz@opt.tu-darmstadt.de, TU Berlin Mikkel Oebro Fields: AFFINE_HULL, CONE_DIM, DIM, EHRHART_POLYNOMIAL, F_VECTOR, FACET_SIZES, FACET_WIDTHS, FACETS, H_STAR_VECTOR, LATTICE_DEGREE, LATTICE_VOLUME, LINEALITY_SPACE, N_BOUNDARY_LATTICE_POINTS, N_EDGES, N_FACETS, N_INTERIOR_LATTICE_POINTS, N_LATTICE_POINTS, N_RIDGES, N_VERTICES, REFLEXIVE, SMOOTH, SELF_DUAL, SIMPLE, TERMINAL, VERTEX_SIZES, VERTICES, VERTICES_IN_FACETS, VERY_AMPLE, ALTSHULER_DET, BALANCED, CENTROID, DIAMETER, NORMAL, N_HILBERT_BASIS, IS_PRISM, IS_PRODUCT, IS_SKEW_PRISM, IS_SIMPLEX_SUM, PRISM_BASE, PRODUCT_FACTORS, SIMPLEX_SUM_BASES, SKEW_PRISM_BASES, Dict{String,Any}("DIM" => Dict{String,Any}("$lte" => 3),"N_VERTICES" => Dict{String,Any}("\$eq" => 8)))
source
Polymake.Polydb.@mapMacro

Polymake.Polydb.@map [optFields...]

This macro can be used as part of a chain for easy (i.e. human readable) querying. Generate a method running a query given a Tuple{Collection, Dict}. If optFields are given (as Strings), the results only contain the stated fields and the objects metadata.

See also: @select, @filter

Examples

julia> db = Polymake.Polydb.get_db();

julia> results = db |>
Polymake.Polydb.@select("Polytopes.Lattice.SmoothReflexive") |>
Polymake.Polydb.@filter("DIM" == 3, "N_VERTICES" == 8) |>
Polymake.Polydb.@map() |>
collect
7-element Vector{Polymake.BigObject}:
Polymake.BigObjectAllocated(Ptr{Nothing} @0x00000000028c5320)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x000000000abd7b40)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x000000000a6d7bf0)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x000000000a431470)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x000000000bcaf290)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x00000000098fb670)
Polymake.BigObjectAllocated(Ptr{Nothing} @0x000000000a1ba460)
source