示例#1
0
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)
示例#2
0
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()
示例#3
0
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))