Both sides previous revision Previous revision Next revision | Previous revisionLast revisionBoth sides next revision |
tutorial:perl_continued [2011/05/09 14:54] – herr | tutorial:perl_continued [2017/07/11 09:04] – oroehrig |
---|
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: | 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: |
<code> | <code> |
polytope > i=5; | polytope > i=5; |
polymake: ERROR: Unquoted string "i" may clash with future reserved word. | polymake: ERROR: Unquoted string "i" may clash with future reserved word. |
</code>\\ | </code>\\ |
Here are some simple commands illustrating how to use the different data structures: | Here are some simple commands illustrating how to use the different data structures: |
* **Scalars** <code> | ==Scalars== |
$i=5; | <code> |
$j=6; | > $i=5; |
$sum=$i+$j; print $sum; | > $j=6; |
| > $sum=$i+$j; print $sum; |
</code> | </code> |
* **Arrays** <code> | ==Arrays== |
@array=("a","b","c"); print scalar(@array); | <code> |
push(@array,"d"); print "@array"; | > @array=("a","b","c"); print scalar(@array); |
$first_entry=$array[0]; print $first_entry; | > push(@array,"d"); print "@array"; |
print join("\n",@array); | > $first_entry=$array[0]; print $first_entry; |
@array2=(3,1,4,2); | > print join("\n",@array); |
print sort(@array2); | > @array2=(3,1,4,2); |
| > print sort(@array2); |
| </code> |
| ==Hashes== |
| <code> |
| > %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); |
</code> | </code> |
* **Hashes** <code> | |
%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); | |
</code>\\ | |
| |
==="Small objects": Data structures inherited from C++=== | ==="Small objects": Data structures inherited from C++=== |
| In addition to the three standard data structures, the enriched version of ''Perl'' used in ''polymake'' also provides special data structures that are inherited from the ''C++''-side of ''polymake''. |
| A complete list of these so-called "small objects" can be found in the [[:release_docs:latest:common.html|online documentation]] under the heading "Property types". To define a ''Perl''-variable of such a type, you initialize the variable via |
<code> | <code> |
$arr1=new Array<String>(\@array); print $arr1; | > $my_var = new [SMALL_OBJECT]([INITIALIZATION]); |
$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; | |
@arr4=@{$arr4}; | |
print $arr2; | |
$set=new Set<Int>(3,2,5); print $set; | |
$mat=new Matrix<Rational>([[2,1,4,0,0],[3,1,5,2,1],[1,0,4,0,6]]); print $mat; | |
$mat->row(1)->[1]=7; print $mat; | |
$mat->(1,2)=8; print $mat; | |
print 4*unit_matrix<Rational>(3); | |
$m_rat=new Matrix<Rational>(3/5*unit_matrix<Rational>(5)); print $m_rat; | |
$m2=$mat/$m_rat; print $m2; | |
$m_int=new Matrix<Int>(unit_matrix<Rational>(5)); print $m_int; | |
$m3=$m_rat/$m_int; | |
$m3=$m_rat/(convert_to<Rational>($m_int)); print $m3; | |
$z_vec=zero_vector<Int>($m_int->rows); | |
$extended_matrix=($z_vec|$m_int); print $extended_matrix; | |
$template_Ex=new Array<Set<Int>>((new Set<Int>(5,2,6)),$set); print | |
$template_Ex; | |
</code> | </code> |
| Note that the ''Perl''-type of the variable //my_var// is ''Scalar'', as the variable is internally treated as a reference to a ''C++''-object. You can find out the (''C++''-)type of your variable via |
| <code> |
| > print ref($my_var); |
| </code> |
| 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: |
| <code> |
| > @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; |
| </code> It is also possible to convert the ''C++''-object ''Array'' into a ''Perl''-array by writing <code> |
| > @arr4=@{$arr4}; print $arr2; |
| </code> or simply<code> |
| > @arr4=@$arr4; |
| </code> |
| ==Sets== |
| On ''C++''-side sets are stored in a balanced binary search (AVL) tree. For more information see the [[https://polymake.org/release_docs/master/PTL/classpm_1_1Set.html|PTL-documentation]]. In many cases, the small objects can be converted into ''Perl''-types in the expected way: <code> |
| > $set=new Set<Int>(3,2,5); print $set; |
| > print $set->size; |
| > @array_from_set=@$set; |
| </code> |
| ==Matrices== |
| Here is a simple way to initialize a matrix:<code> |
| > $mat=new Matrix<Rational>([[2,1,4,0,0],[3,1,5,2,1],[1,0,4,0,6]]); |
| > print $mat; |
| </code> You could also define it by passing a reference to an (''Perl''-)array of ''Vectors''. The single entries are interpreted as different rows: <code> |
| > $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); |
| </code> 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''!):<code> |
| > $mat->row(1)->[1]=7; print $mat->row(1)->[1]; |
| > print $mat; |
| > $mat->(1,2)=8; print $mat; |
| </code> A unit matrix of a certain dimension can be defined via the user-function ''unit_matrix<COORDINATE_TYPE>(.)'': <code> |
| > $unit_mat=4*unit_matrix<Rational>(3); |
| > print $unit_mat; |
| </code> The reason for the "strange output" is the implementation as //sparse matrix//: <code> |
| > print ref($unit_mat); |
| </code>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:<code> |
| > $dense=new Matrix<Rational>($unit_mat);print $dense; |
| </code> or just<code> |
| > $dense2=dense($unit_mat);print $dense2; |
| </code> You can also work with matrices that have different types of coordinates like ''Rational'', ''Float'', or ''Int'': <code> |
| > $m_rat=new Matrix<Rational>(3/5*unit_matrix<Rational>(5)); print $m_rat; |
| > $m2=$mat/$m_rat; print $m2; |
| > $m_int=new Matrix<Int>(unit_matrix<Rational>(5)); print $m_int; |
| > $m3=$m_rat/$m_int; |
| </code> The error message <code> |
| polymake: ERROR: undefined operator Matrix<Rational> / Matrix<Int> at input line 1. |
| </code>indicates that you need to convert the integer matrix to a rational matrix first:<code> |
| > $m3=$m_rat/(convert_to<Rational>($m_int)); print $m3; |
| </code> By "/" you can add rows to a matrix, whereas "|" adds columns. By the way, this also works for ''Vector''.<code> |
| > $z_vec=zero_vector<Int>($m_int->rows); |
| > $extended_matrix=($z_vec|$m_int); print $extended_matrix; |
| </code> |
| It is also possible to nest template parameters in any way you like, e.g. |
| <code> |
| > $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); |
| </code> |
| 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=== | ==="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. 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. |
<code> | <code> |
$p=new Polytope<Rational>(POINTS=>cube(4)->VERTICES); | > $p=new Polytope<Rational>(POINTS=>cube(4)->VERTICES); |
$lp=new LinearProgram<Rational>(LINEAR_OBJECTIVE=>[0,1,1,1,1]); | > $lp=new LinearProgram<Rational>(LINEAR_OBJECTIVE=>[0,1,1,1,1]); |
$p->LP=$lp; | > # access the property named ''LP'': |
print $p->LP->MAXIMAL_VALUE; | > $p->LP=$lp; |
| > # properties can have properties themselves. |
| > print $p->LP->MAXIMAL_VALUE; |
</code> | </code> |
===Working with Perl in polymake=== | ===Working with Perl in polymake=== |
{{:points.demo|}} | {{:points.demo|}} |
<code> | <code> |
open(INPUT, "< /home/katrin/polymake/demo/Workshop2011/points.demo"); | open(INPUT, "< $HOME/polymake/demo/Workshop2011/points.demo"); |
$matrix=new Matrix<Rational>(<INPUT>); | $matrix=new Matrix<Rational>(<INPUT>); |
close(INPUT); | close(INPUT); |
print $p->DIM; | print $p->DIM; |
print $p->VERTEX_SIZES; | print $p->VERTEX_SIZES; |
;### choose "simple" vertices | ### choose "simple" vertices |
for(my $i=0;$i<scalar(@{$p->VERTEX_SIZES});$i++){ | for(my $i=0;$i<scalar(@{$p->VERTEX_SIZES});$i++){ |
if($p->VERTEX_SIZES->[$i]==$p->DIM){ | if($p->VERTEX_SIZES->[$i]==$p->DIM){ |
} | } |
$special_points=$p->VERTICES->minor($s,All); print $special_points; | $special_points=$p->VERTICES->minor($s,All); print $special_points; |
; | |
foreach(@{$s}){ | foreach(@{$s}){ |
print $p->VERTICES->row($_)."\n"; | print $p->VERTICES->row($_)."\n"; |
</code> | </code> |
| |
===Scripts=== | ===Scripts=== |
[[scripting:start|Scripting]] | [[scripting:start|Scripting]] |