Files
ConformalLabpp/code/include/discrete_elliptic_utility.hpp
Tarik Moussa c5a86cb30a
All checks were successful
C++ Tests / test (push) Successful in 2m39s
Mirror to Codeberg / mirror (push) Successful in 24s
tests: port DiscreteEllipticUtility + P2 tests; stub HDS-blocked tests
Fully ported (pure math, no HDS required):
  test_discrete_elliptic_utility.cpp  – 2 tests
    normalizeModulus: move tau into SL(2,Z) fundamental domain
  test_p2_utility.cpp                 – 3 tests
    P2 projective geometry (perpendicularBisector, pointFromLines,
    makeDirectIsometryFromFrames double vs long double precision)

New headers:
  include/discrete_elliptic_utility.hpp  – normalizeModulus
  include/p2_utility.hpp                 – P2 Euclidean geometry (templated
    on scalar type so double and long double share one implementation)

Stubs (GTEST_SKIP, blocked until HDS port – Phase 4):
  test_hyper_ideal_functional.cpp          – 5 tests (1 @Ignore in Java)
  test_hyper_ideal_hyperelliptic_utility.cpp – 3 tests
  test_spherical_functional.cpp            – 5 tests
  All use CoHDS + HalfEdgeUtils which are not yet ported to C++.

Result: 34 tests total | 21 passed | 13 skipped | 0 failed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:15:18 +02:00

44 lines
1.4 KiB
C++

#pragma once
// 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