SAGE中关于多面体计算的较长介绍¶
本教程旨在展示Sage在多面体几何和组合学方面的一些可能性。
关于这一主题的经典文献包括:
对于命名法,Sage试图遵循以下原则:
Handbook of Discrete and Computational Geometry ,第15章, [Goo2004]
本文件的编写部分得到了OpenDreamKit项目的支持,并在Olot(西班牙)举行的SageDays 84期间编写。
第0课:基本定义和结构¶
一个真正的 (ktimes d) -矩阵 A 和一个实数向量 b 在……里面 mathbb{R}^d 定义一个(凸) polyhedron P 作为线性不等式组的解的集合:
Each row of A defines a closed half-space of mathbb{R}^d. Hence a polyhedron is the intersection of finitely many closed half-spaces in mathbb{R}^d. The matrix A may contain equal rows, which may lead to a set of equalities satisfied by the polyhedron. If there are no redundant rows in the above definition, this definition is referred to as the mathbf{H} -representation of a polyhedron.
一个极大仿射子空间 L 包含在多面体中的是一个 lineality 空间 P 。固定一个点 o 关于线性性空间 L 充当 origin ,一个人可以写下每一分 p 在多面体内部作为组合
where ellin L (using o as the origin), sum_{i=1}^nlambda_i=1, lambda_igeq0, mu_igeq0, and r_ineq0 for all 0leq ileq m and the set of r_i 's are positively independent (the origin is not in their positive span). For a given point p there may be many equivalent ways to write the above using different sets {v_i}_{i=1}^{n} and {r_i}_{i=1}^{m}. Hence we require the sets to be inclusion minimal sets such that we can get the above property equality for any point pin P.
The vectors v_i are called the vertices of P and the vectors r_i are called the rays of P. This way to represent a polyhedron is referred to as the mathbf{V} -representation of a polyhedron. The first sum represents the convex hull of the vertices v_i 's and the second sum represents a pointed polyhedral cone generated by finitely many rays.
当线度空间和射线被简化为一点(即,没有射线和线)时,对象通常被称为 polytope 。
备注
正如在构造函数的文档中提到的那样,当输入 Polyhedron?
:
You may either define it with vertex/ray/line or inequalities/equations data, but not both. Redundant data will automatically be removed (unless "minimize=False"), and the complementary representation will be computed.
以下是的构造函数的文档 sage.geometry.polyhedron.constructor 。
V -表示法¶
首先,让我们将多面体对象定义为一组点和一些光线的凸壳。
sage: P1 = Polyhedron(vertices=[[1, 0], [0, 1]], rays=[[1, 1]])
sage: P1
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
字符串表示已经提供了很多信息:
多面体的维度(包含它的最小仿射空间)
定义它的空间的维度
底环 (mathbb{Z}^2 多面体位于其上)(这指定父类,请参见 sage.geometry.polyhedron.parent )
顶点数
射线的数量
当然,您想知道这个对象是什么样子:
sage: P1.plot()
Graphics object consisting of 5 graphics primitives
我们还可以添加一个线性空间。
sage: P2 = Polyhedron(vertices=[[1/2, 0, 0], [0, 1/2, 0]],
....: rays=[[1, 1, 0]],
....: lines=[[0, 0, 1]])
sage: P2
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 2 vertices, 1 ray, 1 line
sage: P2.plot()
Graphics3d Object
请注意,基环因值的不同而更改 frac{1}{2} 。事实上,Sage找到了一个合适的环来定义对象。
sage: P1.parent()
Polyhedra in QQ^2
sage: P2.parent()
Polyhedra in QQ^3
选择的铃声取决于输入格式。
sage: P3 = Polyhedron(vertices=[[0.5, 0], [0, 0.5]])
sage: P3
A 1-dimensional polyhedron in RDF^2 defined as the convex hull of 2 vertices
sage: P3.parent()
Polyhedra in RDF^2
警告
底环 RDF
应谨慎使用。由于它不是精确的环,某些计算可能会中断或默默地产生错误的结果,例如在处理非单纯多面体时。
下面的示例演示了 RDF
。
sage: D = polytopes.dodecahedron() # needs sage.rings.number_field
sage: D # needs sage.rings.number_field
A 3-dimensional polyhedron
in (Number Field in sqrt5 with defining polynomial x^2 - 5
with sqrt5 = 2.236067977499790?)^3
defined as the convex hull of 20 vertices
sage: vertices_RDF = [n(v.vector(),digits=6) for v in D.vertices()] # needs sage.rings.number_field
sage: D_RDF = Polyhedron(vertices=vertices_RDF, base_ring=RDF) # needs sage.rings.number_field
doctest:warning
...
UserWarning: This polyhedron data is numerically complicated; cdd
could not convert between the inexact V and H representation
without loss of data. The resulting object might show
inconsistencies.
sage: D_RDF = Polyhedron(vertices=sorted(vertices_RDF), base_ring=RDF) # needs sage.rings.number_field
Traceback (most recent call last):
...
ValueError: *Error: Numerical inconsistency is found. Use the GMP exact arithmetic.
如果多面体的输入由 Python 组成 float
,它会自动将数据转换为 RDF
:
sage: Polyhedron(vertices=[[float(1.1)]])
A 0-dimensional polyhedron in RDF^1 defined as the convex hull of 1 vertex
定义代数上的多面体也是可能的。
sage: # needs sage.rings.number_field
sage: sqrt_2 = AA(2)^(1/2)
sage: cbrt_2 = AA(2)^(1/3)
sage: timeit('Polyhedron(vertices=[[sqrt_2, 0], [0, cbrt_2]])') # random
5 loops, best of 3: 43.2 ms per loop
sage: P4 = Polyhedron(vertices=[[sqrt_2, 0], [0, cbrt_2]]); P4
A 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices
还有一种方法可以创建代数数上的多面体:
sage: # needs sage.rings.number_field
sage: K.<a> = NumberField(x^2 - 2, embedding=AA(2)**(1/2))
sage: L.<b> = NumberField(x^3 - 2, embedding=AA(2)**(1/3))
sage: timeit('Polyhedron(vertices=[[a, 0], [0, b]])') # random
5 loops, best of 3: 39.9 ms per loop
sage: P5 = Polyhedron(vertices=[[a, 0], [0, b]]); P5
A 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices
如果基环是已知的,则使用适当的 sage.rings.number_field.number_field.number_field.composite_fields()
:
sage: # needs sage.rings.number_field
sage: J = K.composite_fields(L)[0]
sage: timeit('Polyhedron(vertices=[[J(a), 0], [0, J(b)]])') # random
25 loops, best of 3: 9.8 ms per loop
sage: P5_comp = Polyhedron(vertices=[[J(a), 0], [0, J(b)]]); P5_comp
A 1-dimensional polyhedron
in (Number Field in ab with defining polynomial
x^6 - 6*x^4 - 4*x^3 + 12*x^2 - 24*x - 4
with ab = -0.1542925124782219?)^2
defined as the convex hull of 2 vertices
的多面体计算 Symbolic Ring
都没有实现。不可能在其上定义多面体:
sage: sqrt_2s = sqrt(2) # needs sage.symbolic
sage: cbrt_2s = 2^(1/3) # needs sage.symbolic
sage: Polyhedron(vertices=[[sqrt_2s, 0], [0, cbrt_2s]]) # needs sage.symbolic
Traceback (most recent call last):
...
ValueError: no default backend for computations with Symbolic Ring
同样,不可能在上面创建多面体对象 RR
(无论精度有多高)。
sage: F45 = RealField(45)
sage: F100 = RealField(100)
sage: f = 1.1
sage: Polyhedron(vertices=[[F45(f)]])
Traceback (most recent call last):
...
ValueError: the only allowed inexact ring is 'RDF' with backend 'cdd'
sage: Polyhedron(vertices=[[F100(f)]])
Traceback (most recent call last):
...
ValueError: the only allowed inexact ring is 'RDF' with backend 'cdd'
有一个例外,当精度位数为53时,基环转换为 RDF
:
sage: F53 = RealField(53)
sage: Polyhedron(vertices=[[F53(f)]])
A 0-dimensional polyhedron in RDF^1 defined as the convex hull of 1 vertex
sage: type(Polyhedron(vertices=[[F53(f)]]))
<class 'sage.geometry.polyhedron.parent.Polyhedra_RDF_cdd_with_category.element_class'>
这种行为可以被视为错误的,但它允许Sage接受以下行为:
sage: Polyhedron([(1.0, 2.3), (3.5, 2.0)])
A 1-dimensional polyhedron in RDF^2 defined as the convex hull of 2 vertices
没有指定底环的情况下 RDF
由用户执行。
H -表示法¶
如果多面体对象是通过 V -代表,Sage可以提供 H -对象的表示。
sage: for h in P1.Hrepresentation():
....: print(h)
An inequality (1, 1) x - 1 >= 0
An inequality (1, -1) x + 1 >= 0
An inequality (-1, 1) x + 1 >= 0
每行都给出了矩阵的一行 A 和向量的条目 b 。变量 x 是环境空间中的一个矢量 P1
是被定义的。这个 H -表示可能包含方程式:
sage: P3.Hrepresentation()
(An inequality (-2.0, 0.0) x + 1.0 >= 0,
An inequality (1.0, 0.0) x + 0.0 >= 0,
An equation (1.0, 1.0) x - 0.5 == 0)
通过其构造多面体对象 H -表示,需要精确的格式。每个不等式 (a_{i1}, dots, a_{id})cdot x + b_i geq 0 必须写成 [b_i,a_i1, ..., a_id]
。
sage: P3_H = Polyhedron(ieqs = [[1.0, -2, 0], [0, 1, 0]], eqns = [[-0.5, 1, 1]])
sage: P3 == P3_H
True
sage: P3_H.Vrepresentation()
(A vertex at (0.0, 0.5), A vertex at (0.5, 0.0))
该参数值得使用 eqns
以缩短对象的构造。在下面的示例中,前四行是第二组四行的负数。
sage: H = [[0, 0, 0, 0, 0, 0, 0, 0, 1],
....: [0, 0, 0, 0, 0, 0, 1, 0, 0],
....: [-2, 1, 1, 1, 1, 1, 0, 0, 0],
....: [0, 0, 0, 0, 0, 0, 0, 1, 0],
....: [0, 0, 0, 0, 0, 0, 0, 0, -1],
....: [0, 0, 0, 0, 0, 0, -1, 0, 0],
....: [2, -1, -1, -1, -1, -1, 0, 0, 0],
....: [0, 0, 0, 0, 0, 0, 0, -1, 0],
....: [2, -1, -1, -1, -1, 0, 0, 0, 0],
....: [0, 0, 0, 0, 1, 0, 0, 0, 0],
....: [0, 0, 0, 1, 0, 0, 0, 0, 0],
....: [0, 0, 1, 0, 0, 0, 0, 0, 0],
....: [-1, 1, 1, 1, 1, 0, 0, 0, 0],
....: [1, 0, 0, -1, 0, 0, 0, 0, 0],
....: [0, 1, 0, 0, 0, 0, 0, 0, 0],
....: [1, 0, 0, 0, -1, 0, 0, 0, 0],
....: [1, 0, -1, 0, 0, 0, 0, 0, 0],
....: [1, -1, 0, 0, 0, 0, 0, 0, 0]]
sage: timeit('Polyhedron(ieqs = H)') # random
125 loops, best of 3: 5.99 ms per loop
sage: timeit('Polyhedron(ieqs = H[8:], eqns = H[:4])') # random
125 loops, best of 3: 4.78 ms per loop
sage: Polyhedron(ieqs = H) == Polyhedron(ieqs = H[8:], eqns = H[:4])
True
当然,这只是一个玩具示例,但如果可能的话,在定义多面体之前对数据进行预处理通常是值得的。
第1课:表示对象¶
许多对象都与 H -以及 V -申述。Sage已经为它们实现了类。
H -表示法¶
您可以存储 H -在变量中表示,并使用不等式和等式作为对象。
sage: P3_QQ = Polyhedron(vertices=[[0.5, 0], [0, 0.5]], base_ring=QQ)
sage: HRep = P3_QQ.Hrepresentation()
sage: H1 = HRep[0]; H1
An equation (2, 2) x - 1 == 0
sage: H2 = HRep[1]; H2
An inequality (0, -2) x + 1 >= 0
sage: H1.<tab> # not tested
sage: H1.A()
(2, 2)
sage: H1.b()
-1
sage: H1.is_equation()
True
sage: H1.is_inequality()
False
sage: H1.contains(vector([0,0]))
False
sage: H2.contains(vector([0,0]))
True
sage: H1.is_incident(H2)
True
可以获得不同对象的 H -陈述如下。
sage: P3_QQ.equations()
(An equation (2, 2) x - 1 == 0,)
sage: P3_QQ.inequalities()
(An inequality (0, -2) x + 1 >= 0, An inequality (0, 1) x + 0 >= 0)
备注
建议使用 equations
或 equation_generator
(对于不等式也是如此),如果想要迭代它们而不是 equations_list
。
V -表示法¶
同样,您可以访问多面体的顶点、射线和线。
sage: VRep = P2.Vrepresentation(); VRep
(A line in the direction (0, 0, 1),
A vertex at (0, 1/2, 0),
A vertex at (1/2, 0, 0),
A ray in the direction (1, 1, 0))
sage: L = VRep[0]; L
A line in the direction (0, 0, 1)
sage: V = VRep[1]; V
A vertex at (0, 1/2, 0)
sage: R = VRep[3]; R
A ray in the direction (1, 1, 0)
sage: L.is_line()
True
sage: L.is_incident(V)
True
sage: R.is_incident(L)
False
sage: L.vector()
(0, 0, 1)
sage: V.vector()
(0, 1/2, 0)
可以获得不同对象的 V -陈述如下。
sage: P2.vertices()
(A vertex at (0, 1/2, 0), A vertex at (1/2, 0, 0))
sage: P2.rays()
(A ray in the direction (1, 1, 0),)
sage: P2.lines()
(A line in the direction (0, 0, 1),)
sage: P2.vertices_matrix()
[ 0 1/2]
[1/2 0]
[ 0 0]
备注
建议使用 vertices
或 vertex_generator
(对于射线和线也是类似的),如果希望迭代它们而不是 vertices_list
。
第2课:多面体计算的后端¶
为了处理多面体对象,Sage目前有四个可用的后端。这些后端提供各种功能,并有其特定的优势和限制。
sage.geometry.polyhedron.backend_cdd
sage.geometry.polyhedron.backend_ppl
sage.geometry.polyhedron.backend_polymake
sage.geometry.polyhedron.backend_field
这是一个
python
提供在无理坐标上实现多面体的后端。sage.geometry.polyhedron.backend_normaliz ,(需要可选程序包
pynormaliz
)
默认后端为 ppl
。任何需要的时候 speed 尝试不同的后端是很好的。后端 field
是 not 专为处理极端计算而设计,但可以在精确坐标下进行计算。
这个 cdd
后端¶
为了使用特定的后端,我们指定 backend
参数。
sage: P1_cdd = Polyhedron(vertices=[[1, 0], [0, 1]], rays=[[1, 1]], backend='cdd')
sage: P1_cdd
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
先验的,看起来什么都没有改变,但是...
sage: P1_cdd.parent()
Polyhedra in QQ^2
多面体 P1_cdd
现在被后端视为有理多面体 cdd
。我们还可以使用以下命令检查后端和父级 type
:
sage: type(P1_cdd)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category.element_class'>
sage: type(P1)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_ppl_with_category.element_class'>
我们看到了
使用的后端(例如:
backend_cdd
)后面跟一个圆点‘’
家长(例如:
Polyhedra_QQ
)之后再次是后端,
出于本教程的目的,您可以安全地忽略其余部分。
这个 cdd
后端还接受 RDF
:
sage: P3_cdd = Polyhedron(vertices=[[0.5, 0], [0, 0.5]], backend='cdd')
sage: P3_cdd
A 1-dimensional polyhedron in RDF^2 defined as the convex hull of 2 vertices
而不是代数值或符号值:
sage: P4_cdd = Polyhedron(vertices=[[sqrt_2, 0], [0, cbrt_2]], backend='cdd') # needs sage.rings.number_field
Traceback (most recent call last):
...
ValueError: No such backend (=cdd) implemented for given basering (=Algebraic Real Field).
sage: P5_cdd = Polyhedron(vertices=[[sqrt_2s, 0], [0, cbrt_2s]], backend='cdd') # needs sage.symbolic
Traceback (most recent call last):
...
ValueError: No such backend (=cdd) implemented for given basering (=Symbolic Ring).
有可能获得 cdd
上定义的任何多面体对象的格式 mathbb{Z} , mathbb{Q} ,或 RDF
:
sage: print(P1.cdd_Vrepresentation())
V-representation
begin
3 3 rational
0 1 1
1 0 1
1 1 0
end
sage: print(P3.cdd_Hrepresentation())
H-representation
linearity 1 1
begin
3 3 real
-0.5 1.0 1.0
1.0 -2.0 0.0
0.0 1.0 0.0
end
还可以使用方法将此数据写入文件 .write_cdd_Hrepresentation(filename)
或 .write_cdd_Vrepresentation(filename)
,在哪里 filename
是包含要写入的文件的路径的字符串。
这个 ppl
后端¶
多面体对象的默认后端是 ppl
。
sage: type(P1)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_ppl_with_category.element_class'>
sage: type(P2)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_ppl_with_category.element_class'>
sage: type(P3) # has entries like 0.5
<class 'sage.geometry.polyhedron.parent.Polyhedra_RDF_cdd_with_category.element_class'>
如您所见,它不接受 RDF
多面体构造函数使用 cdd
后端。
这个 polymake
后端¶
这个 polymake
安装SAGE实验包PolyMake时提供后台。
sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], # optional - jupymake
....: rays=[(1,1)], lines=[],
....: backend='polymake', base_ring=QQ)
具有二次域的示例:
sage: V = polytopes.dodecahedron().vertices_list() # needs sage.rings.number_field
sage: Polyhedron(vertices=V, backend='polymake') # optional - jupymake # needs sage.rings.number_field
A 3-dimensional polyhedron
in (Number Field in sqrt5 with defining polynomial x^2 - 5
with sqrt5 = 2.236067977499790?)^3
defined as the convex hull of 20 vertices
这个 field
后端¶
事实证明,有理数并不足以代表多面体的所有组合类型。例如,Perles构建了一个 8 -具有以下功能的维度多面体 12 没有有理坐标实现的顶点,请参见的示例6.21第172页 [Zie2007]. 此外,如果想要实现具有特定的几何属性,例如对称性,有时还需要无理坐标。
后端 field
提供了处理此类示例所需的工具。
sage: type(D) # needs sage.rings.number_field
<class 'sage.geometry.polyhedron.parent.Polyhedra_field_with_category.element_class'>
任何时候,坐标应该在有理数的扩展中,后端 field
被称为。
sage: # needs sage.rings.number_field
sage: P4.parent()
Polyhedra in AA^2
sage: P5.parent()
Polyhedra in AA^2
sage: type(P4)
<class 'sage.geometry.polyhedron.parent.Polyhedra_field_with_category.element_class'>
sage: type(P5)
<class 'sage.geometry.polyhedron.parent.Polyhedra_field_with_category.element_class'>
这个 normaliz
后端¶
第四个后端是 normaliz
并且是可选的Sage包。
sage: # optional - pynormaliz
sage: P1_normaliz = Polyhedron(vertices=[[1, 0], [0, 1]], rays=[[1, 1]],
....: backend='normaliz')
sage: type(P1_normaliz)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_normaliz_with_category.element_class'>
sage: P2_normaliz = Polyhedron(vertices=[[1/2, 0, 0], [0, 1/2, 0]],
....: rays=[[1, 1, 0]],
....: lines=[[0, 0, 1]], backend='normaliz')
sage: type(P2_normaliz)
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_normaliz_with_category.element_class'>
此后端不能与 RDF
或其他不精确的字段。
sage: P3_normaliz = Polyhedron(vertices=[[0.5, 0], [0, 0.5]], backend='normaliz') # optional - pynormaliz
Traceback (most recent call last):
...
ValueError: No such backend (=normaliz) implemented for given basering (=Real Double Field).
这个 normaliz
后端提供了使用代数数的快速计算。它们可以作为嵌入数字字段、代数数字字段甚至符号环的元素输入。在内部,使用嵌入的数字字段来完成计算。
sage: # optional - pynormaliz
sage: P4_normaliz = Polyhedron(vertices=[[sqrt_2, 0], [0, cbrt_2]],
....: backend='normaliz')
sage: P4_normaliz
A 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices
sage: P5_normaliz = Polyhedron(vertices=[[sqrt_2s, 0], [0, cbrt_2s]],
....: backend='normaliz')
sage: P5_normaliz
A 1-dimensional polyhedron in (Symbolic Ring)^2 defined as the convex hull of 2 vertices
后端 normaliz
提供其他方法,如 integral_hull
,它也适用于无界多面体。
sage: # optional - pynormaliz
sage: P6 = Polyhedron(vertices=[[0, 0], [3/2, 0], [3/2, 3/2], [0, 3]],
....: backend='normaliz')
sage: IH = P6.integral_hull(); IH
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
sage: P6.plot(color='blue') + IH.plot(color='red')
Graphics object consisting of 12 graphics primitives
sage: P1_normaliz.integral_hull()
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
第三课:对于每个多面体,适当的父类¶
为了 know all the methods that a polyhedron object has 我们必须研究它的 base class
:
sage.geometry.polyhedron.base :这是多面体相关对象的泛型类。
Base class for polyhedra over Z
Base class for polyhedra over Q
sage.geometry.polyhedron.base_RDF
如果班级看起来空荡荡的,不要感到惊讶!这些类主要包含私有方法,这些方法实现了一些比较方法:验证基环中的数的相等和不等以及其他内部函数。
要全面了解提供给您的方法, sage.geometry.polyhedron.base 是你第一个想去的地方。
第四讲:多面体的类库¶
类库里有很多现成的多面体,请参阅 sage.geometry.polyhedron.library 。看看它们是否已经定义了您的多面体!
sage: A = polytopes.buckyball(); A # can take long # needs sage.rings.number_field
A 3-dimensional polyhedron
in (Number Field in sqrt5 with defining polynomial x^2 - 5
with sqrt5 = 2.236067977499790?)^3
defined as the convex hull of 60 vertices
sage: B = polytopes.cross_polytope(4); B
A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 8 vertices
sage: C = polytopes.cyclic_polytope(3,10); C
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 10 vertices
sage: E = polytopes.snub_cube(exact=False); E
A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices
sage: polytopes.<tab> # not tested, to view all the possible polytopes