예제 #1
0
void sample_extremes(T const (&est_p)[A][B][C], T const (&err_p)[A][B][C], T (&out_p)[A][B][C])
{
    vector<int> permutation;
    for (int i = 0; i < A; ++i)
    {
        for (int j = 0; j < B; ++j)
        {
            // use a random ordering to get an extreme point here
            sample_permutation(C, permutation);
            
            // first set the elements to the lower bounds to give some leeway
            T lsum = 0;
            for (int k = 0; k < C; ++k)
            {
                T lb = max(0.0, est_p[i][j][k] - err_p[i][j][k]);
                out_p[i][j][k] = lb;
                lsum += lb;
            }
            // then give as much weight as possible to each of the picks in turn
            T leeway = 1 - lsum;
            for (int k = 0; k < C; ++k)
            {
                if (leeway <= 0)
                {
                    break; // done
                }
                int curr_ix = permutation[k];
                T ub = min(1.0, est_p[i][j][curr_ix] + err_p[i][j][curr_ix]);
                T avail = min(leeway, ub - out_p[i][j][curr_ix]);
                out_p[i][j][curr_ix] += avail;
                leeway -= avail;
            }
        }
    }
}
예제 #2
0
파일: KL_funcs.c 프로젝트: cran/VBLPCM
void gr_KL_V_psi2_n (const gsl_vector *v_V_psi2_n, void * null, gsl_vector *df)
{
  int i, p=*params->p, j, pe;
  int D = *params->D;     
  double tmp1=0.0, cov=0.0, cov2;
  int N = *params->N;
  int P_e = *params->P_e;
  double KL;
  int *sample_non_edges = calloc(*params->NnonE, sizeof(int));
  int NC1;
  params->V_psi2_n[*params->p] = gsl_vector_get(v_V_psi2_n, 0);
  KL = 0.0;
  for (i = 0; i < *params->NE; i++) // loop over all edges
    {
    if (*params->imodel==1)
      cov = params->V_xi_n[(params->E[i*2]-1)];
    if (*params->imodel==2)
      cov = params->V_xi_n[(params->E[i*2+1]-1)];
    if (*params->imodel==3)
      cov = params->V_xi_n[(params->E[i*2]-1)] + params->V_xi_n[N+(params->E[i*2+1]-1)];
    cov2 = params->V_psi2_n[p];
    for (pe=0;pe<P_e;pe++)
      {
      cov += params->V_xi_e[pe]*params->XX_e[((params->E[i*2]-1)*N + params->E[i*2+1]-1)* P_e + pe];
      cov2+= params->V_psi2_e[pe]*params->XX_e[((params->E[i*2]-1)*N + params->E[i*2+1]-1)* P_e + pe];
      }
    tmp1 += -0.5/(1.0+exp(-cov + params->dists[((params->E[i*2]-1)*N + params->E[i*2+1]-1)] - 0.5*cov2));
    }
  sample_permutation(*params->NnonE, sample_non_edges, params->seed);
  NC1=MIN(*params->NnonE, (int)(*params->NC* *params->NE));
  for (j=0;j<NC1;j++) // loop over a sample of the non-edges
    {
    i=sample_non_edges[j];
    if (*params->imodel==1)
      cov = params->V_xi_n[(params->nonE[i*2]-1)];
    if (*params->imodel==2)
      cov = params->V_xi_n[(params->nonE[i*2+1]-1)];
    if (*params->imodel==3)
      cov = params->V_xi_n[(params->nonE[i*2]-1)] + params->V_xi_n[N+(params->nonE[i*2+1]-1)];
    cov2= params->V_psi2_n[p];
    for (pe=0;pe<P_e;pe++)
      {
      cov += params->V_xi_e[pe]*params->XX_e[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)* P_e + pe];
      cov2+= params->V_psi2_e[pe]*params->XX_e[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)* P_e + pe];
      }
    tmp1 += *params->NnonE/NC1*(-0.5/(1.0+exp(-cov + params->dists[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)] - 0.5*cov2)));
    }
  KL = tmp1 + 0.5 * (D / params->V_psi2_n[*params->p] - D / *params->psi2);
  gsl_vector_set(df, 0, -KL);
  free(sample_non_edges);
  return;
}
예제 #3
0
파일: KL_funcs.c 프로젝트: cran/VBLPCM
void gr_KL_V_xi_e (const gsl_vector *v_V_xi_e, void *null, gsl_vector *df)
{
  int i, j, p=*params->p, pn;
  int P_e=*params->P_e, P_n=*params->P_n;
  params->V_xi_e[p] = gsl_vector_get(v_V_xi_e, 0);
  double tmpsum = 0.0, cov, cov2;
  int N = *params->N;
  double KL;
  int *sample_non_edges = calloc(*params->NnonE, sizeof(int));
  int NC1;
  for (i = 0; i < *params->NE; i++) // loop over all edges
    {
    cov = params->V_xi_e[p]*params->XX_e[((params->E[i*2]-1)*N + params->E[i*2+1]-1)* P_e + p];
    cov2= params->V_psi2_e[p]*params->XX_e[((params->E[i*2]-1)*N + params->E[i*2+1]-1)* P_e + p]; 
    if (*params->imodel==1)
      cov += params->V_xi_n[(params->E[i*2]-1)];
    if (*params->imodel==2)
      cov += params->V_xi_n[(params->E[i*2+1]-1)];
    if (*params->imodel==3)
      cov += params->V_xi_n[(params->E[i*2]-1)] + params->V_xi_n[N+(params->E[i*2+1]-1)];
    for (pn=0;pn<P_n;pn++)
      cov2+= params->V_psi2_n[pn];
    tmpsum += params->XX_e[((params->E[i*2]-1)*N + params->E[i*2+1]-1)* P_e + p]*
              (1.0 - 1.0/(1.0 + exp (-cov + params->dists[((params->E[i*2]-1)*N + params->E[i*2+1]-1)] - 0.5 * cov2)));
    }
  sample_permutation(*params->NnonE, sample_non_edges, params->seed);
  NC1=MIN(*params->NnonE, (int)(*params->NC* *params->NE));
  for (j=0;j<NC1;j++) // loop over a sample of the non-edges
    {
    i=sample_non_edges[j];
    cov = params->V_xi_e[p]*params->XX_e[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)* P_e + p];
    cov2= params->V_psi2_e[p]*params->XX_e[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)* P_e + p]; 
    if (*params->imodel==1)
      cov += params->V_xi_n[(params->nonE[i*2]-1)];
    if (*params->imodel==2)
      cov += params->V_xi_n[(params->nonE[i*2+1]-1)];
    if (*params->imodel==3)
      cov += params->V_xi_n[(params->nonE[i*2]-1)] + params->V_xi_n[N+(params->nonE[i*2+1]-1)];
    for (pn=0;pn<P_n;pn++)
      cov2+= params->V_psi2_n[pn];
    tmpsum += *params->NnonE/NC1*(params->XX_e[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)* P_e + p]*
                (- 1.0/(1.0 + exp (-cov + params->dists[((params->nonE[i*2]-1)*N + params->nonE[i*2+1]-1)] - 0.5 * cov2))));
      }
  KL = tmpsum - 0.5*(params->V_xi_e[p] - *params->xi) / *params->psi2;
  free(sample_non_edges);
  gsl_vector_set(df, 0, -KL);
  return;
}
예제 #4
0
파일: KL_funcs.c 프로젝트: cran/VBLPCM
void gr_KL_V_xi_n (const gsl_vector *v_V_xi_n, void *null, gsl_vector *df)
{
  int i=*params->i, p=*params->p, P_e=*params->P_e, j, pe;
  int N = *params->N;
  params->V_xi_n[i+N*p] = gsl_vector_get(v_V_xi_n, 0);
  double tmpsum = 0.0, cov=0.0, cov2;
  int *sample_nodes, hsum, h, Nnon, k;
  double KL;
  int diam=*params->diam;
  int NC2;
  for (j = 2+diam; j < params->hopslist[i*(CONST+diam+N)+1]+2+diam; j++) // loop over all edges
    {
    // i->j part
    cov2 = 0.0;
    if (*params->imodel==1)
      cov = params->V_xi_n[i];
    if (*params->imodel==2)
       cov = params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
    if (*params->imodel==3)
      cov = params->V_xi_n[i] + params->V_xi_n[N+(params->hopslist[i*(CONST+diam+N)+j]-1)];
    for (pe=0;pe<P_e;pe++)
      {
      cov += params->V_xi_e[pe]*params->XX_e[(i*N + params->hopslist[i*(CONST+diam+N)+j]-1)* P_e + pe];  
      cov2+= params->V_psi2_e[pe]*params->XX_e[(i*N + params->hopslist[i*(CONST+diam+N)+j]-1)* P_e + pe];
      }
    cov2 += params->V_psi2_n[0];
    if (*params->imodel==3)
      cov2 += params->V_psi2_n[1];
    tmpsum += (params->Y[i*N+(params->hopslist[i*(CONST+diam+N)+j]-1)] - 
               1.0/(1.0 + exp (-cov + params->dists[i*N + (params->hopslist[i*(CONST+diam+N)+j]-1)] - 0.5 * cov2)));
    // j->i part
    cov2 = 0.0;
    if (*params->imodel==1)
      cov = params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
    if (*params->imodel==2)
      cov = params->V_xi_n[i];
    if (*params->imodel==3)
      cov = params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)] + params->V_xi_n[N+i];
    for (pe=0;pe<P_e;pe++)
      {
      cov += params->V_xi_e[pe]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* P_e + pe];  
      cov2+= params->V_psi2_e[pe]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* P_e + pe];
      }
    cov2 += params->V_psi2_n[0];
    if (*params->imodel==3)
      cov2 += params->V_psi2_n[1];
    tmpsum += (params->Y[(params->hopslist[i*(CONST+diam+N)+j]-1)*N+i] - 
               1.0/(1.0 + exp (-cov + params->dists[(params->hopslist[i*(CONST+diam+N)+j]-1)*N+i] - 0.5 * cov2)));
    }
  hsum = 0;
  for (h=2;h<1+diam;h++) // <1+diam because we don't sample unknown edges
    {
    Nnon=params->hopslist[i*(CONST+diam+N)+h];
    if (Nnon>0)
      {
      sample_nodes = calloc(Nnon, sizeof(int));
      sample_permutation(Nnon, sample_nodes, params->seed);
      NC2=MIN(Nnon, (int)(*params->NC*params->hopslist[i*(CONST+diam+N)+1]));
      for (k=0;k<NC2;k++)  // loop over some of the non-edges
        {
        j=params->hopslist[i*(CONST+diam+N)+2+diam+params->hopslist[i*(CONST+diam+N)+1]+hsum+sample_nodes[k]]-1;
	// this part for Yij = 0 
        if (*params->imodel==1)
          cov = params->V_xi_n[i]; 
        if (*params->imodel==2)
          cov = params->V_xi_n[j];
        if (*params->imodel==3)
          cov = params->V_xi_n[i] + params->V_xi_n[N+j];
    cov2 = params->V_psi2_n[0];
    if (*params->imodel==3)
      cov2 += params->V_psi2_n[1];
	for (pe=0;pe<P_e;pe++)
          {
          cov += params->V_xi_e[pe]*params->XX_e[(i*N + j)* P_e + pe];
          cov2+= params->V_psi2_e[pe]*params->XX_e[(i*N + j)* P_e + pe];
          }
        tmpsum += Nnon/NC2*(- 1.0/(1.0 + exp (-cov + params->dists[i*N + j] - 0.5 * cov2)));
	// this part for Yji = 0 
	if (*params->imodel==1)
          cov = params->V_xi_n[j];
        if (*params->imodel==2)
          cov = params->V_xi_n[i];
        if (*params->imodel==3)
          cov = params->V_xi_n[N+i] + params->V_xi_n[j];
    cov2 = params->V_psi2_n[0];
    if (*params->imodel==3)
      cov2 += params->V_psi2_n[1];
        for (pe=0;pe<P_e;pe++)
          {
          cov += params->V_xi_e[pe]*params->XX_e[(j*N + i)* P_e + pe];
          cov2+= params->V_psi2_e[pe]*params->XX_e[(j*N + i)* P_e + pe];
          }
        tmpsum += Nnon/NC2*(- 1.0/(1.0 + exp (-cov + params->dists[i*N + j] - 0.5 * cov2)));
        }
      hsum += Nnon;
      free(sample_nodes);
      }
    }
  KL = tmpsum - 0.5*(params->V_xi_n[i+N*p] - *params->xi) / *params->psi2;
  gsl_vector_set(df, 0, -KL);
  return;
}
예제 #5
0
파일: KL_funcs.c 프로젝트: cran/VBLPCM
void gr_KL_V_sigma2_i (const gsl_vector *v_V_sigma2_i, void *null, gsl_vector *df)
{
  int i = *params->i, j, k, d = *params->d;
  int D = *params->D;     
  int g, G = *params->G, hsum, h;
  double tmpsum = 0.0, tmp;
  int p, N = *params->N;
  int diam=*params->diam;
  int P_n=*params->P_n;
  double KL;
  double cov, cov2;
  double V_sigma2_i = gsl_vector_get(v_V_sigma2_i, 0);
  int Nnon=N-params->hopslist[i*(CONST+diam+N)+1]-params->hopslist[i*(CONST+diam+N)+1+diam];
  int *sample_nodes = 0;
  int NC2;
  for (j = 2+diam; j < params->hopslist[i*(CONST+diam+N)+1]+2+diam; j++) // loop over all edges
    {
    tmp = 0.0;
    for (d = 0; d < D; d++)
      tmp += pow (params->V_z[i * D + d] - params->V_z[(params->hopslist[i*(CONST+diam+N)+j]-1) * D + d], 2.0);
    cov=0.0; cov2=0.0;
    if (params->Y[i*N+(params->hopslist[i*(CONST+diam+N)+j]-1)]>0) // i is sender and j is receiver
      {
      if (*params->imodel==1)
        cov += params->V_xi_n[i];
      if (*params->imodel==2)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
      if (*params->imodel==3)
        cov += params->V_xi_n[i] + params->V_xi_n[N+(params->hopslist[i*(CONST+diam+N)+j]-1)];
      for (p=0;p<*params->P_e;p++)
        {
        cov += params->V_xi_e[p]*params->XX_e[(i*N + (params->hopslist[i*(CONST+diam+N)+j]-1))* *params->P_e + p];
        cov2+= params->V_psi2_e[p]*params->XX_e[(i*N + (params->hopslist[i*(CONST+diam+N)+j]-1))* *params->P_e + p];
        }
      }
    if (params->Y[(params->hopslist[i*(CONST+diam+N)+j]-1)*N+i]>0) // j is sender and i is receiver
      {
      if (*params->imodel==1)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
      if (*params->imodel==2)
        cov += params->V_xi_n[i];
      if (*params->imodel==3)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)] + params->V_xi_n[N+i];
      for (p=0;p<*params->P_e;p++)
        {
        cov += params->V_xi_e[p]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* *params->P_e + p];
        cov2+= params->V_psi2_e[p]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* *params->P_e + p];
        }
      }
    for (p=0;p<P_n;p++)
      cov2+= params->V_psi2_n[p];
    tmp = SQRT (tmp + D * (V_sigma2_i + params->V_sigma2[(params->hopslist[i*(CONST+diam+N)+j]-1)]));
    tmpsum = tmpsum - D + D / (V_sigma2_i * (1.0 + exp (-cov + tmp - 0.5 * cov2)));
    }
  hsum = 0;
  for (h=2;h<1+diam;h++) // <1+diam because we don't sample unknown edges
    {
    Nnon=params->hopslist[i*(CONST+diam+N)+h];
    if (Nnon>0)
      {
      sample_nodes = calloc(Nnon, sizeof(int));
      sample_permutation(Nnon, sample_nodes, params->seed);
      NC2=MIN(Nnon, (int)(*params->NC*params->hopslist[i*(CONST+diam+N)+1]));
      for (k=0;k<NC2;k++)  // loop over some of the non-edges
        {
        j=params->hopslist[i*(CONST+diam+N)+2+diam+params->hopslist[i*(CONST+diam+N)+1]+hsum+sample_nodes[k]]-1;
        tmp = 0.0;
        for (d = 0; d < D; d++)
          tmp += pow (params->V_z[i * D + d] - params->V_z[j * D + d], 2.0);
        cov=0.0; cov2=0.0;
        if (*params->imodel==1)
          cov += params->V_xi_n[i];
        if (*params->imodel==2)
          cov +=  params->V_xi_n[j];
        if (*params->imodel==3)
          cov += params->V_xi_n[i] + params->V_xi_n[N+j];
        for (p=0;p<P_n;p++)
          cov2+= params->V_psi2_n[p];
        for (p=0;p<*params->P_e;p++)
          {
          cov += params->V_xi_e[p]*params->XX_e[(i*N + j)* *params->P_e + p];
          cov2+= params->V_psi2_e[p]*params->XX_e[(i*N + j)* *params->P_e + p];
          }
          tmp = SQRT (tmp + D * (V_sigma2_i + params->V_sigma2[j]));
          tmpsum = tmpsum + Nnon/NC2*(D / (V_sigma2_i * (1.0 + exp (-cov + tmp - 0.5 * cov2))));
        }
      hsum += Nnon;
      free(sample_nodes);
      }
    }
  tmp = 0.0;
  for (g = 0; g < G; g++)
    tmp += params->V_lambda[g * N + i] * *params->inv_sigma02 * params->V_alpha[g];
  KL = tmpsum - 0.5 * tmp + 0.5 * D / V_sigma2_i;
  gsl_vector_set(df, 0, -KL);
  return;
}
예제 #6
0
파일: KL_funcs.c 프로젝트: cran/VBLPCM
void gr_KL_V_z_i (const gsl_vector *v_V_z_i, void *null, gsl_vector *df)
{
  int i = *params->i, j, k, d;
  int D = *params->D;     
  double tmp;
  for (d=0; d<D; d++)
    params->V_z[i * D + d] = gsl_vector_get(v_V_z_i, d);
  int g, p, G = *params->G;
  int N = *params->N, h, Nnon, hsum;
  int diam=*params->diam;
  int P_n=*params->P_n;
  double *KL = calloc(D, sizeof(double));
  double *tmpsum = calloc(D, sizeof(double));
  double cov, cov2;
  int *sample_nodes;
  int NC2;
  for (j = 2+diam; j < params->hopslist[i*(CONST+diam+N)+1]+2+diam; j++) // loop over all edges
    {
    tmp = 0.0;
    for (d=0; d<D; d++)
      tmp += pow(params->V_z[i * D + d] - params->V_z[(params->hopslist[i*(CONST+diam+N)+j]-1) * D + d], 2.0);
    tmp = SQRT(tmp + D *(params->V_sigma2[i] + params->V_sigma2[(params->hopslist[i*(CONST+diam+N)+j]-1)]));
    cov=0.0; cov2=0.0;
    if (params->Y[i*N+(params->hopslist[i*(CONST+diam+N)+j]-1)]>0) // i is sender and j is receiver
      {
      if (*params->imodel==1)
        cov += params->V_xi_n[i];
      if (*params->imodel==2)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
      if (*params->imodel==3)
        cov += params->V_xi_n[i] + params->V_xi_n[N+(params->hopslist[i*(CONST+diam+N)+j]-1)];
      for (p=0;p<*params->P_e;p++)
        {
        cov += params->V_xi_e[p]*params->XX_e[(i*N + (params->hopslist[i*(CONST+diam+N)+j]-1))* *params->P_e + p];
        cov2+= params->V_psi2_e[p]*params->XX_e[(i*N + (params->hopslist[i*(CONST+diam+N)+j]-1))* *params->P_e + p];
        }
      }
    if (params->Y[(params->hopslist[i*(CONST+diam+N)+j]-1)*N+i]>0) // j is sender and i is receiver
      {
      if (*params->imodel==1)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)];
      if (*params->imodel==2)
        cov += params->V_xi_n[i]; 
      if (*params->imodel==3)
        cov += params->V_xi_n[(params->hopslist[i*(CONST+diam+N)+j]-1)] + params->V_xi_n[N+i];
      for (p=0;p<*params->P_e;p++)
        {
        cov += params->V_xi_e[p]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* *params->P_e + p];
        cov2+= params->V_psi2_e[p]*params->XX_e[((params->hopslist[i*(CONST+diam+N)+j]-1)*N+i)* *params->P_e + p];
        }
      }
    for (p=0;p<P_n;p++)
      cov2+= params->V_psi2_n[p];
    for (d=0; d<D; d++)
        tmpsum[d] +=  (params->V_z[i * D + d] - params->V_z[(params->hopslist[i*(CONST+diam+N)+j]-1) * D + d]) *
                      (1.0 - 1.0/(1.0+exp(-cov + tmp - 0.5*cov2)));
    }
  hsum = 0;
  for (h=2;h<1+diam;h++) // <1+diam because we don't sample unknown edges
    {
    Nnon=params->hopslist[i*(CONST+diam+N)+h];
    if (Nnon>0)
      {
      sample_nodes = calloc(Nnon, sizeof(int));
      sample_permutation(Nnon, sample_nodes, params->seed);
      NC2=MIN(Nnon, (int)(*params->NC*params->hopslist[i*(CONST+diam+N)+1]));
      for (k=0;k<NC2;k++)  // loop over some of the non-edges
        {
        j=params->hopslist[i*(CONST+diam+N)+2+diam+params->hopslist[i*(CONST+diam+N)+1]+hsum+sample_nodes[k]]-1;
        tmp = 0.0;
        for (d=0; d<D; d++)
          tmp += pow(params->V_z[i * D + d] - params->V_z[j * D + d], 2.0);
        tmp = SQRT(tmp + D *(params->V_sigma2[i] + params->V_sigma2[j]));
        cov=0.0; cov2=0.0;
        if (*params->imodel==1)
          cov += params->V_xi_n[i];
        if (*params->imodel==2)
          cov += params->V_xi_n[j];
        if (*params->imodel==3)
          cov += params->V_xi_n[i] + params->V_xi_n[N+j];
        for (p=0;p<P_n;p++)
          cov2+= params->V_psi2_n[p];
        for (p=0;p<*params->P_e;p++)
          {
          cov += params->V_xi_e[p]*params->XX_e[(i*N + j)* *params->P_e + p];
          cov2+= params->V_psi2_e[p]*params->XX_e[(i*N + j)* *params->P_e + p];
          }
        for (d=0; d<D; d++)
            tmpsum[d] +=  Nnon/NC2*(
                          (params->V_z[i * D + d] - params->V_z[j * D + d]) *
                          (- 1.0/(1.0+exp(-cov + tmp - 0.5*cov2))));
        }
      hsum += Nnon;
      free(sample_nodes);
      }
    }
  for (d=0; d<D; d++)
     KL[d] = tmpsum[d];
  for (d=0; d<D; d++)
    tmpsum[d] = 0.0; // there's probably a function for this in C
  for (g = 0; g < G; g++)
    for (d=0; d<D; d++)
      tmpsum[d] = tmpsum[d] + params->V_lambda[g * N + i] *
      0.5* *params->inv_sigma02 * params->V_alpha[g] *
      fabs(params->V_eta[g * D + d] - params->V_z[i * D + d]);
  for (d=0; d<D; d++)
    KL[d] -= tmpsum[d];
    //KL[d] += tmpsum[d];
  for (d=0; d<D; d++)
    gsl_vector_set(df, d, -KL[d]);
  free(tmpsum);
  free(KL);
  return;
}