Ejemplo n.º 1
0
void NR::voltra(const DP t0, const DP h, Vec_O_DP &t, Mat_O_DP &f,
	DP g(const int, const DP),
	DP ak(const int, const int, const DP, const DP))
{
	int i,j,k,l;
	DP d,sum;

	int m=f.nrows();
	int n=f.ncols();
	Vec_INT indx(m);
	Vec_DP b(m);
	Mat_DP a(m,m);
	t[0]=t0;
	for (k=0;k<m;k++) f[k][0]=g(k,t[0]);
	for (i=1;i<n;i++) {
		t[i]=t[i-1]+h;
		for (k=0;k<m;k++) {
			sum=g(k,t[i]);
			for (l=0;l<m;l++) {
				sum += 0.5*h*ak(k,l,t[i],t[0])*f[l][0];
				for (j=1;j<i;j++)
					sum += h*ak(k,l,t[i],t[j])*f[l][j];
				if (k == l)
					a[k][l]=1.0-0.5*h*ak(k,l,t[i],t[i]);
				else
					a[k][l] = -0.5*h*ak(k,l,t[i],t[i]);
			}
			b[k]=sum;
		}
		ludcmp(a,indx,d);
		lubksb(a,indx,b);
		for (k=0;k<m;k++) f[k][i]=b[k];
	}
}
Ejemplo n.º 2
0
static void
irt_rpf_nominal_logprob(const double *spec,
			const double *param, const double *th,
			double *out)
{
  int numOutcomes = spec[RPF_ISpecOutcomes];
  int numDims = spec[RPF_ISpecDims];
  Eigen::VectorXd num(numOutcomes);
  Eigen::VectorXd ak(numOutcomes);
  double discr = dotprod(param, th, numDims);
  double maxZ;
  _nominal_rawprob1(spec, param, th, discr, ak.data(), num.data(), &maxZ);
  double den = 0;

  if (maxZ > EXP_STABLE_DOMAIN) {
    den = maxZ;  // not best approx
  } else {
    for (int kx=0; kx < numOutcomes; kx++) {
      if (num[kx] < -EXP_STABLE_DOMAIN) continue;
      den += exp(num[kx]);
    }
    den = log(den);
  }

  for (int kx=0; kx < numOutcomes; kx++) {
    out[kx] = num[kx] - den;
  }
}
Ejemplo n.º 3
0
void findK()
{
	const int iters=100000, nSteps=100000;
	CDynArray<double> ak(iters);
	CBBSimulator bb(nSteps);
	for(int i=0;i<iters;i++)
	{
		bb.simulate();
		ak[i] = bb.getk();
	}
	std::ofstream kfile("kfile.tsv");
	
	const bool bOutputAll = false;
	if(bOutputAll)
	{
		std::sort(ak.begin(), ak.end());
		ak.pp("\n", kfile);
	}
	else
	{
		double dMean, dVar;
		ak.getMeanVar(dMean, dVar);
		kfile << dMean << endl;
		kfile << dVar << endl;
	}
	
	kfile.close();



}
Ejemplo n.º 4
0
DP NR::fredin(const DP x, const DP a, const DP b, Vec_I_DP &t, Vec_I_DP &f,
	Vec_I_DP &w, DP g(const DP), DP ak(const DP, const DP))
{
	int i;
	DP sum=0.0;

	int n=t.size();
	for (i=0;i<n;i++) sum += ak(x,t[i])*w[i]*f[i];
	return g(x)+sum;
}
Ejemplo n.º 5
0
static void
irt_rpf_nominal_prob(const double *spec,
		     const double *param, const double *th,
		     double *out)
{
  int numOutcomes = spec[RPF_ISpecOutcomes];
  int numDims = spec[RPF_ISpecDims];
  Eigen::VectorXd ak(numOutcomes);
  double discr = dotprod(param, th, numDims);
  _nominal_rawprob2(spec, param, th, discr, ak.data(), out);
}
Ejemplo n.º 6
0
objArrayOop arrayKlass::allocate_arrayArray(int n, int length, TRAPS) {
  if (length < 0) {
    THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
  }
  if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
    THROW_OOP_0(Universe::out_of_memory_error_instance());
  }
  int size = objArrayOopDesc::object_size(length);
  klassOop k = array_klass(n+dimension(), CHECK_0);
  arrayKlassHandle ak (THREAD, k);
  objArrayOop o =
    (objArrayOop)CollectedHeap::array_allocate(ak, size, length, CHECK_0);
  // initialization to NULL not necessary, area already cleared
  return o;
}
Ejemplo n.º 7
0
static void
irt_rpf_mdim_nrm_rescale(const double *spec, double *param, const int *paramMask,
			 const double *mean, const double *cov)
{
  int numDims = spec[RPF_ISpecDims];
  int nzeta = spec[RPF_ISpecOutcomes] - 1;
  double *alpha = param + numDims;
  double *gamma = param + numDims + nzeta;
  const double *Ta  = spec + RPF_ISpecCount;
  const double *Tc  = spec + RPF_ISpecCount + nzeta * nzeta;
  const double *iTc = spec + RPF_ISpecCount + 3 * nzeta * nzeta;

  double madj = dotprod(param, mean, numDims);

  for (int d1=0; d1 < numDims; d1++) {
    if (paramMask[d1] < 0) continue;
    param[d1] = dotprod(param+d1, cov + d1 * numDims + d1, numDims-d1);
  }

  Eigen::VectorXd ak(nzeta);
  ak.setZero();
  Eigen::VectorXd ck(nzeta);
  ck.setZero();

  for (int kx=0; kx < nzeta; kx++) {
    for (int tx=0; tx < nzeta; tx++) {
      int Tcell = tx * nzeta + kx;
      ak[kx] += Ta[Tcell] * alpha[tx];
      ck[kx] += Tc[Tcell] * gamma[tx];
    }
  }

  for (int kx=0; kx < nzeta; kx++) {
    ck[kx] += madj * ak[kx];
  }

  for (int kx=0; kx < nzeta; kx++) {
    int px = numDims + nzeta + kx;
    if (paramMask[px] < 0) continue;

    param[px] = 0;

    for (int tx=0; tx < nzeta; tx++) {
      int Tcell = tx * nzeta + kx;
      param[px] += iTc[Tcell] * ck[tx];
    }
  }
}
Ejemplo n.º 8
0
void NR::fred2(const DP a, const DP b, Vec_O_DP &t, Vec_O_DP &f, Vec_O_DP &w,
	DP g(const DP), DP ak(const DP, const DP))
{
	int i,j;
	DP d;

	int n=t.size();
	Mat_DP omk(n,n);
	Vec_INT indx(n);
	gauleg(a,b,t,w);
	for (i=0;i<n;i++) {
		for (j=0;j<n;j++)
			omk[i][j]=DP(i == j)-ak(t[i],t[j])*w[j];
		f[i]=g(t[i]);
	}
	ludcmp(omk,indx,d);
	lubksb(omk,indx,f);
}
Ejemplo n.º 9
0
static void
irt_rpf_mdim_nrm_dTheta(const double *spec, const double *param,
			const double *where, const double *dir,
			double *grad, double *hess)
{
  int numDims = spec[RPF_ISpecDims];
  int outcomes = spec[RPF_ISpecOutcomes];
  const double *aa = param;
  Eigen::VectorXd num(outcomes);
  Eigen::VectorXd ak(outcomes);
  double discr = dotprod(param, where, numDims);
  _nominal_rawprob2(spec, param, where, discr, ak.data(), num.data());

  double den = 0;
  for (int kx=0; kx < outcomes; kx++) {
    den += num[kx];
  }

  Eigen::VectorXd P(outcomes);
  for (int kx=0; kx < outcomes; kx++) {
    P[kx] = num[kx]/den;
  }

  for(int jx=0; jx < numDims; jx++) {
	  Eigen::VectorXd jak(outcomes);
	  Eigen::VectorXd jak2(outcomes);
    for (int ax=0; ax < outcomes; ax++) {
      jak[ax] = ak[ax] * aa[jx];
      jak2[ax] = jak[ax] * jak[ax];
    }
    double numjak = dotprod(num.data(), jak.data(), outcomes);
    double numjakden2 = numjak / den;
    numjakden2 *= numjakden2;
    double numjak2den = dotprod(num.data(), jak2.data(), outcomes) / den;

    for(int ix=0; ix < outcomes; ix++) {
      grad[ix] += dir[jx] * (ak[ix] * aa[jx] * P[ix] - P[ix] * numjak / den);
      hess[ix] += dir[jx] * (ak[ix]*ak[ix] * aa[jx]*aa[jx] * P[ix] -
			     2 * ak[ix] * aa[jx] * P[ix] * numjak / den +
			     2 * P[ix] * numjakden2 - P[ix] * numjak2den);
    }
  }
}
Ejemplo n.º 10
0
int main(int, char**) {
    int failed = 0;
    scalar_test_group<value>(failed);

    // Sequence tests
    RUN_TEST(failed, sequence_test<std::list<bool> >(ARRAY, many<bool>() + false + true));
    RUN_TEST(failed, sequence_test<std::vector<int> >(ARRAY, many<int>() + -1 + 2));
    RUN_TEST(failed, sequence_test<std::deque<std::string> >(ARRAY, many<std::string>() + "a" + "b"));
    RUN_TEST(failed, sequence_test<std::deque<symbol> >(ARRAY, many<symbol>() + "a" + "b"));
    RUN_TEST(failed, sequence_test<std::vector<value> >(LIST, many<value>() + value(0) + value("a")));
    RUN_TEST(failed, sequence_test<std::vector<scalar> >(LIST, many<scalar>() + scalar(0) + scalar("a")));

    // // Map tests
    typedef std::pair<std::string, uint64_t> pair;
    many<pair> pairs;
    pairs << pair("a", 0) << pair("b", 1) << pair("c", 2);

    RUN_TEST(failed, (map_test<std::map<std::string, uint64_t> >(pairs)));
    RUN_TEST(failed, (map_test<std::vector<pair> >(pairs)));

    many<std::pair<value,value> > value_pairs(pairs);
    RUN_TEST(failed, (map_test<std::map<value, value> >(value_pairs)));

    many<std::pair<scalar,scalar> > scalar_pairs(pairs);
    RUN_TEST(failed, (map_test<std::map<scalar, scalar> >(scalar_pairs)));

    annotation_key ak(pairs[0].first);
    std::pair<annotation_key, message_id> p(pairs[0]);
    many<std::pair<annotation_key, message_id> > restricted_pairs(pairs);
    RUN_TEST(failed, (map_test<std::map<annotation_key, message_id> >(restricted_pairs)));

#if PN_CPP_HAS_CPP11
    RUN_TEST(failed, sequence_test<std::forward_list<binary> >(ARRAY, many<binary>() + binary("xx") + binary("yy")));
    RUN_TEST(failed, (map_test<std::unordered_map<std::string, uint64_t> >(pairs)));
#endif
    return failed;
}
Ejemplo n.º 11
0
static void
irt_rpf_nominal_deriv1(const double *spec,
		       const double *param,
		       const double *where,
		       const double *weight, double *out)
{
  int nfact = spec[RPF_ISpecDims];
  int ncat = spec[RPF_ISpecOutcomes];
  double aTheta = dotprod(param, where, nfact);
  double aTheta2 = aTheta * aTheta;

  Eigen::VectorXd num(ncat);
  Eigen::VectorXd ak(ncat);
  _nominal_rawprob2(spec, param, where, aTheta, ak.data(), num.data());

  Eigen::VectorXd P(ncat);
  Eigen::VectorXd P2(ncat);
  Eigen::VectorXd P3(ncat);
  Eigen::VectorXd ak2(ncat);
  Eigen::VectorXd dat_num(ncat);
  double numsum = 0;
  double numakD = 0;
  double numak2D2 = 0;
  Eigen::VectorXd numakDTheta_numsum(nfact);

  for (int kx=0; kx < ncat; kx++) {
    ak2[kx] = ak[kx] * ak[kx];
    dat_num[kx] = weight[kx]/num[kx];
    numsum += num[kx];
    numakD += num[kx] * ak[kx];
    numak2D2 += num[kx] * ak2[kx];
  }
  double numsum2 = numsum * numsum;

  for (int kx=0; kx < ncat; kx++) {
    P[kx] = num[kx]/numsum;
    P2[kx] = P[kx] * P[kx];
    P3[kx] = P2[kx] * P[kx];
  }

  double sumNumak = dotprod(num.data(), ak.data(), ncat);
  for (int fx=0; fx < nfact; fx++) {
    numakDTheta_numsum[fx] = sumNumak * where[fx] / numsum;
  }

  for (int jx = 0; jx < nfact; jx++) {
    double tmpvec = 0;
    for(int i = 0; i < ncat; i++) {
      tmpvec += dat_num[i] * (ak[i] * where[jx] * P[i] -
			      P[i] * numakDTheta_numsum[jx]) * numsum;
    }
    out[jx] -= tmpvec;
  }
  int dkoffset;
  if (nfact == 0) {
	  dkoffset = 0;
  } else {
	  dkoffset = ncat - 1;
  }
  for(int i = 1; i < ncat; i++) {
	  if (nfact) {
		  double offterm = makeOffterm(weight, P[i], aTheta, ncat, i);
		  double tmpvec = dat_num[i] * (aTheta * P[i] - P2[i] * aTheta) * numsum - offterm;
		  out[nfact + i - 1] -= tmpvec;
	  }
    double offterm2 = makeOffterm(weight, P[i], 1, ncat, i);
    double tmpvec2 = dat_num[i] * (P[i] - P2[i]) * numsum - offterm2;
    out[nfact + dkoffset + i - 1] -= tmpvec2;
  }

  int hessbase = nfact + (ncat-1) + dkoffset;
  int d2ind = 0;
  //a's
  for (int j = 0; j < nfact; j++) {
    for (int k = 0; k <= j; k++) {
      double tmpvec = 0;
      for (int i = 0; i < ncat; i++) {
	tmpvec += dat_num[i] * (ak2[i] * where[j] * where[k] * P[i] -
				ak[i] * where[j] * P[i] * numakDTheta_numsum[k] -
				ak[i] * where[k] * P[i] * numakDTheta_numsum[j] + 
				2 * P[i] * numakD * where[j] * numakD * where[k] / numsum2 -
				P[i] * numak2D2 * where[j] * where[k] / numsum) * numsum - 
	  dat_num[i] * (ak[i] * where[j] * P[i] - P[i] * numakDTheta_numsum[j]) *
	  numsum * ak[i] * where[k] +
	  dat_num[i] * (ak[i] * where[j] * P[i] - P[i] * numakDTheta_numsum[j]) *
	  numakD * where[k];
      }
      out[hessbase + d2ind++] -= tmpvec;
    }
  }
  //a's with ak and d
  for(int k = 1; k < ncat; k++){
    int akrow = hessbase + (nfact+k)*(nfact+k-1)/2;
    int dkrow = hessbase + (nfact+ncat+k-1)*(nfact+ncat+k-2)/2;
    for(int j = 0; j < nfact; j++){
      double tmpvec = 0;
      double tmpvec2 = 0;
      for(int i = 0; i < ncat; i++){
	if(i == k){
	  tmpvec += dat_num[i] * (ak[i]*where[j] * aTheta*P[i] -
				     aTheta*P[i]*numakDTheta_numsum[j] +
				     where[j]*P[i] - 2*ak[i]*where[j]*aTheta*P2[i] +
				     2*aTheta*P2[i]*numakDTheta_numsum[j] -
				     where[j]*P2[i])*numsum -
	    dat_num[i]*(aTheta*P[i] - aTheta*P2[i])*numsum*ak[i]*where[j] +
	    dat_num[i]*(aTheta*P[i] - aTheta*P2[i])*(numakD*where[j]);
	  tmpvec2 += dat_num[i]*(ak[i]*where[j]*P[i] -
				      2*ak[i]*where[j]*P2[i] -
				      P[i]*numakDTheta_numsum[j] +
				      2*P2[i]*numakDTheta_numsum[j])*numsum -
	    dat_num[i]*(P[i] - P2[i])*numsum*ak[i]*where[j] +
	    dat_num[i]*(P[i] - P2[i])*(numakD*where[j]);
	} else {
	  tmpvec += -weight[i]*ak[k]*aTheta*where[j]*P[k] +
	    weight[i]*P[k]*aTheta*numakDTheta_numsum[j] -
	    weight[i]*P[k]*where[j];
	  tmpvec2 += -weight[i]*ak[k]*where[j]*P[k] +
	    weight[i]*P[k]*numakDTheta_numsum[j];
	}
      }
      out[akrow + j] -= tmpvec;
      out[dkrow + j] -= tmpvec2;
    }
  }
  //ak's and d's
  for(int j = 1; j < ncat; j++){
    int akrow = hessbase + (nfact+j)*(nfact+j-1)/2;
    int dkrow = hessbase + (nfact+dkoffset+j)*(nfact+dkoffset+j-1)/2;

    double tmpvec = makeOffterm(weight, P2[j], aTheta2, ncat, j);
    double tmpvec2 = makeOffterm(weight, P[j], aTheta2, ncat, j);
    double offterm = tmpvec - tmpvec2;
    tmpvec = makeOffterm(weight, P2[j], 1, ncat, j);
    tmpvec2 = makeOffterm(weight, P[j], 1, ncat, j);
    double offterm2 = tmpvec - tmpvec2;

    if (nfact) {
	    out[akrow + nfact + j - 1] -=
		    (dat_num[j]*(aTheta2*P[j] - 3*aTheta2*P2[j] +
				 2*aTheta2*P3[j])*numsum - weight[j]/num[j] *
		     (aTheta*P[j] - aTheta*P2[j])*numsum*aTheta + weight[j] *
		     (aTheta*P[j] - aTheta*P2[j])*aTheta + offterm);
    }

    out[dkrow + nfact + dkoffset + j - 1] -=
      (dat_num[j]*(P[j] - 3*P2[j] + 2*P3[j])*numsum - weight[j]/num[j] *
	      (P[j] - P2[j])*numsum + weight[j] *
	      (P[j] - P2[j]) + offterm2);

    for(int i = 1; i < ncat; i++) {
      if(j > i) {
	      if (nfact) {
		      offterm = makeOffterm2(weight, P[j], P[i], aTheta2, ncat, i);
		      tmpvec = dat_num[i] * (-aTheta2*P[i]*P[j] + 2*P2[i] *aTheta2*P[j])*numsum + 
			      dat_num[i] * (aTheta*P[i] - P2[i] * aTheta)*aTheta*num[j]+offterm;
		      out[akrow + nfact + i - 1] -= tmpvec;
	      }
	offterm2 = makeOffterm2(weight, P[j], P[i], 1, ncat, i);
	tmpvec2 = dat_num[i] * (-P[i]*P[j] + 2*P2[i] *P[j]) * numsum +
	  dat_num[i] * (P[i] - P2[i]) * num[j] + offterm2;
	out[dkrow + nfact + dkoffset + i - 1] -= tmpvec2;
      }
      if (nfact == 0) continue;
      if (abs(j-i) == 0) {
	tmpvec = makeOffterm(weight, P2[i], aTheta, ncat, i);
	tmpvec2 = makeOffterm(weight, P[i], aTheta, ncat, i);
	offterm = tmpvec - tmpvec2;
	tmpvec = dat_num[i]*(aTheta*P[i] - 3*aTheta*P2[i] +
			     2*aTheta*P3[i]) * numsum - dat_num[i] *
	  (aTheta*P[i] - aTheta*P2[i])*numsum + weight[i] *
	  (P[i] - P2[i])*aTheta + offterm;
	out[dkrow + nfact + i - 1] -= tmpvec;
      } else {
	offterm = makeOffterm2(weight, P[j], P[i], aTheta, ncat, i);
	tmpvec = dat_num[i] * (-aTheta*P[i]*P[j] + 2*P2[i] *aTheta*P[j]) * numsum + 
	  dat_num[i] * (P[i] - P2[i]) * aTheta * num[j] + offterm;
	out[dkrow + nfact + i - 1] -= tmpvec;
      }
    }
  }
}
Ejemplo n.º 12
0
void P_nominal(vector<double> &P, const vector<double> &par,
    const NumericMatrix &Theta, const NumericVector &ot, const int &N,
    const int &nfact, const int &ncat, const int &returnNum,
    const int &israting)
{
    vector<double> a(nfact), ak(ncat), d(ncat);
    for(int i = 0; i < nfact; ++i)
        a[i] = par[i];
    for(int i = 0; i < ncat; ++i){
        ak[i] = par[i + nfact];
        if(israting){
            if(i)
                d[i] = par[i + nfact + ncat] + par[par.size()-1];
        } else {
            d[i] = par[i + nfact + ncat];
        }
    }
    const int USEOT = ot.size() > 1;
    NumericMatrix Num(N, ncat);
    vector<double> z(ncat);
    vector<double> Den(N, 0.0);
    vector<double> innerprod(N, 0.0);

    for(int i = 0; i < N; ++i)
        for(int j = 0; j < nfact; ++j)
            innerprod[i] += Theta(i,j) * a[j];
    if(USEOT){
        for(int i = 0; i < N; ++i){
            for(int j = 0; j < ncat; ++j)
                z[j] = ak[j] * innerprod[i] + d[j] + ot[j];
            double maxz = *std::max_element(z.begin(), z.end());
            for(int j = 0; j < ncat; ++j){
                z[j] = z[j] - maxz;
                if(z[j] < -ABS_MAX_Z) z[j] = -ABS_MAX_Z;
                Num(i,j) = exp(z[j]);
                Den[i] += Num(i,j);
            }
        }
    } else {
        for(int i = 0; i < N; ++i){
            for(int j = 0; j < ncat; ++j)
                z[j] = ak[j] * innerprod[i] + d[j];
            double maxz = *std::max_element(z.begin(), z.end());
            for(int j = 0; j < ncat; ++j){
                z[j] = z[j] - maxz;
                if(z[j] < -ABS_MAX_Z) z[j] = -ABS_MAX_Z;
                Num(i,j) = exp(z[j]);
                Den[i] += Num(i,j);
            }
        }
    }
    int which = 0;
    if(returnNum){
        for(int j = 0; j < ncat; ++j){
            for(int i = 0; i < N; ++i){
                P[which] = Num(i,j);
                ++which;
            }
        }
    } else {
        for(int j = 0; j < ncat; ++j){
            for(int i = 0; i < N; ++i){
                P[which] = Num(i,j) / Den[i];
                ++which;
            }
        }
    }
}
Ejemplo n.º 13
0
void MainWindow::on_pushButton_2_clicked()
{
    adding_keys ak(ldb);
    ak.exec();
    refresh_keywords_list();
}
Ejemplo n.º 14
0
 virtual JsonMapValue*   mapCreateElement(std::string* k,JsonValue* val)     { std::unique_ptr<std::string> ak(k);   std::unique_ptr<JsonValue> aval(val); parent.activate(*ak, *aval); return NULL;}
