SAGE中关于多面体计算的较长介绍

本教程旨在展示Sage在多面体几何和组合学方面的一些可能性。

关于这一主题的经典文献包括:

  • Convex Polytopes 、布兰科·格伦鲍姆, [Gru1967]

  • An Introduction to Convex Polytopes 、阿恩·布朗斯特德, [Bro1983]

  • Lectures on Polytopes ,Günter M.Ziegler, [Zie2007]

对于命名法,Sage试图遵循以下原则:

  • Handbook of Discrete and Computational Geometry ,第15章, [Goo2004]

本文件的编写部分得到了OpenDreamKit项目的支持,并在Olot(西班牙)举行的SageDays 84期间编写。

第0课:基本定义和结构

一个真正的 (ktimes d) -矩阵 A 和一个实数向量 b 在……里面 mathbb{R}^d 定义一个(凸) polyhedron P 作为线性不等式组的解的集合:

\[A\cot x+b\geq 0。\]

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 在多面体内部作为组合

\[p = \ell +\sum_{i=1}^{n}\lambda_iv_i+\sum_{i=1}^{m}\mu_ir_i,\]

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)

备注

建议使用 equationsequation_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]

备注

建议使用 verticesvertex_generator (对于射线和线也是类似的),如果希望迭代它们而不是 vertices_list

第2课:多面体计算的后端

为了处理多面体对象,Sage目前有四个可用的后端。这些后端提供各种功能,并有其特定的优势和限制。

默认后端为 ppl 。任何需要的时候 speed 尝试不同的后端是很好的。后端 fieldnot 专为处理极端计算而设计,但可以在精确坐标下进行计算。

这个 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

目录学

[Bro1983]

《凸多面体导论》,《数学研究生课本》第90卷。斯普林格-维拉格,纽约,1983年。ISBN 978-1-4612-7023-2

[Goo2004]

J.E.Goodman和J.O‘Rourke,编辑,CRC Press LLC,Boca Raton,FL,2004。ISBN978-1584883012(65章+1539页)。

[Gru1967]

[B·Grünbaum,凸多面体,数学研究生课本,第221卷]。斯普林格-维拉格,纽约,2003年。ISBN 978-1-4613-0019-9

[Zie2007] (1,2)

齐格勒,《多面体讲义》,《数学研究生课本》第152卷。施普林格-维拉格,纽约,2007年。ISBN978-0-387-94365-7