Ejemplo n.º 1
0
pure_expr *wrap_gsl_complex_sqrt(pure_expr *x)
{
  gsl_complex z;
  if (pure_is_complex(x, z.dat)) {
    gsl_complex ret = gsl_complex_sqrt(z);
    return pure_complex(ret.dat);
  } else
    return 0;
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
gsl_complex f_envelope(gsl_complex p, const Params *params)
{
    double m = params->m;

    gsl_complex env = gsl_complex_div(
            p,
            gsl_complex_sqrt(gsl_complex_add_real(gsl_complex_mul(p,p), m*m)));

    if (params->smear)
    {
        gsl_complex sp = gsl_complex_mul_real(p, params->sigma);
        env = gsl_complex_mul(env, gsl_complex_exp(gsl_complex_negative(gsl_complex_mul(sp, sp))));
    }

    return env;
}
Ejemplo n.º 4
0
/* 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);
}
Ejemplo n.º 5
0
 /** Square root of a complex number
 \ingroup complex
 \param[in] z Complex number
 \return \f$ \sqrt z \f$*/
 complex sqrt(const complex& z)
 {
   return complex(gsl_complex_sqrt(z.as_gsl_type()));
 }
Ejemplo n.º 6
0
ComplexGSL sqrt( ComplexGSL& c )	{ return ComplexGSL(gsl_complex_sqrt(c.z)); }
Ejemplo n.º 7
0
Archivo: xrr.c Proyecto: 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);
}