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 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
|
# 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.
#-------------------------------------------------------------------------------
# @Category Combinatorics
object Cycle {
# Any cycle is pure-dimensional by default.
rule initial : PURE : {
$this->PURE = 1;
}
# @category Input property
# A list of (non-redundant) vertices and rays of the complex. Note that [[VERTICES]]
# are supposed to be normalized to a leading 0. If you want to input non-normalized vertices,
# use this property.
# [[VERTICES]] will be derived from this: Each row of [[VERTICES]] is just the corresponding row
# of [[PROJECTIVE_VERTICES]], with the first coordinate (i.e. column index 1) normalized to 0.
property PROJECTIVE_VERTICES : Matrix<Rational>;
rule VERTICES : PROJECTIVE_VERTICES {
my $m = new Matrix<Rational>($this->PROJECTIVE_VERTICES);
if ($m->rows() > 0) { # Might be the empty cycle
canonicalize_scalar_to_leading_zero($m->minor(All,~[0]));
}
$this->VERTICES = $m;
}
rule RaysPerm.PERMUTATION : RaysPerm.PROJECTIVE_VERTICES, PROJECTIVE_VERTICES {
$this->RaysPerm->PERMUTATION = find_matrix_row_permutation($this->RaysPerm->PROJECTIVE_VERTICES, $this->PROJECTIVE_VERTICES)
// die "no permutation";
}
rule PROJECTIVE_VERTICES : RaysPerm.PROJECTIVE_VERTICES, RaysPerm.PERMUTATION {
$this->PROJECTIVE_VERTICES = permuted_rows($this->RaysPerm->PROJECTIVE_VERTICES, $this->RaysPerm->PERMUTATION);
}
weight 1.10;
# @Category Weights and lattices
# These are the integer weights associated to the maximal cells of the complex.
# Entries correspond to (rows of) [[MAXIMAL_POLYTOPES]].
property WEIGHTS : Vector<Integer>;
rule WEIGHTS : ConesPerm.WEIGHTS, ConesPerm.PERMUTATION {
$this->WEIGHTS=permuted($this->ConesPerm->WEIGHTS, $this->ConesPerm->PERMUTATION);
}
weight 1.10;
# @Category Combinatorics
# Non-redundant list of all codimension one faces. Indices refer to
# [[VERTICES]]. Does not include any far faces.
property CODIMENSION_ONE_POLYTOPES : IncidenceMatrix;
rule CODIMENSION_ONE_POLYTOPES : RaysPerm.CODIMENSION_ONE_POLYTOPES, RaysPerm.PERMUTATION {
$this->CODIMENSION_ONE_POLYTOPES=permuted_cols($this->RaysPerm->CODIMENSION_ONE_POLYTOPES,
$this->RaysPerm->PERMUTATION);
}
weight 1.10;
# @Category Combinatorics
# Incidence matrix of codimension one polytopes and maximal polytopes.
# Rows refer to [[CODIMENSION_ONE_POLYTOPES]], columns to
# [[MAXIMAL_POLYTOPES]].
property MAXIMAL_AT_CODIM_ONE : IncidenceMatrix;
# @category Combinatorics
# This maps an index pair (i,j), where i corresponds to the i-th row of [[CODIMENSION_ONE_POLYTOPES]] and
# j to the j-th row of [[MAXIMAL_POLYTOPES]], to the matching row number in [[FACET_NORMALS]].
property FACET_NORMALS_BY_PAIRS : Map<Pair<Int,Int>, Int>;
rule MAXIMAL_AT_CODIM_ONE : ConesPerm.MAXIMAL_AT_CODIM_ONE, ConesPerm.PERMUTATION {
$this->MAXIMAL_AT_CODIM_ONE=permuted_cols($this->ConesPerm->MAXIMAL_AT_CODIM_ONE,$this->ConesPerm->PERMUTATION);
}
weight 1.10;
# permuting [[CODIMENSION_ONE_POLYTOPES]]
permutation CodimPerm : PermBase;
rule CodimPerm.PERMUTATION : CodimPerm.CODIMENSION_ONE_POLYTOPES, CODIMENSION_ONE_POLYTOPES {
$this->CodimPerm->PERMUTATION = find_permutation(new Array<Set<Int>>(rows($this->CodimPerm->CODIMENSION_ONE_POLYTOPES)),
new Array<Set<Int>>(rows($this->CODIMENSION_ONE_POLYTOPES)))
// die "no permutation";
}
weight 5.10;
rule MAXIMAL_AT_CODIM_ONE : CodimPerm.MAXIMAL_AT_CODIM_ONE, CodimPerm.PERMUTATION {
$this->MAXIMAL_AT_CODIM_ONE=permuted_rows($this->CodimPerm->MAXIMAL_AT_CODIM_ONE,$this->CodimPerm->PERMUTATION);
}
weight 1.10;
rule FACET_NORMALS_BY_PAIRS : CodimPerm.FACET_NORMALS_BY_PAIRS, CodimPerm.PERMUTATION {
$this->FACET_NORMALS_BY_PAIRS=permute_map_first_factor($this->CodimPerm->FACET_NORMALS_BY_PAIRS, $this->CodimPerm->PERMUTATION);
}
weight 1.10;
rule FACET_NORMALS_BY_PAIRS : ConesPerm.FACET_NORMALS_BY_PAIRS, ConesPerm.PERMUTATION {
$this->FACET_NORMALS_BY_PAIRS=permute_map_second_factor($this->ConesPerm->FACET_NORMALS_BY_PAIRS, $this->ConesPerm->PERMUTATION);
}
weight 1.10;
rule CODIMENSION_ONE_POLYTOPES, MAXIMAL_AT_CODIM_ONE, FACET_NORMALS_BY_PAIRS : MAXIMAL_POLYTOPES, VERTICES, MAXIMAL_POLYTOPES_FACETS, FACET_NORMALS, FAR_VERTICES {
compute_codimension_one_polytopes($this);
}
weight 2.10;
incurs CodimPerm;
# @Category Weights and lattices
# The lattice normals of codimension one faces with respect to adjacent
# maximal cells. It maps a pair of indices (i,j) to the lattice normal
# of the codimension one face given by row i in [[CODIMENSION_ONE_POLYTOPES]]
# in the maximal cell given by row j in [[MAXIMAL_POLYTOPES]].
# The lattice normal is a representative of a generator of the quotient of
# the saturated lattice of the maximal cell by the saturated lattice of the
# codimension one face. It is chosen such that it "points into the maximal cell"
# and is only unique modulo the lattice spanned by the codimension one cell.
property LATTICE_NORMALS : Map<Pair<Int,Int>,Vector<Integer>> {
method equal {
my ($this, $l1, $l2) = @_;
return compare_lattice_normals($this->VERTICES, $this->LINEALITY_SPACE, $this->CODIMENSION_ONE_POLYTOPES, $l1, $l2);
}
};
rule LATTICE_NORMALS : ConesPerm.LATTICE_NORMALS, ConesPerm.PERMUTATION {
$this->LATTICE_NORMALS=permute_map_second_factor($this->ConesPerm->LATTICE_NORMALS, $this->ConesPerm->PERMUTATION);
}
weight 1.10;
rule LATTICE_NORMALS : CodimPerm.LATTICE_NORMALS, CodimPerm.PERMUTATION {
$this->LATTICE_NORMALS=permute_map_first_factor($this->CodimPerm->LATTICE_NORMALS,$this->CodimPerm->PERMUTATION);
}
rule LATTICE_NORMALS : MAXIMAL_POLYTOPES, CODIMENSION_ONE_POLYTOPES, MAXIMAL_AT_CODIM_ONE, MAXIMAL_POLYTOPES_AFFINE_HULL_NORMALS, FACET_NORMALS_BY_PAIRS, FACET_NORMALS, MAXIMAL_POLYTOPES_FACETS, AFFINE_HULL, FAN_DIM {
compute_lattice_normals($this);
}
weight 3.10;
# @Category Affine and projective coordinates
# This is the projective dimension of the cycle.
# Alias for [[DIM]].
property PROJECTIVE_DIM : Int;
rule PROJECTIVE_DIM : FAN_DIM {
$this->PROJECTIVE_DIM = $this->FAN_DIM-1;
}
weight 0.1;
# @Category Affine and projective coordinates
# This is the ambient projective dimension, i.e. it is
# [[FAN_AMBIENT_DIM]]-2.
property PROJECTIVE_AMBIENT_DIM : Int;
rule PROJECTIVE_AMBIENT_DIM : FAN_AMBIENT_DIM {
$this->PROJECTIVE_AMBIENT_DIM = $this->FAN_AMBIENT_DIM-2;
}
weight 0.1;
label with_new_properties
# Note: We need to redefine this rule: If only [[PROJECTIVE_VERTICES]] are present,
# the standard ruleset of fan will give 0 as an ambient dim.
rule with_new_properties : FAN_AMBIENT_DIM : {
my $d=0;
foreach (qw(RAYS INPUT_RAYS LINEALITY_SPACE INPUT_LINEALITY FACET_NORMALS LINEAR_SPAN_NORMALS PROJECTIVE_VERTICES)) {
my $M;
if (defined ($M=$this->lookup($_)) && $M->cols()>0) {
$d=$M->cols();
last;
}
}
$this->FAN_AMBIENT_DIM=$d;
}
precondition : defined(RAYS | INPUT_RAYS | LINEALITY_SPACE | INPUT_LINEALITY | FACET_NORMALS | LINEAR_SPAN_NORMALS | PROJECTIVE_VERTICES);
weight 0.5;
# @category Affine and projective coordinates
# Codimension of the cycle. Same as [[PROJECTIVE_AMBIENT_DIM]] - [[PROJECTIVE_DIM]]
property PROJECTIVE_CODIMENSION : Int;
rule PROJECTIVE_CODIMENSION : PROJECTIVE_AMBIENT_DIM, PROJECTIVE_DIM {
$this->PROJECTIVE_CODIMENSION = $this->PROJECTIVE_AMBIENT_DIM - $this->PROJECTIVE_DIM;
}
weight 0.1;
# @category Weights and lattices
# For a onedimensional cycle, this produces the lengths of the [[MAXIMAL_POLYTOPES]], as multiples of the
# corresponding [[LATTICE_NORMALS]]. The i-th entry is the length of cell i. For unbounded cells
# this number is inf
# @return Array<Rational>
user_method CURVE_EDGE_LENGTHS : VERTICES, FAR_VERTICES, LATTICE_NORMALS, MAXIMAL_POLYTOPES, MAXIMAL_AT_CODIM_ONE {
return cycle_edge_lengths(shift);
}
precondition : PROJECTIVE_DIM {
$this->PROJECTIVE_DIM == 1;
}
# @category Affine and projective coordinates
# This produces a version of the cycle in the coordinates of a standard
# tropical chart, i.e. one coordinate is set to 0.
# It is returned as an ordinary polyhedral complex (which can, for example,
# be used for visualization).
# @param Int chart The coordinate which should be set to 0. Indexed from
# 0 to [[AMBIENT_DIM]]-1 and 0 by default.
# @return fan::PolyhedralComplex<Rational>
user_method affine_chart(;$=0) {
my ($this,$chart) = @_;
if ($this->FAN_AMBIENT_DIM==0) {
$this
} else {
new fan::PolyhedralComplex(VERTICES=>tdehomog($this->VERTICES,$chart),
MAXIMAL_POLYTOPES=>$this->MAXIMAL_POLYTOPES,
LINEALITY_SPACE=>tdehomog($this->LINEALITY_SPACE,$chart));
}
}
# The 'polytope' method in application fan uses lookup to deal with different
# representations but when only projective vertices are present in a Cycle
# we end up with an almost empty object, so we overload that method, compute
# proper vertices and then delegate to the method from application fan.
method polytope($) {
my ($this, $i)=@_;
$this->provide("VERTICES")
if defined($this->lookup("PROJECTIVE_VERTICES"));
return fan::PolyhedralComplex::polytope($this, $i);
}
# @category Weights and lattices
# Convenience function to ask for [[LATTICE_NORMALS]]->{new Pair<Int,Int>(i,j)}
# @param Int i Row index in [[CODIMENSION_ONE_POLYTOPES]].
# @param Int j Row index in [[MAXIMAL_POLYTOPES]].
# @return Vector<Integer>
user_method lattice_normal($,$) {
my ($this, $i, $j)=@_;
return $this->LATTICE_NORMALS->{new Pair<Int,Int>($i,$j)};
}
# @category Combinatorics
# Convenience function to ask for [[FACET_NORMALS_BY_PAIRS]]->{new Pair<Int,Int>(i,i)}
# @param Int i Row index in [[CODIMENSION_ONE_POLYTOPES]].
# @param Int j Row index in [[MAXIMAL_POLYTOPES]].
# @return Int Row index in [[FACET_NORMALS]].
user_method facet_normal($,$) {
my ($this, $i, $j)=@_;
return $this->FACET_NORMALS_BY_PAIRS->{new Pair<Int,Int>($i,$j)};
}
}
# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
|