1#  Copyright (c) 1997-2021
2#  Ewgenij Gawrilow, Michael Joswig, and the polymake team
3#  Technische Universität Berlin, Germany
4#  https://polymake.org
5#
6#  This program is free software; you can redistribute it and/or modify it
7#  under the terms of the GNU General Public License as published by the
8#  Free Software Foundation; either version 2, or (at your option) any
9#  later version: http://www.gnu.org/licenses/gpl.txt.
10#
11#  This program is distributed in the hope that it will be useful,
12#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#  GNU General Public License for more details.
15#-------------------------------------------------------------------------------
16
17# @topic category functions/Formatting
18# Functions for pretty printing, labels or [[latex|latex output]] of polymake types.
19
20# @category Formatting
21# Prepares a matrix for printing, prepends each row with a label and a colon.
22# @param Matrix data  to be printed
23# @param Array<String>  row_labels labels for the rows
24# @param Array<String> elem_labels  optional labels for elements;
25#  if //data// is an [[IncidenceMatrix]], [[Array<Set>]], or similar, each element will be replaced by its label.
26# @return Array<String> each string ending with end-of-line
27# @example
28# > print rows_labeled(polytope::cube(2)->VERTICES,['a','b','c','d']);
29# | a:1 -1 -1
30# | b:1 1 -1
31# | c:1 -1 1
32# | d:1 1 1
33
34user_function rows_labeled($;$$) {
35   my ($data, $row_labels, $elem_labels)=@_;
36   if (defined $row_labels) {
37      is_like_array($row_labels) or croak( "row_labels must be an array" );
38   }
39   if (defined $elem_labels) {
40      is_like_array($elem_labels) or croak( "elem_labels must be an array" );
41   }
42   my $i=-1;
43   map {
44      ++$i;
45      (defined($row_labels) ? $row_labels->[$i] : $i) . ":" . join(" ", defined($elem_labels) ? @$elem_labels[@$_] : @$_) . "\n"
46   } @$data;
47}
48
49# @category Formatting
50# Like above, but specialized for Graphs (defined for convenience: a PTL Graph is not a container)
51# @param GraphAdjacency graph to be printed
52# @param Array<String> elem_labels labels for the elements
53# @return Array<String> each string ending with end-of-line
54# @example
55# > print rows_labeled(graph::cycle_graph(4)->ADJACENCY, ['a','b','c','d']);
56# | a:b d
57# | b:a c
58# | c:b d
59# | d:a c
60
61user_function rows_labeled(GraphAdjacency;$) {
62   my ($graph, $labels)=@_;
63   rows_labeled(adjacency_matrix($graph), $labels, $labels);
64}
65
66# @category Formatting
67# Equivalent to [[rows_labeled]] with omitted //row_labels// argument.
68# Formerly called "numbered".
69# @param Matrix data to be printed
70# @return Array<String> each string ending with end-of-line
71# @example
72# > print rows_numbered(polytope::cube(2)->VERTICES);
73# | 0:1 -1 -1
74# | 1:1 1 -1
75# | 2:1 -1 1
76# | 3:1 1 1
77
78user_function rows_numbered {
79   &rows_labeled;
80}
81
82# @category Formatting
83# LaTeX output of a matrix.
84# @param Matrix data to be printed
85# @param Array<String> elem_labels  optional labels for elements;
86#  if //data// is an [[IncidenceMatrix]], [[Array<Set>]], or similar, each element will be replaced by its label.
87# @return String to be used with \usepackage{amsmath}
88
89user_function latex($;$) {
90   my ($data, $elem_labels)=@_;
91   if (defined $elem_labels) {
92      is_like_array($elem_labels) or croak( "elem_labels must be an array" );
93   }
94   # The matrix environment is more convenient than array as it is not necessary to know the number of
95   # columns in advance.  Also works with rows of varying lengths.
96   my $latex_string="\\begin{matrix}\n";
97   my $first_line=1;
98   foreach (@$data) {
99     $latex_string .= "\\\\\n" unless $first_line;
100     $latex_string .= join(" & ", defined($elem_labels) ? @$elem_labels[@$_] : @$_);
101     $first_line=0;
102   }
103   $latex_string .= "\n\\end{matrix}\n";
104   return $latex_string;
105}
106
107# @category Formatting
108# Prepares a vector for printing, prepends each element with a label and a colon.
109# @param Vector data  to be printed
110# @param Array<String> elem_labels  optional labels for elements;
111#  if //data// is a [[Set]], or similar, each element will be replaced by its label.
112# @return String
113# @example
114# > $v = new Vector(0,1,2);
115# > print labeled($v,["zeroth","first","second"]);
116# | zeroth:0 first:1 second:2
117
118user_function labeled($;$) {
119   my ($data, $elem_labels)=@_;
120   if (defined $elem_labels) {
121      is_like_array($elem_labels) or croak( "elem_labels must be an array" );
122   }
123   my $i=-1;
124   my @result=map {
125      ++$i;
126      (defined($elem_labels) ? $elem_labels->[$i] : $i) . ":" . $_
127   } @$data;
128   return join (" ", @result);
129}
130
131# @category Formatting
132# Equivalent to [[labeled]] with omitted //elem_labels// argument.
133# @param Vector data to be printed
134# @return String
135# @example
136# > $data = new Vector(23,42,666);
137# > print numbered($data);
138# | 0:23 1:42 2:666
139
140user_function numbered {
141   &labeled;
142}
143
144
145# Local Variables:
146# mode: perl
147# c-basic-offset:3
148# End:
149