示例#1
0
double complex_spinor::norm() const{

	double result=0; 
	int new_numSites = this->_numSites;
	int i;

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

		gsl_complex oldUP = this->complex_spinor_get(i, UP);
		gsl_complex oldDOWN = this->complex_spinor_get(i, DOWN);

	result = result + (gsl_complex_abs2(oldUP) + gsl_complex_abs2(oldDOWN));
	}
	return result;
}
示例#2
0
文件: partial.c 项目: tflovorn/ctetra
// Compute partial density of states corresponding to band index `orig_index`.
// Compute only the contribution from eigenvalue index `eig_index`.
// Perform calculation using Gaussian broadening.
double Gauss_PartialDos_Eig(double E, double sigma, int orig_index, int eig_index, EvecCache *evCache) {
    int na = evCache->na;
    int nb = evCache->nb;
    int nc = evCache->nc;
    int Nk = na*nb*nc; // not (n+1)^3 since we will avoid the repeated points
    double fac = sqrt(2.0*M_PI) * sigma * Nk;
    double Ek;
    gsl_matrix_complex *U;
    gsl_complex U_part;
    int i, j, k, k_index;
    double weight, gauss;
    double pdos = 0.0, this_pdos = 0.0;

    for (k = 0; k < nc; k++) {
        for (j = 0; j < nb; j++) {
            for (i = 0; i < na; i++) {
                k_index = submesh_ijk_index(na, nb, nc, i, j, k);

                U = evCache->evecs[k_index];
                U_part = gsl_matrix_complex_get(U, orig_index, eig_index);
                weight = gsl_complex_abs2(U_part);

                Ek = gsl_vector_get(evCache->energies[k_index], eig_index);
                gauss = exp(-pow(E - Ek, 2.0) / (2.0 * pow(sigma, 2.0)));

                this_pdos = weight * gauss;
                pdos += this_pdos;
            }
        }
    }

    return pdos / fac;
}
示例#3
0
/* ------------------------------------------------------ */
gsl_complex gsl_complex_cabs2 (gsl_complex a)
{        
  gsl_complex z;

  GSL_SET_COMPLEX (&z, gsl_complex_abs2(a), 0);

  return z;
}
示例#4
0
double complex_spinor::meanValue(OPERATOR_SPIN operador)const{

	int i;
	double result = 0;
	//Spinor Parameters
	int new_numeroSitios = this->_numSites;

if(operador == S_Z){
	result = 0;
	for(i=0 ; i<new_numeroSitios ; i++){

	gsl_complex oldUP = this->complex_spinor_get(i, UP);
	gsl_complex oldDOWN = this->complex_spinor_get(i, DOWN);

	result = result + (gsl_complex_abs2(oldUP) - gsl_complex_abs2(oldDOWN));
	}
}
	return 0.5*result;
}
示例#5
0
文件: xrr.c 项目: FHe/tdl
/******************************************************************************
* calc_I()
* Calculate the field intensity at an arbitrary point within layer 
* 
* Parameters
* ---------
*
* Returns
* -------
*
* Notes
* -----
* Note assume that 0 <= z <= d[j] (but we dont check that here)
* except for the base layer (j==0), in that case z <= 0
*
******************************************************************************/
double calc_I(int layer_idx, double z, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){
    double  I, k;
    gsl_complex Ai, Ar, Ei, Er, g, phase_i, phase_r;

    k = ref->k;

    GSL_REAL(Ai) = ang_c->Re_Ai[layer_idx];
    GSL_IMAG(Ai) = ang_c->Im_Ai[layer_idx];
    GSL_REAL(Ar) = ang_c->Re_Ar[layer_idx];
    GSL_IMAG(Ar) = ang_c->Im_Ar[layer_idx];
    GSL_REAL(g)  = ang_c->Re_g[layer_idx];
    GSL_IMAG(g)  = ang_c->Im_g[layer_idx];

    // calculate Ei at z within layer j
    // make sure z is neg for base layer
    if (layer_idx == 0){
        if (z > 0) z = -1.0*z;
    } else {
        if (z < 0) z = -1.0*z;
    }
    GSL_REAL(phase_i) = 0.0;
    GSL_IMAG(phase_i) = 1.0*k*z;
    phase_i = gsl_complex_exp( gsl_complex_mul(phase_i,g));
    Ei = gsl_complex_mul(Ai,phase_i);

    // calculate Er at z within layer j
    if (layer_idx > 0) {    
        GSL_REAL(phase_r) = 0.0;
        GSL_IMAG(phase_r) = -1.0*k*z;
        phase_r = gsl_complex_exp( gsl_complex_mul(phase_r,g));
        Er = gsl_complex_mul(Ar,phase_r);
    } else {
        GSL_REAL(phase_r) = 0.0;
        GSL_IMAG(phase_r) = 0.0;
        GSL_REAL(Er) = 0.0;
        GSL_IMAG(Er) = 0.0;
    }

    I = gsl_complex_abs2(gsl_complex_add(Ei,Er));
    return (I);
}
示例#6
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);
}
示例#7
0
 double complex::abs2() const
 {
     return gsl_complex_abs2(_complex);
 }
