Skip to content

Commit 54533c8

Browse files
committed
Fixed: Correctly filters checksum files in CI
Replaces `grep -F` with `awk` to reliably filter checksum files in CI workflows by matching the last field against the target filename. This ensures that the correct checksum is selected, even when the filename contains spaces or special characters. Also, updates the `yaml-fix` recipe in the justfile to use `prettier` if available, falling back to `npx` if not. This resolves an issue where YAML formatting would fail if `prettier` was not globally installed. Adds more terms to the spellcheck dictionary and a reference file. Refs: feat/ldlt
1 parent 686bcbc commit 54533c8

File tree

8 files changed

+101
-24
lines changed

8 files changed

+101
-24
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ jobs:
136136
137137
orig_dir="$PWD"
138138
cd "$tmpdir"
139-
grep -F " $TARBALL" "$CHECKSUMS_FILE" > checksum.txt
139+
awk -v f="$TARBALL" '$NF==f {print; found=1} END {exit found?0:1}' "$CHECKSUMS_FILE" > checksum.txt
140140
verify_sha256 checksum.txt
141141
cd "$orig_dir"
142142
@@ -177,7 +177,7 @@ jobs:
177177
178178
(
179179
cd "$tmpdir"
180-
grep -F " ${SHFMT_ASSET}" sha256sums.txt > checksum.txt
180+
awk -v f="${SHFMT_ASSET}" '$NF==f {print; found=1} END {exit found?0:1}' sha256sums.txt > checksum.txt
181181
sha256sum -c checksum.txt
182182
)
183183
@@ -210,7 +210,7 @@ jobs:
210210
211211
(
212212
cd "$tmpdir"
213-
grep -F " ${SHFMT_ASSET}" sha256sums.txt > checksum.txt
213+
awk -v f="${SHFMT_ASSET}" '$NF==f {print; found=1} END {exit found?0:1}' sha256sums.txt > checksum.txt
214214
shasum -a 256 -c checksum.txt
215215
)
216216

.github/workflows/codecov.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
fi
4949
5050
- name: Install just
51-
uses: taiki-e/install-action@bfc291e1e39400b67eda124e4a7b4380e93b3390 # v2.65.0
51+
uses: taiki-e/install-action@bfc291e1e39400b67eda124e4a7b4380e93b3390 # v2.65.0
5252
with:
5353
tool: just
5454

@@ -76,7 +76,7 @@ jobs:
7676

7777
- name: Upload coverage to Codecov
7878
if: ${{ success() && hashFiles('coverage/cobertura.xml') != '' }}
79-
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
79+
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
8080
with:
8181
files: coverage/cobertura.xml
8282
flags: unittests

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ venv/
1515
.mypy_cache/
1616
uv.lock
1717
/node_modules/
18-
/.package-lock.json
1918
/package-lock.json
20-
/package.json

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,25 @@ for (x_i, e_i) in x.iter().zip(expected.iter()) {
8181
}
8282
```
8383

84-
Compute a determinant for a symmetric SPD matrix via LDLT (no pivoting):
84+
Compute a determinant for a symmetric SPD matrix via LDLT (no pivoting).
85+
86+
For symmetric positive-definite matrices, `LDL^T` is essentially a square-root-free form of the Cholesky decomposition
87+
(you can recover a Cholesky factor by absorbing `sqrt(D)` into `L`):
8588

8689
```rust
8790
use la_stack::prelude::*;
8891

