GithubHelp home page GithubHelp logo

qhull.jl's People

Contributors

blegat avatar bqi343 avatar crbinz avatar danielvandh avatar davidavdav avatar femtocleaner[bot] avatar github-actions[bot] avatar juliatagbot avatar mkborregaard avatar pnvolkmar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

qhull.jl's Issues

chull is more than an order of magnitude slower in Julia compared to Python

This Julia code consistently takes more than 5s for me:

using LinearAlgebra
using QHull

function gen_on_unit_sphere(n::Int)
    x = randn(n, 3)
    x ./ norm.(eachrow(x))
end

function benchmark(n::Int)
    points = gen_on_unit_sphere(n)
    @time hull = chull(points)
    @assert length(hull.vertices) == n
end

for trial=1:3
    benchmark(10000) # ~5-10s
end

#=
5.353007 seconds (655.40 k allocations: 22.665 MiB)
5.631815 seconds (655.37 k allocations: 22.665 MiB, 0.57% gc time)
6.718458 seconds (655.31 k allocations: 22.664 MiB)
=#

but this equivalent Python takes less than 0.5s:

#%%
import time

import numpy as np
from scipy.spatial import ConvexHull


def gen_on_unit_sphere(N):
    points = np.random.randn(int(N), 3)
    points /= np.linalg.norm(points, axis=1, keepdims=True)
    return points

def benchmark(N):
    for trial in range(10):
        points = gen_on_unit_sphere(N)
        start = time.time()
        hull = ConvexHull(points)
        end = time.time()
        assert len(hull.vertices) == N
        print(end - start) # ~ 0.1s

benchmark(10000)
"""
0.10167193412780762
0.10614609718322754
0.06934404373168945
0.132598876953125
0.4867589473724365
0.12485194206237793
0.07023811340332031
0.1384291648864746
0.1513369083404541
0.21898388862609863
"""

Any idea what could explain the difference? I'm running the Python code with the same conda env used to build the Julia package.

Can't install under 0.6.4

I am getting this error with Julia 0.6.4 under Windows 10:

julia> Pkg.add("QHull")
ERROR: unknown package QHull
macro expansion at .\pkg\entry.jl:53 [inlined]
(::Base.Pkg.Entry.##1#3{String,Base.Pkg.Types.VersionSet})() at .\task.jl:335
Stacktrace:
 [1] sync_end() at .\task.jl:287
 [2] macro expansion at .\task.jl:303 [inlined]
 [3] add(::String, ::Base.Pkg.Types.VersionSet) at .\pkg\entry.jl:51
 [4] (::Base.Pkg.Dir.##4#7{Array{Any,1},Base.Pkg.Entry.#add,Tuple{String}})() at .\pkg\dir.jl:36
 [5] cd(::Base.Pkg.Dir.##4#7{Array{Any,1},Base.Pkg.Entry.#add,Tuple{String}}, ::String) at .\file.jl:59
 [6] #cd#1(::Array{Any,1}, ::Function, ::Function, ::String, ::Vararg{String,N} where N) at .\pkg\dir.jl:36

Any ideas?

Many deprecation warnings on standard use

Running the package on Julia 1.1, I get a lot of deprecation warnings:

$ cat qhull-test.jl 

using QHull

points = rand(10, 2)
hull = chull(points)
display(hull)

$ julia qhull-test.jl 
┌ Warning: `getindex(o::PyObject, s::Symbol)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o.s` instead of `o[:s]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:34
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:34
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:35
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:35
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:36
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:36
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:38
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:38
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:42
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:42
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:43
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:43
┌ Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = chull(::Array{Float64,2}) at QHull.jl:44
└ @ QHull ~/.julia/packages/QHull/yeRSS/src/QHull.jl:44
Convex Hull of 10 points in 2 dimensions
Hull segment vertex indices:
[4, 8, 6, 3, 9]
Points on convex hull in original order:

[0.14431 0.70416; 0.874876 0.0934001; 0.561833 0.871743; 0.842075 0.889761; 0.192936 0.0327743]
$ julia --version
julia version 1.1.0

I assume that getindex methods with ::PyObject come from the function calls to the python package.
#19 might therefore fix this indirectly.

removevredundancy is very slow

After #40 is resolved, calling chull on 1000 points on the unit sphere takes less than 0.02s, but doing the same using

p = polyhedron(v, QHull.Library())
# Removing redundant points, i.e. points which are in the interior of the convex hull
removevredundancy!(p)
# Show remaining points, i.e. the non-redundant ones
@show vrep(p)
# Show the H-representation, the facets describing the polytope
@show hrep(p)

takes more than 5s due to this line taking time quadratic in the number of half-spaces just to remove duplicate half-spaces:

hnored = Polyhedra.removeduplicates(h, Polyhedra.OppositeMockOptimizer)

Is there a version of removeduplicates that runs in near-linear time?

Incorrect volume from H-rep

Still concerning the notebook of the previous issue:
Screenshot from 2019-07-12 15-14-54
Originally posted by @ferrolho in #27 (comment)

The value computed and stored for p3 is incorrect:

julia> @show volume(p1) volume(p2) volume(p3);
volume(p1) = 1.0
volume(p2) = 1.0
volume(p3) = 85.33333333333336

This is still related to the H-rep, as demonstrated by the following snippets:

julia> volume(polyhedron(hrep(p3), lib))
85.33333333333336

Constructing a new polyhedron from the V-rep yields the correct volume of the convex set:

julia> volume(polyhedron(vrep(p3), lib))
0.125

Cannot compute Chebyshev center and other operations

I am not being able to:

  • Intersect polyhedrons and get the resultant V-rep
    • e.g., vrep(intersect(p1, p2))
  • Remove H-rep redundancy
    • e.g., removehredundancy!(p1)
  • Compute the Chebyshev center
    • e.g., hchebyshevcenter(p1)

Apparently, all of the above are, at some point, calling hchebyshevcenter, and thus failing.

Here is a notebook with a MWE:
Screenshot from 2019-07-11 15-31-21
And here is the output of the solver when calling vrep(p3) with p1 and p2 having been built using QHull with KNITRO (as opposed to GLPK, in the notebook above):

=======================================
           Academic License
       (NOT FOR COMMERCIAL USE)
         Artelys Knitro 12.0.0
=======================================

Knitro presolve eliminated 0 variables and 0 constraints.

datacheck:               0
hessian_no_f:            1
The problem is identified as an LP.
Knitro changing algorithm from AUTO to 1.
Knitro changing bar_initpt from AUTO to 1.
Knitro changing bar_murule from AUTO to 4.
Knitro changing bar_penaltycons from AUTO to 0.
Knitro changing bar_penaltyrule from AUTO to 2.
Knitro changing bar_switchrule from AUTO to 2.
Knitro changing linesearch from AUTO to 1.
Knitro changing linsolver from AUTO to 2.

Problem Characteristics                                 (   Presolved)
-----------------------
Objective goal:  Maximize
Objective type:  linear
Number of variables:                                 28 (          28)
    bounded below only:                              25 (          25)
    bounded above only:                               0 (           0)
    bounded below and above:                          0 (           0)
    fixed:                                            0 (           0)
    free:                                             3 (           3)
Number of constraints:                               48 (          48)
    linear equalities:                                0 (           0)
    quadratic equalities:                             0 (           0)
    gen. nonlinear equalities:                        0 (           0)
    linear one-sided inequalities:                   48 (          48)
    quadratic one-sided inequalities:                 0 (           0)
    gen. nonlinear one-sided inequalities:            0 (           0)
    linear two-sided inequalities:                    0 (           0)
    quadratic two-sided inequalities:                 0 (           0)
    gen. nonlinear two-sided inequalities:            0 (           0)
Number of nonzeros in Jacobian:                      96 (          96)
Number of nonzeros in Hessian:                        0 (           0)

  Iter      Objective      FeasError   OptError    ||Step||    CGits 
--------  --------------  ----------  ----------  ----------  -------
       0    0.000000e+00   1.500e+00
      10   -2.956290e+00   2.956e+00   3.078e+00   5.167e+00        0
      20   -1.208565e+04   1.209e+04   2.024e+04   2.745e+04        0
      30   -3.333331e-01   3.889e-01   3.889e-01   2.167e-07        5
      40   -2.558210e+00   2.558e+00   2.558e+00   1.051e-01        0
      50   -1.891607e+02   1.892e+02   1.892e+02   1.928e+02        0
      60   -3.691123e-01   4.060e-01   4.060e-01   2.731e-01        0
      70   -3.339335e-01   3.887e-01   3.887e-01   3.753e-04        4
      79    1.323388e-10   7.500e-01   7.500e-01   1.173e-04        0

EXIT: Convergence to an infeasible point. Problem appears to be locally
      infeasible. If problem is believed to be feasible, try multistart 
      to search for feasible points, or decrease infeastol.

Final Statistics
----------------
Final objective value               =   1.32338787650762e-10
Final feasibility error (abs / rel) =   7.50e-01 / 5.00e-01
Final optimality error  (abs / rel) =   7.50e-01 / 7.50e-01
# of iterations                     =         79 
# of CG iterations                  =         45 
# of function evaluations           =          0
# of gradient evaluations           =          0
# of Hessian evaluations            =          0
Total program time (secs)           =       0.00757 (     0.008 CPU time)
Time spent in evaluations (secs)    =       0.00000

===============================================================================

Solver returned LOCALLY_INFEASIBLE when computing the H-Chebyshev center.

Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] hchebyshevcenter(::MixedMatHRep{Float64,Array{Float64,2}}, ::OptimizerFactory) at /home/henrique/.julia/dev/Polyhedra/src/center.jl:35
 [3] chebyshevcenter at /home/henrique/.julia/dev/Polyhedra/src/center.jl:74 [inlined]
 [4] qhull(::MixedMatHRep{Float64,Array{Float64,2}}, ::OptimizerFactory) at /home/henrique/.julia/packages/QHull/kgHQK/src/polyhedron.jl:101
 [5] qhull(::QHull.Polyhedron, ::Symbol) at /home/henrique/.julia/packages/QHull/kgHQK/src/polyhedron.jl:70
 [6] qhull(::QHull.Polyhedron) at /home/henrique/.julia/packages/QHull/kgHQK/src/polyhedron.jl:61
 [7] getext at /home/henrique/.julia/packages/QHull/kgHQK/src/polyhedron.jl:165 [inlined]
 [8] vrep(::QHull.Polyhedron) at /home/henrique/.julia/packages/QHull/kgHQK/src/polyhedron.jl:209
 [9] top-level scope at In[36]:1

ArgumentError: ref of NULL PyObject

julia> using QHull, Polyhedra

julia> v = vrep([x y])
V-representation MixedMatVRep{Float64, Matrix{Float64}}:
4-element iterator of Vector{Float64}:
 [0.0, 0.0]
 [0.0, 1.0]
 [1.0, 0.0]
 [0.1, 0.1]

julia> p = polyhedron(v, QHull.Library())
Polyhedron QHull.Polyhedron:
4-element iterator of Vector{Float64}:
 [0.0, 0.0]
 [0.0, 1.0]
 [1.0, 0.0]
 [0.1, 0.1]

julia> removevredundancy!(p)
ERROR: ArgumentError: ref of NULL PyObject
Stacktrace:
 [1] _getproperty
   @ ~/.julia/packages/PyCall/BD546/src/PyCall.jl:299 [inlined]
 [2] __getproperty(o::PyCall.PyObject, s::Symbol)
   @ PyCall ~/.julia/packages/PyCall/BD546/src/PyCall.jl:306
 [3] getproperty
   @ ~/.julia/packages/PyCall/BD546/src/PyCall.jl:312 [inlined]
 [4] chull(x::Matrix{Float64})
   @ QHull ~/.julia/packages/QHull/iY1Yu/src/QHull.jl:34
 [5] qhull(h::MixedMatVRep{Float64, Matrix{Float64}}, solver::Nothing)
   @ QHull ~/.julia/packages/QHull/iY1Yu/src/polyhedron.jl:84
 [6] qhull(p::QHull.Polyhedron, rep::Symbol)
   @ QHull ~/.julia/packages/QHull/iY1Yu/src/polyhedron.jl:62
 [7] removevredundancy!(p::QHull.Polyhedron)
   @ QHull ~/.julia/packages/QHull/iY1Yu/src/polyhedron.jl:202
 [8] top-level scope
   @ REPL[34]:1

QHull prevent install StaticArrays version 1.0 or higher

Start an clean enviroment with only QHull

(julia) pkg> st
      Status `~/sandbox/julia/Project.toml`
  [a8468747] QHull v0.2.1

Then try to add StaticArrays

(julia) pkg> add StaticArrays
   Resolving package versions...
    Updating `~/sandbox/julia/Project.toml`
  [90137ffa] + StaticArrays v0.12.5
  No Changes to `~/sandbox/julia/Manifest.toml`

It can be seen that StaticArrays version 0.12.5 is installed by default.

Try to add StaticArrays current version will fail as

(julia) pkg> add [email protected]
   Resolving package versions...
ERROR: Unsatisfiable requirements detected for package StaticArrays [90137ffa]:
 StaticArrays [90137ffa] log:
 ├─possible versions are: 0.8.0-1.2.13 or uninstalled
 ├─restricted to versions 1.2.13 by an explicit requirement, leaving only versions 1.2.13
 └─restricted by compatibility requirements with QHull [a8468747] to versions: 0.8.0-0.12.5 — no versions left
   └─QHull [a8468747] log:
     ├─possible versions are: 0.0.1-0.2.1 or uninstalled
     └─restricted to versions * by an explicit requirement, leaving only versions 0.0.1-0.2.1

Default solver missing

For a polyhedron p using QHull.Library(), the following line of code returns Nothing:

julia> typeof(Polyhedra.default_solver(p))
Nothing

I am not entirely sure this is the root cause of the issue, but look at the following notebook showing MethodError: no method matching Model(::Nothing) when a V-rep is requested from a H-rep:

Screenshot from 2019-07-11 15-31-21

Switch to QHull directly?

Hey there,

I use this in one of my packages and this dependency makes a little bit trouble during the installation / first use. On two of my colleagues systems (both Linux) I had to update the scipy version to get this working since Julia choose their global Python toolchain.
To avoid these kinds of problems, maybe we should instead wrap qhull directly? Or do you have other ideas to get the installation process more stable?

Why not Qhull.jl ?

I was just wondering, wouldn't the name Qhull.jl be more helpful for this package since it is a wrapper for the Qhull library ?

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.