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