As a learning exercise, I was trying to create a function that computes a Hermitian conjugate in-place. It should behave like a simple transpose when all entries are real, and hence should work with double. I know that I can specialize separately for double, and it's doable in this particular example. But, I imagine that specializing would become tedious for larger problems like ODE Solvers.
I tried the following
#include <complex>
const size_t ZERO = 0ul;
template <class value_type,
class container_type = value_type*>
auto
hermitianConjugate(container_type buffer, size_t width)
{
for (size_t row = ZERO; row < width; row++)
{
for (size_t col = ZERO; col < width; col++)
{
auto temp = std::conj(buffer[col * width + row]);
if (std::imag(temp) == 0)
{
// works for both double and std::complex
buffer[row * width + col] = buffer[col * width + row];
} else
{
// for std::complex
buffer[row * width + col] = temp;
// raises error when value_type is double
}
}
}
}
Is there a workaround that does not involve explicit specialization? Is there any way to use conditional branching "statically", if that makes sense?