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
18 #include "polymake/client.h"
19 #include "polymake/Set.h"
20 #include "polymake/Matrix.h"
21 #include "polymake/IncidenceMatrix.h"
22 #include "polymake/Graph.h"
23
24 namespace polymake { namespace polytope {
25
26 template <typename Scalar>
normal_cone_impl(BigObject p,const Set<Int> & F,const std::string & ftv_section,const std::string & rays_section,const std::string & facets_section,OptionSet options)27 BigObject normal_cone_impl(BigObject p,
28 const Set<Int>& F,
29 const std::string& ftv_section,
30 const std::string& rays_section,
31 const std::string& facets_section,
32 OptionSet options)
33 {
34 if (p.isa("Polytope")) {
35 const Set<Int> far_face = p.give("FAR_FACE");
36 if (incl(F, far_face) <= 0)
37 throw std::runtime_error("normal_cone: face is contained in the far face");
38 }
39 const bool
40 outer = options["outer"],
41 attach = options["attach"];
42
43 const IncidenceMatrix<> ftv = p.give(ftv_section);
44 const Matrix<Scalar> facet_normals = p.give(facets_section);
45 Matrix<Scalar> cone_normals(facet_normals.minor(accumulate(rows(ftv.minor(F,All)), operations::mul()), range_from(1)));
46 if (outer) cone_normals = -cone_normals;
47
48 BigObject c("Cone", mlist<Scalar>());
49 const Matrix<Scalar> ls = p.give("LINEAR_SPAN");
50 if (attach) {
51 const Matrix<Scalar> rays = p.give(rays_section);
52 c.take("INPUT_RAYS") << rays.minor(F,All) / ( zero_vector<Scalar>() | cone_normals );
53 c.take("INPUT_LINEALITY") << ls;
54 c.take("CONE_AMBIENT_DIM") << cone_normals.cols()+1;
55 } else {
56 c.take("INPUT_RAYS") << cone_normals;
57 c.take("INPUT_LINEALITY") << ls.minor(All, range_from(1));
58 c.take("CONE_AMBIENT_DIM") << cone_normals.cols();
59 }
60 return c;
61 }
62
63 template <typename Scalar>
inner_cone_impl(BigObject p,const Set<Int> & F,OptionSet options)64 BigObject inner_cone_impl(BigObject p,
65 const Set<Int>& F,
66 OptionSet options)
67 {
68 if (p.isa("Polytope")) {
69 const Set<Int> far_face = p.give("FAR_FACE");
70 if (incl(F, far_face) <= 0)
71 throw std::runtime_error("normal_cone: face is contained in the far face");
72 }
73 const bool
74 outer = options["outer"],
75 attach = options["attach"];
76
77 const Graph<> G = p.give("GRAPH.ADJACENCY");
78 const Matrix<Scalar> V = p.give("VERTICES");
79 std::vector<Vector<Scalar>> inner_rays_list;
80 for (Int v : F) {
81 for (Int w : G.out_adjacent_nodes(v) - F) {
82 if (outer) {
83 inner_rays_list.emplace_back(V[v] - V[w]);
84 } else {
85 inner_rays_list.emplace_back(V[w] - V[v]);
86 }
87 }
88 }
89 Matrix<Scalar> inner_rays(inner_rays_list.size(), V.cols(), entire(inner_rays_list));
90 inner_rays.col(0) = zero_vector<Scalar>(inner_rays.rows());
91
92 BigObject c("Cone", mlist<Scalar>());
93 const Matrix<Scalar> ls = p.give("LINEAR_SPAN");
94 if (attach) {
95 const Matrix<Scalar> rays = p.give("RAYS");
96 c.take("INPUT_RAYS") << rays.minor(F,All) / inner_rays;
97 c.take("INPUT_LINEALITY") << ls;
98 c.take("CONE_AMBIENT_DIM") << V.cols();
99 } else {
100 c.take("INPUT_RAYS") << inner_rays.minor(All, range_from(1));
101 c.take("INPUT_LINEALITY") << ls.minor(All, range_from(1));
102 c.take("CONE_AMBIENT_DIM") << V.cols()-1;
103 }
104 return c;
105 }
106
107 FunctionTemplate4perl("normal_cone_impl<Scalar>($$$$$$)");
108
109 FunctionTemplate4perl("inner_cone_impl<Scalar>($$$)");
110
111 } }
112
113 // Local Variables:
114 // mode:C++
115 // c-basic-offset:3
116 // indent-tabs-mode:nil
117 // End:
118