Skip to content

Commit f74315d

Browse files
committed
expand readme;
expand doxygen pages;
1 parent 54108e6 commit f74315d

8 files changed

Lines changed: 1094 additions & 2 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,5 @@ cython_debug/
204204
marimo/_static/
205205
marimo/_lsp/
206206
__marimo__/
207+
208+
doxygen/html

README.md

Lines changed: 347 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,347 @@
1-
# SamplingLCD
2-
Fast LCD & mCvM sampling, with bindings to Python & Julia.
1+
# Deterministic Gaussian Sampling (C++)
2+
3+
Deterministic approximation and reduction of multivariate **Dirac mixtures** and **Gaussian distributions** using a high-performance C++ implementation.
4+
5+
The library provides optimization-based approximation algorithms with analytical gradients and optional multi-threaded execution.
6+
7+
Prebuilt binaries for **Linux** and **Windows** are automatically generated via GitHub Actions and attached to tagged releases.
8+
9+
---
10+
11+
# Requirements
12+
13+
## Core
14+
15+
- C++17 or newer
16+
- CMake ≥ 3.15
17+
- OpenMP
18+
- GSL (GNU Scientific Library)
19+
20+
## Optional
21+
22+
- GoogleTest (unit tests)
23+
- Google Benchmark (benchmarks)
24+
25+
---
26+
27+
# Build
28+
29+
The project supports:
30+
31+
- Native Windows build (MinGW + vcpkg)
32+
- Linux build (Docker-based)
33+
- CI-based release artifacts
34+
35+
---
36+
37+
# 🔹 Windows Build (MinGW + vcpkg)
38+
39+
Dependencies are managed via **vcpkg**.
40+
41+
## 1️⃣ Install MinGW
42+
43+
Install via Chocolatey:
44+
45+
```powershell
46+
choco install mingw -y
47+
```
48+
49+
Ensure MinGW is in your `PATH`.
50+
51+
---
52+
53+
## 2️⃣ Install Dependencies (vcpkg)
54+
55+
```powershell
56+
git clone https://github.com/microsoft/vcpkg.git
57+
.\vcpkg\bootstrap-vcpkg.bat
58+
59+
.\vcpkg\vcpkg install `
60+
gsl:x64-mingw-static `
61+
gsl:x64-mingw-dynamic `
62+
gtest:x64-mingw-static `
63+
benchmark:x64-mingw-static
64+
```
65+
66+
---
67+
68+
## 3️⃣ Configure and Build
69+
70+
```powershell
71+
mkdir build
72+
cd build
73+
74+
cmake .. -G "MinGW Makefiles" `
75+
-DCMAKE_BUILD_TYPE=Release `
76+
-DCMAKE_PREFIX_PATH="../vcpkg/installed/x64-mingw-static;../vcpkg/installed/x64-mingw-dynamic" `
77+
-DOpenMP_C_FLAGS="-fopenmp" `
78+
-DOpenMP_CXX_FLAGS="-fopenmp"
79+
80+
cmake --build . --target install
81+
```
82+
83+
---
84+
85+
## Run Tests
86+
87+
```powershell
88+
.\lib\unit.exe
89+
```
90+
91+
---
92+
93+
# 🔹 Linux Build (Docker)
94+
95+
Linux builds are performed inside a Docker container to ensure reproducibility.
96+
97+
## Build Docker Image
98+
99+
```bash
100+
docker build -f Dockerfile.linux -t libapproxlcd-builder .
101+
```
102+
103+
## Run Build Container
104+
105+
```bash
106+
docker run --rm \
107+
-e BUILD_DIR="/work/build" \
108+
-e ARTIFACT_DIR="/work/artifacts" \
109+
-v "$PWD:/work" \
110+
libapproxlcd-builder
111+
```
112+
113+
Artifacts will be placed in:
114+
115+
```
116+
artifacts/linux
117+
```
118+
119+
---
120+
121+
# 🔹 Prebuilt Binaries
122+
123+
Every tagged release (`v*`) automatically generates:
124+
125+
- `linux.zip`
126+
- `windows.zip`
127+
128+
These archives contain:
129+
130+
- Installed headers
131+
- Libraries
132+
- Unit test executable
133+
- Benchmark executable
134+
- Example application (main)
135+
136+
Download them from the **GitHub Releases** page.
137+
138+
---
139+
140+
# Overview
141+
142+
The library provides the following main components:
143+
144+
```cpp
145+
dirac_to_dirac_approx_short
146+
dirac_to_dirac_approx_short_thread
147+
dirac_to_dirac_approx_short_function
148+
gm_to_dirac_short
149+
gm_to_dirac_short_standard_normal_deviation
150+
```
151+
152+
They allow you to:
153+
154+
- Reduce large Dirac mixtures to compact deterministic representations
155+
- Approximate Gaussian distributions with optimized Dirac support points
156+
- Compute the modified van Mises distance
157+
- Compute the analytic gradient
158+
- Use custom weight functions
159+
- Switch between single-threaded and multi-threaded execution
160+
161+
---
162+
163+
# 1️⃣ Dirac-to-Dirac Reduction
164+
165+
Reduce `M` Dirac components in ℝᴺ to `L < M` optimized deterministic components.
166+
167+
---
168+
169+
## Basic Example (Single-Threaded)
170+
171+
```cpp
172+
#include <vector>
173+
#include <iostream>
174+
#include "dirac_to_dirac_approx_short.h"
175+
176+
size_t M = 3000;
177+
size_t N = 2;
178+
size_t L = 12;
179+
size_t bMax = 10;
180+
181+
std::vector<double> y(M * N);
182+
std::vector<double> x(L * N);
183+
184+
dirac_to_dirac_approx_short<double> reducer;
185+
186+
GslminimizerResult result;
187+
188+
bool ok = reducer.approximate(
189+
y.data(),
190+
M,
191+
L,
192+
N,
193+
bMax,
194+
x.data()
195+
);
196+
197+
std::cout << "Success: " << ok << std::endl;
198+
```
199+
200+
---
201+
202+
## Multi-Threaded Version
203+
204+
```cpp
205+
#include "dirac_to_dirac_approx_short_thread.h"
206+
207+
dirac_to_dirac_approx_short_thread<double> reducer;
208+
209+
bool ok = reducer.approximate(
210+
y.data(),
211+
M,
212+
L,
213+
N,
214+
bMax,
215+
x.data()
216+
);
217+
```
218+
219+
Produces the same result as the single-threaded version, but parallelizes internal computations.
220+
221+
---
222+
223+
## Custom Weight Functions
224+
225+
```cpp
226+
#include <cmath>
227+
#include "dirac_to_dirac_approx_short_function.h"
228+
229+
static void wXcallback(const double* x,
230+
double* res,
231+
size_t L,
232+
size_t N)
233+
{
234+
for (size_t i = 0; i < L; ++i) {
235+
double sum = 0.0;
236+
for (size_t k = 0; k < N; ++k) {
237+
double v = x[i * N + k];
238+
sum += v * v;
239+
}
240+
res[i] = std::exp(-sum);
241+
}
242+
}
243+
244+
static void wXDcallback(const double* x,
245+
double* grad,
246+
size_t L,
247+
size_t N)
248+
{
249+
for (size_t i = 0; i < L; ++i)
250+
for (size_t k = 0; k < N; ++k)
251+
grad[i * N + k] = -2.0 * x[i * N + k];
252+
}
253+
```
254+
255+
---
256+
257+
# 2️⃣ Gaussian-to-Dirac Approximation
258+
259+
Approximate a multivariate Gaussian distribution with `L` deterministic Dirac points.
260+
261+
---
262+
263+
## Standard Normal Deviation Variant
264+
265+
```cpp
266+
#include "gm_to_dirac_short_standard_normal_deviation.h"
267+
268+
gm_to_dirac_short_standard_normal_deviation<double> approx;
269+
270+
std::vector<double> x(L * N);
271+
272+
bool ok = approx.approximate(
273+
L,
274+
N,
275+
bMax,
276+
x.data()
277+
);
278+
```
279+
280+
---
281+
282+
## Diagonal Covariance Variant
283+
284+
```cpp
285+
#include "gm_to_dirac_short.h"
286+
287+
std::vector<double> covDiag = {2.0, 1.5};
288+
std::vector<double> x(L * N);
289+
290+
gm_to_dirac_short<double> approx;
291+
292+
bool ok = approx.approximate(
293+
covDiag.data(),
294+
L,
295+
N,
296+
bMax,
297+
x.data()
298+
);
299+
```
300+
301+
---
302+
303+
# Distance and Gradient
304+
305+
### Compute Distance
306+
307+
```cpp
308+
double distance = 0.0;
309+
310+
reducer.modified_van_mises_distance_sq(
311+
&distance,
312+
y.data(),
313+
M,
314+
L,
315+
N,
316+
bMax,
317+
x.data()
318+
);
319+
```
320+
321+
### Compute Analytic Gradient
322+
323+
```cpp
324+
std::vector<double> gradient(L * N);
325+
326+
reducer.modified_van_mises_distance_sq_derivative(
327+
gradient.data(),
328+
y.data(),
329+
M,
330+
L,
331+
N,
332+
bMax,
333+
x.data()
334+
);
335+
```
336+
337+
---
338+
339+
# Notes
340+
341+
- High-performance C++ implementation
342+
- Analytical gradients
343+
- GSL-based optimization backend
344+
- OpenMP-enabled threaded variants
345+
- Docker-based reproducible Linux builds
346+
- Automated Windows + Linux release packaging
347+
- Designed for high-dimensional and performance-critical applications

0 commit comments

Comments
 (0)