squarenet 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.4
2
+ Name: squarenet
3
+ Version: 0.1.0
4
+ Summary: Sparse local operations for point clouds in any dimension.
5
+ Author-email: ArmanddeCacqueray <armanddecacqueray@sfr.fr>
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE.txt
9
+ Requires-Dist: numpy
10
+ Requires-Dist: matplotlib
11
+ Provides-Extra: demo
12
+ Requires-Dist: geopandas; extra == "demo"
13
+ Requires-Dist: shapely; extra == "demo"
14
+ Dynamic: license-file
15
+
16
+ # SquareNet
17
+
18
+ **SquareNet** is a lightweight framework for mapping unstructured point clouds into structured N-dimensional grids, enabling fast and efficient local operations.
19
+
20
+ ## ✨ Key Idea
21
+
22
+ SquareNet builds a bijective mapping between point indices and a structured grid:
23
+
24
+ * **Bijection**: each point maps to exactly one grid cell
25
+ * **Neighborhood preservation**: nearby points remain close in the grid
26
+
27
+ This allows replacing expensive spatial queries (k-NN, radius search) with simple **array slicing**.
28
+
29
+ ---
30
+
31
+ ## πŸš€ Features
32
+
33
+ * Fast point cloud β†’ grid mapping
34
+ * Invertible transformation
35
+ * Efficient local neighborhood operations
36
+ * Sparse Gram matrix computation via sliding windows
37
+ * NumPy-friendly (no heavy dependencies required)
38
+
39
+ ---
40
+
41
+ ## πŸ“¦ Installation
42
+
43
+ ```bash
44
+ pip install squarenet
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 🧠 Basic Usage
50
+
51
+ ```python
52
+ from squarenet import SquareNet
53
+
54
+ sqnet = SquareNet(IJ=(L, W, H, ...), max_iter = 100)
55
+
56
+ # Original data: (N, D)
57
+ points = np.random.rand(N, D)
58
+ Sqnet.fit(points)
59
+
60
+ # Map (N, *) to the grid: (L, W, H, ..., *)
61
+ sqX = sqnet.map(X)
62
+
63
+ # Back to original ordering
64
+ X_rec = sqnet.invert_map(sqX)
65
+ ```
66
+
67
+ ---
68
+
69
+ ## πŸ”¬ Local Processing Example
70
+
71
+ Compute a **local (sparse) Gram matrix** using a sliding window:
72
+
73
+ ```python
74
+ G = sqnet.gram(X, ws=(5, 5))
75
+ ```
76
+
77
+ Instead of computing a full `(N Γ— N)` matrix, SquareNet only computes interactions within local neighborhoods.
78
+
79
+ ---
80
+
81
+ ## πŸ—ΊοΈ Demo Dataset
82
+
83
+ A small demo dataset (France map) is included:
84
+
85
+ ```python
86
+ Sqnet.fit("france")
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 🧱 Project Structure
92
+
93
+ ```
94
+ src/
95
+ squarenet/
96
+ __init__.py
97
+ core.py
98
+ utils.py
99
+ data/france.geojson
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 🎯 Why SquareNet?
105
+
106
+ Traditional point cloud pipelines rely on:
107
+
108
+ * k-NN search (O(N log N))
109
+ * irregular memory access
110
+ * poor GPU utilization
111
+
112
+ SquareNet enables:
113
+
114
+ * **O(N)** local operations
115
+ * contiguous memory access
116
+ * vectorized operations on a sliding window
117
+
118
+ ---
119
+
120
+ ## πŸ“ˆ Use Cases
121
+
122
+ * Point cloud processing
123
+ * Graph-to-grid transformations
124
+ * Fast kernel methods
125
+ * Local feature aggregation
126
+ * Deep learning preprocessing
127
+
128
+ ---
129
+
130
+ ## πŸ› οΈ Development
131
+
132
+ ```bash
133
+ git clone https://github.com/ArmanddeCacqueray/SquareNet
134
+ cd squarenet
135
+ pip install -e .
136
+ ```
137
+
138
+ ---
139
+
140
+ ## πŸ“„ License
141
+
142
+ MIT License
143
+
144
+ ---
145
+
146
+ ## 🀝 Contributing
147
+
148
+ Contributions are welcome. Please open an issue or submit a pull request.
149
+
@@ -0,0 +1,134 @@
1
+ # SquareNet
2
+
3
+ **SquareNet** is a lightweight framework for mapping unstructured point clouds into structured N-dimensional grids, enabling fast and efficient local operations.
4
+
5
+ ## ✨ Key Idea
6
+
7
+ SquareNet builds a bijective mapping between point indices and a structured grid:
8
+
9
+ * **Bijection**: each point maps to exactly one grid cell
10
+ * **Neighborhood preservation**: nearby points remain close in the grid
11
+
12
+ This allows replacing expensive spatial queries (k-NN, radius search) with simple **array slicing**.
13
+
14
+ ---
15
+
16
+ ## πŸš€ Features
17
+
18
+ * Fast point cloud β†’ grid mapping
19
+ * Invertible transformation
20
+ * Efficient local neighborhood operations
21
+ * Sparse Gram matrix computation via sliding windows
22
+ * NumPy-friendly (no heavy dependencies required)
23
+
24
+ ---
25
+
26
+ ## πŸ“¦ Installation
27
+
28
+ ```bash
29
+ pip install squarenet
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 🧠 Basic Usage
35
+
36
+ ```python
37
+ from squarenet import SquareNet
38
+
39
+ sqnet = SquareNet(IJ=(L, W, H, ...), max_iter = 100)
40
+
41
+ # Original data: (N, D)
42
+ points = np.random.rand(N, D)
43
+ Sqnet.fit(points)
44
+
45
+ # Map (N, *) to the grid: (L, W, H, ..., *)
46
+ sqX = sqnet.map(X)
47
+
48
+ # Back to original ordering
49
+ X_rec = sqnet.invert_map(sqX)
50
+ ```
51
+
52
+ ---
53
+
54
+ ## πŸ”¬ Local Processing Example
55
+
56
+ Compute a **local (sparse) Gram matrix** using a sliding window:
57
+
58
+ ```python
59
+ G = sqnet.gram(X, ws=(5, 5))
60
+ ```
61
+
62
+ Instead of computing a full `(N Γ— N)` matrix, SquareNet only computes interactions within local neighborhoods.
63
+
64
+ ---
65
+
66
+ ## πŸ—ΊοΈ Demo Dataset
67
+
68
+ A small demo dataset (France map) is included:
69
+
70
+ ```python
71
+ Sqnet.fit("france")
72
+ ```
73
+
74
+ ---
75
+
76
+ ## 🧱 Project Structure
77
+
78
+ ```
79
+ src/
80
+ squarenet/
81
+ __init__.py
82
+ core.py
83
+ utils.py
84
+ data/france.geojson
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 🎯 Why SquareNet?
90
+
91
+ Traditional point cloud pipelines rely on:
92
+
93
+ * k-NN search (O(N log N))
94
+ * irregular memory access
95
+ * poor GPU utilization
96
+
97
+ SquareNet enables:
98
+
99
+ * **O(N)** local operations
100
+ * contiguous memory access
101
+ * vectorized operations on a sliding window
102
+
103
+ ---
104
+
105
+ ## πŸ“ˆ Use Cases
106
+
107
+ * Point cloud processing
108
+ * Graph-to-grid transformations
109
+ * Fast kernel methods
110
+ * Local feature aggregation
111
+ * Deep learning preprocessing
112
+
113
+ ---
114
+
115
+ ## πŸ› οΈ Development
116
+
117
+ ```bash
118
+ git clone https://github.com/ArmanddeCacqueray/SquareNet
119
+ cd squarenet
120
+ pip install -e .
121
+ ```
122
+
123
+ ---
124
+
125
+ ## πŸ“„ License
126
+
127
+ MIT License
128
+
129
+ ---
130
+
131
+ ## 🀝 Contributing
132
+
133
+ Contributions are welcome. Please open an issue or submit a pull request.
134
+
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "squarenet"
7
+ version = "0.1.0"
8
+ description = "Sparse local operations for point clouds in any dimension."
9
+ authors = [{ name = "ArmanddeCacqueray", email = "armanddecacqueray@sfr.fr" }]
10
+ readme = "README.md"
11
+ requires-python = ">=3.8"
12
+ dependencies = [
13
+ "numpy",
14
+ "matplotlib"
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ demo = [
19
+ "geopandas",
20
+ "shapely"
21
+ ]
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["src"]
25
+
26
+ [tool.setuptools.package-data]
27
+ "squarenet" = ["data/*.json"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ from .core import SquareNet
2
+ from .utils import checkerboard, initpoint, grid_disorder, gram
3
+
4
+ __all__ = ["squarenet"]
5
+ __version__ = "0.1.0"
@@ -0,0 +1,133 @@
1
+ import numpy as np
2
+ from .utils import initpoint, grid_disorder, checkerboard, gram
3
+
4
+ class SquareNet:
5
+ """
6
+ An iterative grid-straightening algorithm that untangles a D-dimensional mesh
7
+ by sorting nodes along each spatial axis to enforce a structured ordering.
8
+
9
+ The grid is represented as an (I, J, ..., D) array, where D is the number of spatial dimensions.
10
+ Each iteration attempts to minimize disorder along each dimension independently.
11
+ """
12
+
13
+ def __init__(self, IJ=(100, 100), max_iter=100):
14
+ """
15
+ Initialize the SquareNet.
16
+
17
+ Args:
18
+ IJ (tuple): Grid dimensions (Rows, Cols, ...). Supports any number of dimensions.
19
+ max_iter (int): Maximum number of straightening iterations.
20
+ """
21
+ self.IJ = tuple(IJ)
22
+ self.D = len(self.IJ) # Spatial dimensions (x, y, z,...)
23
+ self.N = np.prod(IJ)
24
+ self.max_iter = max_iter
25
+ self.learning_curve = []
26
+
27
+ # Internal state
28
+ self.points = None # Points as given by the user
29
+ self.net = None # Grid with attached original indices
30
+ self.mapID = None # Permutation map after sorting
31
+
32
+ def map(self, X):
33
+ """
34
+ Reorders any input array according to the optimized grid structure.
35
+
36
+ Args:
37
+ X (np.ndarray): Array of shape (N, ...) to be remapped.
38
+
39
+ Returns:
40
+ np.ndarray: Reshaped and reordered array of shape (*IJ, ...).
41
+ """
42
+ return X[self.mapID].reshape(*self.IJ, *X.shape[1:])
43
+
44
+ def invert_map(self, X):
45
+ """
46
+ Restores the original ordering from the grid representation.
47
+
48
+ Args:
49
+ sqX (np.ndarray): Array of shape (*IJ, ...)
50
+
51
+ Returns:
52
+ np.ndarray: Array of shape (N, ...)
53
+ """
54
+ return (X.reshape(-1, *X.shape[len(self.IJ):]))[self.inv_mapID]
55
+
56
+ def fit(self, points):
57
+ """
58
+ Fit the grid to a set of points in D dimensions.
59
+
60
+ Args:
61
+ points (np.ndarray or str): Array of shape (N, D) or a method name supported
62
+ by .utils.initpoint.
63
+ """
64
+ if isinstance(points, str):
65
+ points = initpoint(method=points, size=(self.N, self.D))
66
+
67
+ self.points = points
68
+ self.learning_curve = []
69
+
70
+ N, D = points.shape
71
+ assert N == self.N, f"Input points ({N}) must match grid size {self.N}"
72
+ assert D == self.D, f"Input points dimension ({D}) must match D={self.D}"
73
+
74
+ # Attach an ID to each point for tracking during swaps
75
+ indexed_points = np.concatenate([points, np.arange(N)[:, None]], axis=-1)
76
+
77
+ # Reshape into structured grid: (*IJ, D+1)
78
+ self.net = indexed_points.reshape(*self.IJ, self.D + 1)
79
+
80
+ # Iteratively sort along each spatial axis
81
+ for k in range(self.max_iter):
82
+ error = self.sort_increasing()
83
+ if error ==0:
84
+ print(f"succesfully sorted at step {k}")
85
+ break
86
+
87
+ # Extract permutation map and clean the coordinate grid
88
+ self.mapID = self.net[..., -1].astype(int).ravel()
89
+ self.inv_mapID = np.empty_like(self.mapID)
90
+ self.inv_mapID[self.mapID] = np.arange(len(self.mapID))
91
+ self.net = self.net[..., :-1]
92
+
93
+ def sort_increasing(self):
94
+ """
95
+ Aligns the grid by sorting nodes along each spatial axis.
96
+ Ensures that the points are generally ordered along all dimensions.
97
+ """
98
+ for axis in range(self.D):
99
+ # np.argsort along the current spatial axis
100
+ # Keep the last dimension (original index) attached
101
+ flat_axis = axis
102
+ idx = np.argsort(self.net[..., flat_axis], axis=axis)
103
+ # Expand idx to match last dimension for np.take_along_axis
104
+ idx_expanded = np.expand_dims(idx, axis=-1)
105
+ self.net = np.take_along_axis(self.net, idx_expanded.repeat(self.D + 1, axis=-1), axis=axis)
106
+
107
+ error = grid_disorder(self.net[..., :-1])
108
+ self.learning_curve.append(error)
109
+ return(error)
110
+
111
+ def checkerboard(self, scales= [2, 4, 8, 16]):
112
+ """
113
+ plot the net as a chekerboard at different scales
114
+ """
115
+ assert self.D == 2, "only valid in 2D"
116
+ checkerboard(self.net, scales)
117
+
118
+ def gram(self, X, ws=5):
119
+ """
120
+ Compute a sparse Gram matrix using local neighborhoods within a window.
121
+
122
+ Args:
123
+ X (np.ndarray): Input features of shape (N, C)
124
+ ws (int or sequence): Half window size per dimension.
125
+ If int β†’ same for all dims
126
+ If sequence β†’ one per grid dim
127
+
128
+ Returns:
129
+ np.ndarray: Sparse Gram matrix of shape (N, K)
130
+ """
131
+
132
+ return gram(self, X, ws)
133
+
@@ -0,0 +1,148 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from numpy.lib.stride_tricks import sliding_window_view
4
+ from importlib import resources
5
+
6
+ def checkerboard(grid, scales):
7
+ n = grid.shape[0]
8
+ I, J = np.arange(n)[:, None], np.arange(n)[None, :]
9
+
10
+ fig, axes = plt.subplots(2, 2, figsize=(8, 8)) # grille 2x2
11
+
12
+ for ax, i in zip(axes.flat, scales):
13
+ H = n // i
14
+ mask = (I // H) % 2 == (J // H) % 2
15
+
16
+ ax.scatter(grid[mask, 0], grid[mask, 1],
17
+ color="blue", s=3)
18
+ ax.set_aspect("equal")
19
+ ax.set_xticks([])
20
+ ax.set_yticks([])
21
+ for spine in ax.spines.values():
22
+ spine.set_visible(False)
23
+
24
+ plt.tight_layout()
25
+ plt.show()
26
+
27
+ def grid_disorder(net):
28
+ """
29
+ Measures the "disorder" of a D-dimensional grid.
30
+
31
+ Args:
32
+ net (np.ndarray): Grid of shape (*IJ, D), points already sorted with attached coordinates.
33
+
34
+ Returns:
35
+ int: Total number of consecutive inversions along all axes (lower is better).
36
+ """
37
+ total_disorder = 0
38
+ D = net.shape[-1]
39
+ for axis in range(D):
40
+ # Move the sorting axis to the front
41
+ axes_order = (axis,) + tuple(i for i in range(net.ndim - 1) if i != axis) + (net.ndim - 1,)
42
+ net_perm = np.transpose(net, axes_order)
43
+
44
+ # Flatten all remaining axes except the sorting axis
45
+ shape = net_perm.shape
46
+ flat_net = net_perm.reshape(shape[0], -1, D)
47
+
48
+ # Count consecutive inversions along the axis
49
+ coords = flat_net[..., axis] # shape (axis_size, n_cols)
50
+ inv = np.sum(coords[:-1, :] > coords[1:, :]) # i > i+1
51
+ total_disorder += inv
52
+ return total_disorder
53
+
54
+ def initpoint(method, size):
55
+ N, D = size
56
+ if method == "test":
57
+ points = np.random.rand(N, D)
58
+ if method == "france":
59
+ import geopandas as gpd
60
+ from shapely.geometry import Point
61
+
62
+ # Charger le GeoJSON
63
+ with resources.files("squarenet.data").joinpath("france.geojson").open("r") as f:
64
+ gdf = gpd.read_file(f)
65
+ metropole = gdf[~gdf['nom'].isin([
66
+ 'Guadeloupe', 'Martinique', 'Guyane', 'La RΓ©union', 'Mayotte', 'Corse'
67
+ ])]
68
+
69
+
70
+ # Merge regions
71
+ france = metropole.union_all()
72
+
73
+ # Bounding box
74
+ minx, miny, maxx, maxy = france.bounds
75
+
76
+ def sample_points(polygon, n_points):
77
+ points = []
78
+
79
+ while len(points) < n_points:
80
+ x = np.random.uniform(minx, maxx)
81
+ y = np.random.uniform(miny, maxy)
82
+ p = Point(x, y)
83
+
84
+ if polygon.contains(p):
85
+ points.append(p)
86
+
87
+ return np.array([[p.x, p.y] for p in points])
88
+
89
+ # Generate sample
90
+ points = sample_points(france, N)
91
+ return points
92
+
93
+ def gram(self, X, ws):
94
+ """
95
+ Compute a sparse Gram matrix using local neighborhoods within a window.
96
+
97
+ Args:
98
+ X (np.ndarray): Input features of shape (N, C)
99
+ ws (int or sequence): Half window size per dimension.
100
+ If int β†’ same for all dims
101
+ If sequence β†’ one per grid dim
102
+
103
+ Returns:
104
+ np.ndarray: Sparse Gram matrix of shape (N, K)
105
+ """
106
+
107
+ # Map to grid β†’ (*IJ, C)
108
+ Xg = self.map(X)
109
+ *grid_shape, C = Xg.shape
110
+ ndim = len(grid_shape)
111
+ d = ws
112
+
113
+ # Handle window size
114
+ if isinstance(d, int):
115
+ d = [d] * ndim
116
+ else:
117
+ assert len(d) == ndim, "d must match number of grid dimensions"
118
+
119
+ # Padding
120
+ pad_width = [(di, di) for di in d] + [(0, 0)]
121
+ X_padded = np.pad(Xg, pad_width, mode='constant')
122
+
123
+ # Window shape
124
+ window_shape = tuple(2 * di + 1 for di in d)
125
+
126
+ # Extract patches
127
+ patches = sliding_window_view(
128
+ X_padded,
129
+ window_shape=window_shape,
130
+ axis=tuple(range(ndim))
131
+ )
132
+
133
+ # Compute K = number of neighbors
134
+ K = np.prod(window_shape)
135
+
136
+ # reshape β†’ (*IJ, K, C)
137
+ patches = patches.reshape(*grid_shape, K, C)
138
+
139
+ # center β†’ (*IJ, 1, C)
140
+ center = Xg[(...,) + (None, slice(None))]
141
+
142
+ # dot product β†’ (*IJ, K)
143
+ G = np.sum(center * patches, axis=-1)
144
+
145
+ # back to (N, K)
146
+ G = self.invert_map(G)
147
+
148
+ return G
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.4
2
+ Name: squarenet
3
+ Version: 0.1.0
4
+ Summary: Sparse local operations for point clouds in any dimension.
5
+ Author-email: ArmanddeCacqueray <armanddecacqueray@sfr.fr>
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE.txt
9
+ Requires-Dist: numpy
10
+ Requires-Dist: matplotlib
11
+ Provides-Extra: demo
12
+ Requires-Dist: geopandas; extra == "demo"
13
+ Requires-Dist: shapely; extra == "demo"
14
+ Dynamic: license-file
15
+
16
+ # SquareNet
17
+
18
+ **SquareNet** is a lightweight framework for mapping unstructured point clouds into structured N-dimensional grids, enabling fast and efficient local operations.
19
+
20
+ ## ✨ Key Idea
21
+
22
+ SquareNet builds a bijective mapping between point indices and a structured grid:
23
+
24
+ * **Bijection**: each point maps to exactly one grid cell
25
+ * **Neighborhood preservation**: nearby points remain close in the grid
26
+
27
+ This allows replacing expensive spatial queries (k-NN, radius search) with simple **array slicing**.
28
+
29
+ ---
30
+
31
+ ## πŸš€ Features
32
+
33
+ * Fast point cloud β†’ grid mapping
34
+ * Invertible transformation
35
+ * Efficient local neighborhood operations
36
+ * Sparse Gram matrix computation via sliding windows
37
+ * NumPy-friendly (no heavy dependencies required)
38
+
39
+ ---
40
+
41
+ ## πŸ“¦ Installation
42
+
43
+ ```bash
44
+ pip install squarenet
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 🧠 Basic Usage
50
+
51
+ ```python
52
+ from squarenet import SquareNet
53
+
54
+ sqnet = SquareNet(IJ=(L, W, H, ...), max_iter = 100)
55
+
56
+ # Original data: (N, D)
57
+ points = np.random.rand(N, D)
58
+ Sqnet.fit(points)
59
+
60
+ # Map (N, *) to the grid: (L, W, H, ..., *)
61
+ sqX = sqnet.map(X)
62
+
63
+ # Back to original ordering
64
+ X_rec = sqnet.invert_map(sqX)
65
+ ```
66
+
67
+ ---
68
+
69
+ ## πŸ”¬ Local Processing Example
70
+
71
+ Compute a **local (sparse) Gram matrix** using a sliding window:
72
+
73
+ ```python
74
+ G = sqnet.gram(X, ws=(5, 5))
75
+ ```
76
+
77
+ Instead of computing a full `(N Γ— N)` matrix, SquareNet only computes interactions within local neighborhoods.
78
+
79
+ ---
80
+
81
+ ## πŸ—ΊοΈ Demo Dataset
82
+
83
+ A small demo dataset (France map) is included:
84
+
85
+ ```python
86
+ Sqnet.fit("france")
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 🧱 Project Structure
92
+
93
+ ```
94
+ src/
95
+ squarenet/
96
+ __init__.py
97
+ core.py
98
+ utils.py
99
+ data/france.geojson
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 🎯 Why SquareNet?
105
+
106
+ Traditional point cloud pipelines rely on:
107
+
108
+ * k-NN search (O(N log N))
109
+ * irregular memory access
110
+ * poor GPU utilization
111
+
112
+ SquareNet enables:
113
+
114
+ * **O(N)** local operations
115
+ * contiguous memory access
116
+ * vectorized operations on a sliding window
117
+
118
+ ---
119
+
120
+ ## πŸ“ˆ Use Cases
121
+
122
+ * Point cloud processing
123
+ * Graph-to-grid transformations
124
+ * Fast kernel methods
125
+ * Local feature aggregation
126
+ * Deep learning preprocessing
127
+
128
+ ---
129
+
130
+ ## πŸ› οΈ Development
131
+
132
+ ```bash
133
+ git clone https://github.com/ArmanddeCacqueray/SquareNet
134
+ cd squarenet
135
+ pip install -e .
136
+ ```
137
+
138
+ ---
139
+
140
+ ## πŸ“„ License
141
+
142
+ MIT License
143
+
144
+ ---
145
+
146
+ ## 🀝 Contributing
147
+
148
+ Contributions are welcome. Please open an issue or submit a pull request.
149
+
@@ -0,0 +1,11 @@
1
+ LICENSE.txt
2
+ README.md
3
+ pyproject.toml
4
+ src/squarenet/__init__.py
5
+ src/squarenet/core.py
6
+ src/squarenet/utils.py
7
+ src/squarenet.egg-info/PKG-INFO
8
+ src/squarenet.egg-info/SOURCES.txt
9
+ src/squarenet.egg-info/dependency_links.txt
10
+ src/squarenet.egg-info/requires.txt
11
+ src/squarenet.egg-info/top_level.txt
@@ -0,0 +1,6 @@
1
+ numpy
2
+ matplotlib
3
+
4
+ [demo]
5
+ geopandas
6
+ shapely
@@ -0,0 +1 @@
1
+ squarenet