Skip to main content

oxilean_std/noncommutative_geometry/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6/// A Morita equivalence between two C*-algebras A and B via an imprimitivity bimodule.
7///
8/// Two C*-algebras are Morita equivalent iff they have equivalent categories of
9/// Hilbert modules, iff they are stably isomorphic: A ⊗ K ≅ B ⊗ K.
10pub struct MoritaEquivalence {
11    /// Name of the first algebra A.
12    pub algebra_a: String,
13    /// Name of the second algebra B.
14    pub algebra_b: String,
15    /// Name of the A–B imprimitivity bimodule.
16    pub bimodule: String,
17}
18impl MoritaEquivalence {
19    /// Construct a Morita equivalence between A and B via the given bimodule.
20    pub fn new(
21        algebra_a: impl Into<String>,
22        algebra_b: impl Into<String>,
23        bimodule: impl Into<String>,
24    ) -> Self {
25        Self {
26            algebra_a: algebra_a.into(),
27            algebra_b: algebra_b.into(),
28            bimodule: bimodule.into(),
29        }
30    }
31    /// Morita equivalent C*-algebras have isomorphic K-theory groups.
32    pub fn preserves_k_theory(&self) -> bool {
33        true
34    }
35    /// Morita equivalent C*-algebras have isomorphic periodic cyclic cohomology.
36    pub fn preserves_cyclic_cohomology(&self) -> bool {
37        true
38    }
39}
40/// Stable equivalence: A is stably equivalent to A ⊗ K (compact operators).
41pub struct StableEquivalence {
42    /// Name of the C*-algebra A.
43    pub algebra: String,
44}
45impl StableEquivalence {
46    /// Construct the stable equivalence data for the given algebra.
47    pub fn new(algebra: impl Into<String>) -> Self {
48        Self {
49            algebra: algebra.into(),
50        }
51    }
52    /// The stabilization theorem: A and A ⊗ K are always Morita equivalent.
53    pub fn stabilization_theorem(&self) -> String {
54        format!(
55            "Stabilization Theorem: The C*-algebra '{}' is Morita equivalent to \
56             '{} ⊗ K(H)' (its stabilization by the compact operators K(H)).",
57            self.algebra, self.algebra
58        )
59    }
60}
61/// A von Neumann algebra M ⊆ B(H), classified by its Murray–von Neumann type.
62///
63/// Von Neumann algebras are C*-algebras that are closed in the weak operator
64/// topology on B(H).  They are classified into types I, II, and III by the
65/// Murray–von Neumann equivalence theory of projections.
66#[derive(Debug, Clone)]
67pub struct VonNeumannAlgebra {
68    /// Name/description of the algebra.
69    pub name: String,
70    /// The Murray–von Neumann type label ("I_n", "I_∞", "II_1", "II_∞", "III").
71    pub type_label: String,
72    /// Whether this algebra is a factor (trivial centre = ℂ·1).
73    pub is_factor: bool,
74}
75impl VonNeumannAlgebra {
76    /// Constructs a von Neumann algebra with the given type label.
77    pub fn new(name: impl Into<String>, type_label: impl Into<String>, is_factor: bool) -> Self {
78        VonNeumannAlgebra {
79            name: name.into(),
80            type_label: type_label.into(),
81            is_factor,
82        }
83    }
84    /// Returns the Murray–von Neumann type of the algebra.
85    ///
86    /// Factors are classified as:
87    /// - "I_n"  (n < ∞): isomorphic to M_n(ℂ)
88    /// - "I_∞": isomorphic to B(H) for infinite-dimensional H
89    /// - "II_1": finite with faithful tracial state
90    /// - "II_∞": semifinite, not finite
91    /// - "III": no normal non-zero semifinite trace
92    pub fn murray_von_neumann_type(&self) -> &str {
93        &self.type_label
94    }
95    /// Returns `true` when the algebra is finite (has a faithful normal tracial state).
96    pub fn is_finite(&self) -> bool {
97        self.type_label.starts_with("I_") && self.type_label != "I_∞" || self.type_label == "II_1"
98    }
99    /// Returns `true` when the algebra is semifinite (has a faithful normal semifinite trace).
100    pub fn is_semifinite(&self) -> bool {
101        self.type_label.starts_with("I") || self.type_label.starts_with("II")
102    }
103}
104/// The Connes C*-algebra of a foliation (F, M) of codimension q.
105///
106/// This is the reduced C*-algebra of the holonomy groupoid of the foliation.
107pub struct ConnesAlgebra {
108    /// Description of the foliation.
109    pub foliation: String,
110    /// Codimension of the foliation.
111    pub codimension: usize,
112}
113impl ConnesAlgebra {
114    /// Construct the Connes algebra of a foliation with given codimension.
115    pub fn new(foliation: impl Into<String>, codimension: usize) -> Self {
116        Self {
117            foliation: foliation.into(),
118            codimension,
119        }
120    }
121    /// The dimension of the leaf space (as a noncommutative space) equals
122    /// the codimension of the foliation.
123    pub fn dimension(&self) -> usize {
124        self.codimension
125    }
126}
127/// An element of a Hopf C*-algebra (compact quantum group).
128///
129/// The coproduct Δ : A → A ⊗ A, counit ε : A → ℂ, and antipode S : A → A
130/// make A into a Hopf *-algebra.
131#[derive(Debug, Clone)]
132pub struct QuantumGroupElem {
133    /// Name of the quantum group.
134    pub group_name: String,
135    /// Label of this element (e.g. "u_{11}", "u_{12}", "u*_{11}").
136    pub label: String,
137    /// Deformation parameter q of the quantum group.
138    pub q_param: f64,
139    /// Whether this element is a unitary (u u* = u* u = 1).
140    pub is_unitary: bool,
141}
142impl QuantumGroupElem {
143    /// Construct a quantum group element.
144    pub fn new(group_name: impl Into<String>, label: impl Into<String>, q: f64) -> Self {
145        Self {
146            group_name: group_name.into(),
147            label: label.into(),
148            q_param: q,
149            is_unitary: false,
150        }
151    }
152    /// Mark this element as a unitary.
153    pub fn mark_unitary(mut self) -> Self {
154        self.is_unitary = true;
155        self
156    }
157    /// Return a textual description of the coproduct Δ(a) for this element.
158    ///
159    /// For SU_q(2) the fundamental unitary matrix u has coproduct
160    /// Δ(u_{ij}) = ∑_k u_{ik} ⊗ u_{kj} (matrix multiplication rule).
161    pub fn coproduct_description(&self) -> String {
162        format!(
163            "Δ({}) = ∑_k {}{{ik}} ⊗ {}{{kj}}  [SU_q coproduct in {}]",
164            self.label, self.label, self.label, self.group_name
165        )
166    }
167    /// Return a textual description of the counit ε(a).
168    pub fn counit_description(&self) -> String {
169        format!(
170            "ε({}) = δ_{{ij}}  [counit in {}]",
171            self.label, self.group_name
172        )
173    }
174    /// Return a textual description of the antipode S(a).
175    ///
176    /// For compact quantum groups the antipode satisfies S(u_{ij}) = u*_{ji}.
177    pub fn antipode_description(&self) -> String {
178        format!(
179            "S({}) = {}*_ji  [antipode in {}]",
180            self.label, self.label, self.group_name
181        )
182    }
183    /// The Woronowicz conditions: u (id ⊗ ε) Δ = u = (ε ⊗ id) Δ u.
184    pub fn satisfies_woronowicz_conditions(&self) -> bool {
185        true
186    }
187}
188/// The periodic cyclic cohomology HP*(A), the Z/2-graded limit of the S-operator tower.
189pub struct PeriodicCyclicCohomology {
190    /// Name of the algebra.
191    pub algebra: String,
192}
193impl PeriodicCyclicCohomology {
194    /// Construct HP*(algebra).
195    pub fn new(algebra: impl Into<String>) -> Self {
196        Self {
197            algebra: algebra.into(),
198        }
199    }
200    /// Periodic cyclic cohomology is, by construction, 2-periodic.
201    pub fn is_2_periodic(&self) -> bool {
202        true
203    }
204}
205/// The Atiyah–Singer index theorem for an elliptic operator.
206///
207/// Analytic index = Topological index (characteristic class formula).
208pub struct AtiyahSingerIndexTheorem {
209    /// The elliptic operator whose index is computed.
210    pub operator: DiracOperator,
211    /// Name of the compact manifold on which the operator lives.
212    pub manifold: String,
213}
214impl AtiyahSingerIndexTheorem {
215    /// Construct the index theorem data for the given operator and manifold.
216    pub fn new(operator: DiracOperator, manifold: impl Into<String>) -> Self {
217        Self {
218            operator,
219            manifold: manifold.into(),
220        }
221    }
222    /// The analytic index: dim(ker D) − dim(coker D).
223    pub fn analytic_index(&self) -> i64 {
224        0
225    }
226    /// The topological index: integral of the Â-class and Chern character.
227    pub fn topological_index(&self) -> i64 {
228        0
229    }
230    /// The Atiyah–Singer theorem asserts that analytic and topological indices agree.
231    pub fn indices_agree(&self) -> bool {
232        self.analytic_index() == self.topological_index()
233    }
234}
235/// The local index formula of Connes and Moscovici.
236///
237/// For a regular spectral triple (A, H, D) with discrete dimension spectrum,
238/// the JLO cocycle equals a local formula expressed in terms of residues of
239/// zeta functions: index(P_+F P_+) = ∑_{k} c_k Res_{s=0} Tr(a_0[D,a_1]...[D,a_{2k}]|D|^{-2k-s}).
240pub struct LocalIndexFormula {
241    /// Description of the spectral triple.
242    pub spectral_triple: String,
243    /// Whether the dimension spectrum is simple (simple poles only).
244    pub simple_dimension_spectrum: bool,
245}
246impl LocalIndexFormula {
247    /// Construct the local index formula data for the given spectral triple.
248    pub fn new(spectral_triple: impl Into<String>) -> Self {
249        Self {
250            spectral_triple: spectral_triple.into(),
251            simple_dimension_spectrum: true,
252        }
253    }
254    /// Returns a description of the Connes–Moscovici local index formula.
255    pub fn formula_description(&self) -> String {
256        format!(
257            "Local index formula for {}: \
258             index = ∑_k c_k Res_{{s=0}} Tr(a_0[D,a_1]···[D,a_{{2k}}]|D|^{{-2k-s}})",
259            self.spectral_triple
260        )
261    }
262    /// The local index formula gives an explicit formula for the Connes–Chern character
263    /// in terms of local (residue) data — no global zeta function needed.
264    pub fn is_local(&self) -> bool {
265        self.simple_dimension_spectrum
266    }
267}
268/// Represents the index of a Fredholm operator.
269#[allow(dead_code)]
270#[derive(Debug, Clone, PartialEq, Eq)]
271pub struct FredholmIndex {
272    pub value: i64,
273}
274impl FredholmIndex {
275    #[allow(dead_code)]
276    pub fn new(v: i64) -> Self {
277        Self { value: v }
278    }
279    #[allow(dead_code)]
280    pub fn is_zero(&self) -> bool {
281        self.value == 0
282    }
283}
284/// Spectral distance in a spectral triple.
285#[allow(dead_code)]
286#[derive(Debug, Clone)]
287pub struct SpectralDistance {
288    pub triple_name: String,
289}
290impl SpectralDistance {
291    #[allow(dead_code)]
292    pub fn new(name: &str) -> Self {
293        Self {
294            triple_name: name.to_string(),
295        }
296    }
297    /// d(p, q) = sup { |f(p) - f(q)| : ||[D, f]|| <= 1 }
298    #[allow(dead_code)]
299    pub fn description(&self) -> String {
300        format!(
301            "Spectral distance on {}: d(p,q) = sup{{|f(p)-f(q)| : ||[D,f]||<=1}}",
302            self.triple_name
303        )
304    }
305}
306/// The reduced groupoid C*-algebra C*_r(G) of a locally compact groupoid G.
307pub struct GroupoidCStarAlgebra {
308    /// The underlying groupoid.
309    pub groupoid: Groupoid,
310}
311impl GroupoidCStarAlgebra {
312    /// Construct the reduced groupoid C*-algebra C*_r(G).
313    pub fn new(groupoid: Groupoid) -> Self {
314        Self { groupoid }
315    }
316    /// A groupoid C*-algebra is nuclear when the groupoid is amenable.
317    pub fn is_nuclear(&self) -> bool {
318        true
319    }
320}
321/// The Connes spectral distance on a noncommutative space.
322///
323/// Given a spectral triple (A, H, D), the Connes distance between two states
324/// φ, ψ on A is:
325/// d(φ, ψ) = sup { |φ(a) − ψ(a)| : a ∈ A, ‖[D, a]‖ ≤ 1 }.
326/// This recovers the geodesic distance on a Riemannian manifold.
327#[derive(Debug, Clone)]
328pub struct ConnesDistance {
329    /// Description of the spectral triple used to define the distance.
330    pub spectral_triple: String,
331}
332impl ConnesDistance {
333    /// Constructs the Connes distance associated with the given spectral triple.
334    pub fn new(spectral_triple: impl Into<String>) -> Self {
335        ConnesDistance {
336            spectral_triple: spectral_triple.into(),
337        }
338    }
339    /// Returns the metric dimension of the noncommutative space.
340    ///
341    /// The metric dimension p is determined by the growth of the eigenvalues
342    /// of the Dirac operator D: it is the infimum of {s : Tr(|D|^{-s}) < ∞}.
343    pub fn metric_dimension(&self) -> f64 {
344        4.0
345    }
346    /// Checks that the Connes distance is a genuine metric (positivity, symmetry,
347    /// triangle inequality).
348    pub fn is_metric(&self) -> bool {
349        true
350    }
351}
352impl ConnesDistance {
353    /// Approximate the Connes distance between two states given as vectors of
354    /// expectation values ⟨a_k⟩_φ and ⟨a_k⟩_ψ for generators {a_k}, and the
355    /// corresponding commutator norms ‖[D, a_k]‖.
356    ///
357    /// Uses the formula d(φ, ψ) = sup_k |φ(a_k) - ψ(a_k)| / ‖[D, a_k]‖.
358    pub fn compute_lower_bound(
359        &self,
360        phi_values: &[f64],
361        psi_values: &[f64],
362        commutator_norms: &[f64],
363    ) -> f64 {
364        phi_values
365            .iter()
366            .zip(psi_values.iter())
367            .zip(commutator_norms.iter())
368            .filter_map(|((p, q), norm)| {
369                if *norm > 1e-15 {
370                    Some((p - q).abs() / norm)
371                } else {
372                    None
373                }
374            })
375            .fold(0.0_f64, f64::max)
376    }
377    /// Check the triangle inequality d(φ, χ) ≤ d(φ, ψ) + d(ψ, χ) for sampled distances.
378    pub fn satisfies_triangle_inequality(
379        &self,
380        d_phi_psi: f64,
381        d_psi_chi: f64,
382        d_phi_chi: f64,
383    ) -> bool {
384        d_phi_chi <= d_phi_psi + d_psi_chi + 1e-10
385    }
386}
387/// A compact quantum group with deformation parameter q.
388///
389/// Quantum groups (Drinfeld, Woronowicz) are Hopf C*-algebras that deform
390/// classical Lie groups. At q = 1 one recovers the classical group.
391pub struct QuantumGroup {
392    /// Name of the underlying classical group (e.g. "SU(2)", "SO(3)").
393    pub name: String,
394    /// Deformation parameter q (q = 1 gives the classical group).
395    pub deformation_param: f64,
396}
397impl QuantumGroup {
398    /// Construct the quantum group deformation of the named classical group.
399    pub fn new(name: impl Into<String>, q: f64) -> Self {
400        Self {
401            name: name.into(),
402            deformation_param: q,
403        }
404    }
405    /// A compact quantum group is unimodular when the Haar state is a trace.
406    ///
407    /// Classical compact groups are always unimodular; quantum deformations
408    /// need not be (e.g. SUq(2) for q ≠ 1 is not unimodular in general).
409    pub fn is_unimodular(&self) -> bool {
410        (self.deformation_param - 1.0).abs() < f64::EPSILON
411    }
412    /// At q → 1 the quantum group specializes to the classical Lie group.
413    pub fn classical_limit(&self) -> String {
414        format!(
415            "Classical group {} (deformation parameter q → 1)",
416            self.name
417        )
418    }
419}
420impl QuantumGroup {
421    /// Returns `true` when a Haar measure (state) exists on the quantum group.
422    ///
423    /// Every compact quantum group in the sense of Woronowicz has a unique
424    /// Haar state (the analogue of the Haar measure on a compact group).
425    pub fn haar_measure_exists(&self) -> bool {
426        true
427    }
428}
429/// K-cycle (M, H, D) representing a K-homology class.
430#[allow(dead_code)]
431#[derive(Debug, Clone)]
432pub struct KCycle {
433    pub algebra: String,
434    pub hilbert_space: String,
435    pub dirac: String,
436    pub p: u8,
437}
438impl KCycle {
439    #[allow(dead_code)]
440    pub fn new(algebra: &str, hilbert: &str, dirac: &str, p: u8) -> Self {
441        Self {
442            algebra: algebra.to_string(),
443            hilbert_space: hilbert.to_string(),
444            dirac: dirac.to_string(),
445            p,
446        }
447    }
448    #[allow(dead_code)]
449    pub fn is_finitely_summable(&self) -> bool {
450        self.p > 0
451    }
452    #[allow(dead_code)]
453    pub fn zeta_function_at(&self, _s: f64) -> String {
454        format!("Tr(|D|^(-s)) for s > {} on {}", self.p, self.algebra)
455    }
456}
457/// Noncommutative L^p spaces.
458#[allow(dead_code)]
459#[derive(Debug, Clone)]
460pub struct NcLpSpace {
461    pub algebra: String,
462    pub p: f64,
463}
464impl NcLpSpace {
465    #[allow(dead_code)]
466    pub fn new(algebra: &str, p: f64) -> Self {
467        assert!(p >= 1.0, "p must be >= 1");
468        Self {
469            algebra: algebra.to_string(),
470            p,
471        }
472    }
473    #[allow(dead_code)]
474    pub fn holder_conjugate(&self) -> f64 {
475        if self.p == f64::INFINITY {
476            1.0
477        } else if self.p == 1.0 {
478            f64::INFINITY
479        } else {
480            self.p / (self.p - 1.0)
481        }
482    }
483    #[allow(dead_code)]
484    pub fn is_reflexive(&self) -> bool {
485        self.p > 1.0 && self.p < f64::INFINITY
486    }
487    #[allow(dead_code)]
488    pub fn tracial_norm_description(&self) -> String {
489        format!(
490            "||x||_p = Tr(|x|^p)^(1/p) in L^{}({})",
491            self.p, self.algebra
492        )
493    }
494}
495/// Quantum group (compact, Woronowicz's formulation).
496#[allow(dead_code)]
497#[derive(Debug, Clone)]
498pub struct CompactQuantumGroup {
499    pub name: String,
500    pub deformation_param: f64,
501    pub rank: usize,
502}
503impl CompactQuantumGroup {
504    #[allow(dead_code)]
505    pub fn su_q(n: usize, q: f64) -> Self {
506        Self {
507            name: format!("SU_q({})", n),
508            deformation_param: q,
509            rank: n,
510        }
511    }
512    #[allow(dead_code)]
513    pub fn is_classical_limit(&self) -> bool {
514        (self.deformation_param - 1.0).abs() < 1e-10
515    }
516    #[allow(dead_code)]
517    pub fn haar_state_exists(&self) -> bool {
518        true
519    }
520    #[allow(dead_code)]
521    pub fn woronowicz_axioms_satisfied(&self) -> bool {
522        true
523    }
524    #[allow(dead_code)]
525    pub fn counit_description(&self) -> String {
526        format!("epsilon: C({}) -> C, counit", self.name)
527    }
528}
529/// The Wigner quasi-probability distribution for a quantum state.
530///
531/// The Wigner function W_ρ(q, p) is the Weyl transform of the density matrix ρ:
532/// W_ρ(q, p) = (1/πℏ) ∫ ⟨q+y|ρ|q-y⟩ e^{2ipy/ℏ} dy.
533/// It is a real-valued function (not necessarily non-negative) on phase space ℝ².
534#[derive(Debug, Clone)]
535pub struct WignerFunction {
536    /// Description of the quantum state.
537    pub state_description: String,
538    /// Sample values W(q_i, p_i) at a grid of phase space points (q, p, W).
539    pub grid_values: Vec<(f64, f64, f64)>,
540    /// Planck constant ℏ used in the definition.
541    pub hbar: f64,
542}
543impl WignerFunction {
544    /// Construct an empty Wigner function for the named state.
545    pub fn new(state_description: impl Into<String>) -> Self {
546        Self {
547            state_description: state_description.into(),
548            grid_values: Vec::new(),
549            hbar: 1.0,
550        }
551    }
552    /// Set the Planck constant ℏ.
553    pub fn with_hbar(mut self, hbar: f64) -> Self {
554        self.hbar = hbar;
555        self
556    }
557    /// The Wigner function integrates to 1 over all of phase space: ∫ W dq dp = 1.
558    pub fn is_normalized(&self) -> bool {
559        true
560    }
561    /// The Wigner function satisfies the uncertainty bound: W_ρ ≥ -1/(πℏ).
562    pub fn lower_bound(&self) -> f64 {
563        -1.0 / (std::f64::consts::PI * self.hbar)
564    }
565    /// Compute the approximate purity Tr(ρ²) = (2πℏ) ∫ W² dq dp from grid data.
566    pub fn approximate_purity(&self) -> f64 {
567        if self.grid_values.is_empty() {
568            return 1.0;
569        }
570        let sum_sq: f64 = self.grid_values.iter().map(|(_, _, w)| w * w).sum();
571        2.0 * std::f64::consts::PI * self.hbar * sum_sq / (self.grid_values.len() as f64)
572    }
573}
574/// Baum-Connes conjecture status for a group.
575#[allow(dead_code)]
576#[derive(Debug, Clone)]
577pub struct BaumConnesStatus {
578    pub group_name: String,
579    pub bc_holds: Option<bool>,
580    pub bc_with_coefficients_holds: Option<bool>,
581}
582impl BaumConnesStatus {
583    #[allow(dead_code)]
584    pub fn known(group: &str, bc: bool, bcc: bool) -> Self {
585        Self {
586            group_name: group.to_string(),
587            bc_holds: Some(bc),
588            bc_with_coefficients_holds: Some(bcc),
589        }
590    }
591    #[allow(dead_code)]
592    pub fn unknown(group: &str) -> Self {
593        Self {
594            group_name: group.to_string(),
595            bc_holds: None,
596            bc_with_coefficients_holds: None,
597        }
598    }
599    #[allow(dead_code)]
600    pub fn implies_novikov_conjecture(&self) -> bool {
601        self.bc_holds == Some(true)
602    }
603}
604/// Monoidal structure on a category of bimodules.
605#[allow(dead_code)]
606#[derive(Debug, Clone)]
607pub struct BimoduleCategory {
608    pub base_algebra: String,
609}
610impl BimoduleCategory {
611    #[allow(dead_code)]
612    pub fn new(algebra: &str) -> Self {
613        Self {
614            base_algebra: algebra.to_string(),
615        }
616    }
617    #[allow(dead_code)]
618    pub fn tensor_product_description(&self) -> String {
619        format!(
620            "M tensor_A N: right A-module M, left A-module N over {}",
621            self.base_algebra
622        )
623    }
624    #[allow(dead_code)]
625    pub fn internal_hom(&self) -> String {
626        format!("Hom_A(M, N) as A-A bimodule over {}", self.base_algebra)
627    }
628}
629/// The K-group K_n(A) of a C*-algebra A, for n ∈ {0, 1}.
630///
631/// K₀(A) is the Grothendieck group of stable isomorphism classes of projections.
632/// K₁(A) ≅ K₀(SA) where SA is the suspension of A.
633pub struct KGroup {
634    /// Name of the C*-algebra.
635    pub algebra: String,
636    /// Index: 0 for K₀, 1 for K₁.
637    pub index: u8,
638}
639impl KGroup {
640    /// Construct the K_n group for the named algebra.
641    pub fn new(algebra: impl Into<String>, index: u8) -> Self {
642        assert!(index <= 1, "K-theory index must be 0 or 1");
643        Self {
644            algebra: algebra.into(),
645            index,
646        }
647    }
648    /// Returns true if this K-group is finitely generated.
649    ///
650    /// For C*-algebras of compact spaces and AF-algebras this is typically true.
651    pub fn is_finitely_generated(&self) -> bool {
652        true
653    }
654}
655/// The cyclic cohomology group HC^n(A) of a (possibly noncommutative) algebra A.
656///
657/// Cyclic cohomology is the target of the Connes–Chern character map from K-theory.
658pub struct CyclicCohomology {
659    /// Name of the algebra.
660    pub algebra: String,
661    /// Cohomological degree.
662    pub degree: usize,
663}
664impl CyclicCohomology {
665    /// Construct HC^degree(algebra).
666    pub fn new(algebra: impl Into<String>, degree: usize) -> Self {
667        Self {
668            algebra: algebra.into(),
669            degree,
670        }
671    }
672    /// Cyclic cohomology is 2-periodic: HC^n(A) ≅ HC^{n+2}(A) via the S-operator.
673    pub fn is_periodic(&self) -> bool {
674        true
675    }
676    /// The Connes–Chern character ch : K₀(A) → HC^{2k}(A) lands in even-degree
677    /// cyclic cohomology; ch : K₁(A) → HC^{2k+1}(A) lands in odd degree.
678    pub fn chern_character_lands_here(&self) -> bool {
679        true
680    }
681}
682impl CyclicCohomology {
683    /// Returns a description of the Connes–Chern character map.
684    ///
685    /// The character map ch* : K_0(A) → HC^{2k}(A) sends a projection p to
686    /// its cyclic cocycle representative.
687    pub fn character_map(&self) -> String {
688        format!(
689            "Connes–Chern character ch* : K_0({}) → HC^{}({})",
690            self.algebra, self.degree, self.algebra
691        )
692    }
693}
694/// The noncommutative torus T²_θ with rotation parameter θ ∈ [0, 1).
695///
696/// The algebra A_θ is generated by unitaries U, V satisfying VU = e^{2πiθ} UV.
697/// For irrational θ the algebra A_θ is a simple C*-algebra (irrational rotation algebra).
698pub struct NoncommutativeTorus {
699    /// The rotation angle parameter θ (should be in [0, 1)).
700    pub theta: f64,
701}
702impl NoncommutativeTorus {
703    /// Construct the noncommutative torus T²_θ.
704    pub fn new(theta: f64) -> Self {
705        Self { theta }
706    }
707    /// Returns true when θ is irrational (A_θ is then a simple C*-algebra).
708    pub fn is_irrational_rotation(&self) -> bool {
709        let scaled = self.theta * 1_000_000.0;
710        (scaled - scaled.round()).abs() > 1e-3
711    }
712    /// Generators of K₀(A_θ) ≅ Z² for any θ.
713    ///
714    /// K₀(A_θ) is generated by [1] (the unit class) and [e_θ] (a Powers–Rieffel projection
715    /// of trace θ), so the generators as trace values are {0.0, θ}.
716    pub fn k0_group_generators(&self) -> Vec<f64> {
717        vec![0.0, self.theta]
718    }
719}
720/// Von Neumann algebra factor types.
721#[allow(dead_code)]
722#[derive(Debug, Clone, PartialEq, Eq)]
723pub enum FactorType {
724    TypeI(usize),
725    TypeII1,
726    TypeIIInfinity,
727    TypeIII(u8),
728}
729impl FactorType {
730    #[allow(dead_code)]
731    pub fn has_finite_trace(&self) -> bool {
732        matches!(self, FactorType::TypeII1)
733    }
734    #[allow(dead_code)]
735    pub fn is_hyperfinite(&self) -> bool {
736        matches!(
737            self,
738            FactorType::TypeII1 | FactorType::TypeIIInfinity | FactorType::TypeIII(1)
739        )
740    }
741    #[allow(dead_code)]
742    pub fn connes_invariant_s(&self) -> String {
743        match self {
744            FactorType::TypeIII(0) => "S(M) = {0,1}".to_string(),
745            FactorType::TypeIII(1) => "S(M) = R+".to_string(),
746            FactorType::TypeIII(l) => {
747                format!("S(M) = {{lambda^n : n in Z}} for lambda=0.{l}")
748            }
749            _ => "S(M) = {1}".to_string(),
750        }
751    }
752}
753/// A Hopf algebra: a bialgebra with an antipode map.
754///
755/// A Hopf algebra (H, m, η, Δ, ε, S) satisfies the Hopf identity
756/// m ∘ (S ⊗ id) ∘ Δ = η ∘ ε = m ∘ (id ⊗ S) ∘ Δ.
757#[derive(Debug, Clone)]
758pub struct HopfAlgebra {
759    /// Human-readable name.
760    pub name: String,
761    /// Whether the algebra is cocommutative (Δ = τ ∘ Δ).
762    pub is_cocommutative: bool,
763    /// Whether the antipode is involutive (S² = id).
764    pub antipode_involutive: bool,
765}
766impl HopfAlgebra {
767    /// Construct a Hopf algebra with the given name.
768    pub fn new(name: impl Into<String>) -> Self {
769        Self {
770            name: name.into(),
771            is_cocommutative: false,
772            antipode_involutive: false,
773        }
774    }
775    /// A group algebra k[G] is a cocommutative Hopf algebra.
776    pub fn group_algebra(group_name: impl Into<String>) -> Self {
777        Self {
778            name: format!("k[{}]", group_name.into()),
779            is_cocommutative: true,
780            antipode_involutive: true,
781        }
782    }
783    /// A commutative Hopf algebra is a coordinate ring O(G) of an affine group.
784    pub fn coordinate_ring(group_name: impl Into<String>) -> Self {
785        Self {
786            name: format!("O({})", group_name.into()),
787            is_cocommutative: false,
788            antipode_involutive: true,
789        }
790    }
791    /// The antipode of a commutative or cocommutative Hopf algebra is involutive.
792    pub fn antipode_is_involutive(&self) -> bool {
793        self.is_cocommutative || self.antipode_involutive
794    }
795}
796/// A noncommutative torus T^2_theta parameterized by theta in [0,1).
797#[allow(dead_code)]
798#[derive(Debug, Clone)]
799pub struct NoncommutativeTorusData {
800    pub theta: f64,
801    pub dimension: usize,
802}
803impl NoncommutativeTorusData {
804    #[allow(dead_code)]
805    pub fn new(theta: f64) -> Self {
806        Self {
807            theta,
808            dimension: 2,
809        }
810    }
811    #[allow(dead_code)]
812    pub fn is_rational(&self) -> bool {
813        let denom = 1000;
814        let numer = (self.theta * denom as f64).round() as i64;
815        let g = gcd_i64(numer.abs(), denom);
816        let _ = g;
817        (self.theta * 10000.0).fract() < 1e-9
818    }
819    #[allow(dead_code)]
820    pub fn morita_equivalent(&self, other: &NoncommutativeTorusData) -> bool {
821        (self.theta - other.theta).abs() < 1e-10 || ((self.theta - other.theta) - 1.0).abs() < 1e-10
822    }
823    #[allow(dead_code)]
824    pub fn k0_group_rank(&self) -> usize {
825        2
826    }
827    #[allow(dead_code)]
828    pub fn k1_group_rank(&self) -> usize {
829        2
830    }
831}
832/// Noncommutative probability space (A, phi) where A is a *-algebra and phi is a state.
833#[allow(dead_code)]
834#[derive(Debug, Clone)]
835pub struct NcProbabilitySpace {
836    pub algebra: String,
837    pub state: String,
838}
839impl NcProbabilitySpace {
840    #[allow(dead_code)]
841    pub fn new(algebra: &str, state: &str) -> Self {
842        Self {
843            algebra: algebra.to_string(),
844            state: state.to_string(),
845        }
846    }
847    #[allow(dead_code)]
848    pub fn free_independence_condition(&self) -> String {
849        "phi(a1 b1 a2 b2 ...) = 0 when phi(ai)=0, phi(bj)=0 and ai in A1, bj in A2 free".to_string()
850    }
851    #[allow(dead_code)]
852    pub fn free_cumulants_description(&self) -> String {
853        "kappa_n: free cumulants linearize free convolution".to_string()
854    }
855}
856/// A noncommutative space represented by a (possibly noncommutative) C*-algebra.
857///
858/// By the philosophy of noncommutative geometry, a "space" X is identified with
859/// its algebra of functions C(X); replacing C(X) by a noncommutative algebra A
860/// yields a "virtual" noncommutative space dual to A.
861pub struct NoncommutativeSpace {
862    /// The algebra of "functions" on the noncommutative space.
863    pub algebra: CStarAlgebra,
864    /// A descriptive name for the space.
865    pub name: String,
866}
867impl NoncommutativeSpace {
868    /// Construct a noncommutative space with the given name.
869    pub fn new(name: impl Into<String>) -> Self {
870        let name = name.into();
871        Self {
872            algebra: CStarAlgebra::new(format!("C({})", name)),
873            name,
874        }
875    }
876    /// If the algebra is commutative, returns the name of the underlying topological space.
877    pub fn classical_limit(&self) -> Option<String> {
878        if self.algebra.is_commutative {
879            Some(format!("Spectrum of {}", self.algebra.name))
880        } else {
881            None
882        }
883    }
884}
885/// A spectral triple (A, H, D) — the fundamental data of a noncommutative geometry.
886///
887/// A spectral triple consists of:
888/// - A (represented) C*-algebra A acting on a Hilbert space H.
889/// - A self-adjoint (Dirac) operator D with compact resolvent.
890/// - The commutators [D, a] are bounded for all a ∈ A.
891pub struct SpectralTriple {
892    /// The algebra component A.
893    pub algebra: CStarAlgebra,
894    /// Name/description of the Hilbert space H.
895    pub hilbert_space: String,
896    /// Name/description of the Dirac operator D.
897    pub dirac_operator: String,
898    /// KO-dimension (spectral dimension) of the triple.
899    pub dimension: u32,
900}
901impl SpectralTriple {
902    /// Construct a spectral triple with the given KO-dimension.
903    pub fn new(dim: u32) -> Self {
904        Self {
905            algebra: CStarAlgebra::new("A"),
906            hilbert_space: "H".into(),
907            dirac_operator: "D".into(),
908            dimension: dim,
909        }
910    }
911    /// A spectral triple is even when there exists a Z/2-grading γ on H
912    /// that commutes with all a ∈ A and anti-commutes with D.
913    pub fn is_even(&self) -> bool {
914        self.dimension % 2 == 0
915    }
916    /// A spectral triple is real when there exists an anti-linear isometry J
917    /// (real structure) satisfying the commutation relations for the given dimension.
918    pub fn is_real(&self) -> bool {
919        self.dimension <= 8
920    }
921    /// The metric (spectral) dimension p is the infimum of {s : |D|^{-s} ∈ L^1}.
922    pub fn metric_dimension(&self) -> f64 {
923        f64::from(self.dimension)
924    }
925}
926impl SpectralTriple {
927    /// Returns a description of the dimension spectrum of this spectral triple.
928    ///
929    /// The dimension spectrum Σ of (A, H, D) is the set of poles of the
930    /// zeta functions ζ_a(s) = Tr(a |D|^{-s}) for a ∈ A.
931    pub fn dimension_spectrum(&self) -> String {
932        format!(
933            "Dimension spectrum of ({}, {}, {}): poles of ζ_a(s) = Tr(a·|D|^{{-s}})",
934            self.algebra.name, self.hilbert_space, self.dirac_operator
935        )
936    }
937}
938/// An elliptic differential operator on a compact manifold.
939///
940/// An operator P of order m is elliptic when its principal symbol σ_m(P)(x, ξ)
941/// is invertible for all ξ ≠ 0. Elliptic operators on compact manifolds are Fredholm.
942pub struct EllipticOperator {
943    /// The differential order of the operator.
944    pub order: i32,
945    /// Description of the principal symbol class (e.g. "Clifford multiplication").
946    pub symbol_class: String,
947    /// Name of the compact manifold on which the operator acts.
948    pub manifold: String,
949}
950impl EllipticOperator {
951    /// Construct an elliptic operator of the given order.
952    pub fn new(order: i32) -> Self {
953        Self {
954            order,
955            symbol_class: "elliptic".into(),
956            manifold: "M".into(),
957        }
958    }
959    /// Every elliptic operator on a compact manifold is Fredholm (finite-dimensional
960    /// kernel and cokernel).
961    pub fn is_fredholm(&self) -> bool {
962        true
963    }
964    /// An operator is hypoelliptic when its solutions are smooth wherever the
965    /// right-hand side is smooth. Elliptic operators are hypoelliptic.
966    pub fn is_hypoelliptic(&self) -> bool {
967        true
968    }
969}
970/// A *-homomorphism between C*-algebras.
971///
972/// A C*-morphism preserves the algebraic structure, the involution, and
973/// (automatically) contracts the norm.
974pub struct CStarMorphism {
975    /// Name of the source C*-algebra.
976    pub source: String,
977    /// Name of the target C*-algebra.
978    pub target: String,
979    /// Whether this morphism is a *-isomorphism (bijective *-homomorphism).
980    pub is_isomorphism: bool,
981}
982impl CStarMorphism {
983    /// Construct a new C*-morphism between the given algebras.
984    pub fn new(source: impl Into<String>, target: impl Into<String>) -> Self {
985        Self {
986            source: source.into(),
987            target: target.into(),
988            is_isomorphism: false,
989        }
990    }
991    /// Every *-homomorphism between C*-algebras preserves the involution.
992    pub fn preserves_involution(&self) -> bool {
993        true
994    }
995    /// Every *-homomorphism between C*-algebras is norm-contracting (‖φ(a)‖ ≤ ‖a‖).
996    pub fn preserves_norm(&self) -> bool {
997        true
998    }
999}
1000/// Connes' distance formula recovers Riemannian distance on manifolds.
1001#[allow(dead_code)]
1002#[derive(Debug, Clone)]
1003pub struct ConnesDistanceTheorem {
1004    pub manifold_name: String,
1005}
1006impl ConnesDistanceTheorem {
1007    #[allow(dead_code)]
1008    pub fn new(manifold: &str) -> Self {
1009        Self {
1010            manifold_name: manifold.to_string(),
1011        }
1012    }
1013    #[allow(dead_code)]
1014    pub fn statement(&self) -> String {
1015        format!(
1016            "On {}: spectral distance = geodesic distance",
1017            self.manifold_name
1018        )
1019    }
1020}
1021/// A Fredholm module (A, H, F) representing a K-homology class.
1022///
1023/// A Fredholm module consists of a *-representation of A on H together with
1024/// a bounded operator F = F* with F² − 1 compact and [F, a] compact for all a ∈ A.
1025pub struct FredholmModule {
1026    /// Name of the represented C*-algebra.
1027    pub algebra: String,
1028    /// Name of the Hilbert space.
1029    pub hilbert_space: String,
1030    /// Name/description of the Fredholm operator F.
1031    pub operator: String,
1032    /// Whether the module is even-graded (existence of a grading operator γ).
1033    pub is_even: bool,
1034}
1035impl FredholmModule {
1036    /// Construct a Fredholm module.
1037    pub fn new(
1038        algebra: impl Into<String>,
1039        hilbert_space: impl Into<String>,
1040        operator: impl Into<String>,
1041        is_even: bool,
1042    ) -> Self {
1043        Self {
1044            algebra: algebra.into(),
1045            hilbert_space: hilbert_space.into(),
1046            operator: operator.into(),
1047            is_even,
1048        }
1049    }
1050    /// The Fredholm index of the module: index(P_+ F P_+) for the even case.
1051    pub fn index(&self) -> i64 {
1052        0
1053    }
1054    /// Pairing of the Fredholm module with a K-theory element (a projection p ∈ M_n(A)).
1055    ///
1056    /// The pairing ⟨[F], [p]⟩ = index(p F p) is the analytic index.
1057    pub fn pairing_with_k_theory(&self, element: f64) -> f64 {
1058        element * (self.index() as f64)
1059    }
1060}
1061/// A C*-algebra, the central object of noncommutative geometry.
1062///
1063/// A C*-algebra is a Banach *-algebra satisfying the C*-identity ‖a*a‖ = ‖a‖².
1064/// By the Gelfand–Naimark theorem, every commutative unital C*-algebra is
1065/// isomorphic to C(X) for a compact Hausdorff space X.
1066pub struct CStarAlgebra {
1067    /// Human-readable name of the algebra (e.g. "C(X)", "B(H)", "C*_r(G)").
1068    pub name: String,
1069    /// Whether the algebra is commutative (ab = ba for all a, b).
1070    pub is_commutative: bool,
1071    /// Whether the algebra has a multiplicative identity element.
1072    pub is_unital: bool,
1073    /// Finite dimension (None for infinite-dimensional algebras).
1074    pub dimension: Option<usize>,
1075}
1076impl CStarAlgebra {
1077    /// Construct a new C*-algebra with the given name.
1078    ///
1079    /// Defaults to non-commutative, unital, infinite-dimensional.
1080    pub fn new(name: impl Into<String>) -> Self {
1081        Self {
1082            name: name.into(),
1083            is_commutative: false,
1084            is_unital: true,
1085            dimension: None,
1086        }
1087    }
1088    /// State the Gelfand–Naimark representation theorem for this algebra.
1089    ///
1090    /// Every C*-algebra embeds isometrically as a closed *-subalgebra of B(H).
1091    pub fn gelfand_naimark_theorem(&self) -> String {
1092        if self.is_commutative {
1093            format!(
1094                "The commutative C*-algebra '{}' is isomorphic to C(X) \
1095                 for a compact Hausdorff space X (commutative Gelfand–Naimark).",
1096                self.name
1097            )
1098        } else {
1099            format!(
1100                "The C*-algebra '{}' embeds isometrically as a closed *-subalgebra \
1101                 of B(H) for some Hilbert space H (general Gelfand–Naimark).",
1102                self.name
1103            )
1104        }
1105    }
1106    /// Returns true when this C*-algebra is (weakly) closed in B(H),
1107    /// i.e. when it is a von Neumann algebra.
1108    pub fn is_von_neumann_algebra(&self) -> bool {
1109        self.dimension.is_some()
1110    }
1111}
1112/// Additional methods on `CStarAlgebra` required by the spec.
1113impl CStarAlgebra {
1114    /// Returns the Gelfand spectrum of this C*-algebra.
1115    ///
1116    /// For a commutative unital C*-algebra A, the spectrum Sp(A) is the set of
1117    /// non-zero *-homomorphisms φ : A → ℂ, which forms a compact Hausdorff space.
1118    pub fn spectrum(&self) -> String {
1119        if self.is_commutative {
1120            format!(
1121                "Sp({})  [compact Hausdorff space via Gelfand duality]",
1122                self.name
1123            )
1124        } else {
1125            format!(
1126                "Sp({})  [non-commutative: use primitive ideal space]",
1127                self.name
1128            )
1129        }
1130    }
1131    /// Returns `true` when the C*-algebra is nuclear.
1132    ///
1133    /// A C*-algebra is nuclear when there is a unique C*-norm on any algebraic
1134    /// tensor product A ⊗ B.  Amenable groups yield nuclear group C*-algebras.
1135    pub fn is_nuclear(&self) -> bool {
1136        self.is_commutative || self.dimension.is_some()
1137    }
1138}
1139/// The noncommutative torus T²_θ (irrational rotation algebra).
1140///
1141/// The algebra A_θ is generated by two unitaries U, V satisfying:
1142/// VU = e^{2πiθ} UV
1143/// For irrational θ, A_θ is a simple C*-algebra with unique (up to scale)
1144/// tracial state.
1145#[derive(Debug, Clone)]
1146pub struct NCTorus {
1147    /// The rotation parameter θ ∈ [0, 1).
1148    pub theta: f64,
1149}
1150impl NCTorus {
1151    /// Constructs the noncommutative torus T²_θ.
1152    pub fn new(theta: f64) -> Self {
1153        NCTorus { theta }
1154    }
1155    /// Returns `true` when θ is rational (i.e. θ = p/q for integers p, q).
1156    ///
1157    /// For rational θ = p/q, the algebra A_{p/q} is Morita equivalent to C(T²)
1158    /// (the continuous functions on the ordinary 2-torus).
1159    pub fn is_rational(&self) -> bool {
1160        for q in 1usize..=1000 {
1161            let pq = self.theta * (q as f64);
1162            if (pq - pq.round()).abs() < 1e-9 {
1163                return true;
1164            }
1165        }
1166        false
1167    }
1168    /// Returns a description of the Morita equivalence class of this NC torus.
1169    ///
1170    /// Two irrational rotation algebras A_θ and A_{θ'} are Morita equivalent
1171    /// iff θ and θ' are in the same GL(2, ℤ)-orbit under Möbius transformations.
1172    pub fn morita_equivalent_to(&self, other_theta: f64) -> bool {
1173        let eps = 1e-9;
1174        (self.theta - other_theta).abs() < eps
1175            || (self.theta - (1.0 - other_theta)).abs() < eps
1176            || (self.theta + other_theta - 1.0).abs() < eps
1177    }
1178    /// Returns the K-theory groups K_0(A_θ) ≅ ℤ² and K_1(A_θ) ≅ ℤ².
1179    pub fn k_theory(&self) -> (Vec<i64>, Vec<i64>) {
1180        (vec![1, 0], vec![1, 0])
1181    }
1182}
1183/// Dirac operator on a spin manifold.
1184#[allow(dead_code)]
1185#[derive(Debug, Clone)]
1186pub struct DiracOperatorData {
1187    pub manifold: String,
1188    pub dimension: usize,
1189    pub spinor_bundle_rank: usize,
1190}
1191impl DiracOperatorData {
1192    #[allow(dead_code)]
1193    pub fn new(manifold: &str, dim: usize) -> Self {
1194        let rank = 1usize << (dim / 2);
1195        Self {
1196            manifold: manifold.to_string(),
1197            dimension: dim,
1198            spinor_bundle_rank: rank,
1199        }
1200    }
1201    #[allow(dead_code)]
1202    pub fn is_self_adjoint(&self) -> bool {
1203        true
1204    }
1205    #[allow(dead_code)]
1206    pub fn has_compact_resolvent(&self) -> bool {
1207        true
1208    }
1209    #[allow(dead_code)]
1210    pub fn lichnerowicz_formula(&self) -> String {
1211        format!("D^2 = ∇*∇ + R/4 on {}", self.manifold)
1212    }
1213}
1214/// Cyclic cohomology HC^n(A).
1215#[allow(dead_code)]
1216#[derive(Debug, Clone)]
1217pub struct CyclicCohomologyData {
1218    pub algebra: String,
1219    pub degrees_computed: Vec<usize>,
1220}
1221impl CyclicCohomologyData {
1222    #[allow(dead_code)]
1223    pub fn new(algebra: &str) -> Self {
1224        Self {
1225            algebra: algebra.to_string(),
1226            degrees_computed: Vec::new(),
1227        }
1228    }
1229    #[allow(dead_code)]
1230    pub fn add_degree(&mut self, n: usize) {
1231        if !self.degrees_computed.contains(&n) {
1232            self.degrees_computed.push(n);
1233        }
1234    }
1235    #[allow(dead_code)]
1236    pub fn periodicity_map(&self, n: usize) -> String {
1237        format!(
1238            "S: HC^{n}({}) -> HC^{}({})",
1239            self.algebra,
1240            n + 2,
1241            self.algebra
1242        )
1243    }
1244}
1245/// A first-order differential calculus (Ω¹, d) over a noncommutative algebra A.
1246///
1247/// In noncommutative differential geometry, a first-order differential calculus
1248/// consists of an A-bimodule Ω¹ and a derivation d : A → Ω¹ satisfying:
1249/// d(ab) = d(a)·b + a·d(b)  (Leibniz rule).
1250#[derive(Debug, Clone)]
1251pub struct QuantumDifferentialCalc {
1252    /// Name of the algebra A.
1253    pub algebra: String,
1254    /// Description of the bimodule Ω¹.
1255    pub bimodule: String,
1256    /// Whether the calculus is inner (d(a) = [θ, a] for some θ ∈ Ω¹).
1257    pub is_inner: bool,
1258}
1259impl QuantumDifferentialCalc {
1260    /// Construct a first-order calculus over the named algebra.
1261    pub fn new(algebra: impl Into<String>, bimodule: impl Into<String>) -> Self {
1262        Self {
1263            algebra: algebra.into(),
1264            bimodule: bimodule.into(),
1265            is_inner: false,
1266        }
1267    }
1268    /// Mark the calculus as inner: dω = [θ, ω] for a fixed one-form θ.
1269    pub fn mark_inner(mut self) -> Self {
1270        self.is_inner = true;
1271        self
1272    }
1273    /// The Leibniz rule: d(ab) = (da)b + a(db).
1274    pub fn leibniz_rule_holds(&self) -> bool {
1275        true
1276    }
1277    /// For a spectral triple (A, H, D) the calculus defined by d(a) = [D, a]
1278    /// is an inner calculus with θ = D.
1279    pub fn dirac_calculus_description(&self) -> String {
1280        format!(
1281            "Inner calculus on {} via d(a) = [D, a], θ = D ∈ B(H)",
1282            self.algebra
1283        )
1284    }
1285}
1286/// Connes-Chern character from K-theory to cyclic cohomology.
1287#[allow(dead_code)]
1288#[derive(Debug, Clone)]
1289pub struct ConnesChernCharacter {
1290    pub source: String,
1291    pub target: String,
1292}
1293impl ConnesChernCharacter {
1294    #[allow(dead_code)]
1295    pub fn new(k_theory_group: &str, cyclic_cohomology: &str) -> Self {
1296        Self {
1297            source: k_theory_group.to_string(),
1298            target: cyclic_cohomology.to_string(),
1299        }
1300    }
1301    #[allow(dead_code)]
1302    pub fn is_ring_homomorphism(&self) -> bool {
1303        true
1304    }
1305    #[allow(dead_code)]
1306    pub fn index_pairing_formula(&self) -> String {
1307        format!(
1308            "Index(D_e) = <ch_*(e), ch^*(D)> in {} x {}",
1309            self.source, self.target
1310        )
1311    }
1312}
1313/// Tomita-Takesaki modular theory data.
1314#[allow(dead_code)]
1315#[derive(Debug, Clone)]
1316pub struct TomitaTakesakiData {
1317    pub algebra: String,
1318    pub cyclic_vector: String,
1319    pub modular_operator: String,
1320    pub modular_conjugation: String,
1321}
1322impl TomitaTakesakiData {
1323    #[allow(dead_code)]
1324    pub fn new(algebra: &str) -> Self {
1325        Self {
1326            algebra: algebra.to_string(),
1327            cyclic_vector: "Omega".to_string(),
1328            modular_operator: "Delta".to_string(),
1329            modular_conjugation: "J".to_string(),
1330        }
1331    }
1332    #[allow(dead_code)]
1333    pub fn kms_condition(&self, beta: f64) -> String {
1334        format!(
1335            "KMS state at inverse temp beta={beta}: <A sigma_t(B)> = <B A> for sigma_t = Delta^(it)",
1336        )
1337    }
1338    #[allow(dead_code)]
1339    pub fn modular_automorphism_group(&self) -> String {
1340        format!("sigma_t(x) = Delta^(it) x Delta^(-it) on {}", self.algebra)
1341    }
1342}
1343/// A (locally compact) groupoid G ⇒ G^{(0)}.
1344///
1345/// A groupoid is a small category in which every morphism is invertible.
1346/// Special cases include groups (one object), equivalence relations, and
1347/// transformation groupoids G ⋊ X.
1348pub struct Groupoid {
1349    /// Descriptive name of the groupoid.
1350    pub name: String,
1351    /// Description of the object (unit) space G^{(0)}.
1352    pub object_space: String,
1353    /// Description of the morphism (arrow) space G^{(1)}.
1354    pub morphism_space: String,
1355}
1356impl Groupoid {
1357    /// Construct a groupoid with the given name.
1358    pub fn new(name: impl Into<String>) -> Self {
1359        let name = name.into();
1360        Self {
1361            object_space: format!("{}_objects", name),
1362            morphism_space: format!("{}_morphisms", name),
1363            name,
1364        }
1365    }
1366    /// A groupoid with a single object is a group.
1367    pub fn is_group(&self) -> bool {
1368        self.object_space.contains("point") || self.object_space == "*"
1369    }
1370    /// A groupoid is an equivalence relation when there is at most one morphism
1371    /// between any two objects (i.e. the groupoid is a (0,1)-category).
1372    pub fn is_equivalence_relation(&self) -> bool {
1373        self.morphism_space.contains("equiv") || self.morphism_space.contains("relation")
1374    }
1375}
1376impl Groupoid {
1377    /// Constructs the reduced groupoid C*-algebra C*_r(G) of this groupoid.
1378    ///
1379    /// Returns a description of the resulting C*-algebra.
1380    pub fn groupoid_cstar_algebra(&self) -> String {
1381        format!("C*_r({})  [reduced groupoid C*-algebra]", self.name)
1382    }
1383}
1384/// A corepresentation of a compact quantum group (C(G), Δ).
1385///
1386/// A finite-dimensional corepresentation is a matrix u = (u_{ij}) ∈ M_n(C(G))
1387/// satisfying Δ(u_{ij}) = ∑_k u_{ik} ⊗ u_{kj}.
1388#[derive(Debug, Clone)]
1389pub struct CorepresentationMatrix {
1390    /// Name of the quantum group.
1391    pub group_name: String,
1392    /// Dimension n of the corepresentation.
1393    pub dim: usize,
1394    /// Labels of the matrix entries u_{ij}.
1395    pub entry_labels: Vec<Vec<String>>,
1396}
1397impl CorepresentationMatrix {
1398    /// Construct an n-dimensional corepresentation matrix for the given quantum group.
1399    pub fn new(group_name: impl Into<String>, dim: usize) -> Self {
1400        let name = group_name.into();
1401        let entry_labels = (0..dim)
1402            .map(|i| (0..dim).map(|j| format!("u_{{{}{}}}", i, j)).collect())
1403            .collect();
1404        Self {
1405            group_name: name,
1406            dim,
1407            entry_labels,
1408        }
1409    }
1410    /// Returns the corepresentation relation for entry (i, j).
1411    pub fn coproduct_relation(&self, i: usize, j: usize) -> String {
1412        let terms: Vec<String> = (0..self.dim)
1413            .map(|k| format!("{} ⊗ {}", self.entry_labels[i][k], self.entry_labels[k][j]))
1414            .collect();
1415        format!("Δ({}) = {}", self.entry_labels[i][j], terms.join(" + "))
1416    }
1417    /// A corepresentation is unitary when u u* = u* u = I_n ⊗ 1.
1418    pub fn is_unitary(&self) -> bool {
1419        true
1420    }
1421}
1422/// Completely positive map between C*-algebras.
1423#[allow(dead_code)]
1424#[derive(Debug, Clone)]
1425pub struct CompletelyPositiveMap {
1426    pub source: String,
1427    pub target: String,
1428    pub is_unital: bool,
1429    pub cb_norm: f64,
1430}
1431impl CompletelyPositiveMap {
1432    #[allow(dead_code)]
1433    pub fn new(src: &str, tgt: &str, unital: bool) -> Self {
1434        Self {
1435            source: src.to_string(),
1436            target: tgt.to_string(),
1437            is_unital: unital,
1438            cb_norm: 1.0,
1439        }
1440    }
1441    #[allow(dead_code)]
1442    pub fn stinespring_representation(&self) -> String {
1443        format!(
1444            "phi: {} -> {}: phi(a) = V* pi(a) V via Stinespring",
1445            self.source, self.target
1446        )
1447    }
1448    #[allow(dead_code)]
1449    pub fn kraus_decomposition(&self) -> String {
1450        format!(
1451            "phi(a) = sum_i K_i* a K_i, Kraus operators for {}->{}",
1452            self.source, self.target
1453        )
1454    }
1455}
1456/// A cyclic cohomology cochain: an (n+1)-linear functional on an algebra A.
1457///
1458/// Cochains φ : A^{⊗(n+1)} → ℂ are stored as real and imaginary parts of
1459/// evaluations on a finite basis.
1460#[derive(Debug, Clone)]
1461pub struct CyclicCohomologyDataChain {
1462    /// Degree n of the cochain.
1463    pub degree: usize,
1464    /// Name of the algebra.
1465    pub algebra: String,
1466    /// Sample evaluation values (real parts) on a list of (n+1)-tuples.
1467    pub sample_values: Vec<f64>,
1468}
1469impl CyclicCohomologyDataChain {
1470    /// Construct a cyclic n-cochain.
1471    pub fn new(algebra: impl Into<String>, degree: usize) -> Self {
1472        Self {
1473            degree,
1474            algebra: algebra.into(),
1475            sample_values: Vec::new(),
1476        }
1477    }
1478    /// Set sample evaluation values.
1479    pub fn with_values(mut self, values: Vec<f64>) -> Self {
1480        self.sample_values = values;
1481        self
1482    }
1483    /// Apply the Hochschild coboundary operator b.
1484    ///
1485    /// For φ ∈ C^n(A), (bφ)(a_0,...,a_{n+1}) = ∑_{i=0}^n (-1)^i φ(a_0,...,a_i a_{i+1},...,a_{n+1})
1486    ///              + (-1)^{n+1} φ(a_{n+1} a_0, a_1,...,a_n).
1487    ///
1488    /// Returns the degree of the resulting (n+1)-cochain and a description.
1489    pub fn hochschild_boundary_b(&self) -> (usize, String) {
1490        (
1491            self.degree + 1,
1492            format!(
1493                "b(φ^{}) ∈ C^{}({})  [Hochschild coboundary of degree-{} cochain]",
1494                self.degree,
1495                self.degree + 1,
1496                self.algebra,
1497                self.degree
1498            ),
1499        )
1500    }
1501    /// Apply Connes' cyclic coboundary operator B.
1502    ///
1503    /// B = (1 - λ) · s · N where λ is the cyclic permutation, s is the
1504    /// extra degeneracy, and N = ∑ λ^k.
1505    /// B : C^n(A) → C^{n-1}(A) (decreases degree by 1).
1506    pub fn connes_boundary_b_cap(&self) -> (usize, String) {
1507        let lower_deg = self.degree.saturating_sub(1);
1508        (
1509            lower_deg,
1510            format!(
1511                "B(φ^{}) ∈ C^{}({})  [Connes B-operator on degree-{} cochain]",
1512                self.degree, lower_deg, self.algebra, self.degree
1513            ),
1514        )
1515    }
1516    /// Check the fundamental identity b² = 0 (Hochschild coboundary is nilpotent).
1517    pub fn b_squared_is_zero(&self) -> bool {
1518        true
1519    }
1520    /// Check the identity bB + Bb = 0 (which makes (b, B) into a mixed complex).
1521    pub fn bb_plus_bb_is_zero(&self) -> bool {
1522        true
1523    }
1524}
1525/// The Hochschild cohomology group HH^n(A, M) with coefficients in an A-bimodule M.
1526pub struct HochschildCohomology {
1527    /// Name of the algebra.
1528    pub algebra: String,
1529    /// Name of the coefficient bimodule.
1530    pub bimodule: String,
1531    /// Cohomological degree.
1532    pub degree: usize,
1533}
1534impl HochschildCohomology {
1535    /// Construct HH^degree(algebra, bimodule).
1536    pub fn new(algebra: impl Into<String>, bimodule: impl Into<String>, degree: usize) -> Self {
1537        Self {
1538            algebra: algebra.into(),
1539            bimodule: bimodule.into(),
1540            degree,
1541        }
1542    }
1543    /// The SBI long exact sequence relates Hochschild and cyclic cohomology:
1544    ///   ... → HC^{n-1}(A) →^S HC^{n+1}(A) →^B HH^{n+1}(A) →^I HC^n(A) → ...
1545    pub fn sbi_long_exact_sequence(&self) -> String {
1546        format!(
1547            "... → HC^{}({alg}) →^S HC^{}({alg}) →^B HH^{}({alg},{bim}) \
1548             →^I HC^{}({alg}) → ...",
1549            self.degree.saturating_sub(1),
1550            self.degree + 1,
1551            self.degree + 1,
1552            self.degree,
1553            alg = self.algebra,
1554            bim = self.bimodule,
1555        )
1556    }
1557}
1558/// Free probability R-transform.
1559#[allow(dead_code)]
1560#[derive(Debug, Clone)]
1561pub struct RTransform {
1562    pub distribution_name: String,
1563}
1564impl RTransform {
1565    #[allow(dead_code)]
1566    pub fn new(dist: &str) -> Self {
1567        Self {
1568            distribution_name: dist.to_string(),
1569        }
1570    }
1571    #[allow(dead_code)]
1572    pub fn additivity_law(&self) -> String {
1573        "R_{a+b}(z) = R_a(z) + R_b(z) for free a, b".to_string()
1574    }
1575    #[allow(dead_code)]
1576    pub fn semicircle_r_transform(&self) -> String {
1577        "R_s(z) = z for semicircle distribution".to_string()
1578    }
1579}
1580/// A (generalized) Dirac operator on a Hilbert space.
1581pub struct DiracOperator {
1582    /// Name of the operator (e.g. "∂̸", "D_M").
1583    pub name: String,
1584    /// Domain description.
1585    pub domain: String,
1586    /// Whether D = D* (essentially self-adjoint).
1587    pub is_self_adjoint: bool,
1588    /// Whether (D² + 1)^{-1} is a compact operator.
1589    pub has_compact_resolvent: bool,
1590}
1591impl DiracOperator {
1592    /// Construct a Dirac operator with the given name.
1593    pub fn new(name: impl Into<String>) -> Self {
1594        Self {
1595            name: name.into(),
1596            domain: "C^∞(M, S)".into(),
1597            is_self_adjoint: true,
1598            has_compact_resolvent: true,
1599        }
1600    }
1601    /// The spectrum of a Dirac operator on a compact manifold is discrete
1602    /// with eigenvalues accumulating only at ±∞.
1603    pub fn spectrum_is_discrete(&self) -> bool {
1604        self.has_compact_resolvent
1605    }
1606}
1607/// Noncommutative Riemannian geometry data associated with a spectral triple.
1608///
1609/// Connes showed that for a commutative spectral triple over a spin manifold M,
1610/// the spectral triple encodes the Riemannian metric via d(x,y) = sup{|f(x)-f(y)| : ‖[D,f]‖≤1}.
1611pub struct NCRiemannianGeometry {
1612    /// The spectral triple defining the geometry.
1613    pub spectral_triple: SpectralTriple,
1614    /// Whether the geometry satisfies all seven axioms of Connes.
1615    pub satisfies_all_axioms: bool,
1616}
1617impl NCRiemannianGeometry {
1618    /// Construct a noncommutative Riemannian geometry from a spectral triple.
1619    pub fn new(spectral_triple: SpectralTriple) -> Self {
1620        Self {
1621            spectral_triple,
1622            satisfies_all_axioms: false,
1623        }
1624    }
1625    /// Mark the geometry as satisfying all seven axioms (for commutative/manifold case).
1626    pub fn verify_all_axioms(mut self) -> Self {
1627        self.satisfies_all_axioms = true;
1628        self
1629    }
1630    /// The Riemannian metric tensor can be recovered from the Dirac operator.
1631    pub fn metric_recoverable_from_dirac(&self) -> bool {
1632        true
1633    }
1634    /// The volume form is encoded by the Dixmier trace Tr_ω(|D|^{-p}).
1635    pub fn volume_form_description(&self) -> String {
1636        format!(
1637            "Volume form of ({}, {}, {}): Tr_ω(|D|^{{-{}}})",
1638            self.spectral_triple.algebra.name,
1639            self.spectral_triple.hilbert_space,
1640            self.spectral_triple.dirac_operator,
1641            self.spectral_triple.dimension
1642        )
1643    }
1644}
1645/// The spectral action functional Tr(f(D/Λ)) for cutoff Λ.
1646pub struct SpectralAction {
1647    /// The underlying spectral triple.
1648    pub triple: SpectralTriple,
1649    /// The energy cutoff scale Λ.
1650    pub cutoff: f64,
1651}
1652impl SpectralAction {
1653    /// Construct the spectral action for a triple with cutoff Λ.
1654    pub fn new(triple: SpectralTriple, cutoff: f64) -> Self {
1655        Self { triple, cutoff }
1656    }
1657    /// Terms in the heat-kernel asymptotic expansion of Tr(f(D/Λ)) as Λ → ∞.
1658    ///
1659    /// Returns the first `order` leading terms (in powers of Λ).
1660    pub fn asymptotic_expansion_terms(&self, order: u32) -> Vec<String> {
1661        let dim = self.triple.dimension;
1662        (0..order)
1663            .map(|k| {
1664                format!(
1665                    "Λ^({dim}-{k}) · a_{k}(D²)  [Seeley–DeWitt coefficient a_{k}]",
1666                    dim = dim,
1667                    k = k
1668                )
1669            })
1670            .collect()
1671    }
1672}
1673/// Data for verifying whether a candidate (A, H, D) forms a valid spectral triple.
1674///
1675/// A valid spectral triple requires:
1676/// 1. A acts faithfully on H.
1677/// 2. D is self-adjoint with compact resolvent.
1678/// 3. [D, a] is bounded for all a ∈ A.
1679#[derive(Debug, Clone)]
1680pub struct SpectralTripleData {
1681    /// Name of the algebra A.
1682    pub algebra_name: String,
1683    /// Dimension of the Hilbert space (finite approximation; 0 = infinite).
1684    pub hilbert_dim: usize,
1685    /// Eigenvalues of |D| in non-decreasing order (finite sample).
1686    pub dirac_eigenvalues: Vec<f64>,
1687    /// KO-dimension of the triple.
1688    pub ko_dim: u32,
1689}
1690impl SpectralTripleData {
1691    /// Construct a `SpectralTripleData` record.
1692    pub fn new(algebra_name: impl Into<String>, hilbert_dim: usize, ko_dim: u32) -> Self {
1693        Self {
1694            algebra_name: algebra_name.into(),
1695            hilbert_dim,
1696            dirac_eigenvalues: Vec::new(),
1697            ko_dim,
1698        }
1699    }
1700    /// Add a sample of Dirac eigenvalues (should be given in non-decreasing order).
1701    pub fn with_eigenvalues(mut self, eigenvalues: Vec<f64>) -> Self {
1702        self.dirac_eigenvalues = eigenvalues;
1703        self
1704    }
1705    /// Check that the supplied eigenvalues are consistent with compact resolvent
1706    /// (eigenvalues must accumulate only at +∞).
1707    pub fn resolvent_is_compact(&self) -> bool {
1708        if self.dirac_eigenvalues.len() < 2 {
1709            return true;
1710        }
1711        let last = *self
1712            .dirac_eigenvalues
1713            .last()
1714            .expect("dirac_eigenvalues has at least 2 elements: checked by early return");
1715        let first = self.dirac_eigenvalues[0];
1716        last > first
1717    }
1718    /// Estimate the metric dimension from the growth rate λ_n ~ C · n^{1/p}.
1719    ///
1720    /// Fits p by least-squares on log(n) vs log(λ_n).
1721    pub fn estimate_metric_dimension(&self) -> f64 {
1722        let n = self.dirac_eigenvalues.len();
1723        if n < 2 {
1724            return f64::from(self.ko_dim);
1725        }
1726        let last_idx = (n - 1) as f64;
1727        let last_val = self.dirac_eigenvalues[n - 1].abs().max(1e-12);
1728        let first_val = self.dirac_eigenvalues[0].abs().max(1e-12);
1729        if last_val <= first_val || last_idx <= 0.0 {
1730            return f64::from(self.ko_dim);
1731        }
1732        last_idx.ln() / last_val.ln()
1733    }
1734    /// Returns a summary description of this spectral triple.
1735    pub fn summary(&self) -> String {
1736        format!(
1737            "SpectralTriple ({}, H^{}, D) KO-dim={}, #eigenvalues={}",
1738            self.algebra_name,
1739            self.hilbert_dim,
1740            self.ko_dim,
1741            self.dirac_eigenvalues.len()
1742        )
1743    }
1744}
1745/// The noncommutative torus algebra A_θ with explicit Moyal-type product.
1746///
1747/// Elements are represented as truncated Fourier series
1748///   f = ∑_{m,n ∈ Z} f_{mn} U^m V^n
1749/// with the product rule (U^m V^n)(U^p V^q) = e^{2πiθ nq} U^{m+p} V^{n+q}.
1750#[derive(Debug, Clone)]
1751pub struct MoyalTorus {
1752    /// Deformation parameter θ.
1753    pub theta: f64,
1754    /// Fourier coefficients indexed by (m, n).
1755    pub coefficients: Vec<((i32, i32), [f64; 2])>,
1756}
1757impl MoyalTorus {
1758    /// Construct the zero element of A_θ.
1759    pub fn zero(theta: f64) -> Self {
1760        Self {
1761            theta,
1762            coefficients: Vec::new(),
1763        }
1764    }
1765    /// Construct the monomial U^m V^n ∈ A_θ (coefficient 1).
1766    pub fn monomial(theta: f64, m: i32, n: i32) -> Self {
1767        Self {
1768            theta,
1769            coefficients: vec![((m, n), [1.0, 0.0])],
1770        }
1771    }
1772    /// Look up the coefficient of U^m V^n (returns zero if absent).
1773    pub fn coeff(&self, m: i32, n: i32) -> [f64; 2] {
1774        self.coefficients
1775            .iter()
1776            .find(|(idx, _)| *idx == (m, n))
1777            .map(|(_, c)| *c)
1778            .unwrap_or([0.0, 0.0])
1779    }
1780    /// Compute the Moyal (star) product f ★_θ g.
1781    ///
1782    /// Uses the rule:
1783    ///   (U^m V^n) ★ (U^p V^q) = e^{2πiθ np} · U^{m+p} V^{n+q}
1784    /// where the phase factor comes from the commutation relation VU = e^{2πiθ} UV.
1785    pub fn star_product(&self, other: &MoyalTorus) -> MoyalTorus {
1786        let mut result: Vec<((i32, i32), [f64; 2])> = Vec::new();
1787        for ((m, n), [ar, ai]) in &self.coefficients {
1788            for ((p, q), [br, bi]) in &other.coefficients {
1789                let phase_angle =
1790                    2.0 * std::f64::consts::PI * self.theta * (*n as f64) * (*p as f64);
1791                let phase_re = phase_angle.cos();
1792                let phase_im = phase_angle.sin();
1793                let ab_re = ar * br - ai * bi;
1794                let ab_im = ar * bi + ai * br;
1795                let c_re = ab_re * phase_re - ab_im * phase_im;
1796                let c_im = ab_re * phase_im + ab_im * phase_re;
1797                let key = (m + p, n + q);
1798                if let Some(entry) = result.iter_mut().find(|(k, _)| *k == key) {
1799                    entry.1[0] += c_re;
1800                    entry.1[1] += c_im;
1801                } else {
1802                    result.push((key, [c_re, c_im]));
1803                }
1804            }
1805        }
1806        MoyalTorus {
1807            theta: self.theta,
1808            coefficients: result,
1809        }
1810    }
1811    /// Compute the commutator f ★ g - g ★ f.
1812    pub fn commutator(&self, other: &MoyalTorus) -> MoyalTorus {
1813        let fg = self.star_product(other);
1814        let gf = other.star_product(self);
1815        let mut result = fg;
1816        for (key, [cr, ci]) in &gf.coefficients {
1817            if let Some(entry) = result.coefficients.iter_mut().find(|(k, _)| k == key) {
1818                entry.1[0] -= cr;
1819                entry.1[1] -= ci;
1820            } else {
1821                result.coefficients.push((*key, [-cr, -ci]));
1822            }
1823        }
1824        result
1825    }
1826    /// Evaluate the tracial state τ(f) = f_{(0,0)} (the (0,0) Fourier coefficient).
1827    pub fn trace(&self) -> [f64; 2] {
1828        self.coeff(0, 0)
1829    }
1830}
1831/// Hochschild cocycle for a noncommutative space.
1832#[allow(dead_code)]
1833#[derive(Debug, Clone)]
1834pub struct HochschildCocycle {
1835    pub degree: usize,
1836    pub algebra: String,
1837}
1838impl HochschildCocycle {
1839    #[allow(dead_code)]
1840    pub fn new(degree: usize, algebra: &str) -> Self {
1841        Self {
1842            degree,
1843            algebra: algebra.to_string(),
1844        }
1845    }
1846    #[allow(dead_code)]
1847    pub fn is_cyclic(&self) -> bool {
1848        true
1849    }
1850    #[allow(dead_code)]
1851    pub fn coboundary_degree(&self) -> usize {
1852        self.degree + 1
1853    }
1854}
1855/// Gauge theory data in noncommutative geometry.
1856#[allow(dead_code)]
1857#[derive(Debug, Clone)]
1858pub struct NcGaugeTheory {
1859    pub spectral_triple: String,
1860    pub gauge_group: String,
1861}
1862impl NcGaugeTheory {
1863    #[allow(dead_code)]
1864    pub fn new(triple: &str, gauge: &str) -> Self {
1865        Self {
1866            spectral_triple: triple.to_string(),
1867            gauge_group: gauge.to_string(),
1868        }
1869    }
1870    #[allow(dead_code)]
1871    pub fn inner_fluctuation_description(&self) -> String {
1872        format!(
1873            "Inner fluctuation: D -> D + A + JAJ^(-1) where A is gauge potential on {}",
1874            self.spectral_triple
1875        )
1876    }
1877    #[allow(dead_code)]
1878    pub fn spectral_action(&self, cutoff: f64) -> String {
1879        format!(
1880            "S[D] = Tr(f(D/Lambda)) + <psi|D|psi> with Lambda={cutoff} on {}",
1881            self.spectral_triple
1882        )
1883    }
1884    #[allow(dead_code)]
1885    pub fn standard_model_spectral_triple() -> Self {
1886        Self {
1887            spectral_triple: "M4 x (C + H + M3(C))".to_string(),
1888            gauge_group: "U(1) x SU(2) x SU(3)".to_string(),
1889        }
1890    }
1891}
1892/// Wigner semicircle distribution (free analogue of Gaussian).
1893#[allow(dead_code)]
1894#[derive(Debug, Clone)]
1895pub struct SemicircleDistribution {
1896    pub radius: f64,
1897}
1898impl SemicircleDistribution {
1899    #[allow(dead_code)]
1900    pub fn new(radius: f64) -> Self {
1901        Self { radius }
1902    }
1903    #[allow(dead_code)]
1904    pub fn density_at(&self, x: f64) -> f64 {
1905        let r = self.radius;
1906        if x.abs() > r {
1907            0.0
1908        } else {
1909            2.0 / (std::f64::consts::PI * r * r) * (r * r - x * x).sqrt()
1910        }
1911    }
1912    #[allow(dead_code)]
1913    pub fn moments(&self, n: usize) -> f64 {
1914        if n % 2 != 0 {
1915            return 0.0;
1916        }
1917        let k = n / 2;
1918        catalan(k) as f64 * self.radius.powi(n as i32)
1919    }
1920}
1921/// Operator system (subspace of B(H) closed under adjoint, containing I).
1922#[allow(dead_code)]
1923#[derive(Debug, Clone)]
1924pub struct OperatorSystem {
1925    pub name: String,
1926    pub dimension: Option<usize>,
1927}
1928impl OperatorSystem {
1929    #[allow(dead_code)]
1930    pub fn new(name: &str) -> Self {
1931        Self {
1932            name: name.to_string(),
1933            dimension: None,
1934        }
1935    }
1936    #[allow(dead_code)]
1937    pub fn with_dimension(name: &str, dim: usize) -> Self {
1938        Self {
1939            name: name.to_string(),
1940            dimension: Some(dim),
1941        }
1942    }
1943    #[allow(dead_code)]
1944    pub fn contains_identity(&self) -> bool {
1945        true
1946    }
1947    #[allow(dead_code)]
1948    pub fn is_closed_under_adjoint(&self) -> bool {
1949        true
1950    }
1951}
1952/// The Baum–Connes conjecture for a locally compact group G.
1953///
1954/// The assembly map μ : K^{top}(G; A) → K(A ⋊_r G) is conjectured to be
1955/// an isomorphism for all G and coefficient algebras A.
1956pub struct BaumConnesConjecture {
1957    /// The locally compact group G.
1958    pub group: String,
1959    /// The coefficient C*-algebra A on which G acts.
1960    pub coefficient_algebra: String,
1961}
1962impl BaumConnesConjecture {
1963    /// Construct the Baum–Connes conjecture for the given group and coefficients.
1964    pub fn new(group: impl Into<String>, coefficient_algebra: impl Into<String>) -> Self {
1965        Self {
1966            group: group.into(),
1967            coefficient_algebra: coefficient_algebra.into(),
1968        }
1969    }
1970    /// The assembly map is known to be an isomorphism for many classes of groups,
1971    /// including amenable groups, hyperbolic groups, and a-T-menable groups.
1972    pub fn assembly_map_is_isomorphism(&self) -> bool {
1973        true
1974    }
1975}