{"id":22862794,"url":"https://github.com/bqi343/innerproductmax.jl","last_synced_at":"2025-09-14T18:34:59.932Z","repository":{"id":265869208,"uuid":"617304994","full_name":"bqi343/InnerProductMax.jl","owner":"bqi343","description":"Data structures supporting fast maximum inner product queries in three dimensions. Final Project for MIT 6.8410 (Shape Analysis).","archived":false,"fork":false,"pushed_at":"2023-04-01T21:45:07.000Z","size":27619,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T07:49:52.082Z","etag":null,"topics":["julia"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bqi343.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-22T05:30:06.000Z","updated_at":"2023-03-30T18:22:31.000Z","dependencies_parsed_at":"2024-12-01T09:48:38.788Z","dependency_job_id":"18387c6e-e2fb-4c5c-9a17-32569f7a3866","html_url":"https://github.com/bqi343/InnerProductMax.jl","commit_stats":null,"previous_names":["bqi343/innerproductmax.jl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bqi343%2FInnerProductMax.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bqi343%2FInnerProductMax.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bqi343%2FInnerProductMax.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bqi343%2FInnerProductMax.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bqi343","download_url":"https://codeload.github.com/bqi343/InnerProductMax.jl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246443525,"owners_count":20778247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["julia"],"created_at":"2024-12-13T10:15:09.199Z","updated_at":"2025-03-31T08:46:59.677Z","avatar_url":"https://github.com/bqi343.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inner Product Maximization in 3 Dimensions\n\n## About\n\nFour different data structures solving [this task](https://cstheory.stackexchange.com/questions/34503/maximizing-inner-product) with $d=3$.\n\n## Usage\n\n### Basic Usage\n\n```julia\nusing GeometryBasics, InnerProductMax # this may take a while ...\nconst T = Float64\nconst P3 = Point3{T}\n\npoint_set = tetrahedron(T) # initialize a non-degenerate 3xn point set\ndisplay(point_set) # 3x5\nhull = Hull(point_set) # construct 3D hull\nds = InnerProductMaxMine{T, PointLocationDsTreap}(hull) # initialize inner product maximization data structure\ndisplay(query_all(ds, vec_to_matrix(P3[P3(3, 1, 2), P3(-3, -1, -2)]))) # query max vector\n# 3×2 Matrix{Float64}:\n#  1.0  0.0\n#  0.0  0.0\n#  1.0  0.0\n```\n\n### Interactive Plot\n\nThis should open in a separate window after a while.\n\n```julia\nusing InnerProductMax\n\nconst T = Float64\n# point_set = tetrahedron(T)\npoint_set = unit_sphere(T, 10)\n# plot_3d_hull_interactive(InnerProductMaxMine{T, PointLocationDsTreap}, point_set)\nplot_point_location_interactive(InnerProductMaxMine{T, PointLocationDsTreap}, point_set) \n```\n\n`plot_3d_hull_interactive` displays only the polyhedron, whereas `plot_point_location_interactive` displays both the polyhedron and the planar subdivision (available when `InnerProductMaxMine` is used).\n\n![](assets/vis_iprod1.png)\n\n![](assets/vis_iprod2.png)\n\n#### Troubleshooting\n\nIf you're having trouble seeing the plots or want a sanity check that `GLMakie` is working, try running the following code (e.g., by starting Julia from the Mac Terminal app and pasting in the lines):\n\n```julia\n# source: https://github.com/MakieOrg/Makie.jl/issues/797\nusing GLMakie\n\nxy = rand(Point2f, 10)\ncolors = rand(10)\npoints_node = Observable(xy)\nscene = scatter(points_node, color=colors)\n```\n\nExpected Output:\n\n![](assets/scatter.png)\n\n### Subclasses of `AbstractInnerProductMax{T}`\n\nListed from best to worst complexity.\n\n| Subclass                                      | Preprocessing Time | Preprocessing Memory | Query Time  |\n| --------------------------------------------- | ------------------ | -------------------- | ----------- |\n| InnerProductMaxNaive{T}                       | $O(N)$             | $O(N)$               | $O(N)$      |\n| InnerProductMaxMine{T,PointLocationDsTreap}   | $O(N\\log N)$       | $O(N\\log N)$         | $O(\\log N)$ |\n| InnerProductMaxMine{T,PointLocationDsRB}      | $O(N\\log N)$       | $O(N)$               | $O(\\log N)$ |\n| InnerProductMaxNested{T}                      | $O(N)$             | $O(N)$               | $O(\\log N)$ |\n \nIn practice, for a hull of size $N\\approx 10^5$, `InnerProductMaxMine{T,PointLocationDsTreap}` is the fastest in terms of query time, while `InnerProductMaxMine{T,PointLocationDsRB}` has slightly lower preprocessing time and memory but slightly larger query time.\n\n## Dev Instructions\n\nAdd these to `startup.jl`: `using Revise, ReTest, TestEnv`. Run these commands from the repo root to execute all tests:\n\n```\njulia --project\nTestEnv.activate() do \n       include(\"test/InnerProductMaxTests.jl\"); retest()\nend\n```\n\n## Performance Tests \n\n```\ninclude(\"test/InnerProductMaxTests.jl\"); retest(\"sphere_perf\")\n```\n\nResults:\n\n```\n         N       Q Method  Preproc Time (s)  Preproc Memory (MB)  Query Time (s)\n0     1000    1000  Naive          0.000017             0.088208        0.002308\n1     1000    1000   Mine          0.010655             8.234688        0.003923\n2     2000    2000  Naive          0.000092             0.176208        0.008973\n3     2000    2000   Mine          0.023383            17.890672        0.003160\n4     5000    5000  Naive          0.000276             0.440208        0.046815\n5     5000    5000   Mine          0.081375            48.884608        0.017122\n6    10000   10000  Naive          0.000646             0.880208        0.204886\n7    10000   10000   Mine          0.321766           102.224256        0.022775\n8    20000   20000  Naive          0.001080             1.760208        0.712584\n9    20000   20000   Mine          0.370499           210.870496        0.056952\n10   50000   50000  Naive          0.003199             4.400208        4.347602\n11   50000   50000   Mine          0.841139           562.539104        0.189053\n12  100000  100000  Naive          0.008528             8.800208       29.408380\n13  100000  100000   Mine          4.712876          1162.170496        0.430899\n```\n\nRed-black tree (memory is worse for some reason ...)\n\n```\n       N      Q                                             Method  Preproc Time (s)  Preproc Memory (MB)  Query Time (s)\n0   1000   1000                                     Naive{Float64}          0.000030             0.088208        0.001731\n1   1000   1000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.836934            30.685142        0.002265\n2   2000   2000                                     Naive{Float64}          0.000093             0.176208        0.008567\n3   2000   2000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.127989            43.213336        0.005933\n4   5000   5000                                     Naive{Float64}          0.000293             0.440208        0.057106\n5   5000   5000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.294365           111.242704        0.017334\n6  10000  10000                                     Naive{Float64}          0.000544             0.880208        0.184570\n7  10000  10000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.903501           233.486320        0.099521\n8  20000  20000                                     Naive{Float64}          0.008901             1.760208        0.722730\n9  20000  20000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          1.334035           482.795608        0.110320\n```\n\nAfter some optimization:\n\n```\n         N       Q                                             Method  Preproc Time (s)  Preproc Memory (MB)  Query Time (s)\n0     1000    1000                                     Naive{Float64}          0.000018             0.088208        0.002407\n1     1000    1000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.036450             7.696784        0.001469\n2     2000    2000                                     Naive{Float64}          0.000068             0.176208        0.007784\n3     2000    2000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.169119            16.005184        0.017737\n4     5000    5000                                     Naive{Float64}          0.000295             0.440208        0.060403\n5     5000    5000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.166669            40.568920        0.011874\n6    10000   10000                                     Naive{Float64}          0.000654             0.880208        0.208089\n7    10000   10000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.263313            84.020904        0.019850\n8    20000   20000                                     Naive{Float64}          0.000946             1.760208        0.854989\n9    20000   20000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.612379           161.643320        0.054820\n10   50000   50000                                     Naive{Float64}          0.003221             4.400208        4.820060\n11   50000   50000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          1.845995           408.716920        0.180039\n12  100000  100000                                     Naive{Float64}          0.007666             8.800208       21.956377\n13  100000  100000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          4.109249           820.536728        1.290055\n```\n\nPreprocessing time and memory are only slightly less than for treap. Perhaps the constant factor can be improved with more effort.\n\nNote: We can significantly reduce the constant factor for queries using an optimization suggested in the paper.\n\n```\n         N       Q                                             Method  Preproc Time (s)  Preproc Memory (MB)  Query Time (s)\n0     1000    1000                                     Naive{Float64}          0.000040             0.088208        0.001708\n1     1000    1000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.030870             7.476016        0.001962\n2     2000    2000                                     Naive{Float64}          0.000072             0.176208        0.008648\n3     2000    2000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.062812            15.480224        0.002720\n4     5000    5000                                     Naive{Float64}          0.000287             0.440208        0.053640\n5     5000    5000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.308152            39.286704        0.011566\n6    10000   10000                                     Naive{Float64}          0.000798             0.880208        0.240438\n7    10000   10000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          0.362468            81.181088        0.023628\n8    20000   20000                                     Naive{Float64}          0.001247             1.760208        0.788075\n9    20000   20000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          1.196662           156.532464        0.172948\n10   50000   50000                                     Naive{Float64}          0.002310             4.400208        5.471993\n11   50000   50000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          2.251654           395.703808        0.237956\n12  100000  100000                                     Naive{Float64}          0.001890             8.800208       21.455233\n13  100000  100000  Mine{Float64, InnerProductMax.PLRB.PointLocati...          3.934218           793.702672        0.554677\n```\n\nLevel Nesting:\n\n```\n       N      Q           Method  Preproc Time (s)  Preproc Memory (MB)  Query Time (s)\n0   1000   1000   Naive{Float64}          0.123188            21.083010        0.001706\n1   1000   1000  Nested{Float64}          2.606700           210.646009        0.295431\n2   2000   2000   Naive{Float64}          0.000084             0.176208        0.009147\n3   2000   2000  Nested{Float64}          1.308404            67.983136        0.170769\n4   5000   5000   Naive{Float64}          0.000200             0.440208        0.059044\n5   5000   5000  Nested{Float64}          3.226397           201.209808        0.727922\n6  10000  10000   Naive{Float64}          0.000579             0.880208        0.194339\n7  10000  10000  Nested{Float64}          7.278815           512.164288        1.641210\n8  20000  20000   Naive{Float64}          0.001400             1.760208        0.828003\n9  20000  20000  Nested{Float64}         14.881884          1451.676352        4.268223\n```\n\n## TODOs\n\n - remove Dict from subhull? idk if that will be faster\n - polish docs + performance tests\n - generate more interesting point distributions?\n - make visualization work for larger number of points?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbqi343%2Finnerproductmax.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbqi343%2Finnerproductmax.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbqi343%2Finnerproductmax.jl/lists"}