user_guide:tutorials:perl_intro

This tutorial is probably also available as a Jupyter notebook in the demo folder in the polymake source and on github.

Different versions of this tutorial: latest release, release 4.11, release 4.10, release 4.9, release 4.8, release 4.7, release 4.6, release 4.5, release 4.4, release 4.3, release 4.2, release 4.1, release 4.0, release 3.6, nightly master

Using Perl within polymake

The language that the interactive version of polymake speaks is a dialect of Perl that we refer to as polymake/Perl. See www.perl.org for comprehensive Perl information. Note also that the ordinary Perl manual pages are particularly useful, especially the perlintro man page which is also available on perldoc. This short section here cannot be a replacement for a thorough introduction to this language, but we want to focus on a few key points that are relevant to polymake.

The Perl programming language originally provides three different data structures, scalars($), arrays(@), and hashes(%). The user always has to specify the type of a variable using the appropriate symbol $, @, or %. If you forget to do so, you will receive the following error message:

> i=5;
polymake:  ERROR: Unquoted string "i" may clash with future reserved word.

Here are some simple commands illustrating how to use the different data structures:

Scalars
> $i=5;
> $j=6;
> $sum=$i+$j; print $sum;
11
Arrays
> @array=("a","b","c"); print scalar(@array);
> push(@array,"d"); print "@array"; 
> $first_entry=$array[0]; print $first_entry;
> print join("\n",@array);
> @array2=(3,1,4,2);
> print sort(@array2);
3a b c daa
b
c
d1234
Hashes
> %hash=();
> $hash{"zero"}=0;
> $hash{"four"}=4;
> print keys %hash;
> print join(", ",keys %hash);
> print join(", ",values %hash);
> %hash=("one",1,"two",2);
> %hash=("one"=>1,"two"=>2);
fourzerofour, zero4, 0

In addition to the three standard data structures, the enriched version of Perl used in polymake also provides special data structures for dealing with more complicated concepts. For an introduction to the polymake object model see here.

polymake's object hierarchy is completely reflected on the Perl side. Let us create a small polytope as an example object.

> $p = new Polytope(POINTS=>[[1,0,1],[1,0,-1],[1,1,0],[1,-1,0]]);

Note that the Perl-type of the variable $p is Scalar, as the variable is internally treated as a reference to a C++-object. The true nature of the object becomes visible if it is printed:

> print $p;
Polymake::polytope::Polytope__Rational=ARRAY(0x55c8aa54c778)

In this case it is a polymake object from the application polytope, and it happens to be of type Polytope<Rational>. Technically, $p is a reference to an array (but it should be never treated as an array unless you are deliberately trying to crash polymake). If you want less technical information on the type of your object, use this:

> print $p->type->full_name;
Polytope<Rational>

"Small objects": Data structures inherited from C++

You can use objects that are inherited from the C++-side of polymake in the interactive shell. A complete list of so-called “small objects” can be found in the online documentation. Here is a selection of three different structures that facilitate everyday work with polymake:

Arrays

The small object Array can be initialized in different ways and with different template parameters:

> @array=("a","b","c");
> $arr1=new Array<String>(\@array); print $arr1;
> $arr2=new Array<Int>([3,2,5]); print $arr2;
> $arr3=new Array<Int>(0,1,2,3); print $arr3;
> $arr4=new Array<Int>(0..4); print $arr4;
> $arr5=new Array<Int>($arr4); print $arr5;
a b c3 2 50 1 2 30 1 2 3 40 1 2 3 4

You have random access:

> $arr5->[0] = 100;
> print $arr5;
100 1 2 3 4

It is also possible to convert the C++-object Array into a Perl-array by writing

> @arr4=@{$arr4}; print $arr2;
3 2 5

or simply

> @arr4=@$arr4;
Sets

On C++-side sets are stored in a balanced binary search (AVL) tree. For more information see the PTL-documentation. In many cases, the small objects can be converted into Perl-types in the expected way:

> $set=new Set<Int>(3,2,5); print $set;
> print $set->size;
> @array_from_set=@$set;
{2 3 5}3
Matrices

Here is a simple way to initialize a matrix:

> $mat=new Matrix<Rational>([[2,1,4,0,0],[3,1,5,2,1],[1,0,4,0,6]]);
> print $mat;
2 1 4 0 0
3 1 5 2 1
1 0 4 0 6

You could also define it by passing a reference to an (Perl-)array of Vectors. The single entries are interpreted as different rows:

> $row1=new Vector<Rational>([2,1,4,0,0]);
> $row2=new Vector<Rational>([3,1,5,2,1]);
> $row3=new Vector<Rational>([1,0,4,0,6]);
> @matrix_rows=($row1,$row2,$row3);
> $matrix_from_array=new Matrix<Rational>(\@matrix_rows);

You can change a single entry of a matrix in the following way (if it is not already assigned to an immutable property like VERTICES!):

> $mat->row(1)->[1]=7;
> print $mat->row(1)->[1], "\n";
> print $mat, "\n";
> $mat->elem(1,2)=8;
> print $mat;
7
2 1 4 0 0
3 7 5 2 1
1 0 4 0 6
 
2 1 4 0 0
3 7 8 2 1
1 0 4 0 6

