laprust 1.0.0__cp315-cp315-win_amd64.whl

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.
laprust/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Native Rust linear assignment solvers with implicit rejection and batch solving."""
2
+ from ._lapjv import lapjv, lapjv_batch
3
+
4
+ __version__ = "1.0.0"
5
+ __author__ = 'Ratha SIV'
6
+ __description__ = 'Native Rust linear assignment solvers with implicit rejection and batch solving.'
7
+ __homepage__ = 'https://github.com/rathaROG/laprust'
8
+ __all__ = ["lapjv", "lapjv_batch"]
laprust/__init__.pyi ADDED
@@ -0,0 +1,3 @@
1
+ from ._lapjv import lapjv as lapjv, lapjv_batch as lapjv_batch
2
+ __version__: str
3
+ __all__: list[str]
Binary file
laprust/_lapjv.pyi ADDED
@@ -0,0 +1,214 @@
1
+ # Copyright (c) 2026 Ratha SIV | MIT License
2
+
3
+ """Static signatures and documentation for the laprust entry points."""
4
+
5
+ from typing import Any, List, Optional, Tuple, Union, overload
6
+ from typing import Literal, Protocol
7
+ import numpy as np
8
+
9
+ _Precision = Literal["native", "float32", "float64"]
10
+ _Output = Literal["indices", "pairs"]
11
+
12
+ class _SingleSolver(Protocol):
13
+ @overload
14
+ def __call__(
15
+ self, cost: Any,
16
+ extend_cost: bool = False,
17
+ cost_limit: float = ...,
18
+ return_cost: Literal[True] = True,
19
+ *,
20
+ precision: _Precision = "native",
21
+ output: Literal["indices"] = "indices",
22
+ ) -> Tuple[float, np.ndarray, np.ndarray]: ...
23
+
24
+ @overload
25
+ def __call__(
26
+ self, cost: Any,
27
+ extend_cost: bool,
28
+ cost_limit: float,
29
+ return_cost: Literal[False],
30
+ *,
31
+ precision: _Precision = "native",
32
+ output: Literal["indices"] = "indices",
33
+ ) -> Tuple[np.ndarray, np.ndarray]: ...
34
+
35
+ @overload
36
+ def __call__(
37
+ self, cost: Any,
38
+ extend_cost: bool = False,
39
+ cost_limit: float = ...,
40
+ *,
41
+ return_cost: Literal[False],
42
+ precision: _Precision = "native",
43
+ output: Literal["indices"] = "indices",
44
+ ) -> Tuple[np.ndarray, np.ndarray]: ...
45
+
46
+ @overload
47
+ def __call__(
48
+ self, cost: Any,
49
+ extend_cost: bool = False,
50
+ cost_limit: float = ...,
51
+ return_cost: bool = True,
52
+ *,
53
+ precision: _Precision = "native",
54
+ output: Literal["indices"] = "indices",
55
+ ) -> Union[Tuple[float, np.ndarray, np.ndarray], Tuple[np.ndarray, np.ndarray]]: ...
56
+
57
+ @overload
58
+ def __call__(
59
+ self, cost: Any,
60
+ extend_cost: bool = False,
61
+ cost_limit: float = ...,
62
+ return_cost: Literal[True] = True,
63
+ *,
64
+ precision: _Precision = "native",
65
+ output: Literal["pairs"],
66
+ ) -> Tuple[float, np.ndarray]: ...
67
+
68
+ @overload
69
+ def __call__(
70
+ self, cost: Any,
71
+ extend_cost: bool,
72
+ cost_limit: float,
73
+ return_cost: Literal[False],
74
+ *,
75
+ precision: _Precision = "native",
76
+ output: Literal["pairs"],
77
+ ) -> np.ndarray: ...
78
+
79
+ @overload
80
+ def __call__(
81
+ self, cost: Any,
82
+ extend_cost: bool = False,
83
+ cost_limit: float = ...,
84
+ *,
85
+ return_cost: Literal[False],
86
+ precision: _Precision = "native",
87
+ output: Literal["pairs"],
88
+ ) -> np.ndarray: ...
89
+
90
+ @overload
91
+ def __call__(
92
+ self, cost: Any,
93
+ extend_cost: bool = False,
94
+ cost_limit: float = ...,
95
+ return_cost: bool = True,
96
+ *,
97
+ precision: _Precision = "native",
98
+ output: Literal["pairs"],
99
+ ) -> Union[Tuple[float, np.ndarray], np.ndarray]: ...
100
+
101
+ @overload
102
+ def __call__(
103
+ self, cost: Any, extend_cost: bool = False,
104
+ cost_limit: float = ..., return_cost: bool = True,
105
+ *, precision: _Precision = "native", output: _Output = "indices",
106
+ ) -> Union[Tuple[float, np.ndarray, np.ndarray], Tuple[np.ndarray, np.ndarray], Tuple[float, np.ndarray], np.ndarray]: ...
107
+
108
+ class _BatchSolver(Protocol):
109
+ @overload
110
+ def __call__(
111
+ self, costs: Any,
112
+ extend_cost: bool = False,
113
+ cost_limit: float = ...,
114
+ return_cost: Literal[True] = True,
115
+ n_threads: Optional[int] = 0,
116
+ *,
117
+ precision: _Precision = "native",
118
+ output: Literal["indices"] = "indices",
119
+ ) -> Tuple[np.ndarray, List[np.ndarray], List[np.ndarray]]: ...
120
+
121
+ @overload
122
+ def __call__(
123
+ self, costs: Any,
124
+ extend_cost: bool,
125
+ cost_limit: float,
126
+ return_cost: Literal[False],
127
+ n_threads: Optional[int] = 0,
128
+ *,
129
+ precision: _Precision = "native",
130
+ output: Literal["indices"] = "indices",
131
+ ) -> Tuple[List[np.ndarray], List[np.ndarray]]: ...
132
+
133
+ @overload
134
+ def __call__(
135
+ self, costs: Any,
136
+ extend_cost: bool = False,
137
+ cost_limit: float = ...,
138
+ *,
139
+ return_cost: Literal[False],
140
+ n_threads: Optional[int] = 0,
141
+ precision: _Precision = "native",
142
+ output: Literal["indices"] = "indices",
143
+ ) -> Tuple[List[np.ndarray], List[np.ndarray]]: ...
144
+
145
+ @overload
146
+ def __call__(
147
+ self, costs: Any,
148
+ extend_cost: bool = False,
149
+ cost_limit: float = ...,
150
+ return_cost: bool = True,
151
+ n_threads: Optional[int] = 0,
152
+ *,
153
+ precision: _Precision = "native",
154
+ output: Literal["indices"] = "indices",
155
+ ) -> Union[Tuple[np.ndarray, List[np.ndarray], List[np.ndarray]], Tuple[List[np.ndarray], List[np.ndarray]]]: ...
156
+
157
+ @overload
158
+ def __call__(
159
+ self, costs: Any,
160
+ extend_cost: bool = False,
161
+ cost_limit: float = ...,
162
+ return_cost: Literal[True] = True,
163
+ n_threads: Optional[int] = 0,
164
+ *,
165
+ precision: _Precision = "native",
166
+ output: Literal["pairs"],
167
+ ) -> Tuple[np.ndarray, List[np.ndarray]]: ...
168
+
169
+ @overload
170
+ def __call__(
171
+ self, costs: Any,
172
+ extend_cost: bool,
173
+ cost_limit: float,
174
+ return_cost: Literal[False],
175
+ n_threads: Optional[int] = 0,
176
+ *,
177
+ precision: _Precision = "native",
178
+ output: Literal["pairs"],
179
+ ) -> List[np.ndarray]: ...
180
+
181
+ @overload
182
+ def __call__(
183
+ self, costs: Any,
184
+ extend_cost: bool = False,
185
+ cost_limit: float = ...,
186
+ *,
187
+ return_cost: Literal[False],
188
+ n_threads: Optional[int] = 0,
189
+ precision: _Precision = "native",
190
+ output: Literal["pairs"],
191
+ ) -> List[np.ndarray]: ...
192
+
193
+ @overload
194
+ def __call__(
195
+ self, costs: Any,
196
+ extend_cost: bool = False,
197
+ cost_limit: float = ...,
198
+ return_cost: bool = True,
199
+ n_threads: Optional[int] = 0,
200
+ *,
201
+ precision: _Precision = "native",
202
+ output: Literal["pairs"],
203
+ ) -> Union[Tuple[np.ndarray, List[np.ndarray]], List[np.ndarray]]: ...
204
+
205
+ @overload
206
+ def __call__(
207
+ self, costs: Any, extend_cost: bool = False,
208
+ cost_limit: float = ..., return_cost: bool = True,
209
+ n_threads: Optional[int] = 0,
210
+ *, precision: _Precision = "native", output: _Output = "indices",
211
+ ) -> Union[Tuple[np.ndarray, List[np.ndarray], List[np.ndarray]], Tuple[List[np.ndarray], List[np.ndarray]], Tuple[np.ndarray, List[np.ndarray]], List[np.ndarray]]: ...
212
+
213
+ lapjv: _SingleSolver
214
+ lapjv_batch: _BatchSolver
laprust/py.typed ADDED
@@ -0,0 +1,3 @@
1
+ # PEP 561 marker: tells type checkers that lap provides inline type annotations.
2
+ # Keep this file in source distributions and wheels so IDEs can use those types.
3
+ # This file is package metadata; Python does not execute it.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: laprust
3
+ Version: 1.0.0
4
+ Summary: Native Rust linear assignment solvers with implicit rejection and batch solving.
5
+ Home-page: https://github.com/rathaROG/laprust
6
+ Author: Ratha SIV
7
+ Maintainer: rathaROG
8
+ License: MIT
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Programming Language :: Python :: 3.15
22
+ Classifier: Topic :: Education
23
+ Classifier: Topic :: Education :: Testing
24
+ Classifier: Topic :: Scientific/Engineering
25
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
26
+ Classifier: Topic :: Software Development
27
+ Classifier: Topic :: Software Development :: Libraries
28
+ Classifier: Operating System :: Microsoft :: Windows
29
+ Classifier: Operating System :: POSIX
30
+ Classifier: Operating System :: Unix
31
+ Classifier: Operating System :: MacOS
32
+ Requires-Python: >=3.9
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ License-File: NOTICE
36
+ License-File: tests/LICENSE
37
+ License-File: src/_lapjv/LICENSE
38
+ License-File: src/_lapjv/THIRD_PARTY_NOTICES
39
+ Requires-Dist: numpy>=1.21.6
40
+ Provides-Extra: test
41
+ Requires-Dist: pytest>=7; extra == "test"
42
+ Requires-Dist: scipy>=1.9; extra == "test"
43
+ Requires-Dist: pytest-timeout; extra == "test"
44
+ Provides-Extra: benchmark
45
+ Requires-Dist: scipy>=1.9; extra == "benchmark"
46
+ Requires-Dist: lapx==0.11.1; extra == "benchmark"
47
+ Provides-Extra: dev
48
+ Requires-Dist: build; extra == "dev"
49
+ Requires-Dist: setuptools>=77; extra == "dev"
50
+ Requires-Dist: wheel; extra == "dev"
51
+ Requires-Dist: pytest>=7; extra == "dev"
52
+ Requires-Dist: scipy>=1.9; extra == "dev"
53
+ Requires-Dist: pytest-timeout; extra == "dev"
54
+ Requires-Dist: pyright; extra == "dev"
55
+ Dynamic: author
56
+ Dynamic: classifier
57
+ Dynamic: description
58
+ Dynamic: description-content-type
59
+ Dynamic: home-page
60
+ Dynamic: license
61
+ Dynamic: license-file
62
+ Dynamic: maintainer
63
+ Dynamic: provides-extra
64
+ Dynamic: requires-dist
65
+ Dynamic: requires-python
66
+ Dynamic: summary
67
+
68
+ # laprust
69
+
70
+ **laprust** solves dense linear assignment problems with a native
71
+ Rust implementation and a NumPy API. Python **3.9 or newer** is required.
72
+ It exposes two solvers: `lapjv` and `lapjv_batch`.
73
+
74
+ laprust 1.0.0 derives from the `lapjvr` solver in LAPX 0.11.1.
75
+ Future solver development is led by lapcpp for C++ and laprust for Rust;
76
+ LAPX will incorporate their fixes and improvements.
77
+
78
+ It solves rectangular problems directly and handles unmatched rows and columns
79
+ implicitly when a finite `cost_limit` is supplied, without allocating an expanded
80
+ square cost matrix.
81
+ The square path uses Jonker–Volgenant initialization, reduction, and shortest
82
+ augmenting paths. This package is independent of LAPX and imports as `laprust`.
83
+
84
+ ## Installation
85
+
86
+ Once available on PyPI:
87
+
88
+ ```sh
89
+ python -m pip install laprust
90
+ ```
91
+
92
+ A source build requires a C++17 compiler and, for `laprust`, Rust/Cargo 1.83+
93
+ with a compatible target. Build dependencies (NumPy, Cython, setuptools) are
94
+ installed automatically by pip. NumPy is the only Python runtime dependency.
95
+ An installed wheel needs no compiler or Rust toolchain.
96
+
97
+ ## Quick start
98
+
99
+ ```python
100
+ import numpy as np
101
+ import laprust
102
+
103
+ cost = np.array([[3., 1.], [1., 4.]])
104
+ total, rows, cols = laprust.lapjv(cost)
105
+ # total = 2.0; rows = [0, 1]; cols = [1, 0]
106
+
107
+ costs = np.stack([cost, cost]) # (batch, rows, columns)
108
+ totals, rows, cols = laprust.lapjv_batch(costs, n_threads=2)
109
+ # totals = [2., 2.]; rows and cols are lists of arrays, one per problem
110
+
111
+ rectangular = np.array([[.1, .8, .9], [.9, .7, .8]], dtype=np.float32)
112
+ total, rows, cols = laprust.lapjv(rectangular, cost_limit=.5)
113
+ # Only (0, 0) is selected; total is about .1, excluding rejection penalties.
114
+ ```
115
+
116
+ ## API
117
+
118
+ ```python
119
+ lapjv(cost, extend_cost=False, cost_limit=np.inf, return_cost=True,
120
+ *, precision="native", output="indices")
121
+ lapjv_batch(costs, extend_cost=False, cost_limit=np.inf, return_cost=True,
122
+ n_threads=0, *, precision="native", output="indices")
123
+ ```
124
+
125
+ | Option | Behavior |
126
+ | --- | --- |
127
+ | `cost` / `costs` | Real numeric arrays with shape `(N, M)` / `(B, N, M)`. |
128
+ | `extend_cost=True` | Allows rectangular inputs when the limit is infinite; no square padding is used. |
129
+ | `cost_limit` | A finite value permits unmatched endpoints at a penalty of `cost_limit / 2` each. Finite limits also permit rectangles and apply to square inputs. |
130
+ | `return_cost` | Defaults to `True`; totals sum selected original costs in float64 and exclude rejection penalties. `False` omits totals and skips the sum. |
131
+ | `precision` | `"native"` preserves float32/float64; other real numeric inputs use float64. Explicit `"float32"` / `"float64"` select working costs. |
132
+ | `output` | `"indices"` returns aligned row/column arrays; `"pairs"` returns `(K, 2)` arrays. |
133
+ | `n_threads` | Batch only. `0` / `None` selects automatically; negative values use one worker; positive values are capped by batch size. |
134
+
135
+ Rows are sorted and all returned indices are int64. They identify the selected
136
+ pairs; unmatched items are absent. Batch results contain lists because each
137
+ problem may select a different number of pairs. Equal-cost optima may return
138
+ different assignments across solvers or precisions.
139
+
140
+ With a finite limit `L`, the optimized objective is
141
+ `sum(selected costs) + (N + M - 2*K) * L/2`.
142
+ The reported `total` contains only the first term. Joint rejection is different
143
+ from solving a full assignment and then filtering high-cost pairs.
144
+ See [API details](docs/api.md) for numerical and memory behavior.
145
+
146
+ ## Development and checks
147
+
148
+ ```sh
149
+ python -m pip install -e ".[dev]"
150
+ cd tests
151
+ python -m pytest -q -m "not cross_package"
152
+ cd ..
153
+ python -m pytest -q .github/tests -m "not editable"
154
+ python -m build
155
+ ```
156
+
157
+ The test suite covers SciPy and exhaustive-reference comparisons, rectangular
158
+ and finite-limit cases, float32/float64, precision conversion, forbidden edges,
159
+ empty inputs, invalid arguments, repeated workspaces, batch thread counts,
160
+ concurrent calls, package independence, and type annotations.
161
+ Historical LAPX regressions, cross-package concurrency, and isolated editable
162
+ installs are also covered. See the [solver test inventory](tests/README.md),
163
+ [build and packaging checks](.github/tests/README.md), and
164
+ [CONTRIBUTING.md](CONTRIBUTING.md) for commands and coverage.
165
+
166
+ ## Benchmarks
167
+
168
+ All three benchmark scripts compare **SciPy (baseline), lapcpp, laprust,
169
+ LAPX lapjvxa and LAPX lapjvsa**. The LAPX candidates represent the JVX and JVS
170
+ families using pair outputs, including their batch APIs. Once lapcpp and laprust
171
+ are available on PyPI, install the dependencies below. Clone or
172
+ download this repository for the scripts and run them from the repository root.
173
+
174
+ ```sh
175
+ python -m pip install --upgrade lapcpp laprust "lapx==0.11.1" scipy
176
+ python benchmarks/benchmark_single.py --quick --repeats 3
177
+ python benchmarks/benchmark_batch.py --quick --threads 4 --repeats 3
178
+ python benchmarks/benchmark_tracking.py --quick --repeats 3
179
+ ```
180
+
181
+ Use `--json benchmark-results/run.json` to save measurements and environment
182
+ details. Each solver is warmed right before its own sample, and calls repeat
183
+ until a sample lasts at least 10 ms; `--reference-timing` restores the pinned
184
+ LAPX timing. See [benchmark methodology](benchmarks/README.md) for full workloads,
185
+ reference LAPX settings, dedicated solver functions, tracking post-filtering, and
186
+ timing boundaries. Tracking never passes its threshold as solver `cost_limit`.
187
+
188
+ ## Paper
189
+
190
+ The solver, its implicit rejection, and its performance against SciPy and other
191
+ Jonker–Volgenant implementations are described in *Native Rectangular Linear
192
+ Assignment with Implicit Rejection: A Jonker–Volgenant Solver without Square
193
+ Expansion*, where laprust is labeled JVRUST. Read the
194
+ [PDF](https://github.com/rathaROG/lap-paper/blob/main/output/pdf/native_rectangular_assignment.pdf);
195
+ its scripts, raw results, and reproduction steps are in the
196
+ [lap-paper](https://github.com/rathaROG/lap-paper) repository.
197
+
198
+ ## Automation and license
199
+
200
+ GitHub workflows test supported Python versions on Windows, Linux and macOS,
201
+ build and test source archives and wheels, and run the three benchmark modes.
202
+ Wheel builds are also available manually. A version tag triggers the release
203
+ workflow; PyPI publishing uses the repository's `pypi` environment and requires
204
+ its Trusted Publisher configuration. No releases are published by local builds.
205
+
206
+ MIT licensed. See [LICENSE](LICENSE), [NOTICE](NOTICE), and
207
+ [native-source license](src/_lapjv/LICENSE) for attribution.
@@ -0,0 +1,14 @@
1
+ laprust/__init__.py,sha256=9VxJPznoAMLtmDuzAr00HtSEbIrDZBmAJuMrcox5G2A,371
2
+ laprust/__init__.pyi,sha256=lBZQwPZlnjCne2rE5a85Y9diKHVMqyowgBmuA2C9Jo4,102
3
+ laprust/_lapjv.cp315-win_amd64.pyd,sha256=b-VnL9JU36JxQuiNiMIEus5k_GiBwT6ixcEWaDWXz7Q,413696
4
+ laprust/_lapjv.pyi,sha256=Q-TsTNd9LNo0ljHqlDOPhxCOg_hHVXM7oZB5LKp0oXM,6668
5
+ laprust/py.typed,sha256=oD5aTIMVm1T_JgT9BBWE-NnjwwrBB8obapedLpgBAIw,224
6
+ laprust-1.0.0.dist-info/licenses/LICENSE,sha256=CwiIqXxH7u-IMqGpwv76ZusNV6NTJ6lUxtFY7OA3tfs,1086
7
+ laprust-1.0.0.dist-info/licenses/NOTICE,sha256=FxvnuQFiQO2-wduZwHEAhStUh8j9moVPE1rpBeIgJPE,757
8
+ laprust-1.0.0.dist-info/licenses/src/_lapjv/LICENSE,sha256=jX3ViOgZaNCvcXnIYO25Gjz3IuliYGm0SoC1eaHG3jw,1136
9
+ laprust-1.0.0.dist-info/licenses/src/_lapjv/THIRD_PARTY_NOTICES,sha256=-fa9tAbxTwAi9SDl5mIfmLBrB7ancqoxKmnZVBj35HI,7141
10
+ laprust-1.0.0.dist-info/licenses/tests/LICENSE,sha256=ywsyoyzHjv5Up3ccXuz6Z8fyRchCjVhSZkYbaJu2nIs,1361
11
+ laprust-1.0.0.dist-info/METADATA,sha256=X8PF_hZzYMdZNDXk3pAofmk39FW3Vnd8T0DGA4h80Nk,9083
12
+ laprust-1.0.0.dist-info/WHEEL,sha256=0gLwYZa0C2fhgCxWR2c8HahwUiopqonVCV0wVwEg6fE,101
13
+ laprust-1.0.0.dist-info/top_level.txt,sha256=BUxFQq_xCWZ4CGmzKQcNkel539GVMEYyazH6SiT9gFo,8
14
+ laprust-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp315-cp315-win_amd64
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rathaROG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ laprust 1.0.0 is derived from the lapjvr solver family of LAPX 0.11.1
2
+ (rathaROG/lapx, v0.11.1).
3
+
4
+ The square Jonker-Volgenant implementation derives from source{d}/lapjv
5
+ and carries the copyright of Vadim Markovtsev (2016). Native rectangular
6
+ assignment, implicit rejection handling, adapters and batch execution derive
7
+ from Ratha SIV's LAPX work (2026). See src/_lapjv/LICENSE for the full MIT text.
8
+ The top-level LICENSE covers this package. Neither package requires LAPX.
9
+
10
+ Rust dependencies and their notices are listed in src/_lapjv/THIRD_PARTY_NOTICES.
11
+
12
+ Historical regression matrices and fixture generators are adapted from LAPX/gatagat-lap tests under BSD-2-Clause. See tests/LICENSE. The epsilon dataset was contributed by Michael Lewis.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Vadim Markovtsev (source{d})
4
+ Copyright (c) 2026 Ratha SIV
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,188 @@
1
+ Rust dependency notices
2
+
3
+ These dependencies are used under their MIT license option. Versions match Cargo.lock.
4
+
5
+ crossbeam-deque 0.8.8
6
+ https://github.com/crossbeam-rs/crossbeam
7
+
8
+ The MIT License (MIT)
9
+
10
+ Copyright (c) 2019 The Crossbeam Project Developers
11
+
12
+ Permission is hereby granted, free of charge, to any
13
+ person obtaining a copy of this software and associated
14
+ documentation files (the "Software"), to deal in the
15
+ Software without restriction, including without
16
+ limitation the rights to use, copy, modify, merge,
17
+ publish, distribute, sublicense, and/or sell copies of
18
+ the Software, and to permit persons to whom the Software
19
+ is furnished to do so, subject to the following
20
+ conditions:
21
+
22
+ The above copyright notice and this permission notice
23
+ shall be included in all copies or substantial portions
24
+ of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
27
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
28
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
30
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
31
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
33
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34
+ DEALINGS IN THE SOFTWARE.
35
+
36
+
37
+ crossbeam-epoch 0.9.21
38
+ https://github.com/crossbeam-rs/crossbeam
39
+
40
+ The MIT License (MIT)
41
+
42
+ Copyright (c) 2019 The Crossbeam Project Developers
43
+
44
+ Permission is hereby granted, free of charge, to any
45
+ person obtaining a copy of this software and associated
46
+ documentation files (the "Software"), to deal in the
47
+ Software without restriction, including without
48
+ limitation the rights to use, copy, modify, merge,
49
+ publish, distribute, sublicense, and/or sell copies of
50
+ the Software, and to permit persons to whom the Software
51
+ is furnished to do so, subject to the following
52
+ conditions:
53
+
54
+ The above copyright notice and this permission notice
55
+ shall be included in all copies or substantial portions
56
+ of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
59
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
60
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
61
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
62
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
64
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
65
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
66
+ DEALINGS IN THE SOFTWARE.
67
+
68
+
69
+ crossbeam-utils 0.8.23
70
+ https://github.com/crossbeam-rs/crossbeam
71
+
72
+ The MIT License (MIT)
73
+
74
+ Copyright (c) 2019 The Crossbeam Project Developers
75
+
76
+ Permission is hereby granted, free of charge, to any
77
+ person obtaining a copy of this software and associated
78
+ documentation files (the "Software"), to deal in the
79
+ Software without restriction, including without
80
+ limitation the rights to use, copy, modify, merge,
81
+ publish, distribute, sublicense, and/or sell copies of
82
+ the Software, and to permit persons to whom the Software
83
+ is furnished to do so, subject to the following
84
+ conditions:
85
+
86
+ The above copyright notice and this permission notice
87
+ shall be included in all copies or substantial portions
88
+ of the Software.
89
+
90
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
91
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
92
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
93
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
94
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
95
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
96
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
97
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
98
+ DEALINGS IN THE SOFTWARE.
99
+
100
+
101
+ either 1.19.0
102
+ https://github.com/rayon-rs/either
103
+
104
+ Copyright (c) 2015
105
+
106
+ Permission is hereby granted, free of charge, to any
107
+ person obtaining a copy of this software and associated
108
+ documentation files (the "Software"), to deal in the
109
+ Software without restriction, including without
110
+ limitation the rights to use, copy, modify, merge,
111
+ publish, distribute, sublicense, and/or sell copies of
112
+ the Software, and to permit persons to whom the Software
113
+ is furnished to do so, subject to the following
114
+ conditions:
115
+
116
+ The above copyright notice and this permission notice
117
+ shall be included in all copies or substantial portions
118
+ of the Software.
119
+
120
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
121
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
122
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
123
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
124
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
125
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
126
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
127
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
128
+ DEALINGS IN THE SOFTWARE.
129
+
130
+
131
+ rayon 1.12.0
132
+ https://github.com/rayon-rs/rayon
133
+
134
+ Copyright (c) 2010 The Rust Project Developers
135
+
136
+ Permission is hereby granted, free of charge, to any
137
+ person obtaining a copy of this software and associated
138
+ documentation files (the "Software"), to deal in the
139
+ Software without restriction, including without
140
+ limitation the rights to use, copy, modify, merge,
141
+ publish, distribute, sublicense, and/or sell copies of
142
+ the Software, and to permit persons to whom the Software
143
+ is furnished to do so, subject to the following
144
+ conditions:
145
+
146
+ The above copyright notice and this permission notice
147
+ shall be included in all copies or substantial portions
148
+ of the Software.
149
+
150
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
151
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
152
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
153
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
154
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
155
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
156
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
157
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
158
+ DEALINGS IN THE SOFTWARE.
159
+
160
+
161
+ rayon-core 1.13.0
162
+ https://github.com/rayon-rs/rayon
163
+
164
+ Copyright (c) 2010 The Rust Project Developers
165
+
166
+ Permission is hereby granted, free of charge, to any
167
+ person obtaining a copy of this software and associated
168
+ documentation files (the "Software"), to deal in the
169
+ Software without restriction, including without
170
+ limitation the rights to use, copy, modify, merge,
171
+ publish, distribute, sublicense, and/or sell copies of
172
+ the Software, and to permit persons to whom the Software
173
+ is furnished to do so, subject to the following
174
+ conditions:
175
+
176
+ The above copyright notice and this permission notice
177
+ shall be included in all copies or substantial portions
178
+ of the Software.
179
+
180
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
181
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
182
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
183
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
184
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
185
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
186
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
187
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
188
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2012-2025, Tomas Kazmar
4
+ Copyright (c) 2026, Ratha SIV
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ laprust