Examples

In this section we just highlight various possible uses of Polymake.jl. Please refer to Polymake syntax translation for more thorough treatment.

polymake big objects (like Polytope, Cone, etc) constructors live within modules named after polymake applications, e.g.

# Call the Polytope constructor
julia> p = polytope.Polytope(POINTS=[1 -1 -1; 1 1 -1; 1 -1 1; 1 1 1; 1 0 0])
type: Polytope<Rational>

POINTS
1 -1 -1
1 1 -1
1 -1 1
1 1 1
1 0 0

Parameters to constructors can be passed as keyword arguments only. All the keys must be compatible with polymake input attribute names.

Properties of such objects can be accessed by the . syntax:

julia> p.INTERIOR_LATTICE_POINTS
pm::Matrix<pm::Integer>
1 0 0

Example script

The following script is modelled on the one from the Using Perl within polymake tutorial:

using Polymake

str = read("points.demo", String)
# eval/parse is a hack for Rational input, don't do this at home!
matrix_str = "["*replace(str, "/"=>"//")*"]"
matrix = eval(Meta.parse(matrix_str))
@show matrix

p = polytope.Polytope(POINTS=matrix)

@show p.FACETS # polymake matrix of polymake rationals
@show polytope.dim(p) # Julia Int64
# note that even in Polymake property DIM is "fake" -- it's actually a function
@show p.VERTEX_SIZES # polymake array of ints
@show p.VERTICES

for (i, vsize) in enumerate(p.VERTEX_SIZES)
  if vsize == polytope.dim(p)
    println("$i : $(p.VERTICES[i,:])")
    # $i will be shifted by one from the polymake version
  end
end

simple_verts = [i for (i, vsize) in enumerate(p.VERTEX_SIZES) if vsize == polytope.dim(p)] # Julia vector of Int64s

special_points = p.VERTICES[simple_verts, :] # polymake Matrix of rationals
@show special_points;

The script included (i.e. in running REPL execute include("example_script.jl");) produces the following output:

matrix = Rational{Int64}[1//1 0//1 0//1 0//1; 1//1 1//16 1//4 1//16; 1//1 3//8 1//4 1//32; 1//1 1//4 3//8 1//32; 1//1 1//16 1//16 1//4; 1//1 1//32 3//8 1//4; 1//1 1//4 1//16 1//16; 1//1 1//32 1//4 3//8; 1//1 3//8 1//32 1//4; 1//1 1//4 1//32 3//8]
p.FACETS = pm::Matrix<pm::Rational>
0 -1 20/7 8/7
0 -1 20 -1
0 20/7 -1 8/7
0 20/7 8/7 -1
0 20 -1 -1
1 16/3 16/3 -20/3
0 8/7 20/7 -1
0 8/7 -1 20/7
1 16/3 -20/3 16/3
0 -1 -1 20
0 -1 8/7 20/7
1 -20/3 16/3 16/3
1 -32/21 -32/21 -32/21

(Polymake.Polytope).dim(p) = 3
p.VERTEX_SIZES = pm::Array<int>
9 3 4 4 3 4 3 4 4 4
p.VERTICES = pm::Matrix<pm::Rational>
1 0 0 0
1 1/16 1/4 1/16
1 3/8 1/4 1/32
1 1/4 3/8 1/32
1 1/16 1/16 1/4
1 1/32 3/8 1/4
1 1/4 1/16 1/16
1 1/32 1/4 3/8
1 3/8 1/32 1/4
1 1/4 1/32 3/8

2 : pm::Vector<pm::Rational>
1 1/16 1/4 1/16
5 : pm::Vector<pm::Rational>
1 1/16 1/16 1/4
7 : pm::Vector<pm::Rational>
1 1/4 1/16 1/16
special_points = pm::Matrix<pm::Rational>
1 1/16 1/4 1/16
1 1/16 1/16 1/4
1 1/4 1/16 1/16

As can be seen we show consecutive steps of computations: the input matrix, FACETS, then we ask for VERTEX_SIZES, which triggers the convex hull computation. Then we show vertices and print those corresponding to simple vertices. Finally we collect them in special_points.

Observe that a polymake matrix (Polymake.Matrix) implements julia abstract array interface: p.VERTICES[2,:] returns a 1-dimensional slice (i.e. Polymake.Vector), while passing a set of indices (p.VERTICES[special_points, :]) returns a 2-dimensional one.

Notes:

The same minor (up to permutation of rows) could be obtained by using sets: either julia or polymake ones. However since by default one can not index arrays with sets, we need to collect them first:

simple_verts = Set(i for (i, vsize) in enumerate(p.VERTEX_SIZES) if vsize == polytope.dim(p)) # Julia set of Int64s

simple_verts = Polymake.Set(i for (i, vsize) in enumerate(p.VERTEX_SIZES) if vsize == polytope.dim(p)) # polymake set of longs

special_points = p.VERTICES[collect(simple_verts), :]

Polymake syntax translation

The following tables explain by example how to quickly translate polymake syntax to Polymake.jl.

Variables

Polymake Julia
$p (reference to 'scalar' variable) p (reference to any variable)
print $p; print(p) or println(p) or @show p, or just p in REPL
$i=5; $j=6; i,j = 5,6 or i=5; j=6
(; is needed for separation, can be used to suppress return value in REPL)
$s = $i + $j; print $s; s = i + j

Arrays

Polymake Julia
Linear containers with random access Linear containers with random access + all the algebra attached
@A = ("a", "b", "c"); A = ["a", "b", "c"]
$first = $A[0];
(first is equal to a)
first = A[1]
(note the 1-based indexing!)
@A2 = (3,1,4,2); A2 = [3,1,4,2]
print sort(@A2);
(a copy of A2 is sorted)
println(sort(A2))
(to sort in place use sort!(A2))
$arr = new Array([3,2,5]);
(a C++ object)
arr = [3,2,5]
(the Int type is inferred)
$arr->[0] = 100;
(assignment)
arr[1] = 100
(assignment; returns 100)

Dictionaries/Hash Tables

Polymake Julia
%h = (); h = Dict()
it is MUCH better to provide types e.g.
h = Dict{String, Int}()
$h{"zero"}=0; $h{"four"}=4; h["zero"] = 0; h["four"] = 4
(call returns the value)
print keys %h; @show keys(h) (NOTE: order is not specified)
print join(", ",keys %hash); join(keys(h), ", ")
(returns String)
%hash=("one",1,"two",2); Dict([("one",1), ("two",2)])
(will infer types)
%hash=("one"=>1,"two"=>2); Dict("one"=>1,"two"=>2)

Sets

Polymake Julia
Balanced binary search trees Hash table with no content
$set=new Set(3,2,5,3); set = Set{Int}([3,2,5,3])
print $set->size; length(set)
@array_from_set=@$set collect(set)
(NOTE: this creates a Vector, but order is NOT specified)

Matrices

Polymake Julia
new Matrix
Container with algebraic operations
Matrix{T} = Array{T, 2}
**Linear** container with available indexing by 2-ples; all algebra attached
$mat=new Matrix([[2,1,4,0,0],[3,1,5,2,1],[1,0,4,0,6]]);
$row1=new Vector([2,1,4,0,0]);
$row2=new Vector([3,1,5,2,1]);
$row3=new Vector([1,0,4,0,6]);
@matrix_rows=($row1,$row2,$row3); (Perl object)
$matrix_from_array=new Matrix(\@matrix_rows); (C++ object)
mat = Rational{Int}[2 1 4 0 0; 3 1 5 2 1; 1 0 4 0 6];
row1 = Rational{Int}[2, 1, 4, 0, 0];
row2 = Rational{Int}[3, 1, 5, 2, 1];
row3 = Rational{Int}[1, 0, 4, 0, 6];
matrix_rows = hcat(row1', row2', row3')
(Julia stores matrices in column major format, so ' i.e. transposition is needed)
$mat->row(1)->[1]=7; $mat->elem(1,2)=8; mat[2,2] = 7; mat[2,3] = 8
$unit_mat=4*unit_matrix(3); unit_mat = Diagonal([4//1 for i in 1:3]) or UniformScaling(4//1)
depending on application; both require using LinearAlgebra
$dense=new Matrix($unit_mat);
$m_rat=new Matrix(3/5*unit_matrix(5));
$m2=$mat/$m_rat;
$m_int=new Matrix(unit_matrix(5));
$m3=$m_rat/$m_int;
(results in an error due to incompatible types)
Array(unit_mat)
m_rat = Diagonal([3//5 for i in 1:5])
m2 = mat/m_rat
m_int = Diagonal([1 for i in 1:5])
m_rat/m_int
(succeeds due to promote happening in /)
convert_to($m_int)
$z_vec=zero_vector($m_int->rows)
$extended_matrix=($z_vec\|$m_int);
(adds z_vec as the first column, result is dense)
convert(Diagonal{Rational{Int}}, m_int)
z_vec = zeros(Int, size(m_int, 1))
extended_matrix = hcat(z_vec, m_int)
(result is sparse)
$set=new Set(3,2,5);
$template_Ex=new Array>((new Set(5,2,6)),$set)
set = Set([3,2,5]);
template_Ex = [Set([5,2,6]), set]

Big objects & properties:

Polymake Julia
$p=new Polytope(POINTS=>cube(4)->VERTICES); p = polytope.Polytope(POINTS=polytope.cube(4).VERTICES)
$lp=new LinearProgram(LINEAR_OBJECTIVE=>[0,1,1,1,1]); lp = polytope.LinearProgram(LINEAR_OBJECTIVE=[0,1,1,1,1])
$p->LP=$lp;
$p->LP->MAXIMAL_VALUE;
p.LP = lp
p.LP.MAXIMAL_VALUE
$i = ($p->N_FACETS * $p->N_FACETS) * 15; i = (p.N_FACETS * p.N_FACETS) * 15
$print p->DIM; polytope.dim(p)
DIM is actually a faux property, which hides a function beneath
application "topaz";
$p = new Polytope(POINTS=>[[1,0,0], [1,1,0], [1,1,1]]);
p = @pm tropical.Polytope{Max, QuadraticExtension}(POINTS=[1 0 0; 1 1 0; 1 1 1])
more information on the @pm macro can be found

here: @pm