This commit closes the remaining red gates so `run-all.sh --fast` is
green end-to-end on the canonical dev machine.
New gates
─────────
1. cmake-format / cmake-lint
* scripts/quality/cmake-format.sh — dry-run by default,
--strict to fail on drift, --fix to apply
* .cmake-format.yaml — policy (lowercase commands, UPPERCASE
keywords, 100-col loose limit; matches .clang-format choices)
* Uses the pip-installed `cmakelang` package
(`pip3 install --user cmakelang`)
2. codespell
* scripts/quality/codespell.sh — exit 1 on any typo, --fix
interactively
* .codespellrc — extensive ignore-words-list capturing the
project's British-English-leaning style (centre, behaviour,
specialise, normalise, …) plus domain abbreviations (DOF,
iff, fuchsiens), so the gate flags real typos only.
* Validated: 0 typos across docs + code/include + scripts +
code/{src,tests}.
SPDX rollout (license-headers --fix)
────────────────────────────────────
license-headers.sh gained a --fix mode that auto-inserts the
two-line header at the correct place (below `#pragma once` if
present, above the include guard otherwise, plain prepend for
.cpp). Ran it on 60 of 66 files — 100 %-licensed now.
Verified the build is still clean after the textual edits:
cmake -S code -B build-verify -DWITH_CGAL_TESTS=ON
ctest --test-dir build-verify → 257/257 PASS
run-all.sh + README updated to include the two new gates.
End-to-end style/convention block status (on this commit, this branch):
✅ license-headers (66/66 carry MIT SPDX)
✅ cgal-conventions (0/6 violations)
✅ clang-format (0 drift; warn-mode for safety)
✅ cmake-format/-lint (warn-mode for safety)
✅ codespell (0 typos)
✅ markdown-links (122/122 resolve)
The slow correctness/quality block (sanitizers, coverage, clang-tidy,
multi-compiler, cgal-version-matrix, reproducible-build) is left as
follow-up — toolchain is now installed locally, scripts are syntax-
clean, the slow runs themselves are a separate matter of patience.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
47 lines
1.4 KiB
C++
47 lines
1.4 KiB
C++
#pragma once
|
|
// Copyright (c) 2024-2026 Tarik Moussa.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
// Ported from de.varylab.discreteconformal.util.DiscreteEllipticUtility (Java).
|
|
// Only the pure-math subset (no HDS required).
|
|
|
|
#include <complex>
|
|
#include <cmath>
|
|
|
|
namespace conformallab {
|
|
|
|
// Move tau into the fundamental domain of the modular group SL(2,Z):
|
|
// |Re(tau)| <= 0.5, Im(tau) >= 0, Re(tau) >= 0, |tau| >= 1
|
|
//
|
|
// Algorithm: iteratively apply
|
|
// 1. T-shift: Re > 0.5 or Re < 0 → Re -= sign(Re)
|
|
// 2. Im-flip: Im < 0 → Im = -Im
|
|
// 3. Re-flip: Re < 0 → Re = -Re
|
|
// 4. S-invert: |tau| < 1 → tau = 1/tau
|
|
//
|
|
// Corresponds to Java DiscreteEllipticUtility.normalizeModulus(Complex).
|
|
inline std::complex<double> normalizeModulus(std::complex<double> tau) {
|
|
int maxIter = 100;
|
|
while (--maxIter > 0) {
|
|
double re = tau.real();
|
|
double im = tau.imag();
|
|
// exit when all conditions satisfied
|
|
if (std::abs(re) <= 0.5 && im >= 0.0 && re >= 0.0 && std::abs(tau) >= 1.0)
|
|
break;
|
|
|
|
if (std::abs(re) > 0.5)
|
|
re -= (re > 0.0 ? 1.0 : -1.0); // signum shift
|
|
if (im < 0.0)
|
|
im = -im;
|
|
if (re < 0.0)
|
|
re = -re;
|
|
tau = std::complex<double>(re, im);
|
|
if (std::abs(tau) < 1.0)
|
|
tau = 1.0 / tau; // S-transformation: invert
|
|
}
|
|
return tau;
|
|
}
|
|
|
|
} // namespace conformallab
|