A unit matrix of a certain dimension can be defined via the user-function unit_matrix<COORDINATE_TYPE>(.):

> $unit_mat=4*unit_matrix<Rational>(3);
> print $unit_mat;
(3) (0 4)
(3) (1 4)
(3) (2 4)

The reason for the “strange output” is the implementation as sparse matrix:

> print ref($unit_mat);
Polymake::common::SparseMatrix_A_Rational_I_NonSymmetric_Z

However, some functions cannot deal with this special type of matrix. In this case it is necessary to transform the sparse matrix into a dense matrix first via:

> $dense=new Matrix<Rational>($unit_mat);print $dense;
4 0 0
0 4 0
0 0 4

or just

> $dense2=dense($unit_mat);print $dense2;
4 0 0
0 4 0
0 0 4

You can also work with matrices that have different types of coordinates like Rational, Float, or Int:

> $m_rat=new Matrix<Rational>(3/5*unit_matrix<Rational>(5)); print $m_rat, "\n"; 
> $m2=$mat/$m_rat; print $m2, "\n";
> $m_int=new Matrix<Int>(unit_matrix<Rational>(5)); print $m_int, "\n";
3/5 0 0 0 0
0 3/5 0 0 0
0 0 3/5 0 0
0 0 0 3/5 0
0 0 0 0 3/5
 
2 1 4 0 0
3 7 8 2 1
1 0 4 0 6
3/5 0 0 0 0
0 3/5 0 0 0
0 0 3/5 0 0
0 0 0 3/5 0
0 0 0 0 3/5
 
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

Sometimes there is incompatible types:

> $m3=$m_rat/$m_int;
C++/perl Interface module compilation failed; most likely due to a type mismatch.
Set the variable $Polymake::User::Verbose::cpp to a positive value and repeat for more details.

The error message indicates that you need to convert the integer matrix to a rational matrix first:

> $m3=$m_rat/(convert_to<Rational>($m_int)); print $m3;
3/5 0 0 0 0
0 3/5 0 0 0
0 0 3/5 0 0
0 0 0 3/5 0
0 0 0 0 3/5
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

By “/” you can add rows to a matrix, whereas “|” adds columns. By the way, this also works for Vector.

> $z_vec=zero_vector<Int>($m_int->rows);
> $extended_matrix=($z_vec|$m_int); print $extended_matrix;
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1

It is also possible to nest template parameters in any way you like, e.g.

> $set=new Set<Int>(3,2,5);
> $template_Ex=new Array<Set<Int>>((new Set<Int>(5,2,6)),$set); print $template_Ex; print ref($template_Ex);
{2 5 6}
{2 3 5}
Polymake::common::Array__Set__Int

However, if you use a template combination, you have never used before, it may take some time until you see the result. This is due to the fact that polymake compiles your new combination on the fly. But this is only a one-time effect, and next time you use this combination it will work without delay.

"Big Objects": Objects with properties

A big object is an instance of a data type which represents a mathematical concept with clear semantics. They may have template parameters.

> $p=new Polytope<Rational>(POINTS=>cube(4)->VERTICES);
> $lp=new LinearProgram<Rational>(LINEAR_OBJECTIVE=>[0,1,1,1,1]);

Big objects have properties which come with a type, which is either built-in or a small object type or a big object type, and which can be accessed using the -``> operator.

> # access the property named `LP`:
> $p->LP=$lp;
> # properties can have properties themselves.
> print $p->LP->MAXIMAL_VALUE;
4

Scalar properties can be used in arithmetic expressions right away.

> $i = ($p->N_FACETS * $p->N_FACETS) * 15;
> print $i;
960

Check out the tutorial on properties to learn more about the way properties are used and computed.

…to demonstrate the usage of polymake/Perl. You can download the matrix file here.

> ### load matrix from file
> open(INPUT, "< demo/Workshop2011/points.demo");
> $matrix=new Matrix<Rational>(<INPUT>);
> close(INPUT);
> print $matrix;
> 
> 
> ### create a polytope from the matrix
> $p=new Polytope<Rational>(POINTS=>$matrix);
> print $p->FACETS;
> print $p->DIM;
> print $p->VERTEX_SIZES;
> 
> 
> ### print "simple" vertices
> for(my $i=0;$i<scalar(@{$p->VERTEX_SIZES});$i++){
>     if($p->VERTEX_SIZES->[$i]==$p->DIM){
>     print $i.": ".$p->VERTICES->row($i)."\n";
>     }
> }
> 
> 
> ### put their indices in a set
> $s=new Set<Int>();
> for(my $i=0;$i<scalar(@{$p->VERTEX_SIZES});$i++){
>     if($p->VERTEX_SIZES->[$i]==$p->DIM){
>     $s+=$i;
>     }
> }
> 
> 
> ### iterate the set in two different ways
> foreach(@{$s}){
>     print $p->VERTICES->row($_)."\n";
> }
> foreach my $index(@{$s}){
>     print $p->VERTICES->row($index)."\n";
> }
> 
> 
> ### create a minor of the vertices matrix that only contains the simple ones
> $special_points=$p->VERTICES->minor($s,All); print $special_points;
-1

Comprehensive information on how to use scripts within polymake can be found here.

  • user_guide/tutorials/perl_intro.txt
  • Last modified: 2019/02/11 16:21
  • by oroehrig