/*! \file symmetries.h
 * \brief Functions providing point group operations operating on translation
 * operators and T-matrices.
 *
 * Here will be functions providing point group operations
 * operating on translation operators and T-matrices
 * similar to tmatrices.py.
 * 
 * At least I want:
 * - Wigner D matrices
 * - Basic mirror operations for T-matrices
 * - Inversion operation for the translation matrices
 *
 * Maybe (much later) also point and space group irrep 
 * functionality as in symmetries.py.
 * However, I think that the group structures can be simply
 * hard-coded/generated by a python script, then there is 
 * no need to check the group consistency etc. at runtime.
 *
 * 
 */
#ifndef SYMMETRIES_H
#define SYMMETRIES_H
#include "qpms_types.h"
#include <cblas.h>

/// Dense matrix representation of the z coordinate sign flip operation (xy-plane mirroring).
complex double *qpms_zflip_uvswi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec);
/// Dense matrix representation of the y coordinate sign flip operation (xz-plane mirroring).
complex double *qpms_yflip_uvswi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec);
/// Dense matrix representation of the x coordinate sign flip operation (yz-plane mirroring).
complex double *qpms_xflip_uvswi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec);
/// Dense matrix representation of a rotation around the z-axis
complex double *qpms_zrot_uvswi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec,
		double phi ///< Rotation angle
		);
/// Dense matrix representation of a "rational" rotation around the z-axis
/** Just for convenience. Corresponds to the angle \f$ \phi = 2\piw/N \f$.
 */
complex double *qpms_zrot_rational_uvswi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec,
		int N,
		int w
		);

/// Dense matrix (uvswi-indexed) representation of any O(3) transformation.
complex double *qpms_irot3_uvswfi_dense(
		complex double *target, ///< If NULL, a new array is allocated.
		const qpms_vswf_set_spec_t *bspec,
		const qpms_irot3_t transf);

// Some auxilliary functions for "numerical cleaning" of the roundoff error

/// Cleans the roundoff error of an array.
/**
 * Replaces all the array members \a x for which |\a x| <= \a atol
 * with exact zeros.
 *
 * Returns the count of modified array members.
 */
size_t qpms_zero_roundoff_clean(double *arr, size_t nmemb, double atol);

/// Cleans the roundoff error of an array.
/**
 * Works on real and imaginary parts separately.
 * TODO doc.
 */
size_t qpms_czero_roundoff_clean(complex double *arr, size_t nmemb, double atol);
#endif // SYMMETRIES_H
