/*****************  wp_shrink4.c  (in su3.a) ****************************
*									*
* Shrink a wilson vector in four directions, producing four		*
*  half_wilson_vectors.							*
* void wp_shrink_4dir(  wilson_vector *a,  half_wilson_vector *b1,	*
*       half_wilson_vector *b2, half_wilson_vector *b3,			*
*       half_wilson_vector *b4, int sign );				*
* B1 <- (1 +- gamma_x)A,, projection					*
*  argument "sign" is sign of gamma matrix.				*
*  See wp_shrink.c for definitions of gamma matrices and eigenvectors.	*
*/
#include "../include/config.h"
#include "../include/complex.h"
#include "../include/su3.h"
#include "../include/dirs.h"
#include "../include/macros.h"

extern __targetConst__ int t_sites_on_node;

__targetHost__ __target__ void wp_shrink_4dir( wilson_vector * a, half_wilson_vector * b1,
		     half_wilson_vector * b2, half_wilson_vector * b3, half_wilson_vector * b4, int sign )
{
    register int i;		/*color */

    /*    wp_shrink( a,b1,XUP,sign); */

    if( sign == PLUS )
    {
	/* case XUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b1->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).imag;
	    b1->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 3 ).real;
	    b1->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b1->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 2 ).real;
	}
    }
    else
    {
	/* case XDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b1->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real + a->COLORSPINOR( i, 3 ).imag;
	    b1->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 3 ).real;
	    b1->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 2 ).imag;
	    b1->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 2 ).real;
	}
    }


    /*wp_shrink( a,b2,YUP,sign); */

    if( sign == PLUS )
    {
	/* case YUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b2->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).real;
	    b2->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 3 ).imag;
	    b2->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 2 ).real;
	    b2->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 2 ).imag;
	}

    }
    else
    {
	/* case YDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b2->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real + a->COLORSPINOR( i, 3 ).real;
	    b2->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 3 ).imag;
	    b2->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 2 ).real;
	    b2->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 2 ).imag;
	}
    }

    /*wp_shrink( a,b3,ZUP,sign); */

    if( sign == PLUS )
    {
	/* case ZUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b3->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b3->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 2 ).real;
	    b3->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 3 ).imag;
	    b3->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 3 ).real;
	}
    }
    else
    {
	/* case ZDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b3->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real + a->COLORSPINOR( i, 2 ).imag;
	    b3->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 2 ).real;
	    b3->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 3 ).imag;
	    b3->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 3 ).real;
	}

    }

    /*wp_shrink( a,b4,TUP,sign); */

    if( sign == PLUS )
    {
	/* case TUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b4->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real + a->COLORSPINOR( i, 2 ).real;
	    b4->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 2 ).imag;
	    b4->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 3 ).real;
	    b4->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 3 ).imag;
	}
    }
    else
    {
	/* case TDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b4->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 2 ).real;
	    b4->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 2 ).imag;
	    b4->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 3 ).real;
	    b4->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 3 ).imag;
	}
    }
}


// version of the above ported to targetDP

__target__ void wp_shrink_4dir_tdp(double * a,  double* b1,
				   double* b2, double* b3, double* b4, int isite, int sign )
{
    int i;		/*color */
    int iv=0; /* targetDP vector index */

    /*    wp_shrink( a,b1,XUP,sign); */



    for ( i = 0; i < 3; i++ )
    {


    if( sign == PLUS )
    {
	/* case XUP: */
	{

	  __targetILP__(iv) b1[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)]- a[WVI(isite+iv,i,3,IMPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)]+ a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] - a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] + a[WVI(isite+iv,i,2,REPART)];
	  
	}
    }
    else
    {
	/* case XDOWN: */
	{

	  __targetILP__(iv) b1[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] + a[WVI(isite+iv,i,3,IMPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] - a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] + a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b1[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] - a[WVI(isite+iv,i,2,REPART)];


	}
    }


    /*wp_shrink( a,b2,YUP,sign); */

    if( sign == PLUS )
    {
	/* case YUP: */
	{

	  __targetILP__(iv) b2[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] - a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b2[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] - a[WVI(isite+iv,i,3,IMPART)];
	  __targetILP__(iv) b2[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] + a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b2[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] + a[WVI(isite+iv,i,2,IMPART)];



	}

    }
    else
    {
	/* case YDOWN: */
	{

	  __targetILP__(iv) b2[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] + a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b2[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] + a[WVI(isite+iv,i,3,IMPART)];
	    __targetILP__(iv) b2[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] - a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b2[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] - a[WVI(isite+iv,i,2,IMPART)];

	}
    }

    /*wp_shrink( a,b3,ZUP,sign); */

    if( sign == PLUS )
    {
	/* case ZUP: */
	{

	  __targetILP__(iv) b3[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] - a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] + a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] + a[WVI(isite+iv,i,3,IMPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] - a[WVI(isite+iv,i,3,REPART)];


	}
    }
    else
    {
	/* case ZDOWN: */
	{

	  __targetILP__(iv) b3[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] + a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] - a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] - a[WVI(isite+iv,i,3,IMPART)];
	  __targetILP__(iv) b3[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] + a[WVI(isite+iv,i,3,REPART)];


	}

    }

    /*wp_shrink( a,b4,TUP,sign); */

    if( sign == PLUS )
    {
	/* case TUP: */
	{

	  __targetILP__(iv) b4[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] + a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] + a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] + a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] + a[WVI(isite+iv,i,3,IMPART)];


	}
    }
    else
    {
	/* case TDOWN: */
	{

	  __targetILP__(iv) b4[HWVI(isite+iv,i,0,REPART)] = a[WVI(isite+iv,i,0,REPART)] - a[WVI(isite+iv,i,2,REPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,0,IMPART)] = a[WVI(isite+iv,i,0,IMPART)] - a[WVI(isite+iv,i,2,IMPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,1,REPART)] = a[WVI(isite+iv,i,1,REPART)] - a[WVI(isite+iv,i,3,REPART)];
	  __targetILP__(iv) b4[HWVI(isite+iv,i,1,IMPART)] = a[WVI(isite+iv,i,1,IMPART)] - a[WVI(isite+iv,i,3,IMPART)];



	}
    }

    }

}




