1 /*
2 	This program is free software; you can redistribute it and/or
3 	modify it under the terms of the GNU General Public License
4 	as published by the Free Software Foundation; either version 2
5 	of the License, or (at your option) any later version.
6 
7 	This program is distributed in the hope that it will be useful,
8 	but WITHOUT ANY WARRANTY; without even the implied warranty of
9 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 	GNU General Public License for more details.
11 
12 	You should have received a copy of the GNU General Public License
13 	along with this program; if not, write to the Free Software
14 	Foundation, Inc., 51 Franklin Street, Fifth Floor,
15 	Boston, MA  02110-1301, USA.
16 
17 	---
18 	Copyright (C) 2011 - 2015, Simon Hampe <simon.hampe@googlemail.com>
19 
20 	---
21 	Copyright (c) 2016-2021
22 	Ewgenij Gawrilow, Michael Joswig, and the polymake team
23 	Technische Universität Berlin, Germany
24 	https://polymake.org
25 
26 	Compute the local fans of a tropical cycle.
27 	*/
28 
29 #include "polymake/client.h"
30 #include "polymake/Rational.h"
31 #include "polymake/Matrix.h"
32 #include "polymake/Vector.h"
33 #include "polymake/tropical/misc_tools.h"
34 #include "polymake/tropical/separated_data.h"
35 
36 namespace polymake { namespace tropical {
37 
38 // Documentation see perl wrapper
39 template <typename Addition>
fan_decomposition(BigObject cycle)40 ListReturn fan_decomposition(BigObject cycle)
41 {
42   // Extract values
43   Matrix<Rational> rays = cycle.give("VERTICES");
44   IncidenceMatrix<> cones = cycle.give("MAXIMAL_POLYTOPES");
45   IncidenceMatrix<> verticesInCones = T(cones);
46   Vector<Integer> weights = cycle.give("WEIGHTS");
47   Matrix<Rational> lineality = cycle.give("LINEALITY_SPACE");
48 
49   IncidenceMatrix<> local_restriction;
50   if (cycle.exists("LOCAL_RESTRICTION")) {
51     cycle.give("LOCAL_RESTRICTION") >> local_restriction;
52   }
53 
54   Set<Int> nonfar = far_and_nonfar_vertices(rays).second;
55 
56   ListReturn result;
57   for (auto nf = entire(nonfar); !nf.at_end(); ++nf) {
58     if (local_restriction.rows() > 0) {
59       if (!is_coneset_compatible(scalar2set(*nf), local_restriction))
60         continue;
61     }
62 
63     Set<Int> conesAtVertex = verticesInCones.row(*nf);
64     Set<Int> usedRays = accumulate(rows( cones.minor(conesAtVertex,All)), operations::add());
65 
66     Matrix<Rational> fanRays(rays);
67     // Replace other nonfar vertices by difference
68     Set<Int> othernonfar = (nonfar * usedRays) - *nf;
69     for (auto onf = entire(othernonfar); !onf.at_end(); ++onf) {
70       fanRays.row(*onf) = fanRays.row(*onf) - fanRays.row(*nf);
71     }
72     fanRays.row(*nf) = unit_vector<Rational>(fanRays.cols(),0);
73     fanRays = fanRays.minor(usedRays,All);
74 
75     BigObject fanCycle("Cycle", mlist<Addition>(),
76                        "PROJECTIVE_VERTICES", fanRays,
77                        "MAXIMAL_POLYTOPES", cones.minor(conesAtVertex,usedRays),
78                        "WEIGHTS", weights.slice(conesAtVertex),
79                        "LINEALITY_SPACE", lineality);
80     result << fanCycle;
81   }
82   return result;
83 }
84 
85 UserFunctionTemplate4perl("# @category Basic polyhedral operations"
86                           "# This computes the local fans at all (nonfar) vertices of a tropical cycle"
87                           "# @param Cycle<Addition> C A tropical cycle"
88                           "# @return Cycle<Addition> A list of local cycles",
89                           "fan_decomposition<Addition>(Cycle<Addition>)");
90 
91 } }
92