Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PolyhedralGeometry: Format most of the files #3591

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ran JuliaFormatter on most of src/PolyhedralGeometry
ab444bbc46b5493588b2c3217ed35d86396d1260
30 changes: 30 additions & 0 deletions .github/workflows/JuliaFormatterCI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: JuliaFormatter test

on:
push:
branches:
- master
- 'release-*'
pull_request:
workflow_dispatch:

concurrency:
# group by workflow and ref; the last slightly strange component ensures that for pull
# requests, we limit to 1 concurrent job, but for the master branch we don't
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.run_number }}
# Cancel intermediate builds, but only if it is a pull request build.
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}

jobs:
check-consistent-formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
- uses: julia-actions/cache@v1
- name: 'Check format with JuliaFormatter'
run: |
julia etc/test_formatting.jl
shell: bash
env:
jf-version: ${{ inputs.version }}
107 changes: 107 additions & 0 deletions etc/test_formatting.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using Pkg
Pkg.activate(temp=true)
Pkg.add("Test")
Pkg.add("JuliaFormatter")
using Test
using JuliaFormatter

# Disclaimer:
# The goal should be to work with
# https://github.com/julia-actions/julia-format
# . However, currently too many files have broken formatting and since there
# are many ongoing pull requests, we will need to extend proper formatting to
# the entire codebase in a step by step fashion.
#
# In case you format some code, also add the commit hash to
# .git-blame-ignore-revs for `git blame` to ignore these commits.


file = @__FILE__
oscardir = replace(file, "etc/test_formatting.jl"=>"")

result = 0

@testset "Formatting" begin

function _gather_source_files(path::String)
queue = [path]
result = String[]
while length(queue) > 0
current_folder = pop!(queue)
next_batch = readdir(current_folder; join=true)
for elem in next_batch
if isfile(elem) && endswith(elem, ".jl")
push!(result, elem)
elseif isdir(elem)
push!(queue, elem)
end
end
end
return result
end

# Since right now only very few files are formatted, we also use a whitelist
# approach.
enabled = [
"src/PolyhedralGeometry",
"src/aliases.jl",
"experimental/LieAlgebras",
"experimental/BasisLieHighestWeight",
]
skip = [
"src/PolyhedralGeometry/Polyhedron/standard_constructions.jl",
"src/PolyhedralGeometry/Polyhedron/properties.jl",
"experimental/LieAlgebras/test/AbstractLieAlgebra-test.jl",
"experimental/LieAlgebras/test/LieAlgebraModule-test.jl",
"experimental/LieAlgebras/src/LieAlgebra.jl",
"experimental/LieAlgebras/src/LieAlgebraHom.jl",
"experimental/LieAlgebras/src/LieSubalgebra.jl",
"experimental/LieAlgebras/src/LinearLieAlgebra.jl",
"experimental/LieAlgebras/src/RootSystem.jl",
"experimental/LieAlgebras/src/Util.jl",
"experimental/BasisLieHighestWeight/src/MainAlgorithm.jl",
]

# Collect all code files.
entire = [
_gather_source_files(joinpath(oscardir, "src/"));
lkastner marked this conversation as resolved.
Show resolved Hide resolved
_gather_source_files(joinpath(oscardir, "experimental/"))
]

failed = String[]

for file in entire
is_enabled = !isnothing(findfirst(e->occursin(e, file), enabled))
should_skip = !isnothing(findfirst(e->occursin(e, file), skip))
if is_enabled && !should_skip
# Do not actually format file, only check whether format is ok.
res = @test format(file; overwrite=false)
if res isa Test.Fail
result = 1
filename = replace(file, oscardir=>"")
push!(failed, filename)
else
filename = replace(file, oscardir=>"")
end
else
@test format(file; overwrite=false) skip=true
end
end

# Produce some nice output at the end so users do not have to scroll through
# entire output.
if length(failed) > 0
println("""
The files
$failed
were not properly formatted. You can fix the formatting by running
```
using JuliaFormatter""")
for fn in failed
println("format(\"$fn\")")
end
println("```\n")
end
end

exit(result)
110 changes: 80 additions & 30 deletions src/PolyhedralGeometry/Cone/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
#interior description?

