/*
   In:  tau (lattice parameter)
   Out: g2 -> g[0]
        g3 -> g[1]
*/
void compute_invariants(gsl_complex tau, gsl_complex *g)
{
  gsl_complex q, q14;
  gsl_complex t2,t3,t24,t34;
  gsl_complex g3_term1, g3_term2;
  gsl_complex g2, g3;

  q = gsl_complex_exp(gsl_complex_mul_imag(tau,M_PI));
  q14 = gsl_complex_exp(gsl_complex_mul_imag(tau,M_PI_4));

  t2=theta20(q,q14);
  t3=theta30(q);
  t24 = pow4(t2);
  t34 = pow4(t3);

  g2 = gsl_complex_mul_real(gsl_complex_sub(gsl_complex_add(gsl_complex_mul(t24,t24),gsl_complex_mul(t34,t34)),gsl_complex_mul(t24,t34)),_CONST_43PI4);

  g3_term1 = gsl_complex_add(gsl_complex_mul(t24,gsl_complex_mul(t24,t24)),gsl_complex_mul(t34,gsl_complex_mul(t34,t34)));
  
  g3_term2 = gsl_complex_mul(gsl_complex_add(t24,t34),gsl_complex_mul(t24,t34));

  g3 = gsl_complex_sub( gsl_complex_mul_real(g3_term1, _CONST_827PI6),
			gsl_complex_mul_real(g3_term2, _CONST_49PI6) );

  g[0] = g2;
  g[1] = g3;
}
Exemple #2
0
/* ------------------------------------------------------ */
gsl_complex gsl_complex_arctan2 (gsl_complex a, gsl_complex b)
{        
  gsl_complex z, p;

  if(GSL_REAL(b) != 0.0)
    {
      z = gsl_complex_arctan(gsl_complex_div(a, b));
      if(GSL_REAL(b) < 0.0){
	GSL_SET_COMPLEX (&p, M_PI, 0);
	if(GSL_REAL(a) >= 0.0)
	  z = gsl_complex_add(z, p);
	else
	  z = gsl_complex_sub(z, p);
      }
    }
  else
    {
      if(GSL_REAL(a) >= 0.0)
	{
	  GSL_SET_COMPLEX (&z, M_PI/2.0, 0.0);
	}
      else
	{
	  GSL_SET_COMPLEX (&z, -M_PI/2.0, 0.0);
	}
    }

  return z;
}
/* NOTE: Assumes z is in fundamental parallelogram  */
void wP_and_prime(gsl_complex z, gsl_complex tau, const gsl_complex *g, gsl_complex *p, gsl_complex *pp)
{
  int N = 6;  /* Enough iterations for good P, not so good P' */
  int i;
  gsl_complex z0;
  gsl_complex z02;
  gsl_complex pout, ppout;
  gsl_complex ppsolve;

  z = near_origin(z,tau);

  z0 = gsl_complex_div_real(z,(double)(1 << N));
  z02 = gsl_complex_mul(z0,z0);

  /* Laurent expansion:  P \approx 1/z^2 + (g2/20)z^2 + (g3/28) z^4 */
  pout = gsl_complex_add(gsl_complex_inverse(z02),
			 gsl_complex_add(gsl_complex_mul(z02,gsl_complex_mul_real(g[0],0.05)),
					 gsl_complex_mul(gsl_complex_mul(z02,z02),gsl_complex_mul_real(g[1],_CONST_1_28))));

  /* Laurent expansion:  P' \approx -2/z^3 + g2/10z + g3/7 z^3 */
  ppout = gsl_complex_add(gsl_complex_mul_real(gsl_complex_inverse(gsl_complex_mul(z0,z02)),-2.0),
			  gsl_complex_add(gsl_complex_mul(z0,gsl_complex_mul_real(g[0],0.1)),
					  gsl_complex_mul(gsl_complex_mul(z0,z02),gsl_complex_mul_real(g[1],_CONST_1_7))));

  for (i=0;i<N;i++) {
    P_and_Pprime_doubler(&pout, &ppout, g);
  }

  /* At this point ppout is a decent but not great approximation of P'(z)        */
  /* Instead of using it directly, we use it as a guide for which square root of */
  /* (4P^3 - g2 P - g3) should be selected.                                      */

  ppsolve = gsl_complex_sqrt(
                gsl_complex_sub(
                    gsl_complex_mul_real(gsl_complex_mul(pout,gsl_complex_mul(pout,pout)),4.0),
		    gsl_complex_add(gsl_complex_mul(g[0],pout),g[1])
                )
	    );

  *p = pout;
  if (gsl_complex_abs(gsl_complex_sub(ppsolve,ppout)) < gsl_complex_abs(gsl_complex_add(ppsolve,ppout)))
    *pp = ppsolve;
  else
    *pp = gsl_complex_negative(ppsolve);
}
/* Assuming z is in the (1,tau) parallelogram, return the point
   closest to the origin among all translates of z by the lattice. */
