tutorial:perl_continued

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revisionBoth sides next revision
tutorial:perl_continued [2011/05/09 14:54] herrtutorial:perl_continued [2017/07/11 09:04] oroehrig
Line 5: Line 5:
 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);
Line 75: Line 131:
 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){
Line 88: Line 144:
 } }
 $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";
Line 97: Line 153:
 </code> </code>
  
-===Scripts=== +===Scripts===
 [[scripting:start|Scripting]] [[scripting:start|Scripting]]