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/Matrix.h"
20 #include "polymake/Vector.h"
21 #include "polymake/Rational.h"
22 #include "polymake/topaz/complex_tools.h"
23 #include "polymake/IncidenceMatrix.h"
24 
25 #include <sstream>
26 
27 namespace polymake { namespace topaz {
28 
29 template <typename Scalar>
foldable_prism(BigObject p_in,OptionSet options)30 BigObject foldable_prism (BigObject p_in, OptionSet options)
31 {
32    const IncidenceMatrix<> C_in = p_in.give("FACETS");
33    const Int n_vert = C_in.cols();
34    const bool is_foldable = p_in.give("FOLDABLE");
35    if (!is_foldable)
36       throw std::runtime_error("foldable_prism: Complex not foldable.");
37 
38    const Array<Int> Coloring = p_in.give("COLORING");
39    std::list<Set<Int>> C_out;
40 
41    Int v = 0;
42    for (auto star = entire(cols(C_in)); !star.at_end(); ++star, ++v)
43       for (auto f = entire(*star); !f.at_end(); ++f) {
44          Set<Int> new_f;
45          for (auto w=entire(C_in[f.index()]); !w.at_end(); ++w) {
46             if (Coloring[v] <= Coloring[*w])
47                new_f += *w + n_vert;
48             if (Coloring[v] >= Coloring[*w])
49                new_f += *w;
50          }
51          C_out.push_back(new_f);
52       }
53 
54    const bool realize = options["geometric_realization"];
55    BigObject p_out = realize
56       ? BigObject("GeometricSimplicialComplex", mlist<Scalar>())
57       : BigObject("SimplicialComplex");
58    p_out.set_description()  << "foldable prism of " << p_in.name() << "."<<endl;
59    p_out.take("FACETS") << as_array(C_out);
60 
61    if (realize) {
62       Matrix<Scalar> GR=p_in.give("COORDINATES");
63       Matrix<Scalar> GR2 = Vector<Scalar>(n_vert, pm::choose_generic_object_traits<Scalar>::one()) | GR;
64       GR = Vector<Scalar>(n_vert) | GR;
65 
66       p_out.take("COORDINATES") << GR/GR2;
67    }
68    return p_out;
69 }
70 
71 UserFunctionTemplate4perl("# @category Producing a new simplicial complex from others\n"
72                           "# Produce a __prism__ over a given [[SimplicialComplex]].\n"
73                           "# @param GeometricSimplicialComplex complex"
74                           "# @option Bool geometric_realization"
75                           "# @return GeometricSimplicialComplex",
76                           "foldable_prism<Scalar>(GeometricSimplicialComplex<Scalar> {geometric_realization => 0})");
77 
78 
79 } }
80 
81 // Local Variables:
82 // mode:C++
83 // c-basic-offset:3
84 // indent-tabs-mode:nil
85 // End:
86