gsl_complex near_origin(gsl_complex z, gsl_complex tau)
{
  gsl_complex znew;

  znew = gsl_complex_sub_real(z,1.0);
  if (gsl_complex_abs(z) > gsl_complex_abs(znew))
    z = znew;

  znew = gsl_complex_sub(z,tau);
  if (gsl_complex_abs(z) > gsl_complex_abs(znew))
    z = znew;

  znew = gsl_complex_sub(z,gsl_complex_add_real(tau,1.0));
  if (gsl_complex_abs(z) > gsl_complex_abs(znew))
    z = znew;

  return z;
}
/* The extended Lattes map (rational function doubling on the elliptic curve) */
void P_and_Pprime_doubler(gsl_complex *p, gsl_complex *pp, const gsl_complex *g)
{
  gsl_complex pp3;
  gsl_complex ppp, ppp3;


  /* p'' */
  ppp = gsl_complex_sub(gsl_complex_mul_real(gsl_complex_mul(*p,*p),6.0),
			gsl_complex_mul_real(g[0],0.5));
  
  ppp3 = gsl_complex_mul(ppp,gsl_complex_mul(ppp,ppp));
  pp3 = gsl_complex_mul(*pp,gsl_complex_mul(*pp,*pp));

  
  *pp = gsl_complex_sub(gsl_complex_add(gsl_complex_mul_real(gsl_complex_div(gsl_complex_mul(*p,ppp),*pp),3.0),
					gsl_complex_mul_real(gsl_complex_div(ppp3,pp3),-0.25)),
			*pp);
  *p = P_doubler(*p,g);
}
Exemple #6
0
/* psi(z) for complex z in the right half-plane */
static int
psi_complex_rhp(
  gsl_complex z,
  gsl_sf_result * result_re,
  gsl_sf_result * result_im
  )
{
  int n_recurse = 0;
  int i;
  gsl_complex a;

  if(GSL_REAL(z) == 0.0 && GSL_IMAG(z) == 0.0)
  {
    result_re->val = 0.0;
    result_im->val = 0.0;
    result_re->err = 0.0;
    result_im->err = 0.0;
    return GSL_EDOM;
  }

  /* compute the number of recurrences to apply */
  if(GSL_REAL(z) < 20.0 && fabs(GSL_IMAG(z)) < 20.0)
  {
    const double sp = sqrt(20.0 + GSL_IMAG(z));
    const double sn = sqrt(20.0 - GSL_IMAG(z));
    const double rhs = sp*sn - GSL_REAL(z);
    if(rhs > 0.0) n_recurse = ceil(rhs);
  }

  /* compute asymptotic at the large value z + n_recurse */
  a = psi_complex_asymp(gsl_complex_add_real(z, n_recurse));

  result_re->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(a));
  result_im->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(a));

  /* descend recursively, if necessary */
  for(i = n_recurse; i >= 1; --i)
  {
    gsl_complex zn = gsl_complex_add_real(z, i - 1.0);
    gsl_complex zn_inverse = gsl_complex_inverse(zn);
    a = gsl_complex_sub(a, zn_inverse);

    /* accumulate the error, to catch cancellations */
    result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(zn_inverse));
    result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(zn_inverse));
  }

  result_re->val = GSL_REAL(a);
  result_im->val = GSL_IMAG(a);

  result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(result_re->val);
  result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(result_im->val);

  return GSL_SUCCESS;
}
Exemple #7
0
double rpp(gsl_matrix_complex * M)
{
	gsl_complex t11, t43, t41, t13, t33, t31, mul1, mul2, mul3, mul4, sub1, sub2, div1;
	t11 = gsl_matrix_complex_get(M,0,0);
	t43 = gsl_matrix_complex_get(M,3,2);
	t41 = gsl_matrix_complex_get(M,3,0);
	t13 = gsl_matrix_complex_get(M,0,2);
	t33 = gsl_matrix_complex_get(M,2,2);
	t31 = gsl_matrix_complex_get(M,2,0);

	mul1 = gsl_complex_mul(t11,t43);
	mul2 = gsl_complex_mul(t41,t13);
	mul3 = gsl_complex_mul(t11,t33);
	mul4 = gsl_complex_mul(t13,t31);

	sub1 = gsl_complex_sub(mul1,mul2);
	sub2 = gsl_complex_sub(mul3,mul4);

	div1 = gsl_complex_div(sub1,sub2);

	return gsl_complex_abs2(div1);
}
Exemple #8
0
void gtmiso(gsl_matrix_complex * Tiso, gsl_complex eiso, double k0, double eta, double diso)
{
	double eta2 = pow(eta,2);
	gsl_complex rb = gsl_complex_rect(eta2,0);

	gsl_complex za = gsl_complex_sub_real(eiso,eta2);
	gsl_complex qiso = gsl_complex_sqrt(za);
	gsl_complex zb = gsl_complex_mul_real(qiso,k0);
	gsl_complex zc = gsl_complex_mul_real(zb,diso);
	gsl_complex zd = gsl_complex_div(rb,eiso);

	gsl_complex carg = gsl_complex_cos(zc);
	gsl_complex sarg = gsl_complex_sin(zc);

	gsl_complex i = gsl_complex_rect(0,1);
	gsl_complex one = gsl_complex_rect(1,0);

	gsl_matrix_complex_set_zero(Tiso);

	gsl_matrix_complex_set(Tiso,0,0,carg);
	gsl_matrix_complex_set(Tiso,1,1,carg);
	gsl_matrix_complex_set(Tiso,2,2,carg);
	gsl_matrix_complex_set(Tiso,3,3,carg);

	gsl_complex zd1 = gsl_complex_sub(one,zd);
	gsl_complex zd2 = eiso;
	gsl_complex zd3 = one;
	gsl_complex zd4 = gsl_complex_sub_real(eiso,eta2);

	gsl_complex zmult1 = gsl_complex_mul(zd1,i);
	gsl_complex zmult2 = gsl_complex_mul(zd2,i);
	gsl_complex zmult3 = gsl_complex_mul(zd3,i);
	gsl_complex zmult4 = gsl_complex_mul(zd4,i);

	gsl_complex zdiv1 = gsl_complex_div(zmult1,qiso);
	gsl_complex zdiv2 = gsl_complex_div(zmult2,qiso);
	gsl_complex zdiv3 = gsl_complex_div(zmult3,qiso);
	gsl_complex zdiv4 = gsl_complex_div(zmult4,qiso);

	gsl_complex zmult5 = gsl_complex_mul(zdiv1,sarg);
	gsl_complex zmult6 = gsl_complex_mul(zdiv2,sarg);
	gsl_complex zmult7 = gsl_complex_mul(zdiv3,sarg);
	gsl_complex zmult8 = gsl_complex_mul(zdiv4,sarg);

	gsl_matrix_complex_set(Tiso,0,1,zmult5);
	gsl_matrix_complex_set(Tiso,1,0,zmult6);
	gsl_matrix_complex_set(Tiso,2,3,zmult7);
	gsl_matrix_complex_set(Tiso,3,2,zmult8);

}
Exemple #9
0
int main(int argc, char** argv)
{
    gsl_complex a,b;
    GSL_SET_COMPLEX(&a,3,4);//a=3+4i
    GSL_SET_COMPLEX(&b,6,8);//b=6+8i
    gsl_complex c = gsl_complex_add(a,b);
    printf("a+b\treal : %f image : %f\n",c.dat[0],c.dat[1]);
    c = gsl_complex_sub(a,b);
    printf("a-b\treal : %f image : %f\n",c.dat[0],c.dat[1]);
    c = gsl_complex_mul(a,b);
    printf("a*b\treal : %f image : %f\n",c.dat[0],c.dat[1]);
    c = gsl_complex_div(a,b);
    printf("a/b\treal : %f image : %f\n",c.dat[0],c.dat[1]);
    // system("PAUSE");
    return 0;
}
/* The Lattes map */
gsl_complex P_doubler(gsl_complex p, const gsl_complex *g)
{
  gsl_complex p2, p3;
  gsl_complex num;
  gsl_complex denom;
  gsl_complex term;

  p2 = gsl_complex_mul(p,p);
  p3 = gsl_complex_mul(p2,p);

  /* denom = 4p^3 - g2p - g3 */
  denom = gsl_complex_sub(gsl_complex_mul_real(p3,4.0),
			  gsl_complex_add(gsl_complex_mul(p,g[0]),g[1]));

  /* num = (p^2 + g2/4)^2 + 2g3p */
  term = gsl_complex_add(p2,gsl_complex_mul_real(g[0],0.25));
  num = gsl_complex_add(gsl_complex_mul(p,gsl_complex_mul_real(g[1],2.0)),
			gsl_complex_mul(term,term));

  return gsl_complex_div(num,denom);
}
Exemple #11
0
void tabulate(FILE *os,
              ComplexFunction fun,
              void *params,
              gsl_complex z0,
              gsl_complex z1,
              int n)
{
    gsl_complex k = gsl_complex_sub(z1, z0);
    for (int i = 0; i < n; ++i)
    {
        double t = (double)i / (n - 1);
        gsl_complex z = gsl_complex_add(z0, gsl_complex_mul_real(k, t));
        gsl_complex f = fun(z, params);
        double abs = gsl_complex_abs(f);

        fprintf(os, "%g %g %g %g %g %g %g\n",
                t,
                GSL_REAL(z), GSL_IMAG(z),
                GSL_REAL(f), GSL_IMAG(f), abs, -abs);
    }
}
Exemple #12
0
Fichier : xrr.c Projet : FHe/tdl
/******************************************************************************
* calc_X()
* This function calcs the X's and g's for a given theta.  
* 
* Parameters
* ---------
*
* Returns
* -------
*
* Notes
* -----
* This function computes
*   X[j] = Ar[j]/Ai[j]
* where Ar[j] and Ai[j] are the field amplitdues within layer j at 
* the j/j-1 interface. For the base layer X[0] = 0, 
* ie there is no reflected field in the substrate. While 
* X[nlayers-1] is the field intensity at the top of the multilayer,
* therefore |X[nlayers-1]|^2 = R
*
* The X's are calculated using the optical recursion formlua, starting at the bottom
* where X[0] = 0 and calc X[1], and proceding to calc of X[nlayer-1]:
*
*   X[j] = ( r[j] + X[j-1]*phase) / (1 + r[j]*X[j-1]*phase)
*
* The r[j] values are the reflection coefficients for the j/j-1 interface, 
* and calculated from:
*
*   r[j] = (g[j]-g[j-1])/(g[j]+g[j-1])
*
* This function also includes an interfacial roughness term mult into 
* the reflection coefficient for the j/j-1 interface:
*
*   r[j] = r[j]*exp(-1.0(q*sig[j])^2)
*
* The phase term accounts for the phase shift and attentuation of the field 
* traversing the j-1 layer (ie from the j-1/j-2 interface to the j/j-1 interface)
*
*   phase = exp( -i* 2*k*d[j-1] * g[j-1])
*
* Note if j == 1 then the phase for layer j-1 is 0.0, 
* ie infinitley thick base layer
*
* Note:  g[j] = sqrt( n[j]^2 - cos(theta)^2 )
* where n[j] is the layers index of refraction: n[j] = 1-del[j]-i*bet[j]
* Hence, each layer has a unique g value. We assume here 
* that the del[j] and bet[j] have already been calculated 
* (see calc_del_bet(), this should be called before this function).
* 
* 
* Note: double check how doing the phase calc below, is that the best way??
* e.g. could we use:
*    phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j]));
* instead of
*    phase = gsl_complex_exp( gsl_complex_mul(phase,g1));
*
* Note we should move the g and r calc to a new function, possibly calc the 
* t values as well and store these so we dont have to recalc in calc_A() (???)
*
******************************************************************************/
int calc_X(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){
    int      i, j;
    double   cos_sqr_thet, k, q, dw;
    double  *d, *sig;
    gsl_complex g1, g2, num, den, r, X2, X1, n1, n2, phase;

    // convenience vars
    cos_sqr_thet = square(cos(theta*M_PI/180.));
    k   = ref->k;
    q   = 2.0*k*sin((theta*M_PI/180.));
    d   = ref->d;
    sig = ref->sigma; 

    // start at bottom
    // ie interface 0
    ang_c->Re_X[0] = GSL_REAL(X1) = 0.0;
    ang_c->Im_X[0] = GSL_IMAG(X1) = 0.0;

    // calc g for base layer (g[0]) 
    // n = 1 - del -i*bet
    // g = sqrt( n^2 - cos(theta)^2 )  
    GSL_REAL(n1) =  1.0 - lay_c->del[0];
    GSL_IMAG(n1) = -1.0*lay_c->bet[0];
    g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) );

    // store g for base layer
    ang_c->Re_g[0] = GSL_REAL(g1);
    ang_c->Im_g[0] = GSL_IMAG(g1);

    // loop over all layers
    // note j is upper layer and i is the interface number
    // the loop starts considering the first interface (i=0)
    // which is the interface between the base layer (j=0)
    // and the first layer (j=1) ie the 1/0 interface
    // note there are nlayer-1 interfaces...
    i = 0;
    for ( j = 1; j < ref->nlayer; j++){
        // calc g for upper layer
        // n = 1 - del -i*bet
        // g2 = sqrt( n^2 - cos(theta)^2 )
        GSL_REAL(n2) = 1.0 - lay_c->del[j];
        GSL_IMAG(n2) = -1.0 * lay_c->bet[j];
        g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) );

        // store g for layer j
        ang_c->Re_g[j] = GSL_REAL(g2);
        ang_c->Im_g[j] = GSL_IMAG(g2);

        // calculate r for the j/j-1 interface
        // r_j = (g2-g1)/(g2+g1)
        //GSL_SET_COMPLEX(&num,0.0,0.0);
        //GSL_SET_COMPLEX(&den,0.0,0.0);
        //GSL_SET_COMPLEX(&r,0.0,0.0);
        num = gsl_complex_sub(g2,g1);
        den = gsl_complex_add(g2,g1);
        r   = gsl_complex_div(num,den);

        // calc r including roughness
        // simple dw roughness model
        // r = r*exp(-1.0(q*sig)^2)
        // sigma[i]
        if (ref->sigma[j] > 0.0){
            //dw = exp(-1.0*square(q*ref->sigma[j]));
            dw = exp(-1.0*square(q*ref->sigma[i]));
            r  = gsl_complex_mul_real(r,dw);
        }

        //calc phase shift and attentuation for 
        //field traversing the j-1 layer
        //phase = exp( -i* 2*k*d[j-1] * g1)
        // if j == 1 then the phase for layer j-1 
        // is 0.0, ie infinitley thick base layer
        if (j == 1){
            GSL_REAL(phase) = 0.0;
            GSL_IMAG(phase) = 0.0;
        } else {
            // check here
            GSL_REAL(phase) = 0.0;
            GSL_IMAG(phase) = -2.0*k*d[j-1];
            phase = gsl_complex_exp( gsl_complex_mul(phase,g1));
        }

        // calc Xj
        // X2 = ( r + X1*phase) / (1 + r*X1*phase)
        //GSL_SET_COMPLEX(&num,0.0,0.0);
        //GSL_SET_COMPLEX(&den,0.0,0.0);
        num = gsl_complex_add(r,gsl_complex_mul(X1,phase));
        den = gsl_complex_add_real(gsl_complex_mul(r,gsl_complex_mul(X1,phase)), 1.0);
        X2 = gsl_complex_div(num,den);
        if (fabs(GSL_REAL(X2)) < 1e-10){
            GSL_REAL(X2) = 0.0;
        }
        if (fabs(GSL_IMAG(X2)) < 1e-10){
            GSL_IMAG(X2) = 0.0;
        }
        // store values of Xj
        ang_c->Re_X[j] = GSL_REAL(X2);
        ang_c->Im_X[j] = GSL_IMAG(X2);

        // use top layer as bottom for next time through
        GSL_REAL(X1) = GSL_REAL(X2);
        GSL_IMAG(X1) = GSL_IMAG(X2);
        // do the same for g's
        GSL_REAL(g1) = GSL_REAL(g2);
        GSL_IMAG(g1) = GSL_IMAG(g2);

        //increment the interface number
        i++;
    }
    return (SUCCESS);
}
Exemple #13
0
int
gsl_linalg_complex_LU_decomp (gsl_matrix_complex * A, gsl_permutation * p, int *signum)
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("LU decomposition requires square matrix", GSL_ENOTSQR);
    }
  else if (p->size != A->size1)
    {
      GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;
      size_t i, j, k;

      *signum = 1;
      gsl_permutation_init (p);

      for (j = 0; j < N - 1; j++)
	{
	  /* Find maximum in the j-th column */

	  gsl_complex ajj = gsl_matrix_complex_get (A, j, j);
          double max = gsl_complex_abs (ajj);
	  size_t i_pivot = j;

	  for (i = j + 1; i < N; i++)
	    {
	      gsl_complex aij = gsl_matrix_complex_get (A, i, j);
              double ai = gsl_complex_abs (aij);

	      if (ai > max)
		{
		  max = ai;
		  i_pivot = i;
		}
	    }

	  if (i_pivot != j)
	    {
	      gsl_matrix_complex_swap_rows (A, j, i_pivot);
	      gsl_permutation_swap (p, j, i_pivot);
	      *signum = -(*signum);
	    }

	  ajj = gsl_matrix_complex_get (A, j, j);

	  if (!(GSL_REAL(ajj) == 0.0 && GSL_IMAG(ajj) == 0.0))
	    {
	      for (i = j + 1; i < N; i++)
		{
		  gsl_complex aij_orig = gsl_matrix_complex_get (A, i, j);
                  gsl_complex aij = gsl_complex_div (aij_orig, ajj);
		  gsl_matrix_complex_set (A, i, j, aij);

		  for (k = j + 1; k < N; k++)
		    {
		      gsl_complex aik = gsl_matrix_complex_get (A, i, k);
		      gsl_complex ajk = gsl_matrix_complex_get (A, j, k);
                      
                      /* aik = aik - aij * ajk */

                      gsl_complex aijajk = gsl_complex_mul (aij, ajk);
                      gsl_complex aik_new = gsl_complex_sub (aik, aijajk);

		      gsl_matrix_complex_set (A, i, k, aik_new);
		    }
		}
	    }
	}
      
      return GSL_SUCCESS;
    }
}
Exemple #14
0
void SoftDemapper::Run() {

  unsigned int nbits,nsymbs,count;


  /// fetch data objects
  gsl_vector_complex_class input = vin1.GetDataObj();	

  // number of input symbs
  nsymbs = input.vec->size;

  //  cout << "received " << nsymbs << " elements in vector." << endl;

  // number of output symbols
  nbits = nsymbs * Nb();


  gsl_vector *llr=gsl_vector_alloc(nbits);
  double *den = (double *)calloc( Nb(), sizeof(double) );
  double *num = (double *)calloc( Nb(), sizeof(double) );


  // determine symb_likelyhood
  for (int i=0;i<nsymbs;i++) {  // cycle through received symbols

    for (int k=0;k<Nb();k++) {
      num[k] = GSL_NEGINF;			
      den[k] = GSL_NEGINF;			
    }

    // the received symbol
    gsl_complex recsym = gsl_vector_complex_get(input.vec,i);

    
//       cout << "received symbol = (" 
// 	   << GSL_REAL(recsym) 
// 	   << ","
// 	   << GSL_IMAG(recsym) 
// 	   << ") " << endl;


    for (int j=0;j<Ns;j++) { // cycle through postulated symbol

      // gray encoded symbol id
      unsigned int symbol_id = gsl_vector_uint_get(gray_encoding,j);
      
      // complex symbol
      gsl_complex refsym = gsl_complex_polar(1.0,symbol_arg * symbol_id );

      // likelyhood metric
      double metric = gsl_complex_abs( gsl_complex_sub(refsym,recsym) );
      metric = -EsNo()*metric*metric;

      //gsl_matrix_complex_set(symb_likelihoods,j,i);


      //
      // HERE is available a metric for symb i and refsymb j
      //      
      int mask = 1 << Nb() - 1;
      
      for (int k=0;k<Nb();k++) {	/* loop over bits */
	if (mask&j) {
	  /* this bit is a one */
	  num[k] = ( *max_star[LMAP()] )( num[k], metric );
	} else {
	  /* this bit is a zero */
	  den[k] = ( *max_star[LMAP()] )( den[k], metric );
	}
	mask = mask >> 1;
      } //bits
    } // alphabet

    for (int k=0;k<Nb();k++) {
      gsl_vector_set(llr,Nb()*i+k,num[k] - den[k]);
    }    
  } // symbols
  

  gsl_vector_class outv(llr);
  
  //  outv.show();

  // output bitwise LLR
  vout1.DeliverDataObj(outv);
  
  gsl_vector_free(llr);


  // free dynamic structures
  free(num);
  free(den);
  
}
Exemple #15
0
 complex& complex::operator-=(const complex& z1)
 {
   _complex = gsl_complex_sub(_complex, z1._complex);
   return *this;
 }
