Skip to content

Commit 5b164dd

Browse files
committed
Improve profile computation memory efficiency
Profile functions (compute_density_profile, compute_speed_profile, compute_profiles) no longer require pre-computed grid intersections. When grid_intersections_area is not provided, intersections are computed per frame internally, avoiding the allocation of the full (grid_cells × pedestrians) matrix. - Add _compute_frame_grid_intersection helper for single-frame intersection - Change _compute_grid_polygon_intersection to process frame-by-frame using NumPy instead of a single broadcast - Make grid_intersections_area optional in compute_density_profile and compute_speed_profile (on-the-fly when omitted) - Simplify compute_profiles to delegate to _compute_density_for_frame and _compute_speed_for_frame per frame with shared intersection - Extract _compute_density_for_frame and _compute_speed_for_frame as single-dispatch helpers; compute_density_profile and compute_speed_profile also delegate here, eliminating duplicated method branches - Move frame-invariant quantities (bounds, grid centers) out of the per-frame loop to avoid redundant recomputation - Update user guide to use the simpler API without compute_grid_cell_polygon_intersection_area
1 parent f70f08d commit 5b164dd

3 files changed

Lines changed: 869 additions & 217 deletions

File tree

notebooks/user_guide.ipynb

Lines changed: 21 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,25 +3499,12 @@
34993499
"metadata": {},
35003500
"outputs": [],
35013501
"source": [
3502-
"from pedpy import (\n",
3503-
" compute_grid_cell_polygon_intersection_area,\n",
3504-
" get_grid_cells,\n",
3505-
")\n",
3506-
"\n",
35073502
"grid_size = 0.4\n",
3508-
"grid_cells, _, _ = get_grid_cells(walkable_area=walkable_area, grid_size=grid_size)\n",
35093503
"\n",
3510-
"min_frame_profiles = 250 # We use here just an excerpt of the\n",
3511-
"max_frame_profiles = 400 # trajectory data to reduce compute time\n",
3504+
"min_frame_profiles = 500 # We use here just an excerpt of the\n",
3505+
"max_frame_profiles = 1000 # trajectory data to reduce compute time\n",
35123506
"\n",
3513-
"profile_data = profile_data[profile_data.frame.between(min_frame_profiles, max_frame_profiles)]\n",
3514-
"\n",
3515-
"# Compute the grid intersection area for the resorted profile data (they have the same sorting)\n",
3516-
"# for usage in multiple calls to not run the compute heavy operation multiple times\n",
3517-
"(\n",
3518-
" grid_cell_intersection_area,\n",
3519-
" resorted_profile_data,\n",
3520-
") = compute_grid_cell_polygon_intersection_area(data=profile_data, grid_cells=grid_cells)"
3507+
"profile_data = profile_data[profile_data.frame.between(min_frame_profiles, max_frame_profiles)]"
35213508
]
35223509
},
35233510
{
@@ -3567,44 +3554,30 @@
35673554
},
35683555
"outputs": [],
35693556
"source": [
3570-
"from pedpy import plot_measurement_setup\n",
3557+
"from pedpy import PEDPY_ORANGE, get_grid_cells, plot_measurement_setup\n",
35713558
"\n",
3572-
"plot_measurement_setup(\n",
3559+
"ax = plot_measurement_setup(\n",
35733560
" walkable_area=walkable_area,\n",
35743561
" measurement_areas=[profile_measurement_area],\n",
35753562
" ma_line_width=2,\n",
35763563
" ma_alpha=0.2,\n",
35773564
").set_aspect(\"equal\")\n",
3578-
"plt.show()"
3579-
]
3580-
},
3581-
{
3582-
"cell_type": "code",
3583-
"execution_count": null,
3584-
"metadata": {},
3585-
"outputs": [],
3586-
"source": [
3587-
"from pedpy import (\n",
3588-
" compute_grid_cell_polygon_intersection_area,\n",
3589-
" get_grid_cells,\n",
3590-
")\n",
35913565
"\n",
3566+
"grid_size = 0.4\n",
35923567
"grid_cells_measurement_area, _, _ = get_grid_cells(\n",
35933568
" axis_aligned_measurement_area=profile_measurement_area,\n",
35943569
" grid_size=grid_size,\n",
35953570
")\n",
3571+
"grid_cells = [MeasurementArea(cell) for cell in grid_cells_measurement_area]\n",
3572+
"plot_measurement_setup(\n",
3573+
" measurement_areas=grid_cells,\n",
3574+
" ma_line_color=PEDPY_ORANGE,\n",
3575+
" ma_line_width=0.3,\n",
3576+
" ma_alpha=0,\n",
3577+
" axes=ax,\n",
3578+
").set_aspect(\"equal\")\n",
35963579
"\n",
3597-
"min_frame_profiles = 250 # We use here just an excerpt of the\n",
3598-
"max_frame_profiles = 400 # trajectory data to reduce compute time\n",
3599-
"\n",
3600-
"profile_data = profile_data[profile_data.frame.between(min_frame_profiles, max_frame_profiles)]\n",
3601-
"\n",
3602-
"# Compute the grid intersection area for the resorted profile data (they have the same sorting)\n",
3603-
"# for usage in multiple calls to not run the compute heavy operation multiple times\n",
3604-
"(\n",
3605-
" grid_cell_intersection_area_measurement_area,\n",
3606-
" resorted_profile_data_measurement_area,\n",
3607-
") = compute_grid_cell_polygon_intersection_area(data=profile_data, grid_cells=grid_cells_measurement_area)"
3580+
"plt.show()"
36083581
]
36093582
},
36103583
{
@@ -3667,17 +3640,15 @@
36673640
"from pedpy import SpeedMethod, compute_speed_profile\n",
36683641
"\n",
36693642
"voronoi_speed_profile = compute_speed_profile(\n",
3670-
" data=resorted_profile_data,\n",
3643+
" data=profile_data,\n",
36713644
" walkable_area=walkable_area,\n",
3672-
" grid_intersections_area=grid_cell_intersection_area,\n",
36733645
" grid_size=grid_size,\n",
36743646
" speed_method=SpeedMethod.VORONOI,\n",
36753647
")\n",
36763648
"\n",
36773649
"arithmetic_speed_profile = compute_speed_profile(\n",
3678-
" data=resorted_profile_data,\n",
3650+
" data=profile_data,\n",
36793651
" walkable_area=walkable_area,\n",
3680-
" grid_intersections_area=grid_cell_intersection_area,\n",
36813652
" grid_size=grid_size,\n",
36823653
" speed_method=SpeedMethod.ARITHMETIC,\n",
36833654
")\n",
@@ -3770,19 +3741,17 @@
37703741
"from pedpy import AxisAlignedMeasurementArea, SpeedMethod, compute_speed_profile\n",
37713742
"\n",
37723743
"voronoi_speed_profile = compute_speed_profile(\n",
3773-
" data=resorted_profile_data_measurement_area,\n",
3744+
" data=profile_data,\n",
37743745
" walkable_area=walkable_area,\n",
37753746
" axis_aligned_measurement_area=profile_measurement_area,\n",
3776-
" grid_intersections_area=grid_cell_intersection_area_measurement_area,\n",
37773747
" grid_size=grid_size,\n",
37783748
" speed_method=SpeedMethod.VORONOI,\n",
37793749
")\n",
37803750
"\n",
37813751
"arithmetic_speed_profile = compute_speed_profile(\n",
3782-
" data=resorted_profile_data_measurement_area,\n",
3752+
" data=profile_data,\n",
37833753
" walkable_area=walkable_area,\n",
37843754
" axis_aligned_measurement_area=profile_measurement_area,\n",
3785-
" grid_intersections_area=grid_cell_intersection_area_measurement_area,\n",
37863755
" grid_size=grid_size,\n",
37873756
" speed_method=SpeedMethod.ARITHMETIC,\n",
37883757
")\n",
@@ -3916,16 +3885,13 @@
39163885
"source": [
39173886
"from pedpy import DensityMethod, compute_density_profile\n",
39183887
"\n",
3919-
"# here it is important to use the resorted data, as it needs to be in the same ordering as \"grid_cell_intersection_area\"\n",
39203888
"voronoi_density_profile = compute_density_profile(\n",
3921-
" data=resorted_profile_data,\n",
3889+
" data=profile_data,\n",
39223890
" walkable_area=walkable_area,\n",
3923-
" grid_intersections_area=grid_cell_intersection_area,\n",
39243891
" grid_size=grid_size,\n",
39253892
" density_method=DensityMethod.VORONOI,\n",
39263893
")\n",
39273894
"\n",
3928-
"# here the unsorted data can be used\n",
39293895
"classic_density_profile = compute_density_profile(\n",
39303896
" data=profile_data,\n",
39313897
" walkable_area=walkable_area,\n",
@@ -4005,17 +3971,14 @@
40053971
"source": [
40063972
"from pedpy import DensityMethod, compute_density_profile\n",
40073973
"\n",
4008-
"# here it is important to use the resorted data, as it needs to be in the same ordering as \"grid_cell_intersection_area\"\n",
40093974
"voronoi_density_profile = compute_density_profile(\n",
4010-
" data=resorted_profile_data_measurement_area,\n",
3975+
" data=profile_data,\n",
40113976
" walkable_area=walkable_area,\n",
40123977
" axis_aligned_measurement_area=profile_measurement_area,\n",
4013-
" grid_intersections_area=grid_cell_intersection_area_measurement_area,\n",
40143978
" grid_size=grid_size,\n",
40153979
" density_method=DensityMethod.VORONOI,\n",
40163980
")\n",
40173981
"\n",
4018-
"# here the unsorted data can be used\n",
40193982
"classic_density_profile = compute_density_profile(\n",
40203983
" data=profile_data,\n",
40213984
" walkable_area=walkable_area,\n",

0 commit comments

Comments
 (0)