Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f0aa3e7
an EventGraph with tests
vineetbansal Jul 8, 2026
c9ac370
ruff fixes
vineetbansal Jul 9, 2026
1140196
mypy fixes
vineetbansal Jul 9, 2026
3845f52
lift_order_temporal moved as a staticmethod inside EventGraph (better…
vineetbansal Jul 9, 2026
8f3c752
lift_order_temporal -> EventGraph.build_edge_index in docs
vineetbansal Jul 10, 2026
2e83665
Added an eg: EventGraph argument to temporal_shortest_paths
vineetbansal Jul 10, 2026
f97ba97
mapping defined for EventGraph; no using the term fo in methods
vineetbansal Jul 10, 2026
84a58e9
A reduce_delta method; A convenience edge_delta_map method
vineetbansal Jul 10, 2026
a0fd316
MultiOrderModel can be constructed from an EventGraph
vineetbansal Jul 10, 2026
03975fb
make from_edge_index respect isolated nodes in mapping
vineetbansal Jul 16, 2026
b1291b3
Align TemporalGraph.from_edge_list with the base class signature
vineetbansal Jul 16, 2026
8d79ec5
Fix higher-order ID detection by checking IndexMap tuple IDs instead …
vineetbansal Jul 16, 2026
b9f83d7
Merge pull request #322 from pathpy/vb/isolated_nodes
vineetbansal Jul 17, 2026
a548e19
Merge branch 'dev' into vb/eventgraph
vineetbansal Jul 17, 2026
1cde6e1
Merge pull request #324 from pathpy/vb/issue323
vineetbansal Jul 20, 2026
8c621f2
Merge branch 'dev' into vb/eventgraph
vineetbansal Jul 20, 2026
1b032c2
Added tests for node labels for an EventGraph; making EventGraph avai…
vineetbansal Jul 27, 2026
d55b174
variable renaming; pushed common __str__ code up for Graph
vineetbansal Jul 27, 2026
f388bfa
variable renaming to get around mypy failures
vineetbansal Jul 27, 2026
92e5103
Add failing test for edge attributes on a pre-sorted edge index
vineetbansal Jul 27, 2026
3406fc9
Keep edge attributes intact for an already-sorted edge index
vineetbansal Jul 27, 2026
eedda14
Merge pull request #326 from pathpy/vb/edge-attr-sort-fix
vineetbansal Jul 28, 2026
6ac7d44
Add failing test for edge attributes on a pre-sorted edge index
vineetbansal Jul 27, 2026
54463e1
Keep edge attributes intact for an already-sorted edge index
vineetbansal Jul 27, 2026
8beed83
Promoting edge attributes in TemporalGraph to node attributes in Even…
vineetbansal Jul 27, 2026
920a2fb
not implementing a custom getitem on EventGraph, and testing on defau…
vineetbansal Aug 12, 2026
0f31940
Update src/pathpyG/algorithms/temporal.py
vineetbansal Aug 31, 2026
bbc7bb4
Update src/pathpyG/algorithms/temporal.py
vineetbansal Aug 31, 2026
d866eb5
Merge pull request #319 from pathpy/vb/eventgraph
vineetbansal Aug 31, 2026
bb17caf
Workflow tweaks for dev and stable docs, per issue #337.
vineetbansal Sep 15, 2026
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
5 changes: 4 additions & 1 deletion .github/workflows/docs-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ jobs:
# First configure git correctly
# Then use the alias of the current dev version to delete it based on its identifier
# Then deploy the new version so that there is only one dev version at a time
# Only make dev the default if no stable version exists yet, so stable stays the default once published
run: |
git config user.name github-actions
git config user.email [email protected]
git fetch origin gh-pages --depth=1
mike delete --push $(mike list | grep dev | awk '{print $1}' | tr -d '()')
mike deploy --push --update-aliases "${{ env.package_version }}-dev" dev
mike set-default --push --allow-empty dev
if ! mike list stable > /dev/null 2>&1; then
mike set-default --push dev
fi
3 changes: 3 additions & 0 deletions .github/workflows/docs-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
python -c 'import pathpyG; print(f"package_version={pathpyG.__version__}")' >> "$GITHUB_ENV"

- name: Publish docs
env:
# Pin "Open in Colab" links to the commit these docs are built from
DOCS_GIT_REF: ${{ github.sha }}
run: |
git config user.name github-actions
git config user.email [email protected]
Expand Down
3 changes: 0 additions & 3 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ uv pip install pathpyg[cu129]

You can install the latest stable release of PathpyG via pip:

!!! warning "TODO"
This is not yet available. We will release the first stable version soon.

```bash
pip install pathpyg
```
Expand Down
2 changes: 1 addition & 1 deletion docs/overrides/home.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "main.html" %}

