File paulivectorsalgebra.h
File List > algebra > su2algebra > helpers > paulivectorsalgebra.h
Go to the documentation of this file
#ifndef TEMPLAT_LATTICE_ALGEBRA_SU2ALGEBRA_HELPERS_PAULIVECTORSALGEBRA_H
#define TEMPLAT_LATTICE_ALGEBRA_SU2ALGEBRA_HELPERS_PAULIVECTORSALGEBRA_H
/* This file is part of TempLat, available at https://cosmolattice.github.io/templat .
Copyright 2021-2026 The TempLat authors, see AUTHORS.md.
Released under the MIT license, see LICENSE.md. */
// File info: Main contributor(s): Adrien Florio, Year: 2025
#include "TempLat/parallel/device.h"
namespace TempLat
{
class PauliVectorsAlgebra
{
public:
/* Put public methods here. These should change very little over time. */
template <typename Array>
requires requires(Array a) {
a[0];
a[1];
a[2];
a[3];
}
DEVICE_INLINE_FUNCTION static void multiply_inplace(Array &res, const Array &cL, const Array &cR)
{
res[0] = cL[0] * cR[0] - cL[1] * cR[1] - cL[2] * cR[2] - cL[3] * cR[3];
res[1] = cL[0] * cR[1] + cL[1] * cR[0] + cL[3] * cR[2] - cL[2] * cR[3];
res[2] = cL[0] * cR[2] + cL[2] * cR[0] + cL[1] * cR[3] - cL[3] * cR[1];
res[3] = cL[0] * cR[3] + cL[3] * cR[0] + cL[2] * cR[1] - cL[1] * cR[2];
}
template <typename ResArray, typename AlgArray>
requires requires(ResArray r, AlgArray a) {
r[0];
r[1];
r[2];
r[3];
a[0];
a[1];
a[2];
}
DEVICE_INLINE_FUNCTION static void expmap_inplace(ResArray &res, const AlgArray &alg)
{
const auto a = device::sqrt(alg[0] * alg[0] + alg[1] * alg[1] + alg[2] * alg[2]);
res[0] = device::cos(a);
const auto sina = device::sin(a);
// Guard: sin(a)/a → 1 as a → 0. Use direct comparison (device-compatible).
if (a > decltype(a)(1e-15)) {
const auto ratio = sina / a;
res[1] = alg[0] * ratio;
res[2] = alg[1] * ratio;
res[3] = alg[2] * ratio;
} else {
res[1] = alg[0];
res[2] = alg[1];
res[3] = alg[2];
}
}
template <typename ResArray>
requires requires(ResArray r) {
r[0];
r[1];
r[2];
r[3];
}
DEVICE_INLINE_FUNCTION static void expmap_inplace(ResArray &res)
{
const auto a = device::sqrt(res[1] * res[1] + res[2] * res[2] + res[3] * res[3]);
res[0] = device::cos(a);
const auto sina = device::sin(a);
// Guard: sin(a)/a → 1 as a → 0. Use direct comparison (device-compatible).
if (a > decltype(a)(1e-15)) {
const auto ratio = sina / a;
res[1] = res[1] * ratio;
res[2] = res[2] * ratio;
res[3] = res[3] * ratio;
} else {
res[1] = res[1];
res[2] = res[2];
res[3] = res[3];
}
}
};
} // namespace TempLat
#endif