struct Cone{T} <: PolyhedralObject{T} #a real polymake polyhedron
pm_cone::Polymake.BigObject
parent_field::Field
# only allowing scalar_types;
# can be improved by testing if the template type of the `BigObject` corresponds to `T`
Cone{T}(c::Polymake.BigObject, f::Field) where T<:scalar_types = new{T}(c, f)
Cone{QQFieldElem}(c::Polymake.BigObject) = new{QQFieldElem}(c, QQ)
pm_cone::Polymake.BigObject
parent_field::Field

# only allowing scalar_types;
# can be improved by testing if the template type of the `BigObject` corresponds to `T`
Cone{T}(c::Polymake.BigObject, f::Field) where {T<:scalar_types} = new{T}(c, f)
Cone{QQFieldElem}(c::Polymake.BigObject) = new{QQFieldElem}(c, QQ)
end

# default scalar type: `QQFieldElem`
Expand All @@ -23,8 +23,8 @@
# Automatic detection of corresponding OSCAR scalar type;
# Avoid, if possible, to increase type stability
function cone(p::Polymake.BigObject)
T, f = _detect_scalar_and_field(Cone, p)
return Cone{T}(p, f)
T, f = _detect_scalar_and_field(Cone, p)
return Cone{T}(p, f)
end

@doc raw"""
Expand Down Expand Up @@ -62,36 +62,63 @@
Polyhedral cone in ambient dimension 2
```
"""
function positive_hull(f::scalar_type_or_field, R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false)
function positive_hull(
f::scalar_type_or_field,
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, R, L)
inputrays = remove_zero_rows(unhomogenized_matrix(R))
if isnothing(L) || isempty(L)
L = Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, _ambient_dim(R))
end

