コード例 #1
0
int igraph_random_sample_alga(igraph_vector_t *res, igraph_integer_t l, igraph_integer_t h, 
			      igraph_integer_t length) {
  igraph_real_t N=h-l+1;
  igraph_real_t n=length;
  
  igraph_real_t top=N-n;
  igraph_real_t Nreal=N;
  igraph_real_t S=0;
  igraph_real_t V, quot;
  
  l=l-1;

  while (n>=2) {
    V=RNG_UNIF01();
    S=1;
    quot=top/Nreal;
    while (quot>V) {
      S+=1;
      top=-1.0+top;
      Nreal=-1.0+Nreal;
      quot=(quot*top)/Nreal;
    }
    l+=S;
    igraph_vector_push_back(res, l);	/* allocated */
    Nreal=-1.0+Nreal; n=-1+n;
  }
  
  S=floor(round(Nreal)*RNG_UNIF01());
  l+=S+1;
  igraph_vector_push_back(res, l);	/* allocated */
  
  return 0;
}
コード例 #2
0
ファイル: miso.c プロジェクト: mlovci/MISO
int splicing_reassign_samples(const splicing_matrix_t *matches, 
			      const splicing_vector_int_t *match_order,
			      const splicing_vector_t *psi, 
			      int noiso, splicing_vector_int_t *result) {

  int noreads = splicing_matrix_ncol(matches);
  int i, w;
  double *prev, *curr;
  double rand, sumpsi;
  int noValid;
  int *order=VECTOR(*match_order);
  splicing_vector_t cumsum;
  splicing_vector_int_t validIso;  

  SPLICING_CHECK(splicing_vector_init(&cumsum, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &cumsum);
  SPLICING_CHECK(splicing_vector_int_init(&validIso, noiso));
  SPLICING_FINALLY(splicing_vector_int_destroy, &validIso);

  SPLICING_CHECK(splicing_vector_int_resize(result, noreads));

  if (noreads == 0) { return 0; }  

  prev = curr = &MATRIX(*matches, 0, order[0]);
  CUMSUM();

  for (i=0; i<noreads; i++) {
    curr = &MATRIX(*matches, 0, order[i]);

    /* Maybe we need to update the cumulative sum */
    if (memcmp(prev, curr, sizeof(double)*noiso) != 0) { CUMSUM(); }

    if (noValid == 0) {
      VECTOR(*result)[order[i]] = -1;
    } else if (noValid == 1) {
      VECTOR(*result)[order[i]] = VECTOR(validIso)[0];
    } else if (noValid == 2) { 
      rand = RNG_UNIF01() * sumpsi;
      w = (rand < VECTOR(cumsum)[0]) ? VECTOR(validIso)[0] : 
	VECTOR(validIso)[1];
      VECTOR(*result)[order[i]] = w;
    } else {
      /* Draw */
      rand = RNG_UNIF01() * sumpsi;
      /* TODO: Binary search for interval, if many classes */
      for (w=0; rand > VECTOR(cumsum)[w]; w++) ;
      VECTOR(*result)[order[i]] = VECTOR(validIso)[w];
    }

    prev=curr;
  }

  splicing_vector_int_destroy(&validIso);
  splicing_vector_destroy(&cumsum);
  SPLICING_FINALLY_CLEAN(2);

  return 0;
}
コード例 #3
0
double igraph_exp_rand(void)
{
    /* q[k-1] = sum(log(2)^k / k!)  k=1,..,n, */
    /* The highest n (here 8) is determined by q[n-1] = 1.0 */
    /* within standard precision */
    const double q[] =
    {
	0.6931471805599453,
	0.9333736875190459,
	0.9888777961838675,
	0.9984959252914960,
	0.9998292811061389,
	0.9999833164100727,
	0.9999985691438767,
	0.9999998906925558,
	0.9999999924734159,
	0.9999999995283275,
	0.9999999999728814,
	0.9999999999985598,
	0.9999999999999289,
	0.9999999999999968,
	0.9999999999999999,
	1.0000000000000000
    };
    double a, u, ustar, umin;
    int i;

    a = 0.;
    /* precaution if u = 0 is ever returned */
    u = RNG_UNIF01();
    while(u <= 0.0 || u >= 1.0) u = RNG_UNIF01();
    for (;;) {
	u += u;
	if (u > 1.0)
	    break;
	a += q[0];
    }
    u -= 1.;

    if (u <= q[0])
	return a + u;

    i = 0;
    ustar = RNG_UNIF01();
    umin = ustar;
    do {
	ustar = RNG_UNIF01();
	if (ustar < umin)
	    umin = ustar;
	i++;
    } while (u > q[i]);
    return a + umin * q[0];
}
コード例 #4
0
ファイル: miso.c プロジェクト: mlovci/MISO
int splicing_drift_proposal(int mode, 
			    const splicing_vector_t *psi, 
			    const splicing_vector_t *alpha, 
			    double sigma, 
			    const splicing_vector_t *otherpsi, 
			    const splicing_vector_t *otheralpha, int noiso,
			    splicing_vector_t *respsi, 
			    splicing_vector_t *resalpha,
			    double *ressigma, double *resscore) {

  switch (mode) {
  case 0: 			/* init */
    {
      SPLICING_CHECK(splicing_vector_resize(respsi, noiso));
      SPLICING_CHECK(splicing_vector_resize(resalpha, noiso-1));
      if (noiso != 2) {
	int i;
	for (i=0; i<noiso; i++) {	
	  VECTOR(*respsi)[i] = 1.0/noiso; 
	}
	for (i=0; i<noiso-1; i++) { 
	  VECTOR(*resalpha)[i] = 1.0/(noiso-1);
	}
	*ressigma = 0.05;
      } else {
	VECTOR(*respsi)[0] = RNG_UNIF01();
	VECTOR(*respsi)[1] = 1 - VECTOR(*respsi)[0];
	VECTOR(*resalpha)[0] = 0.0;
	VECTOR(*resalpha)[1] = 0.0;
	*ressigma = 0.05;
      }
    }
    break;
  case 1:			/* propose */
    {
      int len=noiso-1;
      double sumpsi=0.0;
  
      SPLICING_CHECK(splicing_vector_reserve(respsi, len+1));
      SPLICING_CHECK(splicing_mvrnorm(alpha, sigma, resalpha, len));
      SPLICING_CHECK(splicing_logit_inv(resalpha, respsi, len));
      sumpsi = splicing_vector_sum(respsi);
      SPLICING_CHECK(splicing_vector_resize(respsi, len+1));
      VECTOR(*respsi)[len] = 1-sumpsi;
    }
    break;
  case 2: 			/* score */
    SPLICING_CHECK(splicing_mvplogisnorm(psi, otheralpha, sigma, noiso-1, 
					 resscore));
    break;
  }
  
  return 0;
}
コード例 #5
0
ファイル: dotproduct.c プロジェクト: abeham/igraph
int igraph_dot_product_game(igraph_t *graph, const igraph_matrix_t *vecs,
			    igraph_bool_t directed) {

  igraph_integer_t nrow=igraph_matrix_nrow(vecs);
  igraph_integer_t ncol=igraph_matrix_ncol(vecs);
  int i, j;
  igraph_vector_t edges;
  igraph_bool_t warned_neg=0, warned_big=0;
  
  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
    
  RNG_BEGIN();

  for (i = 0; i < ncol; i++) {
    int from=directed ? 0 : i+1;
    igraph_vector_t v1;
    igraph_vector_view(&v1, &MATRIX(*vecs, 0, i), nrow);
    for (j = from; j < ncol; j++) {
      igraph_real_t prob;
      igraph_vector_t v2;
      if (i==j) { continue; }
      igraph_vector_view(&v2, &MATRIX(*vecs, 0, j), nrow);
      igraph_lapack_ddot(&v1, &v2, &prob);
      if (prob < 0 && ! warned_neg) {
	warned_neg=1;
	IGRAPH_WARNING("Negative connection probability in "
		       "dot-product graph");
      } else if (prob > 1 && ! warned_big) {
	warned_big=1;
	IGRAPH_WARNING("Greater than 1 connection probability in "
		       "dot-product graph");
	IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
	IGRAPH_CHECK(igraph_vector_push_back(&edges, j));
      } else if (RNG_UNIF01() < prob) { 
	IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
	IGRAPH_CHECK(igraph_vector_push_back(&edges, j));
      }
    }
  }

  RNG_END();
  
  igraph_create(graph, &edges, ncol, directed);
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
コード例 #6
0
ファイル: dotproduct.c プロジェクト: abeham/igraph
int igraph_sample_sphere_volume(igraph_integer_t dim, igraph_integer_t n,
				igraph_real_t radius,
				igraph_bool_t positive,
				igraph_matrix_t *res) {

  igraph_integer_t i, j;

  /* Arguments are checked by the following call */

  IGRAPH_CHECK(igraph_sample_sphere_surface(dim, n, radius, positive, res));
  
  RNG_BEGIN();

  for (i = 0; i < n; i++) {
    igraph_real_t *col=&MATRIX(*res, 0, i);
    igraph_real_t U=pow(RNG_UNIF01(), 1.0/dim);
    for (j = 0; j < dim; j++) { col[j] *= U; }
  }

  RNG_END();
  
  return 0;
}
コード例 #7
0
double igraph_rbinom(double nin, double pp)
{
    /* FIXME: These should become THREAD_specific globals : */

    static double c, fm, npq, p1, p2, p3, p4, qn;
    static double xl, xll, xlr, xm, xr;

    static double psave = -1.0;
    static int nsave = -1;
    static int m;

    double f, f1, f2, u, v, w, w2, x, x1, x2, z, z2;
    double p, q, np, g, r, al, alv, amaxp, ffm, ynorm;
    int i,ix,k, n;

    if (!R_FINITE(nin)) ML_ERR_return_NAN;
    n = floor(nin + 0.5);
    if (n != nin) ML_ERR_return_NAN;

    if (!R_FINITE(pp) ||
	/* n=0, p=0, p=1 are not errors <TSL>*/
	n < 0 || pp < 0. || pp > 1.)	ML_ERR_return_NAN;

    if (n == 0 || pp == 0.) return 0;
    if (pp == 1.) return n;

    p = fmin(pp, 1. - pp);
    q = 1. - p;
    np = n * p;
    r = p / q;
    g = r * (n + 1);

    /* Setup, perform only when parameters change [using static (globals): */

    /* FIXING: Want this thread safe
       -- use as little (thread globals) as possible
    */
    if (pp != psave || n != nsave) {
	psave = pp;
	nsave = n;
	if (np < 30.0) {
	    /* inverse cdf logic for mean less than 30 */
	    qn = pow(q, (double) n);
	    goto L_np_small;
	} else {
	    ffm = np + p;
	    m = ffm;
	    fm = m;
	    npq = np * q;
	    p1 = (int)(2.195 * sqrt(npq) - 4.6 * q) + 0.5;
	    xm = fm + 0.5;
	    xl = xm - p1;
	    xr = xm + p1;
	    c = 0.134 + 20.5 / (15.3 + fm);
	    al = (ffm - xl) / (ffm - xl * p);
	    xll = al * (1.0 + 0.5 * al);
	    al = (xr - ffm) / (xr * q);
	    xlr = al * (1.0 + 0.5 * al);
	    p2 = p1 * (1.0 + c + c);
	    p3 = p2 + c / xll;
	    p4 = p3 + c / xlr;
	}
    } else if (n == nsave) {
	if (np < 30.0)
	    goto L_np_small;
    }

    /*-------------------------- np = n*p >= 30 : ------------------- */
    repeat {
      u = RNG_UNIF01() * p4;
      v = RNG_UNIF01();
      /* triangular region */
      if (u <= p1) {
	  ix = xm - p1 * v + u;
	  goto finis;
      }
      /* parallelogram region */
      if (u <= p2) {
	  x = xl + (u - p1) / c;
	  v = v * c + 1.0 - fabs(xm - x) / p1;
	  if (v > 1.0 || v <= 0.)
	      continue;
	  ix = x;
      } else {
	  if (u > p3) {	/* right tail */
	      ix = xr - log(v) / xlr;
	      if (ix > n)
		  continue;
	      v = v * (u - p3) * xlr;
	  } else {/* left tail */
	      ix = xl + log(v) / xll;
	      if (ix < 0)
		  continue;
	      v = v * (u - p2) * xll;
	  }
      }
      /* determine appropriate way to perform accept/reject test */
      k = abs(ix - m);
      if (k <= 20 || k >= npq / 2 - 1) {
	  /* explicit evaluation */
	  f = 1.0;
	  if (m < ix) {
	      for (i = m + 1; i <= ix; i++)
		  f *= (g / i - r);
	  } else if (m != ix) {
	      for (i = ix + 1; i <= m; i++)
		  f /= (g / i - r);
	  }
	  if (v <= f)
	      goto finis;
      } else {
	  /* squeezing using upper and lower bounds on log(f(x)) */
	  amaxp = (k / npq) * ((k * (k / 3. + 0.625) + 0.1666666666666) / npq + 0.5);
	  ynorm = -k * k / (2.0 * npq);
	  alv = log(v);
	  if (alv < ynorm - amaxp)
	      goto finis;
	  if (alv <= ynorm + amaxp) {
	      /* stirling's formula to machine accuracy */
	      /* for the final acceptance/rejection test */
	      x1 = ix + 1;
	      f1 = fm + 1.0;
	      z = n + 1 - fm;
	      w = n - ix + 1.0;
	      z2 = z * z;
	      x2 = x1 * x1;
	      f2 = f1 * f1;
	      w2 = w * w;
	      if (alv <= xm * log(f1 / x1) + (n - m + 0.5) * log(z / w) + (ix - m) * log(w * p / (x1 * q)) + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / f2) / f2) / f2) / f2) / f1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / z2) / z2) / z2) / z2) / z / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / x2) / x2) / x2) / x2) / x1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / w2) / w2) / w2) / w2) / w / 166320.)
		  goto finis;
	  }
      }
  }

 L_np_small:
    /*---------------------- np = n*p < 30 : ------------------------- */

  repeat {
     ix = 0;
     f = qn;
     u = RNG_UNIF01();
     repeat {
	 if (u < f)
	     goto finis;
	 if (ix > 110)
	     break;
	 u -= f;
	 ix++;
	 f *= (g / ix - r);
     }
  }
 finis:
    if (psave > 0.5)
	 ix = n - ix;
  return (double)ix;
}
コード例 #8
0
double igraph_rpois(double mu)
{
    /* Factorial Table (0:9)! */
    const double fact[10] =
    {
	1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880.
    };

    /* These are static --- persistent between calls for same mu : */
    static int l, m;

    static double b1, b2, c, c0, c1, c2, c3;
    static double pp[36], p0, p, q, s, d, omega;
    static double big_l;/* integer "w/o overflow" */
    static double muprev = 0., muprev2 = 0.;/*, muold	 = 0.*/

    /* Local Vars  [initialize some for -Wall]: */
    double del, difmuk= 0., E= 0., fk= 0., fx, fy, g, px, py, t, u= 0., v, x;
    double pois = -1.;
    int k, kflag, big_mu, new_big_mu = FALSE;

    if (!R_FINITE(mu))
	ML_ERR_return_NAN;

    if (mu <= 0.)
	return 0.;

    big_mu = mu >= 10.;
    if(big_mu)
	new_big_mu = FALSE;

    if (!(big_mu && mu == muprev)) {/* maybe compute new persistent par.s */

	if (big_mu) {
	    new_big_mu = TRUE;
	    /* Case A. (recalculation of s,d,l	because mu has changed):
	     * The poisson probabilities pk exceed the discrete normal
	     * probabilities fk whenever k >= m(mu).
	     */
	    muprev = mu;
	    s = sqrt(mu);
	    d = 6. * mu * mu;
	    big_l = floor(mu - 1.1484);
	    /* = an upper bound to m(mu) for all mu >= 10.*/
	}
	else { /* Small mu ( < 10) -- not using normal approx. */

	    /* Case B. (start new table and calculate p0 if necessary) */

	    /*muprev = 0.;-* such that next time, mu != muprev ..*/
	    if (mu != muprev) {
		muprev = mu;
		m = imax2(1, (int) mu);
		l = 0; /* pp[] is already ok up to pp[l] */
		q = p0 = p = exp(-mu);
	    }

	    repeat {
		/* Step U. uniform sample for inversion method */
		u = RNG_UNIF01();
		if (u <= p0)
		    return 0.;

		/* Step T. table comparison until the end pp[l] of the
		   pp-table of cumulative poisson probabilities
		   (0.458 > ~= pp[9](= 0.45792971447) for mu=10 ) */
		if (l != 0) {
		    for (k = (u <= 0.458) ? 1 : imin2(l, m);  k <= l; k++)
			if (u <= pp[k])
			    return (double)k;
		    if (l == 35) /* u > pp[35] */
			continue;
		}
		/* Step C. creation of new poisson
		   probabilities p[l..] and their cumulatives q =: pp[k] */
		l++;
		for (k = l; k <= 35; k++) {
		    p *= mu / k;
		    q += p;
		    pp[k] = q;
		    if (u <= q) {
			l = k;
			return (double)k;
		    }
		}
		l = 35;
	    } /* end(repeat) */
	}/* mu < 10 */

    } /* end {initialize persistent vars} */

/* Only if mu >= 10 : ----------------------- */

    /* Step N. normal sample */
    g = mu + s * igraph_norm_rand();/* norm_rand() ~ N(0,1), standard normal */

    if (g >= 0.) {
	pois = floor(g);
	/* Step I. immediate acceptance if pois is large enough */
	if (pois >= big_l)
	    return pois;
	/* Step S. squeeze acceptance */
	fk = pois;
	difmuk = mu - fk;
	u = RNG_UNIF01(); /* ~ U(0,1) - sample */
	if (d * u >= difmuk * difmuk * difmuk)
	    return pois;
    }

    /* Step P. preparations for steps Q and H.
       (recalculations of parameters if necessary) */

    if (new_big_mu || mu != muprev2) {
        /* Careful! muprev2 is not always == muprev
	   because one might have exited in step I or S
	   */
        muprev2 = mu;
	omega = M_1_SQRT_2PI / s;
	/* The quantities b1, b2, c3, c2, c1, c0 are for the Hermite
	 * approximations to the discrete normal probabilities fk. */

	b1 = one_24 / mu;
	b2 = 0.3 * b1 * b1;
	c3 = one_7 * b1 * b2;
	c2 = b2 - 15. * c3;
	c1 = b1 - 6. * b2 + 45. * c3;
	c0 = 1. - b1 + 3. * b2 - 15. * c3;
	c = 0.1069 / mu; /* guarantees majorization by the 'hat'-function. */
    }

    if (g >= 0.) {
	/* 'Subroutine' F is called (kflag=0 for correct return) */
	kflag = 0;
	goto Step_F;
    }


    repeat {
	/* Step E. Exponential Sample */

	E = igraph_exp_rand();	/* ~ Exp(1) (standard exponential) */

	/*  sample t from the laplace 'hat'
	    (if t <= -0.6744 then pk < fk for all mu >= 10.) */
	u = 2 * RNG_UNIF01() - 1.;
	t = 1.8 + fsign(E, u);
	if (t > -0.6744) {
	    pois = floor(mu + s * t);
	    fk = pois;
	    difmuk = mu - fk;

	    /* 'subroutine' F is called (kflag=1 for correct return) */
	    kflag = 1;

	  Step_F: /* 'subroutine' F : calculation of px,py,fx,fy. */

	    if (pois < 10) { /* use factorials from table fact[] */
		px = -mu;
		py = pow(mu, pois) / fact[(int)pois];
	    }
	    else {
		/* Case pois >= 10 uses polynomial approximation
		   a0-a7 for accuracy when advisable */
		del = one_12 / fk;
		del = del * (1. - 4.8 * del * del);
		v = difmuk / fk;
		if (fabs(v) <= 0.25)
		    px = fk * v * v * (((((((a7 * v + a6) * v + a5) * v + a4) *
					  v + a3) * v + a2) * v + a1) * v + a0)
			- del;
		else /* |v| > 1/4 */
		    px = fk * log(1. + v) - difmuk - del;
		py = M_1_SQRT_2PI / sqrt(fk);
	    }
	    x = (0.5 - difmuk) / s;
	    x *= x;/* x^2 */
	    fx = -0.5 * x;
	    fy = omega * (((c3 * x + c2) * x + c1) * x + c0);
	    if (kflag > 0) {
		/* Step H. Hat acceptance (E is repeated on rejection) */
		if (c * fabs(u) <= py * exp(px + E) - fy * exp(fx + E))
		    break;
	    } else
		/* Step Q. Quotient acceptance (rare case) */
		if (fy - u * fy <= py * exp(px - fx))
		    break;
	}/* t > -.67.. */
    }
    return pois;
}
コード例 #9
0
int igraph_random_sample(igraph_vector_t *res, igraph_integer_t l, igraph_integer_t h, 
			 igraph_integer_t length) {
  igraph_real_t N=h-l+1;
  igraph_real_t n=length;
  int retval;

  igraph_real_t nreal=length;
  igraph_real_t ninv=1.0/nreal;
  igraph_real_t Nreal=N;
  igraph_real_t Vprime;
  igraph_real_t qu1=-n+1+N;
  igraph_real_t qu1real=-nreal+1.0+Nreal;
  igraph_real_t negalphainv=-13;
  igraph_real_t threshold=-negalphainv*n;
  igraph_real_t S;
  
  igraph_vector_clear(res);
  IGRAPH_CHECK(igraph_vector_reserve(res, length));  

  RNG_BEGIN();
  
  Vprime=exp(log(RNG_UNIF01())*ninv);

  while (n>1 && threshold < N) {
    igraph_real_t X, U;
    igraph_real_t limit, t;
    igraph_real_t negSreal, y1, y2, top, bottom;
    igraph_real_t nmin1inv=1.0/(-1.0+nreal);
    while (1) {
      while(1) {
	X=Nreal*(-Vprime+1.0);
	S=floor(X);
	if (S==0) { S=1; }
	if (S <qu1) { break; }
	Vprime = exp(log(RNG_UNIF01())*ninv);
      }
      U=RNG_UNIF01();
      negSreal=-S;
      
      y1=exp(log(U*Nreal/qu1real)*nmin1inv);
      Vprime=y1*(-X/Nreal+1.0)*(qu1real/(negSreal+qu1real));
      if (Vprime <= 1.0) { break; }
      
      y2=1.0;
      top=-1.0+Nreal;
      if (-1+n > S) {
	bottom=-nreal+Nreal; 
	limit=-S+N;
      } else {
	bottom=-1.0+negSreal+Nreal;
	limit=qu1;
      }
      for (t=-1+N; t>=limit; t--) {
	y2=(y2*top)/bottom;
	top=-1.0+top;
	bottom=-1.0+bottom;
      }
      if (Nreal/(-X+Nreal) >= y1*exp(log(y2)*nmin1inv)) {
	Vprime=exp(log(RNG_UNIF01())*nmin1inv);
	break;
      }
      Vprime=exp(log(RNG_UNIF01())*ninv);
    }
        
    l+=S;
    igraph_vector_push_back(res, l);	/* allocated */
    N=-S+(-1+N);   Nreal=negSreal+(-1.0+Nreal);
    n=-1+n;   nreal=-1.0+nreal; ninv=nmin1inv;
    qu1=-S+qu1; qu1real=negSreal+qu1real;
    threshold=threshold+negalphainv;
  }
  
  if (n>1) {
    retval=igraph_random_sample_alga(res, l, h, n);
  } else {
    retval=0;
    S=floor(N*Vprime);
    l+=S;
    igraph_vector_push_back(res, l);	/* allocated */
  }

  RNG_END();
  
  return retval;
}
コード例 #10
0
ファイル: miso.c プロジェクト: mlovci/MISO
int splicing_miso_trinity(const splicing_matrix_t *match_matrix,
			  const splicing_vector_int_t *isolen,
			  int readLength, int noIterations, int noBurnIn,
			  int noLag, const splicing_vector_t *hyperp,
			  splicing_matrix_t *samples, 
			  splicing_vector_t *logLik,
			  splicing_matrix_t *class_templates,
			  splicing_vector_t *class_counts,
			  splicing_vector_int_t *assignment,
			  splicing_miso_rundata_t *rundata) {

  double acceptP, cJS, pJS, sigma;
  int noiso = splicing_matrix_nrow(match_matrix);
  int noReads = splicing_matrix_ncol(match_matrix);
  splicing_vector_int_t *myass=assignment, vass;
  splicing_vector_t vpsi, vpsiNew, valpha, valphaNew, 
    *psi=&vpsi, *psiNew=&vpsiNew, *alpha=&valpha, *alphaNew=&valphaNew;
  int noSamples = (noIterations - noBurnIn + 1) / noLag;
  int i, m, lagCounter=0, noS=0;
  splicing_vector_int_t match_order;
  splicing_vector_int_t effisolen;
  splicing_vector_t isoscores;

  if ( (class_templates ? 1 : 0) + (class_counts ? 1 : 0) == 1) {
    SPLICING_ERROR("Only one of `class_templates' and `class_counts' is "
		   "given", SPLICING_EINVAL);
  }
  
  rundata->noIso=noiso;
  rundata->noIters=noIterations;
  rundata->noBurnIn=noBurnIn;
  rundata->noLag=noLag;
  rundata->noAccepted = rundata->noRejected = 0;

  if (assignment) { 
    SPLICING_CHECK(splicing_vector_int_resize(myass, noReads));
    splicing_vector_int_null(myass);
  } else {
    myass=&vass;
    SPLICING_CHECK(splicing_vector_int_init(myass, noReads));
    SPLICING_FINALLY(splicing_vector_int_destroy, myass);
  }
  SPLICING_CHECK(splicing_vector_init(&vpsi, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &vpsi);
  SPLICING_CHECK(splicing_vector_init(&vpsiNew, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &vpsiNew);
  SPLICING_CHECK(splicing_vector_init(&valpha, noiso-1));
  SPLICING_FINALLY(splicing_vector_destroy, &valpha);
  SPLICING_CHECK(splicing_vector_init(&valphaNew, noiso-1));
  SPLICING_FINALLY(splicing_vector_destroy, &valphaNew);

  SPLICING_CHECK(splicing_vector_int_init(&match_order, noReads));
  SPLICING_FINALLY(splicing_vector_int_destroy, &match_order);
  SPLICING_CHECK(splicing_order_matches(match_matrix, &match_order));

  if (class_templates && class_counts) { 
    SPLICING_CHECK(splicing_i_miso_classes(match_matrix, &match_order, 
					   class_templates, class_counts, 
					   /*bin_class_templates=*/ 0, 
					   /*bin_class_counts=*/ 0));
  }

  SPLICING_CHECK(splicing_vector_int_init(&effisolen, noiso));
  SPLICING_FINALLY(splicing_vector_int_destroy, &effisolen);
  SPLICING_CHECK(splicing_vector_init(&isoscores, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &isoscores);
  for (i=0; i<noiso; i++) { 
    int l=VECTOR(*isolen)[i]-readLength+1;
    VECTOR(effisolen)[i] = l > 0 ? l : 0;
    VECTOR(isoscores)[i] = -log((double) l);
  }

  SPLICING_CHECK(splicing_matrix_resize(samples, noiso, noSamples));
  SPLICING_CHECK(splicing_vector_resize(logLik, noSamples));

  /* Initialize Psi(0) randomly */

  SPLICING_CHECK(splicing_drift_proposal(/* mode= */ 0, 0, 0, 0, 0, 0, 
					 noiso, psi, alpha, &sigma, 0));
  SPLICING_CHECK(splicing_drift_proposal(/* mode= */ 1, psi, alpha, sigma,
					 0, 0, noiso, psi, alpha, 0, 0));

  /* Initialize assignments of reads */  
  
  SPLICING_CHECK(splicing_reassign_samples(match_matrix, &match_order, psi, 
					   noiso, myass));

  /* foreach Iteration m=1, ..., M do */

  for (m=0; m < noIterations; m++) {

    SPLICING_CHECK(splicing_drift_proposal(/* mode= */ 1, psi, alpha, sigma,
					   0, 0, noiso, psiNew, alphaNew, 0,
					   0));
    
    SPLICING_CHECK(splicing_metropolis_hastings_ratio(myass, noReads, psiNew,
						      alphaNew, psi, alpha,
						      sigma, noiso, 
						      &effisolen, hyperp,
						      &isoscores, 
						      m > 0 ? 1 : 0, 
						      &acceptP, &cJS, &pJS));
    
    if (acceptP >= 1 || RNG_UNIF01() < acceptP) {
      splicing_vector_t *tmp;
      tmp=psi; psi=psiNew; psiNew=tmp;
      tmp=alpha; alpha=alphaNew; alphaNew=tmp;
      cJS = pJS;
      rundata->noAccepted ++;
    } else {
      rundata->noRejected ++;
    }
    
    if (m >= noBurnIn) {
      if (lagCounter == noLag - 1) {
	memcpy(&MATRIX(*samples, 0, noS), VECTOR(*psi), 
	       noiso * sizeof(double));
	VECTOR(*logLik)[noS] = cJS;
	noS++;
	lagCounter = 0;
      } else {
	lagCounter ++;
      }
    }
    
    SPLICING_CHECK(splicing_reassign_samples(match_matrix, &match_order, 
					     psi, noiso, myass));

  } /* for m < noIterations */

  splicing_vector_destroy(&isoscores);
  splicing_vector_int_destroy(&effisolen);
  splicing_vector_int_destroy(&match_order);
  splicing_vector_destroy(&valphaNew);
  splicing_vector_destroy(&valpha);
  splicing_vector_destroy(&vpsiNew);
  splicing_vector_destroy(&vpsi);
  SPLICING_FINALLY_CLEAN(7);

  if (!assignment) { 
    splicing_vector_int_destroy(myass);
    SPLICING_FINALLY_CLEAN(1);
  }  
  
  return 0;
}
コード例 #11
0
int splicing_simulate_reads(const splicing_gff_t *gff, int gene,
			    const splicing_vector_t *expression,
			    int noreads, int readLength,
			    splicing_vector_int_t *isoform, 
			    splicing_vector_int_t *position, 
			    splicing_strvector_t *cigar, 
			    splicing_vector_t *sample_prob) {
  
  size_t i, p, noiso, goodiso=0, nogenes;
  splicing_vector_int_t effisolen;
  splicing_vector_t sampleprob;
  double rand, sumpsi=0.0;
  splicing_vector_int_t exstart, exend, exidx;

  SPLICING_CHECK(splicing_gff_nogenes(gff, &nogenes));
  if (gene < 0 || gene >= nogenes) {
    SPLICING_ERROR("Invalid gene id", SPLICING_EINVAL);
  }

  /* TODO: more error checks */

  SPLICING_CHECK(splicing_gff_noiso_one(gff, gene, &noiso));
    
  SPLICING_CHECK(splicing_vector_int_init(&effisolen, noiso));
  SPLICING_FINALLY(splicing_vector_int_destroy, &effisolen);
  SPLICING_CHECK(splicing_vector_init(&sampleprob, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &sampleprob);
  SPLICING_CHECK(splicing_vector_int_resize(isoform, noreads));
  SPLICING_CHECK(splicing_gff_isolength_one(gff, gene, &effisolen));
  for (i=0; i<noiso; i++) {
    int l=VECTOR(effisolen)[i]-readLength+1;
    VECTOR(effisolen)[i] = l > 0 ? l : 0;
    VECTOR(sampleprob)[i] = VECTOR(*expression)[i] * VECTOR(effisolen)[i];
    if (VECTOR(sampleprob)[i] != 0) { goodiso++; }
    sumpsi += VECTOR(sampleprob)[i];
  }

  if (goodiso==0) {
    SPLICING_ERROR("No isoform is possible", SPLICING_FAILURE);
  }

  if (sample_prob) {
    SPLICING_CHECK(splicing_vector_update(sample_prob, &sampleprob));
  }

  for (i=1; i<noiso; i++) {
    VECTOR(sampleprob)[i] += VECTOR(sampleprob)[i-1];
  }

  for (i=0; i<noreads; i++) {
    int w;
    if (noiso==1) {
      w=0;
    } else if (noiso==2) {
      rand = RNG_UNIF01() * sumpsi;
      w = (rand < VECTOR(sampleprob)[0]) ? 0 : 1;
    } else {
      rand = RNG_UNIF01() * sumpsi;
      for (w=0; rand > VECTOR(sampleprob)[w]; w++) ;
    }
    VECTOR(*isoform)[i]=w;
  }
  
  splicing_vector_destroy(&sampleprob);
  SPLICING_FINALLY_CLEAN(1);

  /* OK, we have the isoforms, now we need the read positions, 
     these are uniformly sampled from the individual isoforms. */

  SPLICING_CHECK(splicing_vector_int_resize(position, noreads));
  SPLICING_CHECK(splicing_vector_int_init(&exstart, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exstart);
  SPLICING_CHECK(splicing_vector_int_init(&exend, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exend);
  SPLICING_CHECK(splicing_vector_int_init(&exidx, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exidx);
  SPLICING_CHECK(splicing_gff_exon_start_end(gff, &exstart, &exend, &exidx,
					     gene));

  /* Positions in isoform coordinates first */

  for (i=0; i<noreads; i++) { 
    int iso=VECTOR(*isoform)[i];
    int len=VECTOR(effisolen)[iso];
    VECTOR(*position)[i]=RNG_INTEGER(1, len);
  }

  /* Translate isoform coordinates to genomic coordintes */

  /* TODO: some of this is already calculated */
  SPLICING_CHECK(splicing_iso_to_genomic(gff, gene, isoform, /*converter=*/ 0,
					 position));

  /* CIGAR strings */

  splicing_strvector_clear(cigar);
  SPLICING_CHECK(splicing_strvector_reserve(cigar, noreads));
  for (i=0; i<noreads; i++) {
    char tmp[1000], *tmp2=tmp;
    int iso=VECTOR(*isoform)[i];
    size_t rs=VECTOR(*position)[i];
    int ex=0;
    int rl=readLength;
    for (ex=VECTOR(exidx)[iso]; VECTOR(exend)[ex] < rs; ex++) ;
    while (VECTOR(exend)[ex] < rs+rl-1) {
      tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM%iN",
		       (int) (VECTOR(exend)[ex]-rs+1), 
		       (int) (VECTOR(exstart)[ex+1]-VECTOR(exend)[ex]-1));
      if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
	SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL);
      }
      rl -= (VECTOR(exend)[ex] - rs + 1);
      rs = VECTOR(exstart)[ex+1];
      ex++;
    }
    tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM", rl);
    if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
      SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL); }
    SPLICING_CHECK(splicing_strvector_append(cigar, tmp));
  }

  splicing_vector_int_destroy(&exidx);
  splicing_vector_int_destroy(&exend);
  splicing_vector_int_destroy(&exstart);
  splicing_vector_int_destroy(&effisolen);
  SPLICING_FINALLY_CLEAN(4);
  
  return 0;
}
コード例 #12
0
int splicing_simulate_paired_reads(const splicing_gff_t *gff, int gene,
				   const splicing_vector_t *expression,
				   int noreads, int readLength,
				   const splicing_vector_t *fragmentProb,
				   int fragmentStart, double normalMean,
				   double normalVar, double numDevs,
				   splicing_vector_int_t *isoform,
				   splicing_vector_int_t *position,
				   splicing_strvector_t *cigar, 
				   splicing_vector_t *sampleprob) {
  
  size_t i, j, noiso, il, nogenes;
  splicing_vector_t *mysampleprob=sampleprob, vsampleprob;
  splicing_vector_t px, cpx;
  double sumpx, sumpsi=0.0;
  splicing_vector_int_t isolen;
  int goodiso=0;
  splicing_vector_int_t exstart, exend, exidx;
  splicing_vector_t *myfragmentProb=(splicing_vector_t*) fragmentProb,
    vfragmentProb;
  int fs, fl;

  SPLICING_CHECK(splicing_gff_nogenes(gff, &nogenes));
  if (gene < 0 || gene >= nogenes) {
    SPLICING_ERROR("Invalid gene id", SPLICING_EINVAL);
  }

  /* TODO: more error checks */

  if (!fragmentProb) { 
    myfragmentProb=&vfragmentProb;
    SPLICING_CHECK(splicing_vector_init(&vfragmentProb, 0));
    SPLICING_FINALLY(splicing_vector_destroy, &vfragmentProb);
    SPLICING_CHECK(splicing_normal_fragment(normalMean, normalVar, numDevs, 
					    readLength, myfragmentProb,
					    &fragmentStart));
    splicing_vector_scale(myfragmentProb, 
			  1.0/splicing_vector_sum(myfragmentProb));
  }

  il=splicing_vector_size(myfragmentProb);
  fs=fragmentStart;
  fl=fragmentStart+il-1;

  SPLICING_CHECK(splicing_gff_noiso_one(gff, gene, &noiso));
    
  if ( fabs(splicing_vector_sum(myfragmentProb) - 1.0) > 1e-10 ) {
    SPLICING_ERROR("Fragment length distribution does not sum up to 1", 
		   SPLICING_EINVAL);
  }

  SPLICING_CHECK(splicing_vector_int_init(&isolen, noiso));
  SPLICING_FINALLY(splicing_vector_int_destroy, &isolen);
  SPLICING_CHECK(splicing_gff_isolength_one(gff, gene, &isolen));
  
  SPLICING_CHECK(splicing_vector_copy(&px, myfragmentProb));
  SPLICING_FINALLY(splicing_vector_destroy, &px);
  SPLICING_CHECK(splicing_vector_init(&cpx, il));
  SPLICING_FINALLY(splicing_vector_destroy, &cpx);

  if (!sampleprob) {
    mysampleprob=&vsampleprob;
    SPLICING_CHECK(splicing_vector_init(mysampleprob, noiso));
    SPLICING_FINALLY(splicing_vector_destroy, mysampleprob);
  } else {
    SPLICING_CHECK(splicing_vector_resize(mysampleprob, noiso));
  }

  for (sumpx=VECTOR(px)[0], i=1; i<il; i++) {
    VECTOR(px)[i] += VECTOR(px)[i-1];
    sumpx += VECTOR(px)[i];
  }
  VECTOR(cpx)[0] = VECTOR(px)[0];
  for (i=1; i<il; i++) {
    VECTOR(cpx)[i] = VECTOR(cpx)[i-1] + VECTOR(px)[i];
  }

  for (i=0; i<noiso; i++) {
    int ilen=VECTOR(isolen)[i];
    int r1= ilen >= fl ? ilen - fl + 1 : 0;
    int r2= ilen >= fs ? (ilen >= fl ? fl - fs : ilen - fs + 1) : 0;
    /* int r3= fs - 1; */
    double sp=0.0;
    if (r1 > 0) { sp += r1; } 
    if (r2 > 0) { sp += VECTOR(cpx)[r2-1]; }
    VECTOR(*mysampleprob)[i] = sp * VECTOR(*expression)[i];
    if (VECTOR(*mysampleprob)[i] != 0) { goodiso += 1; }
    sumpsi += VECTOR(*mysampleprob)[i];
  }

  if (goodiso == 0) {
    SPLICING_ERROR("No isoform is possible", SPLICING_FAILURE);
  }

  for (i=1; i<noiso; i++) {
    VECTOR(*mysampleprob)[i] += VECTOR(*mysampleprob)[i-1];
  }

  SPLICING_CHECK(splicing_vector_int_resize(isoform, noreads*2));

  for (i=0; i<2*noreads; i+=2) {
    int w;
    double rand;
    if (noiso==1) {
      w=0;
    } else if (noiso==2) {
      rand = RNG_UNIF01() * sumpsi;
      w = (rand < VECTOR(*mysampleprob)[0]) ? 0 : 1;
    } else {
      rand = RNG_UNIF01() * sumpsi;
      for (w=0; rand > VECTOR(*mysampleprob)[w]; w++) ;
    }
    VECTOR(*isoform)[i]=VECTOR(*isoform)[i+1]=w;
  }

  if (!sampleprob) { 
    splicing_vector_destroy(mysampleprob);
    SPLICING_FINALLY_CLEAN(1);
  } else {
    for (i=noiso-1; i>0; i--) {
      VECTOR(*mysampleprob)[i] -= VECTOR(*mysampleprob)[i-1];
    }
  }

  /* We have the isoforms, now get the read positions. */
  
  SPLICING_CHECK(splicing_vector_int_resize(position, noreads*2));
  SPLICING_CHECK(splicing_vector_int_init(&exstart, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exstart);
  SPLICING_CHECK(splicing_vector_int_init(&exend, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exend);
  SPLICING_CHECK(splicing_vector_int_init(&exidx, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exidx);
  SPLICING_CHECK(splicing_gff_exon_start_end(gff, &exstart, &exend, &exidx,
					     gene));
  
  /* Positions in isoform coordinates first. 
     These are sampled based on the fragment length distribution. */

  for (i=0, j=0; i<noreads; i++) {
    int iso=VECTOR(*isoform)[2*i];
    int ilen=VECTOR(isolen)[iso];
    int r1= ilen >= fl ? ilen - fl + 1 : 0;
    int r2= ilen >= fs ? (ilen >= fl ? fl - fs : ilen - fs + 1) : 0;
    /* int r3= fs - 1; */
    int pos, fragment;
    double sp=0.0;
    if (r1 > 0) { sp += r1; } 
    if (r2 > 0) { sp += VECTOR(cpx)[r2-1]; }
    double rand=RNG_UNIF(0, sp);
    if (rand < r1) { 
      pos = ceil(rand);
    } else {
      int w;
      rand -= r1;
      for (w=0; VECTOR(cpx)[w] < rand; w++) ;
      pos = r1 + r2 - w;
    }

    if (pos <= r1) {
      rand=RNG_UNIF(0, 1.0);
    } else {
      rand=RNG_UNIF(0, VECTOR(px)[r1+r2-pos]);
    }
    for (fragment=0; VECTOR(px)[fragment] < rand; fragment++) ;
    fragment += fragmentStart;

    VECTOR(*position)[j++] = pos;
    VECTOR(*position)[j++] = pos+fragment-readLength;
    
  }

  /* Translate positions to genomic coordinates */

  /* TODO: some of this is already calculated */
  SPLICING_CHECK(splicing_iso_to_genomic(gff, gene, isoform, /*converter=*/ 0,
					 position));

  /* CIGAR strings */

  splicing_strvector_clear(cigar);
  SPLICING_CHECK(splicing_strvector_reserve(cigar, 2*noreads));
  for (j=0; j<2*noreads; j++) {
    char tmp[1000], *tmp2=tmp;
    int iso=VECTOR(*isoform)[j];
    size_t rs=VECTOR(*position)[j];
    int ex=0;
    int rl=readLength;
    for (ex=VECTOR(exidx)[iso]; VECTOR(exend)[ex] < rs; ex++) ;
    while (rs + rl - 1 > VECTOR(exend)[ex]) {
      tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM%iN",
		       (int) (VECTOR(exend)[ex]-rs+1), 
		       (int) (VECTOR(exstart)[ex+1]-VECTOR(exend)[ex]-1));
      if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
	SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL);
      }
      rl -= (VECTOR(exend)[ex] - rs + 1);
      rs = VECTOR(exstart)[ex+1];
      ex++;
    }
    tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM", rl);
    if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
      SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL);
    }
    SPLICING_CHECK(splicing_strvector_append(cigar, tmp));
  }

  splicing_vector_int_destroy(&exidx);
  splicing_vector_int_destroy(&exend);
  splicing_vector_int_destroy(&exstart);
  splicing_vector_destroy(&cpx);
  splicing_vector_destroy(&px);
  splicing_vector_int_destroy(&isolen);
  SPLICING_FINALLY_CLEAN(6);

  if (!fragmentProb) { 
    splicing_vector_destroy(myfragmentProb); 
    SPLICING_FINALLY_CLEAN(1);
  }

  return 0;
}
コード例 #13
0
ファイル: layout_fr.c プロジェクト: FEYoung/rigraph
int igraph_layout_fruchterman_reingold_3d(const igraph_t *graph, 
					  igraph_matrix_t *res,
					  igraph_bool_t use_seed,
					  igraph_integer_t niter,
					  igraph_real_t start_temp,
					  const igraph_vector_t *weight, 
					  const igraph_vector_t *minx,
					  const igraph_vector_t *maxx,
					  const igraph_vector_t *miny,
					  const igraph_vector_t *maxy,
					  const igraph_vector_t *minz,
					  const igraph_vector_t *maxz) {

  igraph_integer_t no_nodes=igraph_vcount(graph);
  igraph_integer_t no_edges=igraph_ecount(graph);
  igraph_integer_t i;
  igraph_vector_float_t dispx, dispy, dispz;
  igraph_real_t temp=start_temp;
  igraph_real_t difftemp=start_temp / niter;
  float width=sqrtf(no_nodes), height=width, depth=width;
  igraph_bool_t conn=1;
  float C;

  if (niter < 0) {
    IGRAPH_ERROR("Number of iterations must be non-negative in "
		 "Fruchterman-Reingold layout", IGRAPH_EINVAL);
  }

  if (use_seed && (igraph_matrix_nrow(res) != no_nodes ||
		   igraph_matrix_ncol(res) != 3)) {
    IGRAPH_ERROR("Invalid start position matrix size in "
		 "Fruchterman-Reingold layout", IGRAPH_EINVAL);
  }

  if (weight && igraph_vector_size(weight) != igraph_ecount(graph)) {
    IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL);
  }

  if (minx && igraph_vector_size(minx) != no_nodes) {
    IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL);
  }
  if (maxx && igraph_vector_size(maxx) != no_nodes) {
    IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL);
  }
  if (minx && maxx && !igraph_vector_all_le(minx, maxx)) {
    IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL);
  }
  if (miny && igraph_vector_size(miny) != no_nodes) {
    IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL);
  }
  if (maxy && igraph_vector_size(maxy) != no_nodes) {
    IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL);
  }
  if (miny && maxy && !igraph_vector_all_le(miny, maxy)) {
    IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL);
  }
  if (minz && igraph_vector_size(minz) != no_nodes) {
    IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL);
  }
  if (maxz && igraph_vector_size(maxz) != no_nodes) {
    IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL);
  }
  if (minz && maxz && !igraph_vector_all_le(minz, maxz)) {
    IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL);
  }

  igraph_is_connected(graph, &conn, IGRAPH_WEAK);
  if (!conn) { C = no_nodes * sqrtf(no_nodes); }

  RNG_BEGIN();

  if (!use_seed) {
    IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3));
    for (i=0; i<no_nodes; i++) {
      igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2;
      igraph_real_t x2=maxx ? VECTOR(*maxx)[i] :  width/2;
      igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2;
      igraph_real_t y2=maxy ? VECTOR(*maxy)[i] :  height/2;
      igraph_real_t z1=minz ? VECTOR(*minz)[i] : -depth/2;
      igraph_real_t z2=maxz ? VECTOR(*maxz)[i] :  depth/2;
      MATRIX(*res, i, 0) = RNG_UNIF(x1, x2);
      MATRIX(*res, i, 1) = RNG_UNIF(y1, y2);
      MATRIX(*res, i, 2) = RNG_UNIF(z1, z2);
    }
  }

  IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx);
  IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy);
  IGRAPH_CHECK(igraph_vector_float_init(&dispz, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispz);

  for (i=0; i<niter; i++) {
    igraph_integer_t v, u, e;
    
    /* calculate repulsive forces, we have a special version
       for unconnected graphs */
    igraph_vector_float_null(&dispx);
    igraph_vector_float_null(&dispy);
    igraph_vector_float_null(&dispz);
    if (conn) {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
	  float dlen=dx * dx + dy * dy + dz * dz;

          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dz = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy + dz * dz;
          }

	  VECTOR(dispx)[v] += dx/dlen;
	  VECTOR(dispy)[v] += dy/dlen;
	  VECTOR(dispz)[v] += dz/dlen;
	  VECTOR(dispx)[u] -= dx/dlen;
	  VECTOR(dispy)[u] -= dy/dlen;
	  VECTOR(dispz)[u] -= dz/dlen;
	}
      }
    } else {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
	  float dlen, rdlen;

	  dlen=dx * dx + dy * dy + dz * dz;
          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dz = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy + dz * dz;
          }

	  rdlen=sqrt(dlen);

	  VECTOR(dispx)[v] += dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dz * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispx)[u] -= dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[u] -= dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispz)[u] -= dz * (C-dlen * rdlen) / (dlen*C);
	}
      }
    }

    /* calculate attractive forces */
    for (e=0; e<no_edges; e++) {
      /* each edges is an ordered pair of vertices v and u */
      igraph_integer_t v=IGRAPH_FROM(graph, e);
      igraph_integer_t u=IGRAPH_TO(graph, e);
      igraph_real_t dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
      igraph_real_t dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
      igraph_real_t dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
      igraph_real_t w=weight ? VECTOR(*weight)[e] : 1.0;
      igraph_real_t dlen=sqrt(dx * dx + dy * dy + dz * dz) * w;
      VECTOR(dispx)[v] -= (dx * dlen);
      VECTOR(dispy)[v] -= (dy * dlen);
      VECTOR(dispz)[v] -= (dz * dlen);
      VECTOR(dispx)[u] += (dx * dlen);
      VECTOR(dispy)[u] += (dy * dlen);
      VECTOR(dispz)[u] += (dz * dlen);
    }
    
    /* limit max displacement to temperature t and prevent from
       displacement outside frame */
    for (v=0; v<no_nodes; v++) {
      igraph_real_t dx=VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dy=VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dz=VECTOR(dispz)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t displen=sqrt(dx * dx + dy * dy + dz * dz);
      igraph_real_t mx=fabs(dx) < temp ? dx : temp;
      igraph_real_t my=fabs(dy) < temp ? dy : temp;
      igraph_real_t mz=fabs(dz) < temp ? dz : temp;
      if (displen > 0) {
        MATRIX(*res, v, 0) += (dx / displen) * mx;
        MATRIX(*res, v, 1) += (dy / displen) * my;
        MATRIX(*res, v, 2) += (dz / displen) * mz;
      }
      if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) { 
	MATRIX(*res, v, 0) = VECTOR(*minx)[v]; 
      }
      if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*maxx)[v];
      }
      if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*miny)[v];
      }
      if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*maxy)[v];
      }
      if (minz && MATRIX(*res, v, 2) < VECTOR(*minz)[v]) {
	MATRIX(*res, v, 2) = VECTOR(*minz)[v];
      }
      if (maxz && MATRIX(*res, v, 2) > VECTOR(*maxz)[v]) {
	MATRIX(*res, v, 2) = VECTOR(*maxz)[v];
      }
    }

    temp -= difftemp;
  }

  RNG_END();

  igraph_vector_float_destroy(&dispx);
  igraph_vector_float_destroy(&dispy);
  igraph_vector_float_destroy(&dispz);
  IGRAPH_FINALLY_CLEAN(3);
  
  return 0;
}
コード例 #14
0
ファイル: layout_fr.c プロジェクト: FEYoung/rigraph
int igraph_layout_i_fr(const igraph_t *graph,
		       igraph_matrix_t *res,
		       igraph_bool_t use_seed,
		       igraph_integer_t niter,
		       igraph_real_t start_temp,
		       const igraph_vector_t *weight,
		       const igraph_vector_t *minx,
		       const igraph_vector_t *maxx,
		       const igraph_vector_t *miny,
		       const igraph_vector_t *maxy) {

  igraph_integer_t no_nodes=igraph_vcount(graph);
  igraph_integer_t no_edges=igraph_ecount(graph);
  igraph_integer_t i;
  igraph_vector_float_t dispx, dispy;
  igraph_real_t temp=start_temp;
  igraph_real_t difftemp=start_temp / niter;
  float width=sqrtf(no_nodes), height=width;
  igraph_bool_t conn=1;
  float C;

  igraph_is_connected(graph, &conn, IGRAPH_WEAK);
  if (!conn) { C = no_nodes * sqrtf(no_nodes); }

  RNG_BEGIN();

  if (!use_seed) {
    IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2));
    for (i=0; i<no_nodes; i++) {
      igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2;
      igraph_real_t x2=maxx ? VECTOR(*maxx)[i] :  width/2;
      igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2;
      igraph_real_t y2=maxy ? VECTOR(*maxy)[i] :  height/2;
      if (!igraph_finite(x1)) { x1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(x2)) { x2 =  sqrt(no_nodes)/2; }
      if (!igraph_finite(y1)) { y1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(y2)) { y2 =  sqrt(no_nodes)/2; }
      MATRIX(*res, i, 0) = RNG_UNIF(x1, x2);
      MATRIX(*res, i, 1) = RNG_UNIF(y1, y2);
    }
  }

  IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx);
  IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy);

  for (i=0; i<niter; i++) {
    igraph_integer_t v, u, e;

    /* calculate repulsive forces, we have a special version
       for unconnected graphs */
    igraph_vector_float_null(&dispx);
    igraph_vector_float_null(&dispy);
    if (conn) {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dlen=dx * dx + dy * dy;

          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy;
          }

	  VECTOR(dispx)[v] += dx/dlen;
	  VECTOR(dispy)[v] += dy/dlen;
	  VECTOR(dispx)[u] -= dx/dlen;
	  VECTOR(dispy)[u] -= dy/dlen;
	}
      }
    } else {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dlen, rdlen;

	  dlen=dx * dx + dy * dy;
          if (dlen == 0) {
            dx = RNG_UNIF(0, 1e-6);
            dy = RNG_UNIF(0, 1e-6);
            dlen = dx * dx + dy * dy;
          }

	  rdlen=sqrt(dlen);

	  VECTOR(dispx)[v] += dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispx)[u] -= dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[u] -= dy * (C-dlen * rdlen) / (dlen*C);
	}
      }
    }

    /* calculate attractive forces */
    for (e=0; e<no_edges; e++) {
      /* each edges is an ordered pair of vertices v and u */
      igraph_integer_t v=IGRAPH_FROM(graph, e);
      igraph_integer_t u=IGRAPH_TO(graph, e);
      igraph_real_t dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
      igraph_real_t dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
      igraph_real_t w=weight ? VECTOR(*weight)[e] : 1.0;
      igraph_real_t dlen=sqrt(dx * dx + dy * dy) * w;
      VECTOR(dispx)[v] -= (dx * dlen);
      VECTOR(dispy)[v] -= (dy * dlen);
      VECTOR(dispx)[u] += (dx * dlen);
      VECTOR(dispy)[u] += (dy * dlen);
    }

    /* limit max displacement to temperature t and prevent from
       displacement outside frame */
    for (v=0; v<no_nodes; v++) {
      igraph_real_t dx=VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dy=VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t displen=sqrt(dx * dx + dy * dy);
      igraph_real_t mx=fabs(dx) < temp ? dx : temp;
      igraph_real_t my=fabs(dy) < temp ? dy : temp;
      if (displen > 0) {
        MATRIX(*res, v, 0) += (dx / displen) * mx;
        MATRIX(*res, v, 1) += (dy / displen) * my;
      }
      if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*minx)[v];
      }
      if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*maxx)[v];
      }
      if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*miny)[v];
      }
      if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*maxy)[v];
      }
    }

    temp -= difftemp;
  }

  RNG_END();

  igraph_vector_float_destroy(&dispx);
  igraph_vector_float_destroy(&dispy);
  IGRAPH_FINALLY_CLEAN(2);
  
  return 0;
}
コード例 #15
0
ファイル: layout_fr.c プロジェクト: FEYoung/rigraph
int igraph_layout_i_grid_fr(const igraph_t *graph,
            igraph_matrix_t *res, igraph_bool_t use_seed,
	    igraph_integer_t niter, igraph_real_t start_temp,
	    const igraph_vector_t *weight, const igraph_vector_t *minx,
	    const igraph_vector_t *maxx, const igraph_vector_t *miny,
	    const igraph_vector_t *maxy) {

  igraph_integer_t no_nodes=igraph_vcount(graph);
  igraph_integer_t no_edges=igraph_ecount(graph);
  float width=sqrtf(no_nodes), height=width;
  igraph_2dgrid_t grid;
  igraph_vector_float_t dispx, dispy;
  igraph_real_t temp=start_temp;
  igraph_real_t difftemp=start_temp / niter;
  igraph_2dgrid_iterator_t vidit;
  igraph_integer_t i;
  const float cellsize=2.0;

  RNG_BEGIN();

  if (!use_seed) {
    IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2));
    for (i=0; i<no_nodes; i++) {
      igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2;
      igraph_real_t x2=maxx ? VECTOR(*maxx)[i] :  width/2;
      igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2;
      igraph_real_t y2=maxy ? VECTOR(*maxy)[i] :  height/2;
      if (!igraph_finite(x1)) { x1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(x2)) { x2 =  sqrt(no_nodes)/2; }
      if (!igraph_finite(y1)) { y1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(y2)) { y2 =  sqrt(no_nodes)/2; }
      MATRIX(*res, i, 0) = RNG_UNIF(x1, x2);
      MATRIX(*res, i, 1) = RNG_UNIF(y1, y2);
    }
  }

  /* make grid */
  IGRAPH_CHECK(igraph_2dgrid_init(&grid, res, -width/2, width/2, cellsize,
				  -height/2, height/2, cellsize));
  IGRAPH_FINALLY(igraph_2dgrid_destroy, &grid);

  /* place vertices on grid */
  for (i=0; i<no_nodes; i++) {
    igraph_2dgrid_add2(&grid, i);
  }

  IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx);
  IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy);

  for (i=0; i<niter; i++) {
    igraph_integer_t v, u, e;

    igraph_vector_float_null(&dispx);
    igraph_vector_float_null(&dispy);

    /* repulsion */
    igraph_2dgrid_reset(&grid, &vidit);
    while ( (v=igraph_2dgrid_next(&grid, &vidit)-1) != -1) {
      while ( (u=igraph_2dgrid_next_nei(&grid, &vidit)-1) != -1) {
	float dx=MATRIX(*res, v, 0)-MATRIX(*res, u, 0);
	float dy=MATRIX(*res, v, 1)-MATRIX(*res, u, 1);
	float dlen=dx * dx + dy * dy;
	if (dlen < cellsize * cellsize) {
	  VECTOR(dispx)[v] += dx/dlen;
	  VECTOR(dispy)[v] += dy/dlen;
	  VECTOR(dispx)[u] -= dx/dlen;
	  VECTOR(dispy)[u] -= dy/dlen;
	}
      }
    }

    /* attraction */
    for (e=0; e<no_edges; e++) {
      igraph_integer_t v=IGRAPH_FROM(graph, e);
      igraph_integer_t u=IGRAPH_TO(graph, e);
      igraph_real_t dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
      igraph_real_t dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
      igraph_real_t w=weight ? VECTOR(*weight)[e] : 1.0;
      igraph_real_t dlen=sqrt(dx * dx + dy * dy) * w;
      VECTOR(dispx)[v] -= (dx * dlen);
      VECTOR(dispy)[v] -= (dy * dlen);
      VECTOR(dispx)[u] += (dx * dlen);
      VECTOR(dispy)[u] += (dy * dlen);
    }

    /* update */
    for (v=0; v<no_nodes; v++) {
      igraph_real_t dx=VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dy=VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t displen=sqrt(dx * dx + dy * dy);
      igraph_real_t mx=fabs(dx) < temp ? dx : temp;
      igraph_real_t my=fabs(dy) < temp ? dy : temp;
      if (displen > 0) {
        MATRIX(*res, v, 0) += (dx / displen) * mx;
        MATRIX(*res, v, 1) += (dy / displen) * my;
      }
      if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*minx)[v];
      }
      if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*maxx)[v];
      }
      if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*miny)[v];
      }
      if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*maxy)[v];
      }
    }

    temp -= difftemp;
  }

  igraph_vector_float_destroy(&dispx);
  igraph_vector_float_destroy(&dispy);
  igraph_2dgrid_destroy(&grid);
  IGRAPH_FINALLY_CLEAN(3);
  return 0;
}