{% block tabs %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css">
Expand Down
9 changes: 7 additions & 2 deletions docs/overrides/main.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
{% extends "base.html" %}

<!-- You can include an announcement bar with the block "announce" -->
{% block announce -%}
{%- if config.extra.docs_version.endswith("-dev") %}
You're viewing the development docs. Features documented here may not be in a released version of pathpyG yet.
{%- endif %}
{%- endblock %}

<!-- Includes a download button in the Jupyter tutorials -->
{% block content %}
{% if page.nb_url %}
<a href="{{ page.nb_url }}" title="Download Notebook" class="md-content__button md-icon">
{% include ".icons/material/download.svg" %}
</a>
<a href="{{ page.edit_url | replace('https://github.com/pathpy/pathpyG/edit/', 'https://colab.research.google.com/github/pathpy/pathpyG/blob/') }}" title="Open in Google Colab" class="md-content__button md-icon">
<a href="https://colab.research.google.com/github/pathpy/pathpyG/blob/{{ config.extra.git_ref }}/docs/{{ page.file.src_uri }}" title="Open in Google Colab" class="md-content__button md-icon">
{% include ".icons/simple/googlecolab.svg" %}
</a>
{% endif %}
{{ super() }}
{% endblock %}

<!-- Adds a warning to the top of the page if the page is not the dev or the stable version -->
<!-- Adds a warning to the top of the page if the page is not the stable version -->
{% block outdated %}
You're not viewing the latest version.
<a href="{{ '../' ~ base_url }}">
Expand Down
16 changes: 8 additions & 8 deletions docs/tutorial/archive/_scalability_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
" res['temp_net_events'] = g.data.edge_index.size(1)\n",
"\n",
" start_time = time.time()\n",
" eg = pp.algorithms.lift_order_temporal(g, delta=exp['delta'])\n",
" eg = pp.core.event_graph.EventGraph.build_edge_index(g, delta=exp['delta'])\n",
" eg.to(exp['device'])\n",
" res['lift_event_graph_time'] = time.time() - start_time\n",
" res['event_graph_edges'] = eg.size(1)\n",
Expand Down Expand Up @@ -1392,13 +1392,13 @@
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[4], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m exp[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmax_order\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m k\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 13\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mtest_mo_scalability\u001b[49m\u001b[43m(\u001b[49m\u001b[43mg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexp\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 14\u001b[0m printer\u001b[38;5;241m.\u001b[39mpprint(res)\n\u001b[1;32m 15\u001b[0m results_rm[delta][k] \u001b[38;5;241m=\u001b[39m res\n",
"Cell \u001b[0;32mIn[2], line 16\u001b[0m, in \u001b[0;36mtest_mo_scalability\u001b[0;34m(g, exp)\u001b[0m\n\u001b[1;32m 13\u001b[0m res[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mevent_graph_edges\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m eg\u001b[38;5;241m.\u001b[39msize(\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m 15\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m---> 16\u001b[0m m \u001b[38;5;241m=\u001b[39m \u001b[43mpp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mMultiOrderModel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_temporal_graph\u001b[49m\u001b[43m(\u001b[49m\u001b[43mg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdelta\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mexp\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mdelta\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_order\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mexp\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mmax_order\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 17\u001b[0m res[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmo_time\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m-\u001b[39m start_time\n\u001b[1;32m 18\u001b[0m res[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmax_order_nodes\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m m\u001b[38;5;241m.\u001b[39mlayers[exp[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmax_order\u001b[39m\u001b[38;5;124m'\u001b[39m]]\u001b[38;5;241m.\u001b[39mN\n",
"File \u001b[0;32m/workspaces/pathpyG/src/pathpyG/core/multi_order_model.py:108\u001b[0m, in \u001b[0;36mMultiOrderModel.from_temporal_graph\u001b[0;34m(g, delta, max_order, weight, cached)\u001b[0m\n\u001b[1;32m 106\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m max_order \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 107\u001b[0m node_sequence \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mcat([node_sequence[edge_index[\u001b[38;5;241m0\u001b[39m]], node_sequence[edge_index[\u001b[38;5;241m1\u001b[39m]][:, \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m:]], dim\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m)\n\u001b[0;32m--> 108\u001b[0m edge_index \u001b[38;5;241m=\u001b[39m \u001b[43mlift_order_temporal\u001b[49m\u001b[43m(\u001b[49m\u001b[43mg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdelta\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 109\u001b[0m edge_weight \u001b[38;5;241m=\u001b[39m aggregate_node_attributes(edge_index, edge_weight, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msrc\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 111\u001b[0m \u001b[38;5;66;03m# Aggregate\u001b[39;00m\n",
"File \u001b[0;32m/workspaces/pathpyG/src/pathpyG/algorithms/temporal.py:39\u001b[0m, in \u001b[0;36mlift_order_temporal\u001b[0;34m(g, delta)\u001b[0m\n\u001b[1;32m 36\u001b[0m dst_node_mask \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39misin(edge_index[\u001b[38;5;241m0\u001b[39m], edge_index[\u001b[38;5;241m1\u001b[39m, src_edge_idx])\n\u001b[1;32m 37\u001b[0m dst_edge_idx \u001b[38;5;241m=\u001b[39m indices[dst_time_mask \u001b[38;5;241m&\u001b[39m dst_node_mask]\n\u001b[0;32m---> 39\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mdst_edge_idx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msize\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m src_edge_idx\u001b[38;5;241m.\u001b[39msize(\u001b[38;5;241m0\u001b[39m) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 40\u001b[0m \n\u001b[1;32m 41\u001b[0m \u001b[38;5;66;03m# compute second-order edges between src and dst idx for all edges where dst in src_edges matches src in dst_edges\u001b[39;00m\n\u001b[1;32m 42\u001b[0m x \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mcartesian_prod(src_edge_idx, dst_edge_idx)\u001b[38;5;241m.\u001b[39mt()\n\u001b[1;32m 43\u001b[0m \u001b[38;5;66;03m# print(x.size(1))\u001b[39;00m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[4], line 13\u001B[0m\n\u001B[1;32m 11\u001B[0m exp[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmax_order\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m k\n\u001B[1;32m 12\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m---> 13\u001B[0m res \u001B[38;5;241m=\u001B[39m \u001B[43mtest_mo_scalability\u001B[49m\u001B[43m(\u001B[49m\u001B[43mg\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mexp\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 14\u001B[0m printer\u001B[38;5;241m.\u001B[39mpprint(res)\n\u001B[1;32m 15\u001B[0m results_rm[delta][k] \u001B[38;5;241m=\u001B[39m res\n",
"Cell \u001B[0;32mIn[2], line 16\u001B[0m, in \u001B[0;36mtest_mo_scalability\u001B[0;34m(g, exp)\u001B[0m\n\u001B[1;32m 13\u001B[0m res[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mevent_graph_edges\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m eg\u001B[38;5;241m.\u001B[39msize(\u001B[38;5;241m1\u001B[39m)\n\u001B[1;32m 15\u001B[0m start_time \u001B[38;5;241m=\u001B[39m time\u001B[38;5;241m.\u001B[39mtime()\n\u001B[0;32m---> 16\u001B[0m m \u001B[38;5;241m=\u001B[39m \u001B[43mpp\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mMultiOrderModel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfrom_temporal_graph\u001B[49m\u001B[43m(\u001B[49m\u001B[43mg\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdelta\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mexp\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mdelta\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmax_order\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mexp\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mmax_order\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 17\u001B[0m res[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmo_time\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m time\u001B[38;5;241m.\u001B[39mtime() \u001B[38;5;241m-\u001B[39m start_time\n\u001B[1;32m 18\u001B[0m res[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmax_order_nodes\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m m\u001B[38;5;241m.\u001B[39mlayers[exp[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmax_order\u001B[39m\u001B[38;5;124m'\u001B[39m]]\u001B[38;5;241m.\u001B[39mN\n",
"File \u001B[0;32m/workspaces/pathpyG/src/pathpyG/core/multi_order_model.py:108\u001B[0m, in \u001B[0;36mMultiOrderModel.from_temporal_graph\u001B[0;34m(g, delta, max_order, weight, cached)\u001B[0m\n\u001B[1;32m 106\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m max_order \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[1;32m 107\u001B[0m node_sequence \u001B[38;5;241m=\u001B[39m torch\u001B[38;5;241m.\u001B[39mcat([node_sequence[edge_index[\u001B[38;5;241m0\u001B[39m]], node_sequence[edge_index[\u001B[38;5;241m1\u001B[39m]][:, \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m1\u001B[39m:]], dim\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1\u001B[39m)\n\u001B[0;32m--> 108\u001B[0m edge_index \u001B[38;5;241m=\u001B[39m \u001B[43mlift_order_temporal\u001B[49m\u001B[43m(\u001B[49m\u001B[43mg\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdelta\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 109\u001B[0m edge_weight \u001B[38;5;241m=\u001B[39m aggregate_node_attributes(edge_index, edge_weight, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124msrc\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 111\u001B[0m \u001B[38;5;66;03m# Aggregate\u001B[39;00m\n",
"File \u001B[0;32m/workspaces/pathpyG/src/pathpyG/algorithms/temporal.py:39\u001B[0m, in \u001B[0;36mlift_order_temporal\u001B[0;34m(g, delta)\u001B[0m\n\u001B[1;32m 36\u001B[0m dst_node_mask \u001B[38;5;241m=\u001B[39m torch\u001B[38;5;241m.\u001B[39misin(edge_index[\u001B[38;5;241m0\u001B[39m], edge_index[\u001B[38;5;241m1\u001B[39m, src_edge_idx])\n\u001B[1;32m 37\u001B[0m dst_edge_idx \u001B[38;5;241m=\u001B[39m indices[dst_time_mask \u001B[38;5;241m&\u001B[39m dst_node_mask]\n\u001B[0;32m---> 39\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[43mdst_edge_idx\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msize\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m)\u001B[49m \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m0\u001B[39m \u001B[38;5;129;01mand\u001B[39;00m src_edge_idx\u001B[38;5;241m.\u001B[39msize(\u001B[38;5;241m0\u001B[39m) \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m0\u001B[39m:\n\u001B[1;32m 40\u001B[0m \n\u001B[1;32m 41\u001B[0m \u001B[38;5;66;03m# compute second-order edges between src and dst idx for all edges where dst in src_edges matches src in dst_edges\u001B[39;00m\n\u001B[1;32m 42\u001B[0m x \u001B[38;5;241m=\u001B[39m torch\u001B[38;5;241m.\u001B[39mcartesian_prod(src_edge_idx, dst_edge_idx)\u001B[38;5;241m.\u001B[39mt()\n\u001B[1;32m 43\u001B[0m \u001B[38;5;66;03m# print(x.size(1))\u001B[39;00m\n",
"\u001B[0;31mKeyboardInterrupt\u001B[0m: "
]
}
],
Expand Down
Loading
Loading