1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
# Copyright (c) 1997-2024
# Ewgenij Gawrilow, Michael Joswig, and the polymake team
# Technische Universität Berlin, Germany
# https://polymake.org
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version: http://www.gnu.org/licenses/gpl.txt.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#-------------------------------------------------------------------------------
object Curve {
# @category Weights and lattices
# The rows of this IncidenceMatrix correspond to the nodes of the tropical graph,
# the columns to the edges.
# Therefore, each row records the indices of the edges incident to that vertex.
property EDGES_THROUGH_VERTICES : IncidenceMatrix;
# @category Weights and lattices
# Some edges can be "marked", which means they go off to infinity, and may not
# be permuted by any automorphism.
# By default there are no marked edges.
property MARKED_EDGES : Set<Int>;
# @category Weights and lattices
# Each vertex may have an integer weight, which is affected by edge contractions:
# if a loop on that vertex is contracted, the weight increases by 1,
# if a non-loop edge incident to that vertex is contracted, the new weight
# is the sum of the weights of the two endpoints.
# Default weights are zero.
property VERTEX_WEIGHTS : Array<Int>;
# @category Weights and lattices
# Each edge may have a Scalar length.
# These are taken into account when determining isomorphism, but not when
# calculating a MODULI_CELL.
property EDGE_LENGTHS : Vector<Scalar>;
# @category Weights and lattices
# Some additional inequalities may be imposed on the lengths of edges.
# The columns of this Matrix correspond to the columns of EDGES_THROUGH_VERTICES.
property INEQUALITIES : Matrix<Scalar>;
# @category Weights and lattices
# The simplicial complex that records exactly one vertex for each
# isomorphism class of assignments of lengths to the edges.
# See the documentation of the function moduli_cell() for an example.
property MODULI_CELL : topaz::GeometricSimplicialComplex;
rule MODULI_CELL : EDGES_THROUGH_VERTICES {
$this->MODULI_CELL = moduli_cell($this);
}
# @category Combinatorics
# Number of edges of the underlying graph.
property N_EDGES : Int;
rule N_EDGES : EDGES_THROUGH_VERTICES {
$this->N_EDGES = $this->EDGES_THROUGH_VERTICES->cols();
}
weight 0.10;
# @category Combinatorics
# Number of vertices (or nodes) of the underlying graph.
property N_VERTICES : Int;
rule N_VERTICES : EDGES_THROUGH_VERTICES {
$this->N_VERTICES = $this->EDGES_THROUGH_VERTICES->rows();
}
weight 0.10;
# @category Weights and lattices
# Genus of the abstract tropical curve, taking [[VERTEX_WEIGHTS]] into account
# @example with weights explicitly given
# > $C = new Curve(EDGES_THROUGH_VERTICES=>[[0,1],[1]], VERTEX_WEIGHTS=>[0,1]);
# > print $C->GENUS;
# | 2
# @example genus as abstract graph
# > $K4 = new Curve(EDGES_THROUGH_VERTICES=>[[0,1,2],[0,3,4],[1,3,5],[2,4,5]]);
# > print $K4->GENUS;
# | 3
property GENUS : Int;
rule GENUS : N_EDGES, N_VERTICES, VERTEX_WEIGHTS {
$this->GENUS = $this->N_EDGES - $this->N_VERTICES + 1 + sum($this->VERTEX_WEIGHTS);
}
# default weights are zero
rule VERTEX_WEIGHTS : N_VERTICES {
$this->VERTEX_WEIGHTS = new Array<Int>($this->N_VERTICES);
}
weight 0.10;
# no marked edges by default
rule MARKED_EDGES : {
$this->MARKED_EDGES = new Set<Int>();
}
weight 0.10;
}
# @category Weights and lattices
# Construct the stacky fan corresponding to a Curve.
# This is a fan with one representative for each orbit of faces under
# the symmetry group of the graph.
# @param Curve G
# @return fan::DisjointStackyFan
# @example
# To find the stacky f-vector of the complex of tropically smooth K_4 plane curves,
# first construct the appropriate Curve:
# > $UnitMatrix = unit_matrix(6);
# > ($u, $v, $w, $x, $y, $z) = 0..5;
# > ($U, $V, $W, $X, $Y, $Z) = map { new Vector($UnitMatrix->[$_]) } (0..5);
# > $D_ineqs = new Matrix( [$U-$V, $V-$W, $W-$Y, $W-$Z, $V-$X] );
# > $skeleton = new IncidenceMatrix([[$u,$v,$x],[$v,$w,$z],[$u,$w,$y],[$x,$y,$z]]);
# > $g = new Curve(EDGES_THROUGH_VERTICES=>$skeleton, INEQUALITIES=>$D_ineqs);
# Now we are ready to compute the stacky f-vector:
# > print stacky_le_fan($g)->STACKY_F_VECTOR;
# | 7 18 25 21 8
user_function stacky_le_fan(Curve) {
my ($tg) = @_;
my $autos = auto_group_on_coordinates($tg);
my $n_marked_edges = $tg->MARKED_EDGES->size();
my $n_unmarked_edges = $tg->EDGES_THROUGH_VERTICES->cols - $n_marked_edges;
my $ineqs = new Matrix(unit_matrix($n_unmarked_edges));
if (defined(my $additional_ineqs = $tg->lookup("INEQUALITIES"))) {
$ineqs /= $additional_ineqs;
}
my $sf = ($autos->size() != 0)
? fan::stacky_le_fan(new polytope::Cone(INEQUALITIES=>$ineqs, GROUP=>new group::Group(HOMOGENEOUS_COORDINATE_ACTION=>new group::PermutationAction(GENERATORS=>$autos))))
: fan::stacky_le_fan(new polytope::Cone(INEQUALITIES=>$ineqs));
return $sf;
}
# @category Weights and lattices
# Calculate the moduli cell of a given tropical graph G.
# This is a simplicial complex with one vertex for each isomorphism class
# of an assignment of lengths to the edges of G, that triangulates the
# space of all such isomorphism classes.
# @param Curve G the input graph. EDGE_LENGTHS are ignored.
# @option Int verbosity 0 (default) = off ... 5 (most verbose)
# @return topaz::GeometricSimplicialComplex
# @example
# The following incidence matrix defines a triangle with edges x,y,z,
# along extra edges a,b,c incident to each vertex.
# > ($a,$b,$c,$x,$y,$z,$w)=0..6;
# > $etv = new IncidenceMatrix([[$a,$x,$z],[$b,$x,$y],[$c,$y,$z]]);
# We consider the edges a,b,c to be marked.
# > $g = new Curve(EDGES_THROUGH_VERTICES=>$etv, MARKED_EDGES=>[$a,$b,$c]);
# The resulting moduli cell is homeomorphic to a 2-sphere:
# > print $g->MODULI_CELL->HOMOLOGY;
# | ({} 0)
# | ({} 0)
# | ({} 1)
# You can also include a matrix of INEQUALITIES among the edges, but be careful
# because the columns of that matrix correspond to the _unmarked_ edges:
# > $h = new Curve(EDGES_THROUGH_VERTICES=>$etv, MARKED_EDGES=>[$a,$b,$c], INEQUALITIES=>new Matrix([[1,-1,0]]));
# > print $h->MODULI_CELL->HOMOLOGY;
# | ({} 0)
# | ({} 0)
# | ({} 0)
user_function moduli_cell(Curve, { verbosity=>0 }) {
my ($tg, $options) = @_;
return moduli_cell_of_curve(fan::stacky_fundamental_domain(stacky_le_fan($tg), $options), $tg, $options);
}
# Local Variables:
# mode: perl
# cperl-indent-level: 3
# indent-tabs-mode:nil
# End:
|