-
Notifications
You must be signed in to change notification settings - Fork 126
/
constructors.jl
164 lines (134 loc) · 7.57 KB
/
constructors.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
###############################################################################
###############################################################################
### Definition and constructors
###############################################################################
###############################################################################
# We introduce this abstract (hidden) type to allow for other objects to be
# used like polyhedral fans without duplicating too much code, concretely we
# want to be able to directly access rays, maximal_cones, etc for
# NormalToricVariety's.
abstract type _FanLikeType{T} <: PolyhedralObject{T} end
struct PolyhedralFan{T} <:_FanLikeType{T}
pm_fan::Polymake.BigObject
parent_field::Field
PolyhedralFan{T}(pm::Polymake.BigObject, f::Field) where T<:scalar_types = new{T}(pm, f)
PolyhedralFan{QQFieldElem}(pm::Polymake.BigObject) = new{QQFieldElem}(pm, QQ)
end
# Automatic detection of corresponding OSCAR scalar type;
# Avoid, if possible, to increase type stability
function polyhedral_fan(p::Polymake.BigObject)
T, f = _detect_scalar_and_field(PolyhedralFan, p)
return PolyhedralFan{T}(p, f)
end
@doc raw"""
polyhedral_fan(T, Rays::AbstractCollection[RayVector], LS::Union{AbstractCollection[RayVector], Nothing}, Incidence::IncidenceMatrix) where T<:scalar_types
Assemble a polyhedral fan from ray generators, lineality generators, and an
`IncidenceMatrix` indicating which rays form a cone.
# Arguments
- `T`: `Type` or parent `Field` of scalar to use, defaults to `QQFieldElem`.
- `Rays::AbstractCollection[RayVector]`: Rays generating the cones of the fan;
encoded row-wise as representative vectors.
- `LS::AbstractCollection[RayVector]`: Contains row-wise generators of the
lineality space of the fan. (optional argument)
- `Cones::IncidenceMatrix`: An incidence matrix; there is a 1 at position (i,j)
if cone i has ray j as extremal ray, and 0 otherwise.
# Examples
To obtain the upper half-space of the plane:
```jldoctest
julia> R = [1 0; 1 1; 0 1; -1 0; 0 -1];
julia> IM=IncidenceMatrix([[1,2],[2,3],[3,4],[4,5],[1,5]]);
julia> PF=polyhedral_fan(R,IM)
Polyhedral fan in ambient dimension 2
```
Polyhedral fan with lineality space:
```jldoctest
julia> R = [1 0 0; 0 0 1];
julia> L = [0 1 0];
julia> IM = IncidenceMatrix([[1],[2]]);
julia> PF=polyhedral_fan(R, L, IM)
Polyhedral fan in ambient dimension 3
julia> lineality_dim(PF)
1
```
"""
function polyhedral_fan(f::Union{Type{T}, Field},
Rays::AbstractCollection[RayVector],
LS::Union{AbstractCollection[RayVector], Nothing},
Incidence::IncidenceMatrix;
non_redundant::Bool = false) where T<:scalar_types
parent_field, scalar_type = _determine_parent_and_scalar(f, Rays, LS)
RM = unhomogenized_matrix(Rays)
if isnothing(LS)
LM = Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(RM, 2))
else
LM = unhomogenized_matrix(LS)
end
if non_redundant
return PolyhedralFan{scalar_type}(Polymake.fan.PolyhedralFan{_scalar_type_to_polymake(scalar_type)}(
RAYS = RM,
LINEALITY_SPACE = LM,
MAXIMAL_CONES = Incidence,
), parent_field)
else
return PolyhedralFan{scalar_type}(Polymake.fan.PolyhedralFan{_scalar_type_to_polymake(scalar_type)}(
INPUT_RAYS = RM,
INPUT_LINEALITY = LM,
INPUT_CONES = Incidence,
), parent_field)
end
end
polyhedral_fan(f::Union{Type{T}, Field}, Rays::AbstractCollection[RayVector], Incidence::IncidenceMatrix; non_redundant::Bool = false) where T<:scalar_types = polyhedral_fan(f, Rays, nothing, Incidence; non_redundant=non_redundant)
polyhedral_fan(Rays::AbstractCollection[RayVector], LS::Union{AbstractCollection[RayVector], Nothing}, Incidence::IncidenceMatrix; non_redundant::Bool = false) = polyhedral_fan(QQFieldElem, Rays, LS, Incidence; non_redundant = non_redundant)
polyhedral_fan(Rays::AbstractCollection[RayVector], Incidence::IncidenceMatrix; non_redundant::Bool = false) = polyhedral_fan(QQFieldElem, Rays, Incidence; non_redundant = non_redundant)
"""
pm_object(PF::PolyhedralFan)
Get the underlying polymake object, which can be used via Polymake.jl.
"""
pm_object(PF::PolyhedralFan) = PF.pm_fan
polyhedral_fan(itr::AbstractVector{Cone{T}}) where T<:scalar_types = PolyhedralFan{T}(Polymake.fan.check_fan_objects(pm_object.(itr)...), coefficient_field(iterate(itr)[1]))
#Same construction for when the user gives Matrix{Bool} as incidence matrix
polyhedral_fan(f::Union{Type{T}, Field}, Rays::AbstractCollection[RayVector], LS::AbstractCollection[RayVector], Incidence::Matrix{Bool}) where T<:scalar_types =
polyhedral_fan(f, Rays, LS, IncidenceMatrix(Polymake.IncidenceMatrix(Incidence)))
polyhedral_fan(f::Union{Type{T}, Field}, Rays::AbstractCollection[RayVector], Incidence::Matrix{Bool}) where T<:scalar_types =
polyhedral_fan(f, Rays, IncidenceMatrix(Polymake.IncidenceMatrix(Incidence)))
function polyhedral_fan(C::Cone{T}) where T<:scalar_types
pmfan = Polymake.fan.check_fan_objects(pm_object(C))
return PolyhedralFan{T}(pmfan, coefficient_field(C))
end
###############################################################################
###############################################################################
### From group action on maximal cones
###############################################################################
###############################################################################
@doc raw"""
polyhedral_fan_from_rays_action([::Union{Type{T}, Field} = QQFieldElem,] Rays::AbstractCollection[RayVector], MC_reps::IncidenceMatrix, perms::AbstractVector{PermGroupElem}) where T<:scalar_types
Construct a polyhedral fan with a group action.
# Arguments
- The first argument either specifies the `Type` of its coefficients or their
parent `Field`.
- `Rays`: The rays of the fan
- `MC_reps`: `IncidenceMatrix` whose rows give the indices of the rays forming
representatives of the maximal cones under the group action.
- `perms`: A vector of permutations `PermGroupElem` that form generators of the
group acting on the rays of the fan.
"""
function polyhedral_fan_from_rays_action(f::Union{Type{T}, Field}, Rays::AbstractCollection[RayVector], MC_reps::IncidenceMatrix, perms::AbstractVector{PermGroupElem}) where T<:scalar_types
parent_field, scalar_type = _determine_parent_and_scalar(f, Rays)
pf = Polymake.fan.PolyhedralFan{_scalar_type_to_polymake(scalar_type)}()
Polymake.take(pf, "RAYS", Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(unhomogenized_matrix(Rays)))
d = length(Rays)
gp = _group_generators_to_pm_arr_arr(perms, d)
Polymake.take(pf, "GROUP.RAYS_ACTION.GENERATORS", gp)
Polymake.take(pf, "GROUP.MAXIMAL_CONES_ACTION.MAXIMAL_CONES_GENERATORS", MC_reps)
return PolyhedralFan{scalar_type}(pf, parent_field)
end
polyhedral_fan_from_rays_action(Rays::AbstractCollection[RayVector], MC_reps::IncidenceMatrix, perms::AbstractVector{PermGroupElem}) = polyhedral_fan_from_rays_action(QQFieldElem, Rays, MC_reps, perms)
###############################################################################
###############################################################################
### Display
###############################################################################
###############################################################################
function Base.show(io::IO, PF::PolyhedralFan{T}) where T<:scalar_types
print(io, "Polyhedral fan in ambient dimension $(ambient_dim(PF))")
T != QQFieldElem && print(io, " with $T type coefficients")
end