Ejemplo n.º 15
0
 virtual std::string*    mapKeyNote(std::string* k)                          { std::unique_ptr<std::string> ak(k);                                         parent.preActivate(*ak);     return ak.release();}
Ejemplo n.º 16
0
/*! \brief Poles, zeros and elliptic cells coefficients computation.
 *
 * Inputs are:
 * \arg eps : Oscillations in working bandwidth
 * \arg A :  Weakening of attenuated band
 * \arg f : Low frequency transition edge  [Hz]
 * \arg fb : High frequency transition edge [Hz]
 * \arg fe : Sampling frequency  [Hz]
 * \arg NCellMax : Maximum number of cells
 *
 * Outputs are :
 * \arg NCells : number of cells, must be positive and lower or equal to NCellMax
 * \arg poles : poles of the cells (imaginary part positive or null) 
 * \arg zero : zeros of the cells (imaginary part positive or null)
 * \arg CoefA : coefficient A of the cells
 * \arg CoefB : coefficient B of the cells
 * \arg CoefC : coefficient C of the cells
 * \arg CoefD : coefficient D of the cells
 *
 * Computations : \n
 * \f$  \omega_c = fb \cdot 2 \cdot \pi \f$ \n
 * \f$  \omega_r = fa \cdot 2 \cdot \pi \f$ \n
 * \f$  T = 1/fe \f$ \n
 * \f$  dk1 = \frac{eps}{\sqrt{A^2-1}} \f$ \n
 * \f$  dk = \frac{tan(\omega_c \cdot \frac{T}{2})}{tan(\omega_r \cdot \frac{T}{2})} \f$ \n
 * \f$  dkp = \sqrt{1-dk^2} \f$ \n
 * \f$  ak1 = ak(dk) \textrm{ using ak function} \f$ \n
 * \f$  ak2 = ak(dk1) \textrm{ using ak function} \f$ \n
 * \f$  ak3 = ak(dkp) \textrm{ using ak function} \f$ \n
 * \f$  ak4 = cak(dk1^2) \textrm{ using cak function} \f$ \n
 *
 * \f$ N = \frac{1}{2} \cdot ceil \big( ceil(\frac{ak4 \cdot ak1}{ak2 \cdot ak3}+1) \big) \f$ \n
 * N is checked : \f$ 0 \le N \le NCellMax \f$ \n
 *
 * \f$  U_0 = -\frac{ak3}{ak4} \cdot \frac{alog(1+\sqrt{(1+eps^2)})}{eps} \f$ \n
 * \arg for  \f$ i=0,\dots,N-1 \f$ \n
 * \f$ xmag = 2 \cdot i \cdot \frac{ak1}{2 \cdot N} \f$ \n
 * \f$ zeros[i] = -ak3 + I \cdot xmag \f$ \n
 * \f$ poles[i] = U_0 + I \cdot xmag \f$ \n
 * \arg for  \f$ i=0,\dots,2 \cdot N-1 \f$ \n
 * \f$ Q = real(zeros[mod(i,N)]) \f$ \n
 * \f$ R = imag(zeros[mod(i,N)]) \f$ \n
 * \f$ a1 = sn(Q, dkp, ak3, ak1) \textrm{ using sn function} \f$ \n
 * \f$ b1 = sn(R, dk,  ak1, ak3) \textrm{ using sn function} \f$ \n
 * \f$ \sigma= \left\{ \begin{array}{ll} 0 & \textrm{if } i \le N \\
 a1 \cdot \sqrt{(1-a1^2)*(1-b1^2)} \cdot \frac{dn}{de} & else \end{array} \right. \f$ \n
 * \f$ dn = \sqrt{1-{(dk \cdot b1)}^2} \f$ \n
 * \f$ de = 1-{(a1 \cdot dn)}^2 \f$ \n
 * \f$ \omega = b1 \cdot \frac{\sqrt{(1-(dkp \cdot a1)^2)}}{de} \f$ \n
 * \f$ C[i] = -2 \cdot \sigma \cdot \omega_c \f$ \n
 * \f$ D[i] = (\sigma^2 + \omega^2) \cdot {\omega_c}^2 \f$ \n
 * \f$ \sigma = \sigma \cdot tan(\omega_c \cdot \frac{T}{2}) \f$ \n
 * \f$ \omega = \omega \cdot tan(\omega_c \cdot \frac{T}{2}) \f$ \n
 * \f$ \left\{ \begin{array}{ll}
 \textrm{if } i \le N & zeros[i] = \sigma + I \cdot \omega \\
 \textrm{else} & poles[i] = \sigma + I \cdot \omega \end{array} \right. \f$ \n
 * \arg for  \f$ i=2 \cdot N-1,\dots,0 \f$ \n
 * \f$ \left\{ \begin{array}{ll} \textrm{if } i \le N -1 & (X,Y)=(real(zeros[i]),imag(zeros[i])) \\
 else & (X,Y)=(real(poles[i]),imag(poles[i])) \end{array} \right. \f$ \n
 * \f$    Re = \frac{1-X^2-Y^2}{(1-X)^2+Y^2} \f$ \n
 * \f$    V = \frac{2 \cdot Y}{(1-X)^2+Y^2} \f$ \n
 * \f$    c1 = -2 \cdot Re \f$ \n
 * \f$    d1 = Re^2 + V^2 \f$ \n
 * \f$ \left\{ \begin{array}{ll}
 \textrm{if } i \le N -1 & \left\{ \begin{array}{l}
zeros[i]=Re+I \cdot V \\ CoefB[i]=c1 \\ CoefA[i]=d1  \end{array} \right. \\
 else & \left\{ \begin{array}{l}
 poles[i-N]=Re+I \cdot V  \\  CoefD[i-N]=c1 \\ CoefC[i-N]=d1 \end{array} \right.
 \end{array} \right. \f$ \n
 */
