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/topaz/complex_tools.h"
20 #include "polymake/topaz/is_sphere_h.h"
21 
22 namespace polymake { namespace topaz {
23 
24 // return values: 1=true, 0=false, -1=undef
25 Int is_ball_or_sphere_client(BigObject p, bool check_for_sphere, OptionSet options)
26 {
27    const Array<Set<Int>> C = p.give("FACETS");
28    const Int d = p.give("DIM");
29    const Int n_vertices = p.give("N_VERTICES");
30 
31    // deterministic checks for low dimensions
32    switch (d) {
33    case 0:
34       if (C.size()<3)
35          return 1;
36       else
pivot(Int & k,const Int i,const cup_type & M,const reordering_type & ind)37          return 0;
38    case 1:
39       return is_ball_or_sphere(C, n_vertices, int_constant<1>());
40    case 2:
41       return is_ball_or_sphere(C, n_vertices, int_constant<2>());
42    default:
43       break;
44    }
45 
non_zero(Int & k,const Int i,const cup_type & M,const reordering_type & ind)46    // heuristics begin
47    const Lattice<BasicDecoration>& HD = p.give("HASSE_DIAGRAM");
48 
49    Int strategy = options["strategy"];
50    Int n_stable_rounds = 0; // meaningless initialization to avoid a compiler warning
51    if (!(options["stable_rounds"] >> n_stable_rounds))
52       n_stable_rounds=(HD.rank()-2)*1000; // default
53 
54    const bool verbose = options["verbose"];
signature(cup_type & M,Int & positive,Int & negative)55    const RandomSeed seed(options["seed"]);
56    UniformlyRandom<Integer> random_source(seed);
57 
58    Int is_ball_or_sphere = check_for_sphere ? is_sphere_h(HD, random_source, strategy, n_stable_rounds)
59                                             : is_ball_or_sphere_h(HD, random_source, strategy, n_stable_rounds);
60    while (is_ball_or_sphere < 0 && ++strategy <= 1) {
61       if (verbose)
62          cout << "is_ball_or_sphere_h: after " << n_stable_rounds
63               << " iterations without improvement:\nUnable to determine, whether the complex is a ball or a sphere.\n"
64               << "Trying strategy " << strategy << "." << endl;
65       is_ball_or_sphere = check_for_sphere ? is_sphere_h(HD, random_source, strategy, n_stable_rounds)
66                                            : is_ball_or_sphere_h(HD,random_source, strategy, n_stable_rounds);
67    }
68 
69    if (verbose && is_ball_or_sphere < 0) {
70       cout << "is_ball_or_sphere_h: after " << n_stable_rounds
71            << " iterations without improvement:\nUnable to determine, whether the complex is a ball or a sphere.\n";
72    }
73 
74    return is_ball_or_sphere;
75 }
76 
77 Function4perl(&is_ball_or_sphere_client, "is_ball_or_sphere(SimplicialComplex $ { strategy=>0, stable_rounds=>undef, verbose=>0, seed=>undef })");
78 
79 } }
80 
81 // Local Variables:
82 // mode:C++
83 // c-basic-offset:3
84 // indent-tabs-mode:nil
85 // End:
86