def _triangulate_cone_internal(C, all_cones=False): rays = list(C.rays()) if any(a < 0 for r in rays for a in r): raise ValueError('Internal triangulation only implemented for non-negative cones.') normalised_rays = [ZZ.one() / v.norm(1) * vector(QQ, v) for v in rays] with TemporaryList() as maximal_faces: for indices in PointConfiguration(normalised_rays).triangulate() if len(normalised_rays) > 1 else [[0]]: subrays = [rays[i] for i in indices] if all_cones: maximal_faces.append(indices) else: multiplicity = prod(a for a in matrix(ZZ, subrays).elementary_divisors() if a != 0) yield SCONE(rays=subrays, multiplicity=multiplicity) if all_cones: X = SimplicialComplex(maximal_faces=maximal_faces, maximality_check=False) for f in X.face_iterator(): yield SCONE(rays=[rays[i] for i in f], multiplicity=-1)
def _mixed_volume_gfan(gen): """ Use gfan to compute the mixed volume of a collection of polytopes. Just like Khovanskii, we use the normalised mixed volume which satisfies mixed_volume([P,...,P]) = volume(P). """ P = list(gen) n = len(P) if any(Q.ambient_dim() != n for Q in P): raise TypeError( 'Number of polytopes and ambient dimension do not match') if n == 0: return 0 elif n == 1: return P[0].volume() R = PolynomialRing(QQ, 'x', n) I = R.ideal([sum(monomial_exp(R, e) for e in Q.vertices()) for Q in P]) return ZZ.one() / Integer(factorial(n)) * I.groebner_fan().mixed_volume()
def make_cond_key(D): D1 = ZZ(D) if D1 < 1: D1 = ZZ.one() D1 = int(D1.log(10)) return '%04d%s' % (D1, str(D))