Exemple #16
0
 complex complex::operator-(const complex& z1) const
 {
   gsl_complex rl = gsl_complex_sub(_complex, z1._complex);
   return complex(rl);
 }
Exemple #17
0
Fichier : xrr.c Projet : FHe/tdl
/******************************************************************************
* calc_A()
* This function calcs the A's for a given theta.  
*
* Parameters
* ---------
*
* Returns
* -------
*
* Notes
* -----
* This function assumes that the X[j] and g[j] values have already 
* been calculated (see calc_X())
* 
* Note:  X[j] = Ar[j]/Ai[j]
* And we can derive:
*
*   Ai[j] = phase*Ai[j+1]*t[j+1] / ( 1 + phase^2 * X[j] * r[j+1])   
*   Ar[j] = Ai[j]*X[j]
*
* where Ar[j] and Ai[j] are the field amplitudes within layer j at 
* the j/j-1 interface. 
*
* For the top layer Ai[nlayer-1] = 1.  ie everything is referenced to 
* unit intensity (Io=|Ai|^2) within the top layer.  Therefore Ar[0] = X[0].
*
* Given the known values for the top layer we can procede to calculate each Ai and Ar
* value starting at the top.  
*
* For the base layer X[0] = 0, ie Ar[0] = 0
*
* The values of r[j+1] and t[j+1] are the reflection and transmission coefficients 
* for the j+1/j interface, respectively, and calculated from:
*
*   r[j+1] = (g[j+1]-g[j])/(g[j+1]+g[j])
*   t[j+1] =  2*g[j+1]/(g[j+1] + g[j]) = 1 + r[j+1]
*
* This function also includes an interfacial roughness term mult into 
* the reflection coefficient for the j+1/j interface:
*
*   r[j+1] = r[j+1]*exp(-1.0(q*sig[j+1])^2)
*
* Note we include roughness in the t calc using the below:
*   t[j+1] = 1 + r[j+1]*exp(-1.0(q*sig[j+1])^2)
* 
* Therefore as r-> 0, t-> 1.  This is only done if calc_params[10] > 0.
* Otherwise t is calc explicitley from the g's
* 
* The phase term accounts for the phase shift and attentuation of the field 
* traversing the j layer (ie from the j+1/j interface to the j/j-1 interface), 
* ie the Ai[j] and Ar[j] are the field amplitudes at the j/j-1 interface: 
*
*   phase = exp( -i*k*d[j] * g[j])
*
* Note if j == 0 then the phase for layer j is 0.0, and X[0] = 0
* ie in the infinitley thick base layer we assumer the is no reflected
* field (Ar[0] = 0.0) and we are calculating the the field amplitude at the
* top of layer 0 rather than the bottom of layer 0.  
*
* 
* Note: double check how doing the phase calc below, is that the best way??
* e.g. could we use:
*  phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j]));
* instead of
*  phase = gsl_complex_exp( gsl_complex_mul(phase,g1));
*
*
******************************************************************************/
int calc_A(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){
    int     i, j, idx;
    double  cos_sqr_thet, k, q, dw;
    double  *d, *sig;
    gsl_complex g1, g2, num, den, r, t, Ai_2, Ar_2, Ai_1, Ar_1, X1, phase, phase_sqr;
    //gsl_complex n1, n2;

    // convenience vars
    cos_sqr_thet = square(cos(theta*M_PI/180.));
    k = ref->k;
    q   = 2.0*k*sin((theta*M_PI/180.));
    d   = ref->d;
    sig = ref->sigma; 

    // start at top
    idx = ref->nlayer - 1;

    // get g for upper layer, ie air/vaccum slab 
    // ie del ~ bet ~ 0.
    // n = 1 - del -i*bet ~ 1
    // g2 = sqrt( n^2 - cos(theta)^2 )  

    //GSL_REAL(n2) = 1.0 - lay_c->del[idx];
    //GSL_IMAG(n2) = -1.0*lay_c->bet[idx];
    //g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) );
    GSL_SET_COMPLEX(&g2,ang_c->Re_g[idx],ang_c->Im_g[idx]); 

    // for the top (j=nlayer-1) layer, Ai =1.0
    // therefore Ar = Ai*X = X
    // store these in A arrays
    ang_c->Re_Ai[idx] = GSL_REAL(Ai_2) = 1.0;
    ang_c->Im_Ai[idx] = GSL_IMAG(Ai_2) = 0.0;
    ang_c->Re_Ar[idx] = GSL_REAL(Ar_2) = ang_c->Re_X[idx];
    ang_c->Im_Ar[idx] = GSL_IMAG(Ar_2) = ang_c->Im_X[idx];
    
    // loop over all layers, start at top - 1
    // ie loop from j = nlayer-2 --> j = 0
    // note j is lower layer in the r and t calcs
    // therefore we are considering the j+1/j interface
    // i is the interface number, ie which interface
    // are the r's and t's calc for
    i = idx - 1;
    for ( j = idx - 1; j > -1 ; j--){
        // calc g and phase for lower layer
        // n = 1 - del -i*bet
        // g1 = sqrt( n^2 - cos(theta)^2 )

        //GSL_REAL(n1) = 1.0 - xpar->del[j];
        //GSL_IMAG(n1) = -1.0 * xpar->bet[j];
        //g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) );
        GSL_SET_COMPLEX(&g1,ang_c->Re_g[j],ang_c->Im_g[j]); 

        //calc phase and attenuation
        // phase = exp( -i*k*d[j] * g1)
        // phase_sqr = (phase)^2
        if (j == 0){
            GSL_REAL(phase) = 1.0;
            GSL_IMAG(phase) = 0.0;
            GSL_REAL(phase_sqr) = 1.0;
            GSL_IMAG(phase_sqr) = 0.0;
        } else {
            GSL_REAL(phase) = 0.0;
            GSL_IMAG(phase) = -1.0*k*d[j];
            phase = gsl_complex_exp( gsl_complex_mul(phase,g1));
            GSL_REAL(phase_sqr) = 0.0;
            GSL_IMAG(phase_sqr) = -2.0*k*d[j];
            phase_sqr = gsl_complex_exp( gsl_complex_mul(phase_sqr,g1));
        }

        // calc r for upper layer
        // r = (g2-g1)/(g2+g1)
        GSL_SET_COMPLEX(&num,0.0,0.0);
        GSL_SET_COMPLEX(&den,0.0,0.0);
        num = gsl_complex_sub(g2,g1);
        den = gsl_complex_add(g2,g1);
        r = gsl_complex_div(num,den);

        // include simple dw type roughness
        // r = r*exp(-1.0(q*sig)^2)
        if (ref->sigma[j+1] > 0.0){
            //dw = exp(-1.0*square(q*ref->sigma[j+1]));
            dw = exp(-1.0*square(q*ref->sigma[i]));
            r  = gsl_complex_mul_real(r,dw);
        }

        // calc t for upper layer
        // t = 2*g2/(g2 + g1)
        if (ref->calc_params[10] == 0.0){
            GSL_SET_COMPLEX(&num,0.0,0.0);
            num = gsl_complex_mul_real(g2, 2.0);
            t = gsl_complex_div(num,den);
        } else {
            // note as as r->0,  t->1
            // ie t = 1+r, so we could just calc t from r?
             t = gsl_complex_add_real(r,1.0);
        }

        // calc Ai_1 and Ar_1
        // these are field mag in the lower slab (layer j)
        // at the bottom of the slab, relative to Ai in the top layer (j=nlayer-1)
        // Ai_1 = phase*Ai_2*t / ( 1 + phase^2 * X1 * r)   
        // Ar_1 = Ai_1*X1
        GSL_REAL(X1) = ang_c->Re_X[j];
        GSL_IMAG(X1) = ang_c->Im_X[j];
        GSL_SET_COMPLEX(&num,0.0,0.0);
        GSL_SET_COMPLEX(&den,0.0,0.0);
        num = gsl_complex_mul(t,gsl_complex_mul(Ai_2,phase));
        den = gsl_complex_add_real(gsl_complex_mul(phase_sqr,gsl_complex_mul(X1,r)),1.0);
        Ai_1 = gsl_complex_div(num,den);
        if (fabs(GSL_REAL(Ai_1)) < 1.0e-12){
            GSL_REAL(Ai_1) = 0.0;
        }
        if (fabs(GSL_IMAG(Ai_1)) < 1.0e-12){
            GSL_IMAG(Ai_1) = 0.0;
        }
        Ar_1 = gsl_complex_mul(Ai_1,X1);

        //store results
        ang_c->Re_Ai[j] = GSL_REAL(Ai_1);
        ang_c->Im_Ai[j] = GSL_IMAG(Ai_1);
        ang_c->Re_Ar[j] = GSL_REAL(Ar_1);
        ang_c->Im_Ar[j] = GSL_IMAG(Ar_1);

        // this is the field intensity at the bottom of layer j
        // except for layer j = 0, this is the intensity at the top
        // of the base layer (bc of how phase is calc above)

        // use bottom layer as top for next time through
        GSL_REAL(Ai_2) = GSL_REAL(Ai_1);
        GSL_IMAG(Ai_2) = GSL_IMAG(Ai_1);
        GSL_REAL(Ar_2) = GSL_REAL(Ar_1);
        GSL_IMAG(Ar_2) = GSL_IMAG(Ar_1);
        // do the same for g's
        GSL_REAL(g2) = GSL_REAL(g1);
        GSL_IMAG(g2) = GSL_IMAG(g1);

        // increment interface number
        i--;
    }
    return (SUCCESS);
}
Exemple #18
0
gsl_complex integrate_line_segment(Params *params,
                                   gsl_complex p0,
                                   gsl_complex p1)
{
    gsl_complex k = gsl_complex_sub(p1, p0);

    const double r = params->r;
    const double a = 0.0; // parameter interval start
    const double b = 1.0; // parameter interval end
    const double L = b - a; // length of parameter interval
    const size_t table_size = 1000;

    // calculate frequency of oscillatory part
    double omega = GSL_REAL(k) * r;

    gsl_integration_workspace *ws = gsl_integration_workspace_alloc(table_size);

    // prepare sine/cosine tables for integration
    gsl_integration_qawo_table *table_cos = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_COSINE, table_size);
    gsl_integration_qawo_table *table_sin = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_SINE, table_size);

    LineSegmentParams lsp;
    lsp.p0 = p0;
    lsp.k = k;
    lsp.damping = params->r * GSL_IMAG(k);
    lsp.params = params;

    //fprintf(stderr, "p0 = %g %g, p1 = %g %g, k = %g %g, r = %g, omega = %g, damping = %g\n",
    //        GSL_REAL(p0), GSL_IMAG(p0), GSL_REAL(p1), GSL_IMAG(p1),
    //        GSL_REAL(k), GSL_IMAG(k), r, omega, lsp.damping);

    gsl_function F;
    F.function = &line_segment_integrand_wrapper;
    F.params = &lsp;

    double result_real_cos, abserr_real_cos;
    double result_real_sin, abserr_real_sin;
    double result_imag_cos, abserr_imag_cos;
    double result_imag_sin, abserr_imag_sin;

    double epsabs = 1e-9;
    double epsrel = 1e-9;

    lsp.part = REAL;
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_real_cos, &abserr_real_cos);
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_real_sin, &abserr_real_sin);

    lsp.part = IMAG;
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_imag_cos, &abserr_imag_cos);
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_imag_sin, &abserr_imag_sin);

    //fprintf(stderr, "    cos: %g (+- %g) %g (+- %g)  sin: %g (+- %g) %g (+- %g)\n",
    //        result_real_cos, abserr_real_cos, result_imag_cos, abserr_imag_cos,
    //        result_real_sin, abserr_real_sin, result_imag_sin, abserr_imag_sin);

    gsl_complex cos_part = gsl_complex_rect(result_real_cos, result_imag_cos);
    gsl_complex sin_part = gsl_complex_rect(-result_imag_sin, result_real_sin);
    gsl_complex sum = gsl_complex_add(cos_part, sin_part);
    gsl_complex result = gsl_complex_mul(
            k,
            gsl_complex_mul(sum, gsl_complex_exp(gsl_complex_mul_imag(p0, params->r))));

    gsl_integration_qawo_table_free(table_sin);
    gsl_integration_qawo_table_free(table_cos);

    gsl_integration_workspace_free(ws);

    return result;
}