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# @Category Combinatorics 18object Cycle { 19 20 # Any cycle is pure-dimensional by default. 21 rule initial : PURE : { 22 $this->PURE = 1; 23 } 24 25 # @category Input property 26 # A list of (non-redundant) vertices and rays of the complex. Note that [[VERTICES]] 27 # are supposed to be normalized to a leading 0. If you want to input non-normalized vertices, 28 # use this property. 29 # [[VERTICES]] will be derived from this: Each row of [[VERTICES]] is just the corresponding row 30 # of [[PROJECTIVE_VERTICES]], with the first coordinate (i.e. column index 1) normalized to 0. 31 property PROJECTIVE_VERTICES : Matrix<Rational>; 32 33 rule VERTICES : PROJECTIVE_VERTICES { 34 my $m = new Matrix<Rational>($this->PROJECTIVE_VERTICES); 35 if ($m->rows() > 0) { # Might be the empty cycle 36 canonicalize_scalar_to_leading_zero($m->minor(All,~[0])); 37 } 38 $this->VERTICES = $m; 39 } 40 41 rule RaysPerm.PERMUTATION : RaysPerm.PROJECTIVE_VERTICES, PROJECTIVE_VERTICES { 42 $this->RaysPerm->PERMUTATION = find_matrix_row_permutation($this->RaysPerm->PROJECTIVE_VERTICES, $this->PROJECTIVE_VERTICES) 43 // die "no permutation"; 44 } 45 46 rule PROJECTIVE_VERTICES : RaysPerm.PROJECTIVE_VERTICES, RaysPerm.PERMUTATION { 47 $this->PROJECTIVE_VERTICES = permuted_rows($this->RaysPerm->PROJECTIVE_VERTICES, $this->RaysPerm->PERMUTATION); 48 } 49 weight 1.10; 50 51 # @Category Weights and lattices 52 # These are the integer weights associated to the maximal cells of the complex. 53 # Entries correspond to (rows of) [[MAXIMAL_POLYTOPES]]. 54 property WEIGHTS : Vector<Integer>; 55 56 rule WEIGHTS : ConesPerm.WEIGHTS, ConesPerm.PERMUTATION { 57 $this->WEIGHTS=permuted($this->ConesPerm->WEIGHTS, $this->ConesPerm->PERMUTATION); 58 } 59 weight 1.10; 60 61 # @Category Combinatorics 62 # Non-redundant list of all codimension one faces. Indices refer to 63 # [[VERTICES]]. Does not include any far faces. 64 property CODIMENSION_ONE_POLYTOPES : IncidenceMatrix; 65 66 rule CODIMENSION_ONE_POLYTOPES : RaysPerm.CODIMENSION_ONE_POLYTOPES, RaysPerm.PERMUTATION { 67 $this->CODIMENSION_ONE_POLYTOPES=permuted_cols($this->RaysPerm->CODIMENSION_ONE_POLYTOPES, 68 $this->RaysPerm->PERMUTATION); 69 } 70 weight 1.10; 71 72 # @Category Combinatorics 73 # Incidence matrix of codimension one polytopes and maximal polytopes. 74 # Rows refer to [[CODIMENSION_ONE_POLYTOPES]], columns to 75 # [[MAXIMAL_POLYTOPES]]. 76 property MAXIMAL_AT_CODIM_ONE : IncidenceMatrix; 77 78 # @category Combinatorics 79 # This maps an index pair (i,j), where i corresponds to the i-th row of [[CODIMENSION_ONE_POLYTOPES]] and 80 # j to the j-th row of [[MAXIMAL_POLYTOPES]], to the matching row number in [[FACET_NORMALS]]. 81 property FACET_NORMALS_BY_PAIRS : Map<Pair<Int,Int>, Int>; 82 83 rule MAXIMAL_AT_CODIM_ONE : ConesPerm.MAXIMAL_AT_CODIM_ONE, ConesPerm.PERMUTATION { 84 $this->MAXIMAL_AT_CODIM_ONE=permuted_cols($this->ConesPerm->MAXIMAL_AT_CODIM_ONE,$this->ConesPerm->PERMUTATION); 85 } 86 weight 1.10; 87 88 # permuting [[CODIMENSION_ONE_POLYTOPES]] 89 permutation CodimPerm : PermBase; 90 91 rule CodimPerm.PERMUTATION : CodimPerm.CODIMENSION_ONE_POLYTOPES, CODIMENSION_ONE_POLYTOPES { 92 $this->CodimPerm->PERMUTATION = find_permutation(new Array<Set<Int>>(rows($this->CodimPerm->CODIMENSION_ONE_POLYTOPES)), 93 new Array<Set<Int>>(rows($this->CODIMENSION_ONE_POLYTOPES))) 94 // die "no permutation"; 95 } 96 weight 5.10; 97 98 rule MAXIMAL_AT_CODIM_ONE : CodimPerm.MAXIMAL_AT_CODIM_ONE, CodimPerm.PERMUTATION { 99 $this->MAXIMAL_AT_CODIM_ONE=permuted_rows($this->CodimPerm->MAXIMAL_AT_CODIM_ONE,$this->CodimPerm->PERMUTATION); 100 } 101 weight 1.10; 102 103 rule FACET_NORMALS_BY_PAIRS : CodimPerm.FACET_NORMALS_BY_PAIRS, CodimPerm.PERMUTATION { 104 $this->FACET_NORMALS_BY_PAIRS=permute_map_first_factor($this->CodimPerm->FACET_NORMALS_BY_PAIRS, $this->CodimPerm->PERMUTATION); 105 } 106 weight 1.10; 107 108 rule FACET_NORMALS_BY_PAIRS : ConesPerm.FACET_NORMALS_BY_PAIRS, ConesPerm.PERMUTATION { 109 $this->FACET_NORMALS_BY_PAIRS=permute_map_second_factor($this->ConesPerm->FACET_NORMALS_BY_PAIRS, $this->ConesPerm->PERMUTATION); 110 } 111 weight 1.10; 112 113 114 115 rule CODIMENSION_ONE_POLYTOPES, MAXIMAL_AT_CODIM_ONE, FACET_NORMALS_BY_PAIRS : MAXIMAL_POLYTOPES, VERTICES, MAXIMAL_POLYTOPES_FACETS, FACET_NORMALS, FAR_VERTICES { 116 compute_codimension_one_polytopes($this); 117 } 118 weight 2.10; 119 incurs CodimPerm; 120 121 122 # @Category Weights and lattices 123 # The lattice normals of codimension one faces with respect to adjacent 124 # maximal cells. It maps a pair of indices (i,j) to the lattice normal 125 # of the codimension one face given by row i in [[CODIMENSION_ONE_POLYTOPES]] 126 # in the maximal cell given by row j in [[MAXIMAL_POLYTOPES]]. 127 # The lattice normal is a representative of a generator of the quotient of 128 # the saturated lattice of the maximal cell by the saturated lattice of the 129 # codimension one face. It is chosen such that it "points into the maximal cell" 130 # and is only unique modulo the lattice spanned by the codimension one cell. 131 property LATTICE_NORMALS : Map<Pair<Int,Int>,Vector<Integer>> { 132 133 method equal { 134 my ($this, $l1, $l2) = @_; 135 return compare_lattice_normals($this->VERTICES, $this->LINEALITY_SPACE, $this->CODIMENSION_ONE_POLYTOPES, $l1, $l2); 136 } 137 138 }; 139 140 rule LATTICE_NORMALS : ConesPerm.LATTICE_NORMALS, ConesPerm.PERMUTATION { 141 $this->LATTICE_NORMALS=permute_map_second_factor($this->ConesPerm->LATTICE_NORMALS, $this->ConesPerm->PERMUTATION); 142 } 143 weight 1.10; 144 145 rule LATTICE_NORMALS : CodimPerm.LATTICE_NORMALS, CodimPerm.PERMUTATION { 146 $this->LATTICE_NORMALS=permute_map_first_factor($this->CodimPerm->LATTICE_NORMALS,$this->CodimPerm->PERMUTATION); 147 } 148 149 150 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 { 151 compute_lattice_normals($this); 152 } 153 weight 3.10; 154 155 156 # @Category Affine and projective coordinates 157 # This is the projective dimension of the cycle. 158 # Alias for [[DIM]]. 159 property PROJECTIVE_DIM : Int; 160 161 rule PROJECTIVE_DIM : FAN_DIM { 162 $this->PROJECTIVE_DIM = $this->FAN_DIM-1; 163 } 164 weight 0.1; 165 166 # @Category Affine and projective coordinates 167 # This is the ambient projective dimension, i.e. it is 168 # [[FAN_AMBIENT_DIM]]-2. 169 property PROJECTIVE_AMBIENT_DIM : Int; 170 171 rule PROJECTIVE_AMBIENT_DIM : FAN_AMBIENT_DIM { 172 $this->PROJECTIVE_AMBIENT_DIM = $this->FAN_AMBIENT_DIM-2; 173 } 174 weight 0.1; 175 176 label with_new_properties 177 178 # Note: We need to redefine this rule: If only [[PROJECTIVE_VERTICES]] are present, 179 # the standard ruleset of fan will give 0 as an ambient dim. 180 rule with_new_properties : FAN_AMBIENT_DIM : { 181 my $d=0; 182 foreach (qw(RAYS INPUT_RAYS LINEALITY_SPACE INPUT_LINEALITY FACET_NORMALS LINEAR_SPAN_NORMALS PROJECTIVE_VERTICES)) { 183 my $M; 184 if (defined ($M=$this->lookup($_)) && $M->cols()>0) { 185 $d=$M->cols(); 186 last; 187 } 188 } 189 $this->FAN_AMBIENT_DIM=$d; 190 } 191 precondition : defined(RAYS | INPUT_RAYS | LINEALITY_SPACE | INPUT_LINEALITY | FACET_NORMALS | LINEAR_SPAN_NORMALS | PROJECTIVE_VERTICES); 192 weight 0.5; 193 194 # @category Affine and projective coordinates 195 # Codimension of the cycle. Same as [[PROJECTIVE_AMBIENT_DIM]] - [[PROJECTIVE_DIM]] 196 property PROJECTIVE_CODIMENSION : Int; 197 198 rule PROJECTIVE_CODIMENSION : PROJECTIVE_AMBIENT_DIM, PROJECTIVE_DIM { 199 $this->PROJECTIVE_CODIMENSION = $this->PROJECTIVE_AMBIENT_DIM - $this->PROJECTIVE_DIM; 200 } 201 weight 0.1; 202 203 # @category Weights and lattices 204 # For a onedimensional cycle, this produces the lengths of the [[MAXIMAL_POLYTOPES]], as multiples of the 205 # corresponding [[LATTICE_NORMALS]]. The i-th entry is the length of cell i. For unbounded cells 206 # this number is inf 207 # @return Array<Rational> 208 user_method CURVE_EDGE_LENGTHS : VERTICES, FAR_VERTICES, LATTICE_NORMALS, MAXIMAL_POLYTOPES, MAXIMAL_AT_CODIM_ONE { 209 return cycle_edge_lengths(shift); 210 } 211 precondition : PROJECTIVE_DIM { 212 $this->PROJECTIVE_DIM == 1; 213 } 214 215 # @category Affine and projective coordinates 216 # This produces a version of the cycle in the coordinates of a standard 217 # tropical chart, i.e. one coordinate is set to 0. 218 # It is returned as an ordinary polyhedral complex (which can, for example, 219 # be used for visualization). 220 # @param Int chart The coordinate which should be set to 0. Indexed from 221 # 0 to [[AMBIENT_DIM]]-1 and 0 by default. 222 # @return fan::PolyhedralComplex<Rational> 223 user_method affine_chart(;$=0) { 224 my ($this,$chart) = @_; 225 if ($this->FAN_AMBIENT_DIM==0) { 226 $this 227 } else { 228 new fan::PolyhedralComplex(VERTICES=>tdehomog($this->VERTICES,$chart), 229 MAXIMAL_POLYTOPES=>$this->MAXIMAL_POLYTOPES, 230 LINEALITY_SPACE=>tdehomog($this->LINEALITY_SPACE,$chart)); 231 } 232 } 233 234 # @category Weights and lattices 235 # Convenience function to ask for [[LATTICE_NORMALS]]->{new Pair<Int,Int>(i,j)} 236 # @param Int i Row index in [[CODIMENSION_ONE_POLYTOPES]]. 237 # @param Int j Row index in [[MAXIMAL_POLYTOPES]]. 238 # @return Vector<Integer> 239 user_method lattice_normal($,$) { 240 my ($this, $i, $j)=@_; 241 return $this->LATTICE_NORMALS->{new Pair<Int,Int>($i,$j)}; 242 } 243 244 # @category Combinatorics 245 # Convenience function to ask for [[FACET_NORMALS_BY_PAIRS]]->{new Pair<Int,Int>(i,i)} 246 # @param Int i Row index in [[CODIMENSION_ONE_POLYTOPES]]. 247 # @param Int j Row index in [[MAXIMAL_POLYTOPES]]. 248 # @return Int Row index in [[FACET_NORMALS]]. 249 user_method facet_normal($,$) { 250 my ($this, $i, $j)=@_; 251 return $this->FACET_NORMALS_BY_PAIRS->{new Pair<Int,Int>($i,$j)}; 252 } 253 254} 255 256 257# Local Variables: 258# mode: perl 259# cperl-indent-level:3 260# indent-tabs-mode:nil 261# End: 262