/********************  msq_wvec.c  (in su3.a) ********************
 *
 * double msq_wvec(wilson_vector *vec)
 *  squared magnitude of a Wilson vector
 * 
 */
#include "../include/config.h"
#include "../include/complex.h"
#include "../include/su3.h"
#include "../include/macros.h"

extern __targetConst__ int t_sites_on_node;

__target__ double magsq_wvec_tdp( double* result, double * vec, int isite);

__targetEntry__ void magsq_wvec_lattice( wilson_vector * vec, double* result ){
  
  int i,s;
  __targetTLP__(i,t_sites_on_node){
    magsq_wvec_tdp(&(result[i]),(double*) vec, i);
  }
  
  return;
  
}

double magsq_wvec( wilson_vector * vec )
{
    register double ar, ai, sum;

    ar = vec->COLORSPINOR( 0, 0 ).real;
    ai = vec->COLORSPINOR( 0, 0 ).imag;
    sum = ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 1, 0 ).real;
    ai = vec->COLORSPINOR( 1, 0 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 2, 0 ).real;
    ai = vec->COLORSPINOR( 2, 0 ).imag;
    sum += ar * ar + ai * ai;

    ar = vec->COLORSPINOR( 0, 1 ).real;
    ai = vec->COLORSPINOR( 0, 1 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 1, 1 ).real;
    ai = vec->COLORSPINOR( 1, 1 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 2, 1 ).real;
    ai = vec->COLORSPINOR( 2, 1 ).imag;
    sum += ar * ar + ai * ai;

    ar = vec->COLORSPINOR( 0, 2 ).real;
    ai = vec->COLORSPINOR( 0, 2 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 1, 2 ).real;
    ai = vec->COLORSPINOR( 1, 2 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 2, 2 ).real;
    ai = vec->COLORSPINOR( 2, 2 ).imag;
    sum += ar * ar + ai * ai;

    ar = vec->COLORSPINOR( 0, 3 ).real;
    ai = vec->COLORSPINOR( 0, 3 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 1, 3 ).real;
    ai = vec->COLORSPINOR( 1, 3 ).imag;
    sum += ar * ar + ai * ai;
    ar = vec->COLORSPINOR( 2, 3 ).real;
    ai = vec->COLORSPINOR( 2, 3 ).imag;
    sum += ar * ar + ai * ai;

    return ( ( double ) sum );
}

// version of the above ported to targetDP
__target__ double magsq_wvec_tdp( double* sum, double * vec, int isite)
{

  int iv=0;
  double ar[VVL], ai[VVL];

  __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,0,0,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,0,0,IMPART)];
    __targetILP__(iv) sum[iv] = ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,1,0,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,1,0,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,2,0,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,2,0,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];

    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,0,1,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,0,1,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,1,1,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,1,1,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,2,1,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,2,1,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];

    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,0,2,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,0,2,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,1,2,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,1,2,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,2,2,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,2,2,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];

    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,0,3,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,0,3,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,1,3,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,1,3,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];
    __targetILP__(iv) ar[iv] = vec[WVI(isite+iv,2,3,REPART)];
    __targetILP__(iv) ai[iv] = vec[WVI(isite+iv,2,3,IMPART)];
    __targetILP__(iv) sum[iv] += ar[iv] * ar[iv] + ai[iv] * ai[iv];

   
}

double magsq_hwvec( half_wilson_vector * vec )
{

#ifdef NATIVEDOUBLE
    register double ar, ai, sum;
#else
    register double ar, ai, sum;
#endif

    ar = vec->h[0].c[0].real;
    ai = vec->h[0].c[0].imag;
    sum = ar * ar + ai * ai;
    ar = vec->h[0].c[1].real;
    ai = vec->h[0].c[1].imag;
    sum += ar * ar + ai * ai;
    ar = vec->h[0].c[2].real;
    ai = vec->h[0].c[2].imag;
    sum += ar * ar + ai * ai;

    ar = vec->h[1].c[0].real;
    ai = vec->h[1].c[0].imag;
    sum += ar * ar + ai * ai;
    ar = vec->h[1].c[1].real;
    ai = vec->h[1].c[1].imag;
    sum += ar * ar + ai * ai;
    ar = vec->h[1].c[2].real;
    ai = vec->h[1].c[2].imag;
    sum += ar * ar + ai * ai;

    return ( ( double ) sum );
}