示例#8
0
double OneSim(param_ param, FILE *pipe, arr_info_ arr_info_0, 
        lattice_point_ **nghb, gsl_complex **K, gsl_complex *W, 
        gsl_complex *CW, gsl_complex *dW, gsl_complex *complex_rot, 
        double *argW, double *absW, double *rec, double *prec, 
        pr_max_ *pr_max){
    
    int i;
    double t = 0.;
    double *p_levl, *r_levl;
    abs_info_ abs_info;
    arr_info_ arr_info;
    pr_ *rW = NULL, *pW = NULL, *eW = NULL;
    
    /*
     * Zero-ing the pr_max array
     */    
    
    for(i=0;i<param.pr_range;i++){
        pr_max[i].rec = 0.;
        pr_max[i].prec = 0.;
    }
    
    /*
     * Need to allocate the int_total array
     * of abs_info.
     */
    
    abs_info.int_total = (int *)malloc(param.pr_range*sizeof(int));
    
    arr_info.nghb_N = arr_info_0.nghb_N;
    arr_info.r_N = 0;
    arr_info.p_N = 0;
    arr_info.e_N = 0;
    
    /*
     * Clutter needs to be started first
     */
    
    InitZeros(param, CW);
    InitAmoeba(param, &arr_info, CW, &rW, &pW, &eW);      
    InitClutter(param, CW); 
    
    /*
     * Reset the important arrays before
     * generating the real amoeba.
     */
    
    free(rW);
    rW = NULL;
    free(pW);
    pW = NULL;
    free(eW);
    eW = NULL;
    
    arr_info.r_N = 0;
    arr_info.p_N = 0;
    arr_info.e_N = 0;
    
    InitZeros(param, W);
    InitAmoeba(param, &arr_info, W, &rW, &pW, &eW);
    
    /*
     * Reserve memory of the levl arrays
     */
    
    p_levl = (double *)malloc(arr_info.p_N*sizeof(double));
    r_levl = (double *)malloc(arr_info.r_N*sizeof(double));
    
    /*
     * Check the exclusion zone
     */
    
    ChckExcl(param, arr_info, CW, eW);
    
    /*
     * Time to add the clutter to the amoeba
     */
    
    for(i=0;i<param.L*param.L;i++)
        if(gsl_complex_abs2(W[i]) < EPS)
            W[i] = CW[i];
    
    AbsArg(param, &abs_info, W, absW, argW, complex_rot);
    
    while(t<param.T){
        t+=param.dt;
                
        Quiver(param,pipe,absW,argW,abs_info.max,t);
        FieldUpdate(param, arr_info, K, W, dW, absW, complex_rot, nghb);      

        #pragma omp parallel for
        
        for(i=0;i<param.L*param.L;i++)                
            W[i]=gsl_complex_add(W[i],gsl_complex_mul_real(dW[i],param.dt));
        
        AbsArg(param, &abs_info, W, absW, argW, complex_rot);                       
                  
        FieldRedux(param, W, absW, abs_info);  
        
        CalculateRecall(param, rec, arr_info, absW, argW, rW, r_levl);
        CalculatePrecision(param, prec, abs_info, arr_info, absW, argW, pW, 
                p_levl);        
        
        /*
        * Time to calculate max precision
        * and recall for all threshold values.
        * We use that to evaluate the performance
        * of the current choice of parameters.
        */
        
        for(i=0;i<param.pr_range;i++)
            if(rec[i]+prec[i] > pr_max[i].rec + pr_max[i].prec){
                pr_max[i].rec = rec[i];
                pr_max[i].prec = prec[i];                    
            }
        
    }
    
    free(rW);
    free(pW);
    free(eW);
    free(p_levl);
    free(r_levl);
    free(abs_info.int_total);
    
    return t;
}
示例#9
0
void MAIAllocator::Run() {

  // fetch channel matrix
  gsl_matrix_complex hmm  =  min1.GetDataObj();

  // hmm : channel coeffs matrix h(n) (M**2xN)
  //                               ij
  // ch matrix structure
  //
  //   +-                 -+
  //   | h(0) . . . . h(n) | |
  //   |  11           11  | |
  //   |                   | | Rx1
  //   | h(0) . . . . h(n) | |
  //   |  12           12  | |
  //   |                   |
  //   | h(0) . . . . h(n) | |
  //   |  21           21  | |
  //   |                   | | Rx2
  //   | h(0) . . . . h(n) | |
  //   |  22           22  | |
  //   +-                 -+
  //
  //   where h(n) represents the channel impulse response
  //          ij
  //
  //   at time n, from tx_i to rx_j
  //   the matrix has MxM rows and N comumns.
  //   The (i,j) channel is locater at row i*M+j
  //   with i,j in the range [0,M-1] and rows counting from 0
  //
  //

  // fetch error report
  // e(u) = errors for user u in the last ERROR_REPORT_INTERVAL (ERI) frames
  gsl_vector_uint temperr  =  vin2.GetDataObj();

  // update error reports at receiver rx_m every ERI
  if (ericount % ERROR_REPORT_INTERVAL == 0) { // once every ERU
	  if (temperr.size == M()) {
		  gsl_vector_uint_memcpy(errs,&temperr);
	  }
	  ericount = 0;
  }

  //
  // every DECISION_INTERVAL frames we updates the CSI knowledge
  //
  if (framecount % DECISION_INTERVAL == 0) {

	  for (int u=0;u<M();u++) { // user loop

		  // extract time domain response from hmm corresponding to txn-->rxn channel
		  gsl_vector_complex_const_view hii = gsl_matrix_complex_const_row(&hmm,u*M()+u);

		  // copy the N-sized vector hii into u-th column of huu
		  gsl_matrix_complex_set_col(huu,u,&hii.vector);

	  } // user loop

	  //cout << "maiallocator:453 - CSI update received" << endl;

  //  huu matrix structure
  //
  //   +-                 -+
  //   | h(0) . . . . h(n) |
  //   |  11           uu  |
  //   |                   |
  //   | h(n) . . . . h(n) |
  //   |  11           uu  |
  //   +-                 -+
  // 
  //   where h(n) represents the channel impulse response
  //          ii
  //
  //   at time n, from tx_u to rx_u
  //   the matrix has N rows and M columns.
  //
  //   ATTENTION! user_0 channel response is the first column

  //
  // Hmat(NxM) = Fourier( huu(NxM) )
  // 
  gsl_blas_zgemm(CblasNoTrans,
		 CblasNoTrans,
		 gsl_complex_rect(1,0),
		 transform_mat,
		 huu,
		 gsl_complex_rect(0,0),
		 Hmat);

#ifdef SHOW_MATRIX
  cout << "Hmat(freq,user) (frame:" << framecount << ") = " << endl;
  gsl_matrix_complex_show(Hmat);
#endif

  //
  // ***********************************************************
  // CARRIER ALLOCATION STRATEGIES
  // ***********************************************************
  //

  switch (Mode()) {

  case 0: // FIXED_ALLOCATION

    break;

  case 1: // GIVE_BEST_CARR

    //
    // SORT CARRIERS OF EACH USERS
    //
    // uses Hmat: the frequency responses of channel tx_n --> rx_n
    //
	// starting from user u ...
	// find the best (in u ranking) unused carrier and assign it to u
	// next user until no more available carriers

  for(int u=0; u<M(); u++) { // cycle through users

    gsl_vector_complex_const_view huser 
      = gsl_matrix_complex_const_column(Hmat,u);

    gsl_vector_uint_view sortindu = gsl_matrix_uint_column(Hperm,u);

    for (int j=0; j<N(); j++) {
      double currpower 
	= gsl_complex_abs2(gsl_vector_complex_get(&huser.vector,j));

      gsl_vector_set(huserabs,j,currpower);
    }

    // sort over c using abs(h(u,c))
    gsl_sort_vector_index(p,huserabs);

    for (int j=0; j<N(); j++) {
      uint currindex = p->data[j];
      gsl_vector_uint_set(&sortindu.vector,j,currindex);
    }
    
  }

  //
  // FIND INITIAL USER RANDOMLY
  //
  curruser = gsl_rng_uniform_int(ran,M());
  
 
  //
  // ASSIGN FREQUENCIES
  //
  gsl_vector_uint_set_all(nextcarr,0);
  gsl_vector_uint_set_all(usedcarr,0);
  for (int j=0; j<J(); j++) {
    for (int uu=0; uu<M(); uu++) {
      int u = (uu+curruser) % M();
      int isassigned = 0;
      while (! isassigned) {
	int tag = gsl_vector_uint_get(nextcarr,u);
	gsl_vector_uint_set(nextcarr,u,++tag);
	int carrier = gsl_matrix_uint_get(Hperm,N()-tag,u);
	if (! gsl_vector_uint_get(usedcarr,carrier)) {
	  isassigned = 1;
	  gsl_vector_uint_set(usedcarr,carrier,isassigned);
	  gsl_matrix_uint_set(signature_frequencies,u,j,carrier);
	} else if (tag==N()) {
	  cerr << "Block: " << BlockName << " allocation problem." << endl;
	  exit(1);
	}
      }
    }
  }



  //
  // show channels and permutations 
  //
  //  gsl_matrix_complex_show(Hmat);
  //gsl_matrix_uint_show(Hperm);
  //gsl_matrix_uint_show(signature_frequencies);

  break;

  case 2: // SWAP_BAD_GOOD

	  //
	  // SWAP_BAD_GOOD
	  //
	  // sort carriers for each user
	  // choose randomly a starting user u
	  // for each user starting with u
	  //    swap worst carrier used by u with best carrier if used by others

	  // sort carriers
	  for(int u=0; u<M(); u++) {

		  gsl_vector_complex_const_view huser
		  = gsl_matrix_complex_const_column(Hmat,u);
		  gsl_vector_uint_view sortindu = gsl_matrix_uint_column(Hperm,u);
		  gsl_vector_view huserabs = gsl_matrix_column(habs,u);

		  for (int j=0; j<N(); j++) {
      double currpower 
	= gsl_complex_abs2(gsl_vector_complex_get(&huser.vector,j));
      gsl_vector_set(&huserabs.vector,j,currpower);
    }

    //
    // sort channels for user <u>
    //
    gsl_sort_vector_index(p,&huserabs.vector);


    for (int j=0; j<N(); j++) {
      uint currindex = p->data[j];
      gsl_vector_uint_set(&sortindu.vector,j,currindex);
    }

  }

  //
  // Hperm(N,USERS) contains sorted channels index for each users
  // habs(N,USERS) contains channel energy per each user
  //
  
  //
  // FIND INITIAL USER RANDOMLY for fairness
  //
  curruser = gsl_rng_uniform_int(ran,M());
  
 
  //
  // ASSIGN FREQUENCIES
  //

  //
  // for each user ...
  //
  for (int uu=0; uu<M(); uu++) {
    int u = (uu+curruser) % M();

 
    //
    // worst allocated channel for user u
    //
    double worstvalue=GSL_POSINF;
    unsigned int worstjindex;
    for (int j=0; j<J(); j++) {
      unsigned int chind = gsl_matrix_uint_get(signature_frequencies,u,j);
      double currh = gsl_matrix_get(habs,chind,u);
	if (currh < worstvalue) {
	  worstvalue = currh;
	  worstjindex = j;
	}
      }


    //
    // find best channel allocated by other users
    // 
    //
    double bestvalue=0;
    unsigned int bestuser, bestjindex;
    for (int uuu=0; uuu<M()-1; uuu++) {
      unsigned int otheru = (uuu+u) % M();
      for (int j=0; j<J(); j++) {
	unsigned int chind 
	  = gsl_matrix_uint_get(signature_frequencies,otheru,j);
	double currh = gsl_matrix_get(habs,chind,otheru);
	if (currh > bestvalue) {
	  bestvalue = currh;
	  bestjindex = j;
	  bestuser = otheru;
	}
      }
    }


    //
    // finally the swap !
    //
    unsigned int chind 
      = gsl_matrix_uint_get(signature_frequencies,u,worstjindex);
    gsl_matrix_uint_set(signature_frequencies,u,worstjindex,
			gsl_matrix_uint_get(signature_frequencies,
					    bestuser,bestjindex));
    gsl_matrix_uint_set(signature_frequencies,bestuser,bestjindex,chind);


//    cout << "\n\nProcessing user " << u << endl
// 	 << "\tSwapped " << u << "." << worstjindex 
// 	 << " <-> " << bestuser << "." << bestjindex << endl;
    

  }


  break;
  case 3:   //  BEST_OVERLAP

  //
  // SORT CARRIERS OF EACH USERS
  //
	    gsl_matrix_uint_memcpy(signature_frequencies,
				   signature_frequencies_init);

  for(int u=0; u<M(); u++) {

    gsl_vector_complex_const_view huser 
      = gsl_matrix_complex_const_column(Hmat,u);
    gsl_vector_uint_view sortindu = gsl_matrix_uint_column(Hperm,u);

    for (int j=0; j<N(); j++) {
      double currpower = gsl_complex_abs2(gsl_vector_complex_get(&huser.vector,
								 j));
      gsl_vector_set(huserabs,j,currpower);
    }

    gsl_sort_vector_index(p,huserabs);

    for (int j=0; j<N(); j++) {
      uint currindex = p->data[j];
      gsl_vector_uint_set(&sortindu.vector,j,currindex);
    }
    
  }
 
  //
  // each user take his best carriers allowing carrier overlap
  //
  for (int u=0; u<M(); u++) {
    for (int j=0; j<J(); j++) {
      int carrier = gsl_matrix_uint_get(Hperm,N()-j-1,u);
      gsl_matrix_uint_set(signature_frequencies,u,j,carrier);
    }
  }
 
  //
  // show channels and permutations 
  //
  //gsl_matrix_complex_show(Hmat);
  //gsl_matrix_uint_show(Hperm);
  //gsl_matrix_uint_show(signature_frequencies);

  break;
  case 4:   //  SOAR_AI


	  //
	  // SOAR
	  //
	  // agent crai5
	  // bases the decisions on the frequency response tx_m --> rx_m in Hmat(N,M)
	  // for each user it proposes a swap between carriers if the instantaneous impulse channel response
	  // is better
	  //
	  // agent crai6
	  // for each user it proposes a swap of allocated carriers with one other users
	  // error report is the metric for correct decisions (RL)


#ifdef PAUSED
      // keypress
      cout << "pause maillocator: before decision loop  ... (press ENTER key)" << endl;
      cin.ignore();
#endif



	  // Every DECISION_INTERVAL we increase the input-time and allow decisions
	  if (framecount % DECISION_INTERVAL == 0) {
		  pAgent->Update(inputTime,++input_time);
		  pAgent->Commit();
	  }


	  // run agent till output
	  noDecisions = 0;

	  numberCommands=0;

    while (! (noDecisions) ) { // main decisional loop

  	  //
  	  // INPUT LINK Update
  	  //
  	  UpdateInputLink();


      //pAgent->RunSelf(1);
      pAgent->RunSelfTilOutput();
      
      numberCommands = pAgent->GetNumberCommands() ;
      

#ifdef PAUSED
      // keypress 
      cout << "pause maillocator: after RunSelfTilOutput() ... (press ENTER key)" << endl;
      cin.ignore();
#endif


      // loop through received commands
      for (int cmd = 0 ; cmd < numberCommands ; cmd++) {

    	  Identifier* pCommand = pAgent->GetCommand(cmd) ;
    	  string name  = pCommand->GetCommandName() ;

    	  if (name == "assign-free") {
    		  std::string sUid = pCommand->GetParameterValue("uid");
    		  std::string sDeassign = pCommand->GetParameterValue("deassign");
    		  std::string sAssign = pCommand->GetParameterValue("assign");
#ifdef SHOW_SOAR
    		  cout << "assign-free command received [ u:"
    				  << sUid << " , -"
    				  << sDeassign << " , +"
    				  << sAssign << " ]"
    				  << endl;
#endif
    		  AssignFree(sUid,sDeassign,sAssign);
    		  pCommand->AddStatusComplete();

    	  } else if (name == "swap-carriers") {

    		  std::string sU1 = pCommand->GetParameterValue("u1");
    		  std::string sC1 = pCommand->GetParameterValue("c1");
    		  std::string sU2 = pCommand->GetParameterValue("u2");
    		  std::string sC2 = pCommand->GetParameterValue("c2");
#ifdef SHOW_SOAR
    		  cout << "swap-carriers command received [ u1:"
    				  << sU1 << " , c1:"
    				  << sC1 << " , u2:"
    				  << sU2 << " , c2:"
    				  << sC2 << " ]" << endl;
#endif
    		  SwapCarriers(sU1,sC1,sU2,sC2);
    		  pCommand->AddStatusComplete();

    	  } else if (name == "increase-power") {

    		  std::string sUid = pCommand->GetParameterValue("uid");
    		  std::string sCid = pCommand->GetParameterValue("cid");
#ifdef SHOW_SOAR
    		  cout << "increase-power command received [ u:"
    				  << sUid << " , c:"
    				  << sCid << " ]" << endl;
#endif
    		  IncreasePower(sUid,sCid);
    		  pCommand->AddStatusComplete();

    		  break;


    	  } else if (name == "no-choices") {

#ifdef SHOW_SOAR
    		  cout << "no-choices command received" << endl;
#endif
    		  noDecisions = 1;
    		  pCommand->AddStatusComplete();

    		  break;


    	  } else {
#ifdef SHOW_SOAR
    		  cout << "ignoring unknown output command from SOAR" << endl;
#endif
    		  break;
    	  }

//    	  cout << "framecount = " << framecount << endl;

      } // end command loop

    } // while (! (noDecisions) )

      break;

  } // switch (Mode())

} // if DECISION_INTERVAL % 0

  //
  // every 10s dump frame count
  //
  time(&nowtime);

  if (difftime(nowtime,reporttime) > TIMEDELTA) {
	  reporttime = nowtime;
	  cout << "frame:" << framecount << "\r";
	  cout.flush();
  }

  //////// production of data
  framecount++;
  ericount++;
  mout1.DeliverDataObj( *signature_frequencies );
  mout2.DeliverDataObj( *signature_powers );

#ifdef SHOW_MATRIX
  cout << "signature frequencies (frame:" << framecount-1 << ") = " << endl;
  gsl_matrix_uint_show(signature_frequencies);
#endif

}
示例#10
0
文件: xrr.c 项目: FHe/tdl
/******************************************************************************
* xref()
* Master function for reflectivity and reflection xsw calculations
*
* Parameters
* ---------
*
* Returns
* -------
*
* Notes
* -----
* take all raw arrays, use static copies of structs and assign pointers
* then pass along.  This is the main public function
*
* Note theta array and results
* arrays are dim nthet
* int     nthet;
* double *theta_arr;
* double *R; 
* double *Y;
******************************************************************************/
int xref( int nlayer, int nelem, int nthet, double *calc_params, 
          double *d, double *rho, double *sigma, double **comp,
          double *elem_z, double *fp, double *fpp, double *amu, double *mu_at,
          double *theta_arr, double *R, double *Y, 
          double *del, double *bet, double *amu_t, double *mu_t,
          double *Re_X, double *Im_X, double *Re_Ai, double *Im_Ai, 
          double *Re_Ar, double *Im_Ar, double *Re_g, double *Im_g)
{

    int         j, ret, fy_idx;
    double      energy, ref_scale;
    double      theta, k, lam, y, wconv;
    ref_model   ref;
    layer_calc  lay_c;    
    angle_calc  ang_c;
    gsl_complex Xtop;

    //calc k
    energy = calc_params[0];
    lam = 12398.0 / (energy);
    k = 2*M_PI/lam;

    // get fy_idx 
    fy_idx = (int) calc_params[6];

    //ref scale factor
    ref_scale = calc_params[13];

    //fill in the data structure
    //ref_model
    ref.calc_params = calc_params;
    ref.k           = k;
    ref.nlayer      = nlayer;
    ref.d           = d;
    ref.rho         = rho;
    ref.comp        = comp;    
    ref.sigma       = sigma;
    ref.nelem       = nelem;
    ref.elem_z      = elem_z;    
    ref.fp          = fp;
    ref.fpp         = fpp;
    ref.amu         = amu;
    ref.mu_at       = mu_at;

    //layer_calc
    lay_c.nlayer    = nlayer;
    lay_c.del       = del;
    lay_c.bet       = bet;
    lay_c.mu_t      = mu_t;
    lay_c.amu_t     = amu_t;

    //angle_calc
    ang_c.nlayer    = nlayer;
    ang_c.Re_X      = Re_X;
    ang_c.Im_X      = Im_X;
    ang_c.Re_Ai     = Re_Ai;
    ang_c.Im_Ai     = Im_Ai;
    ang_c.Re_Ar     = Re_Ar;
    ang_c.Im_Ar     = Im_Ar;
    ang_c.Re_g      = Re_g;
    ang_c.Im_g      = Im_g;

    // get layer_calc data
    // this stuff doesnt depend on
    // incidence angle
    ret = calc_del_bet_mu(&ref, &lay_c);
    if (ret == FAILURE) return(FAILURE);

    // loop over theta
    for (j=0;j<nthet;j++){

        theta = theta_arr[j];
   
        // calc X's and compute reflectivity     
        ret = calc_X(theta, &ref, &ang_c, &lay_c);
        if (ret == FAILURE) return(FAILURE);

        GSL_SET_COMPLEX(&Xtop,ang_c.Re_X[nlayer-1],ang_c.Im_X[nlayer-1]);  
        R[j] = gsl_complex_abs2(Xtop);

        if (calc_params[5] > 0.0){
            R[j] = R[j]*calc_spilloff(theta,calc_params[3],calc_params[2]);
        }
        if (ref_scale > 0.0){
            R[j] = R[j]*ref_scale;
        }

        if (fy_idx >= 0) {
            // calculate A's
            ret = calc_A(theta, &ref, &ang_c, &lay_c);
            if (ret == FAILURE) return(FAILURE);
    
            // calc FY
            y = calc_FY(theta, &ref, &ang_c, &lay_c);

            // mult by area
            if (calc_params[5] > 0.0){
                y = y*calc_area(theta,calc_params[3],calc_params[4],calc_params[2]);
                y = y*calc_spilloff(theta,calc_params[3],calc_params[2]);
            }
            Y[j] = y; 
        }
    }

    // convolve and normalize
    wconv = calc_params[1];

    // Note convolve is not padded!
    if (wconv > 0.0) {
        convolve(theta_arr, R, nthet, wconv);
    } 

    if (fy_idx >= 0){
        //convolve yield
        if (wconv > 0.0){
            convolve(theta_arr, Y, nthet, wconv);
        }
        // normalize yield
        norm_array(theta_arr, Y, nthet, calc_params[9], 1.0);
    }

    return(SUCCESS);
}