if non_redundant
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(RAYS = inputrays, LINEALITY_SPACE = unhomogenized_matrix(L),), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
RAYS=inputrays, LINEALITY_SPACE=unhomogenized_matrix(L)
),
parent_field,
)
else
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(INPUT_RAYS = inputrays, INPUT_LINEALITY = unhomogenized_matrix(L),), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
INPUT_RAYS=inputrays, INPUT_LINEALITY=unhomogenized_matrix(L)
),
parent_field,
)
end
end
# Redirect everything to the above constructor, use QQFieldElem as default for the
# scalar type T.
positive_hull(R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(f::scalar_type_or_field, R::AbstractCollection[RayVector], L::Union{AbstractCollection[RayVector], Nothing} = nothing; non_redundant::Bool = false) = positive_hull(f, R, L; non_redundant=non_redundant)
positive_hull(
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(_guess_fieldelem_type(R, L), R, L; non_redundant=non_redundant)
cone(

Check warning on line 105 in src/PolyhedralGeometry/Cone/constructors.jl

View check run for this annotation

Codecov / codecov/patch

src/PolyhedralGeometry/Cone/constructors.jl#L105

Added line #L105 was not covered by tests
f::scalar_type_or_field,
R::AbstractCollection[RayVector],
L::Union{AbstractCollection[RayVector],Nothing}=nothing;
non_redundant::Bool=false,
) = positive_hull(f, R, L; non_redundant=non_redundant)
cone(f::scalar_type_or_field, x...) = positive_hull(f, x...)


function ==(C0::Cone{T}, C1::Cone{T}) where T<:scalar_types
return Polymake.polytope.equal_polyhedra(pm_object(C0), pm_object(C1))::Bool
function ==(C0::Cone{T}, C1::Cone{T}) where {T<:scalar_types}
return Polymake.polytope.equal_polyhedra(pm_object(C0), pm_object(C1))::Bool
end

# For a proper hash function for cones we should use a "normal form",
# which would require a potentially expensive convex hull computation
# (and even that is not enough). But hash methods should be fast, so we
# just consider the ambient dimension and the precise type of the cone.
function Base.hash(x::T, h::UInt) where {T <: Cone}
function Base.hash(x::T, h::UInt) where {T<:Cone}
h = hash(ambient_dim(x), h)
h = hash(T, h)
return h
Expand Down Expand Up @@ -120,15 +147,34 @@
[1, 1]
```
"""
function cone_from_inequalities(f::scalar_type_or_field, I::AbstractCollection[LinearHalfspace], E::Union{Nothing, AbstractCollection[LinearHyperplane]} = nothing; non_redundant::Bool = false)
function cone_from_inequalities(
f::scalar_type_or_field,
I::AbstractCollection[LinearHalfspace],
E::Union{Nothing,AbstractCollection[LinearHyperplane]}=nothing;
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, I, E)
IM = -linear_matrix_for_polymake(I)
EM = isnothing(E) || isempty(E) ? Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(IM, 2)) : linear_matrix_for_polymake(E)
EM = if isnothing(E) || isempty(E)
Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(IM, 2))
else
linear_matrix_for_polymake(E)
end

if non_redundant
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(FACETS = IM, LINEAR_SPAN = EM), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
FACETS=IM, LINEAR_SPAN=EM
),
parent_field,
)
else
return Cone{scalar_type}(Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(INEQUALITIES = IM, EQUATIONS = EM), parent_field)
return Cone{scalar_type}(
Polymake.polytope.Cone{_scalar_type_to_polymake(scalar_type)}(;
INEQUALITIES=IM, EQUATIONS=EM
),
parent_field,
)
end
end

Expand Down Expand Up @@ -157,16 +203,21 @@
1
```
"""
function cone_from_equations(f::scalar_type_or_field, E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false)
function cone_from_equations(
f::scalar_type_or_field,
E::AbstractCollection[LinearHyperplane];
non_redundant::Bool=false,
)
parent_field, scalar_type = _determine_parent_and_scalar(f, E)
EM = linear_matrix_for_polymake(E)
IM = Polymake.Matrix{_scalar_type_to_polymake(scalar_type)}(undef, 0, size(EM, 2))
return cone_from_inequalities(f, IM, EM; non_redundant = non_redundant)
return cone_from_inequalities(f, IM, EM; non_redundant=non_redundant)
end

cone_from_inequalities(x...) = cone_from_inequalities(QQFieldElem, x...)

cone_from_equations(E::AbstractCollection[LinearHyperplane]; non_redundant::Bool = false) = cone_from_equations(_guess_fieldelem_type(E), E; non_redundant = non_redundant)
cone_from_equations(E::AbstractCollection[LinearHyperplane]; non_redundant::Bool=false) =
cone_from_equations(_guess_fieldelem_type(E), E; non_redundant=non_redundant)

"""
pm_object(C::Cone)
Expand All @@ -175,16 +226,15 @@
"""
pm_object(C::Cone) = C.pm_cone


###############################################################################
###############################################################################
### Display
###############################################################################
###############################################################################

function Base.show(io::IO, C::Cone{T}) where T<:scalar_types
print(io, "Polyhedral cone in ambient dimension $(ambient_dim(C))")
T != QQFieldElem && print(io, " with $T type coefficients")
function Base.show(io::IO, C::Cone{T}) where {T<:scalar_types}
print(io, "Polyhedral cone in ambient dimension $(ambient_dim(C))")
T != QQFieldElem && print(io, " with $T type coefficients")
end

Polymake.visual(C::Cone; opts...) = Polymake.visual(pm_object(C); opts...)
11 changes: 6 additions & 5 deletions src/PolyhedralGeometry/Cone/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -645,11 +645,12 @@
T::Type{PointVector{ZZRingElem}}, C::Cone{QQFieldElem}, i::Base.Integer
) = point_vector(ZZ, view(pm_object(C).HILBERT_BASIS_GENERATORS[1], i, :))::T

_generator_matrix(::Val{_hilbert_generator}, C::Cone; homogenized=false) = if homogenized
homogenize(pm_object(C).HILBERT_BASIS_GENERATORS[1], 0)
else
pm_object(C).HILBERT_BASIS_GENERATORS[1]
end
_generator_matrix(::Val{_hilbert_generator}, C::Cone; homogenized=false) =
if homogenized
homogenize(pm_object(C).HILBERT_BASIS_GENERATORS[1], 0)

Check warning on line 650 in src/PolyhedralGeometry/Cone/properties.jl

View check run for this annotation

Codecov / codecov/patch

src/PolyhedralGeometry/Cone/properties.jl#L650

Added line #L650 was not covered by tests
else
pm_object(C).HILBERT_BASIS_GENERATORS[1]
end

_matrix_for_polymake(::Val{_hilbert_generator}) = _generator_matrix

Expand Down
Loading
Loading