89-
let a = Matrix::<2>::from_rows([[4.0, 2.0], [2.0, 3.0]]);
92+
// This matrix is symmetric positive-definite (A = L*L^T) so LDLT works without pivoting.
93+
let a = Matrix::<5>::from_rows([
94+
[1.0, 1.0, 0.0, 0.0, 0.0],
95+
[1.0, 2.0, 1.0, 0.0, 0.0],
96+
[0.0, 1.0, 2.0, 1.0, 0.0],
97+
[0.0, 0.0, 1.0, 2.0, 1.0],
98+
[0.0, 0.0, 0.0, 1.0, 2.0],
99+
]);
100+
90101
let det = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap().det();
91-
assert!((det - 8.0).abs() <= 1e-12);
102+
assert!((det - 1.0).abs() <= 1e-12);
92103
```
93104

94105
## 🧩 API at a glance

REFERENCES.md

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,41 @@ A Zenodo DOI will be added for tagged releases.
1515
The LU implementation in `la-stack` follows the standard Gaussian elimination / LU factorization
1616
approach with partial pivoting for numerical stability.
1717

18-
- Golub, Gene H., and Charles F. Van Loan. *Matrix Computations* (4th ed.). Johns Hopkins University Press, 2013.
19-
- Higham, Nicholas J. *Accuracy and Stability of Numerical Algorithms* (2nd ed.). SIAM, 2002.
20-
- Trefethen, Lloyd N., and David Bau III. *Numerical Linear Algebra*. SIAM, 1997.
18+
See references [1-3] below.
2119

2220
### LDL^T factorization (symmetric SPD/PSD)
2321

2422
The LDL^T (often abbreviated "LDLT") implementation in `la-stack` is intended for symmetric positive
25-
definite (SPD) and positive semi-definite (PSD) matrices (e.g. Gram matrices), and does not perform
23+
definite (SPD) and positive semi-definite (PSD) matrices (e.g. Gram matrices), and does not perform
2624
pivoting.
2725

28-
- Golub, Gene H., and Charles F. Van Loan. *Matrix Computations* (4th ed.). Johns Hopkins University Press, 2013.
29-
- Higham, Nicholas J. *Accuracy and Stability of Numerical Algorithms* (2nd ed.). SIAM, 2002.
30-
- Trefethen, Lloyd N., and David Bau III. *Numerical Linear Algebra*. SIAM, 1997.
26+
For background on the SPD/PSD setting, see [4-5]. For pivoted variants used for symmetric *indefinite*
27+
matrices, see [6].
28+
29+
## References
30+
31+
### LU / Gaussian elimination
32+
33+
1. Trefethen, Lloyd N., and Robert S. Schreiber. "Average-case stability of Gaussian elimination."
34+
*SIAM Journal on Matrix Analysis and Applications* 11.3 (1990): 335–360.
35+
[PDF](https://people.maths.ox.ac.uk/trefethen/publication/PDF/1990_44.pdf)
36+
2. Businger, P. A. "Monitoring the Numerical Stability of Gaussian Elimination."
37+
*Numerische Mathematik* 16 (1970/71): 360–361.
38+
[Full text](https://eudml.org/doc/132040)
39+
3. Huang, Han, and K. Tikhomirov. "Average-case analysis of the Gaussian elimination with partial pivoting."
40+
*Probability Theory and Related Fields* 189 (2024): 501–567.
41+
[Open-access PDF](https://link.springer.com/article/10.1007/s00440-024-01276-2) (also: [arXiv:2206.01726](https://arxiv.org/abs/2206.01726))
42+
43+
### LDL^T / Cholesky (symmetric SPD/PSD)
44+
45+
4. Cholesky, Andre-Louis. "On the numerical solution of systems of linear equations"
46+
(manuscript dated 2 Dec 1910; published 2005).
47+
Scan + English analysis: [BibNum](https://www.bibnum.education.fr/mathematiques/algebre/sur-la-resolution-numerique-des-systemes-d-equations-lineaires)
48+
5. Brezinski, Claude. "La methode de Cholesky." (2005).
49+
[PDF](https://eudml.org/doc/252115)
50+
51+
### Pivoted LDL^T (symmetric indefinite)
52+
53+
6. Bunch, J. R., L. Kaufman, and B. N. Parlett. "Decomposition of a Symmetric Matrix."
54+
*Numerische Mathematik* 27 (1976/1977): 95–110.
55+
[Full text](https://eudml.org/doc/132435)

cspell.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"acgetchell",
77
"addopts",
88
"blas",
9+
"Brezinski",
10+
"Businger",
911
"capsys",
1012
"Clippy",
1113
"clippy",
@@ -39,6 +41,8 @@
3941
"logscale",
4042
"lu",
4143
"markdownlint",
44+
"Mathematik",
45+
"methode",
4246
"minversion",
4347
"MSRV",
4448
"msvc",
@@ -51,8 +55,10 @@
5155
"noplot",
5256
"nrhs",
5357
"nrows",
58+
"Numerische",
5459
"openblas",
5560
"orcid",
61+
"Parlett",
5662
"pastey",
5763
"patchlevel",
5864
"pipefail",
@@ -68,6 +74,7 @@
6874
"rustup",
6975
"samply",
7076
"sarif",
77+
"Schreiber",
7178
"semgrep",
7279
"setuptools",
7380
"shellcheck",
@@ -78,6 +85,7 @@
7885
"Taplo",
7986
"taplo",
8087
"testpaths",
88+
"Tikhomirov",
8189
"Trefethen",
8290
"tridiagonal",
8391
"unittests",

justfile

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,14 @@ setup-tools:
340340
install_with_brew node
341341
echo ""
342342
else
343-
echo "'brew' not found."
343+
echo "⚠️ 'brew' not found; skipping automatic tool installation."
344344
if [[ "$os" == "Darwin" ]]; then
345-
echo "Install Homebrew from https://brew.sh and re-run: just setup-tools"
346-
exit 1
345+
echo "Install Homebrew from https://brew.sh (recommended), or install the following tools manually:"
346+
else
347+
echo "Install the following tools via your system package manager:"
347348
fi
348-
echo "Install the following tools via your system package manager, then re-run: just setup-tools"
349349
echo " uv, jq, taplo, yamllint, shfmt, shellcheck, actionlint, node+npx"
350-
exit 1
350+
echo ""
351351
fi
352352

353353
echo "Ensuring Rust toolchain + components..."
@@ -517,7 +517,7 @@ validate-json: _ensure-jq
517517
fi
518518

519519
# YAML
520-
yaml-fix: _ensure-npx
520+
yaml-fix:
521521
#!/usr/bin/env bash
522522
set -euo pipefail
523523
files=()
@@ -526,8 +526,26 @@ yaml-fix: _ensure-npx
526526
done < <(git ls-files -z '*.yml' '*.yaml')
527527
if [ "${#files[@]}" -gt 0 ]; then
528528
echo "📝 prettier --write (YAML, ${#files[@]} files)"
529+
530+
cmd=()
531+
if command -v prettier >/dev/null; then
532+
cmd=(prettier --write --print-width 120)
533+
elif command -v npx >/dev/null; then
534+
# Prefer non-interactive installs when supported (newer npm/npx).
535+
# NOTE: With `set -u`, expanding an empty array like "${arr[@]}" can error on older bash.
536+
cmd=(npx)
537+
if npx --help 2>&1 | grep -q -- '--yes'; then
538+
cmd+=(--yes)
539+
fi
540+
cmd+=(prettier --write --print-width 120)
541+
else
542+
echo "❌ 'prettier' not found. Install via npm (recommended): npm i -g prettier"
543+
echo " Or install Node.js (for npx): https://nodejs.org"
544+
exit 1
545+
fi
546+
529547
# Use CLI flags instead of a repo-wide prettier config: keeps the scope to YAML only.
530-
printf '%s\0' "${files[@]}" | xargs -0 -n100 npx prettier --write --print-width 120
548+
printf '%s\0' "${files[@]}" | xargs -0 -n100 "${cmd[@]}"
531549
else
532550
echo "No YAML files found to format."
533551
fi

src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ mod readme_doctests {
2929
/// }
3030
/// ```
3131
fn solve_5x5_example() {}
32+
33+
/// ```rust
34+
/// use la_stack::prelude::*;
35+
///
36+
/// // This matrix is symmetric positive-definite (A = L*L^T) so LDLT works without pivoting.
37+
/// let a = Matrix::<5>::from_rows([
38+
/// [1.0, 1.0, 0.0, 0.0, 0.0],
39+
/// [1.0, 2.0, 1.0, 0.0, 0.0],
40+
/// [0.0, 1.0, 2.0, 1.0, 0.0],
41+
/// [0.0, 0.0, 1.0, 2.0, 1.0],
42+
/// [0.0, 0.0, 0.0, 1.0, 2.0],
43+
/// ]);
44+
///
45+
/// let det = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap().det();
46+
/// assert!((det - 1.0).abs() <= 1e-12);
47+
/// ```
48+
fn det_5x5_ldlt_example() {}
3249
}
3350

3451
mod ldlt;

0 commit comments

Comments
 (0)