use crate::PhysicsError;
use crate::real_from_f64;
use deep_causality_algebra::RealField;
use deep_causality_num::FromPrimitive;
pub fn gell_mann_matrices<R: RealField + FromPrimitive>() -> [[R; 9]; 8] {
let zero = R::zero();
let one = R::one();
let lambda1 = [zero, one, zero, one, zero, zero, zero, zero, zero];
let lambda2 = [zero, zero, zero, zero, zero, zero, zero, zero, zero];
let lambda3 = [one, zero, zero, zero, -one, zero, zero, zero, zero];
let lambda4 = [zero, zero, one, zero, zero, zero, one, zero, zero];
let lambda5 = [zero, zero, zero, zero, zero, zero, zero, zero, zero];
let lambda6 = [zero, zero, zero, zero, zero, one, zero, one, zero];
let lambda7 = [zero, zero, zero, zero, zero, zero, zero, zero, zero];
let inv_sqrt3 = real_from_f64::<R>(1.0 / 3.0_f64.sqrt());
let lambda8 = [
inv_sqrt3,
zero,
zero,
zero,
inv_sqrt3,
zero,
zero,
zero,
real_from_f64::<R>(-2.0) * inv_sqrt3,
];
[
lambda1, lambda2, lambda3, lambda4, lambda5, lambda6, lambda7, lambda8,
]
}
pub fn structure_constant<R: RealField + FromPrimitive>(a: usize, b: usize, c: usize) -> R {
let half = real_from_f64::<R>(0.5);
let sqrt3_half = real_from_f64::<R>(3.0_f64.sqrt() * 0.5);
let mut indices = [a, b, c];
let mut sign = R::one();
for i in 0..2 {
for j in 0..2 - i {
if indices[j] > indices[j + 1] {
indices.swap(j, j + 1);
sign = -sign;
}
}
}
let [i, j, k] = indices;
let value = match (i, j, k) {
(1, 2, 3) => R::one(),
(1, 4, 7) => half,
(1, 5, 6) => -half, (2, 4, 6) => half,
(2, 5, 7) => half,
(3, 4, 5) => half,
(3, 6, 7) => -half, (4, 5, 8) => sqrt3_half,
(6, 7, 8) => sqrt3_half,
_ => R::zero(),
};
sign * value
}
pub fn all_structure_constants<R: RealField + FromPrimitive>() -> Vec<(usize, usize, usize, R)> {
let half = real_from_f64::<R>(0.5);
let sqrt3_half = real_from_f64::<R>(3.0_f64.sqrt() * 0.5);
vec![
(1, 2, 3, R::one()),
(1, 4, 7, half),
(1, 6, 5, half), (2, 4, 6, half),
(2, 5, 7, half),
(3, 4, 5, half),
(3, 7, 6, half), (4, 5, 8, sqrt3_half),
(6, 7, 8, sqrt3_half),
]
}
pub fn covariant_derivative_kernel<R>(
psi: &[R], psi_gradient: &[R], gluon_field: &[R], coupling: R,
) -> Result<Vec<R>, PhysicsError>
where
R: RealField + FromPrimitive,
{
if psi.len() != 6 {
return Err(PhysicsError::DimensionMismatch(format!(
"Psi must have 6 components (3 complex), got {}",
psi.len()
)));
}
if psi_gradient.len() != 24 {
return Err(PhysicsError::DimensionMismatch(format!(
"Psi gradient must have 24 components, got {}",
psi_gradient.len()
)));
}
if gluon_field.len() != 32 {
return Err(PhysicsError::DimensionMismatch(format!(
"Gluon field must have 32 components, got {}",
gluon_field.len()
)));
}
let zero = R::zero();
let half = real_from_f64::<R>(0.5);
let matrices = gell_mann_matrices::<R>();
let mut result = vec![zero; 24];
for mu in 0..4 {
for c in 0..6 {
result[mu * 6 + c] = psi_gradient[mu * 6 + c];
}
for a in 0..8 {
let a_mu_a = gluon_field[mu * 8 + a];
let lambda = &matrices[a];
for i in 0..3 {
for j in 0..3 {
let m_ij = lambda[i * 3 + j] * half; if m_ij != zero {
let psi_re = psi[j * 2];
let psi_im = psi[j * 2 + 1];
let factor = coupling * a_mu_a * m_ij;
result[mu * 6 + i * 2] -= factor * psi_im;
result[mu * 6 + i * 2 + 1] += factor * psi_re;
}
}
}
}
}
if result.iter().any(|v| !v.is_finite()) {
return Err(PhysicsError::NumericalInstability(
"Non-finite result in covariant derivative".into(),
));
}
Ok(result)
}
pub fn wilson_loop_kernel<R>(
gluon_values: &[R],
path_lengths: &[R],
coupling: R,
) -> Result<R, PhysicsError>
where
R: RealField + FromPrimitive,
{
let three = real_from_f64::<R>(3.0);
let num_segments = path_lengths.len();
if gluon_values.len() != num_segments * 8 {
return Err(PhysicsError::DimensionMismatch(format!(
"Expected {} gluon values for {} segments, got {}",
num_segments * 8,
num_segments,
gluon_values.len()
)));
}
if num_segments == 0 {
return Ok(three); }
let mut phase_sum = R::zero();
for i in 0..num_segments {
let dl = path_lengths[i];
let mut a_squared = R::zero();
for a in 0..8 {
let a_a = gluon_values[i * 8 + a];
a_squared += a_a * a_a;
}
phase_sum += a_squared * dl * dl;
}
let neg_half = real_from_f64::<R>(-0.5);
let w = three * (neg_half * coupling * coupling * phase_sum).exp();
if !w.is_finite() {
return Err(PhysicsError::NumericalInstability(
"Non-finite Wilson loop result".into(),
));
}
Ok(w)
}
pub fn confinement_potential_kernel<R>(
distance: R,
string_tension: R,
coulomb_term: Option<R>,
) -> Result<R, PhysicsError>
where
R: RealField,
{
let zero = R::zero();
if distance <= zero {
return Err(PhysicsError::PhysicalInvariantBroken(
"Distance must be positive".into(),
));
}
if !distance.is_finite() || !string_tension.is_finite() {
return Err(PhysicsError::NumericalInstability(
"Non-finite input to confinement potential".into(),
));
}
let mut v = string_tension * distance;
if let Some(alpha) = coulomb_term {
if !alpha.is_finite() {
return Err(PhysicsError::NumericalInstability(
"Non-finite Coulomb coefficient".into(),
));
}
v -= alpha / distance;
}
Ok(v)
}
pub fn running_coupling_kernel<R>(
q_squared: R,
lambda_qcd: R,
n_flavors: u32,
) -> Result<R, PhysicsError>
where
R: RealField + FromPrimitive,
{
let zero = R::zero();
if q_squared <= zero {
return Err(PhysicsError::PhysicalInvariantBroken(
"Q² must be positive".into(),
));
}
if lambda_qcd <= zero {
return Err(PhysicsError::PhysicalInvariantBroken(
"Lambda_QCD must be positive".into(),
));
}
let lambda_squared = lambda_qcd * lambda_qcd;
if q_squared <= lambda_squared {
return Err(PhysicsError::PhysicalInvariantBroken(
"Q² must be greater than Λ_QCD² for perturbative regime".into(),
));
}
let b0_f64 = 11.0 - (2.0 * n_flavors as f64) / 3.0;
if b0_f64 <= 0.0 {
return Err(PhysicsError::PhysicalInvariantBroken(format!(
"Too many flavors ({}): b0 = {} <= 0",
n_flavors, b0_f64
)));
}
let b0 = real_from_f64::<R>(b0_f64);
let log_ratio = (q_squared / lambda_squared).ln();
let four_pi = real_from_f64::<R>(4.0 * std::f64::consts::PI);
let alpha_s = four_pi / (b0 * log_ratio);
if !alpha_s.is_finite() || alpha_s <= zero {
return Err(PhysicsError::NumericalInstability(
"Invalid running coupling (non-finite or non-positive)".into(),
));
}
Ok(alpha_s)
}