void elli(double eps,      // Oscillations in working bandwidth
	  double A,        // Weakening of attenuated band
	  double fa,       // Low frequency transition edge  [Hz]
	  double fb,       // High frequency transition edge [Hz]
	  double fe,       // Sampling frequency  [Hz]
	  int NCellMax,         // Maximum number of cells
	  int *NCells,          // Output number of cells
	  std::complex<double> poles[], // Poles of the cells (imaginary part >= 0) 
	  std::complex<double> zeros[], // Zeros of the cells (imaginary part >= 0)
	  double CoefA[],  // A coef from H(Z) = (1+BZ-1+AZ-2) / (1+DZ-1+BZ-2)
	  double CoefB[],  // B coef from H(Z) = (1+BZ-1+AZ-2) / (1+DZ-1+BZ-2)
	  double CoefC[],  // C coef from H(Z) = (1+BZ-1+AZ-2) / (1+DZ-1+BZ-2)
	  double CoefD[]   // D coef from H(Z) = (1+BZ-1+AZ-2) / (1+DZ-1+BZ-2)
	  ) {

  double *C, *D;
  double T, dk1, dk, dkp, ak1, ak2, ak3, ak4;
  double U0, xmag, Q, R, sigma;
  double a1, b1, dn, de, omega;
  double X, Y, Re, V, c1, d1;
  double wr, wc;
  int i, j, N, NDeu;
  std::complex<double> p;
  
  wc = fb*2*M_PI;
  wr = fa*2*M_PI;

  T = 1/fe;
  dk1 = eps/sqrt(A*A-1);
  dk = tan(wc*T/2.) / tan(wr*T/2.);
  dkp = sqrt(1-dk*dk);
  ak1 = ak(dk);
  ak2 = ak(dk1);
  ak3 = ak(dkp);
  //ak4 = ak(sqrt(1-dk1*dk1));
  ak4 = cak(dk1*dk1);

  N = (int)(ak4*ak1/(ak2*ak3));
  N = (N/2) + 1;
  NDeu = 2*N;

  *NCells = N;
  if ( N<0 || N>NCellMax) {
    fprintf(stderr,"\n\n ***  Maximum number of cells (%d) reached. %d cells needed. Exiting ... ***\n\n",NCellMax,N);
    exit(1);
    return;
  }
  C = (double*)malloc(NDeu*sizeof(double));
  D = (double*)malloc(NDeu*sizeof(double));

  U0 = (-ak3/ak4)*alog((1+sqrtl(1+eps*eps))/eps);
  for (i=1;i<=N;i++) {
    xmag = (2*i-1)*ak1/NDeu;
    zeros[i-1] = -ak3 + Im*xmag;
    poles[i-1] =   U0 + Im*xmag;
  }

  for (i=1; i<=NDeu; i++) {
    if (i<=N) {
      Q = real(zeros[i-1]);
      R = imag(zeros[i-1]);
    }
    else {
      Q = real(poles[i-N-1]);
      R = imag(poles[i-N-1]);
    }

    sigma = 0.;
    a1 = sn(Q, dkp, ak3, ak1);
    b1 = sn(R, dk,  ak1, ak3);

    dn = sqrt(1.-(dk*b1)*(dk*b1));
    de = 1-(a1*dn)*(a1*dn);
    
    if ( i > N ) {
      sigma = a1*sqrt((1-a1*a1)*(1-b1*b1))*dn/de;
    }
    
    omega = b1*sqrt(1-(dkp*a1)*(dkp*a1))/de;

    C[i-1] = -2*sigma*wc;
    D[i-1] = (sigma*sigma + omega*omega)*wc*wc;
    sigma = sigma*tan(wc*T/2.);
    omega = omega*tan(wc*T/2.);
    
    if ( i <= N ) {
      zeros[i-1] = sigma + Im*omega;
    }
    else {
      poles[i-N-1] = sigma + Im*omega;
    }
  }

  for (i=NDeu; i>=1; i--) {
    j = i;
    
    if ( j > NDeu/2 ) j = j - NDeu/2;
    
    
    if ( i<=N ) {
      X = real(zeros[i-1]);
      X = 0;
      Y = imag(zeros[i-1]);
    }
    else {
      X = real(poles[i-N-1]);
      Y = imag(poles[i-N-1]);
    }
    
    Re = (1-X*X-Y*Y)/((1-X)*(1-X)+Y*Y);
    V = 2*Y/((1-X)*(1-X)+Y*Y);
    c1 = -2*Re;
    d1 = Re*Re + V*V;
    if ( i <= N ) {
      zeros[i-1] = Re + Im*V;
      CoefB[i-1] = c1;
      CoefA[i-1] = d1;
    }
    else {
      poles[i-N-1] = Re + Im*V;
      CoefD[i-N-1] = c1;
      CoefC[i-N-1] = d1;
    }

  }


  free(C);
  free(D);

  return;
}