void wp_shrink_4dir_hch( wilson_vector * a, half_wilson_vector * b1,
			 half_wilson_vector * b2, half_wilson_vector * b3, half_wilson_vector * b4, int sign )
{
    register int i;		/*color */

    /*    wp_shrink( a,b1,XUP,sign); */

    if( sign == PLUS )
    {
	/* case XUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b1->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).imag;
	    b1->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 3 ).real;
	    b1->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b1->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 2 ).real;
	}
    }
    else
    {
	/* case XDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b1->h[1].c[i].real = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 2 ).real;
	    b1->h[1].c[i].imag = -a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b1->h[0].c[i].real = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 3 ).real;
	    b1->h[0].c[i].imag = -a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).imag;
	}
    }


    /*wp_shrink( a,b2,YUP,sign); */

    if( sign == PLUS )
    {
	/* case YUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b2->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).real;
	    b2->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 3 ).imag;
	    b2->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 2 ).real;
	    b2->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 2 ).imag;
	}

    }
    else
    {
	/* case YDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b2->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 2 ).real;
	    b2->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 2 ).imag;
	    b2->h[0].c[i].real = -a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 3 ).real;
	    b2->h[0].c[i].imag = -a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 3 ).imag;
	}
    }

    /*wp_shrink( a,b3,ZUP,sign); */

    if( sign == PLUS )
    {
	/* case ZUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b3->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b3->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 2 ).real;
	    b3->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 3 ).imag;
	    b3->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 3 ).real;
	}
    }
    else
    {
	/* case ZDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b3->h[1].c[i].real = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 2 ).real;
	    b3->h[1].c[i].imag = -a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 2 ).imag;
	    b3->h[0].c[i].real = -a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 3 ).real;
	    b3->h[0].c[i].imag = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 3 ).imag;
	}

    }

    /*wp_shrink( a,b4,TUP,sign); */

    if( sign == PLUS )
    {
	/* case TUP: */
	for ( i = 0; i < 3; i++ )
	{
	    b4->h[0].c[i].real = a->COLORSPINOR( i, 0 ).real + a->COLORSPINOR( i, 2 ).real;
	    b4->h[0].c[i].imag = a->COLORSPINOR( i, 0 ).imag + a->COLORSPINOR( i, 2 ).imag;
	    b4->h[1].c[i].real = a->COLORSPINOR( i, 1 ).real + a->COLORSPINOR( i, 3 ).real;
	    b4->h[1].c[i].imag = a->COLORSPINOR( i, 1 ).imag + a->COLORSPINOR( i, 3 ).imag;
	}
    }
    else
    {
	/* case TDOWN: */
	for ( i = 0; i < 3; i++ )
	{
	    b4->h[1].c[i].real = a->COLORSPINOR( i, 0 ).real - a->COLORSPINOR( i, 2 ).real;
	    b4->h[1].c[i].imag = a->COLORSPINOR( i, 0 ).imag - a->COLORSPINOR( i, 2 ).imag;
	    b4->h[0].c[i].real = a->COLORSPINOR( i, 1 ).real - a->COLORSPINOR( i, 3 ).real;
	    b4->h[0].c[i].imag = a->COLORSPINOR( i, 1 ).imag - a->COLORSPINOR( i, 3 ).imag;
	}
    }
}
