Пример #1
0
void Stabilisator::update_pi(CplexSolver & solver, DoubleVector const & pi) {
	DoubleVector rc;
	solver.rc(rc);
	_pi_bar = pi;
	int n_rows((int) _pi_bar.size());
//	std::cout << "avg = " << avg / _pi_bar.size() << std::endl;
	_dual_cost.assign(4 * _pi_bar.size(), 0);
	_cost.assign(4 * _pi_bar.size(), 0);
	_indexes.assign(4 * _pi_bar.size(), 0);

	int index(-1);
	for (int row(0); row < n_rows; ++row) {
		_cost[++index] = gamma1(row);
		_dual_cost[index] = dseta_m();
		_indexes[index] = index;

		_cost[++index] = delta1(row);
		_dual_cost[index] = epsilon_m();
		_indexes[index] = index;

		_cost[++index] = -delta2(row);
		_dual_cost[index] = epsilon_p();
		_indexes[index] = index;

		_cost[++index] = -gamma2(row);
		_dual_cost[index] = dseta_p();
		_indexes[index] = index;
	}
	solver.chgObj(_indexes, _cost);
}
Пример #2
0
std::string ThreeSstarCoeffs::str() const
{
  std::stringstream ss;
  for (int i=0; i<nb_stages(); ++i)
  {
    ss << std::setw(2) << i << ": " 
       << std::setw(9) << delta(i) 
       << std::setw(9) << beta(i)
       << std::setw(9) << gamma1(i)
       << std::setw(9) << gamma2(i)
       << std::setw(9) << gamma3(i);
    ss << std::endl;
  }
  return ss.str();
}
Пример #3
0
RcppExport SEXP nsem3b(SEXP data,  
		      SEXP theta,
		      SEXP Sigma,
		      SEXP modelpar,
		    SEXP control
		    ) {   

  //  srand ( time(NULL) ); /* initialize random seed: */
  
  Rcpp::NumericVector Theta(theta);  
  Rcpp::NumericMatrix D(data);
  unsigned nobs = D.nrow(), k = D.ncol();
  mat Data(D.begin(), nobs, k, false); // Avoid copying
  Rcpp::NumericMatrix V(Sigma);  
  mat S(V.begin(), V.nrow(), V.ncol()); 
  S(0,0) = 1;
  mat iS = inv(S);
  double detS = det(S);
 

  Rcpp::List Modelpar(modelpar);
  // Rcpp::IntegerVector _nlatent = Modelpar["nlatent"]; unsigned nlatent = _nlatent[0];
  Rcpp::IntegerVector _ny0 = Modelpar["nvar0"]; unsigned ny0 = _ny0[0];
  Rcpp::IntegerVector _ny1 = Modelpar["nvar1"]; unsigned ny1 = _ny1[0];
  Rcpp::IntegerVector _ny2 = Modelpar["nvar2"]; unsigned ny2 = _ny2[0];
  Rcpp::IntegerVector _npred0 = Modelpar["npred0"]; unsigned npred0 = _npred0[0];
  Rcpp::IntegerVector _npred1 = Modelpar["npred1"]; unsigned npred1 = _npred1[0];
  Rcpp::IntegerVector _npred2 = Modelpar["npred2"]; unsigned npred2 = _npred2[0];
  Rcpp::List Control(control);   
  Rcpp::NumericVector _lambda = Control["lambda"]; double lambda = _lambda[0];
  Rcpp::NumericVector _niter = Control["niter"]; double niter = _niter[0];
  Rcpp::NumericVector _Dtol = Control["Dtol"]; double Dtol = _Dtol[0];


  rowvec mu0(ny0), lambda0(ny0);
  rowvec mu1(ny1), lambda1(ny1);
  rowvec mu2(ny2), lambda2(ny2);
  rowvec beta0(npred0); 
  rowvec beta1(npred1); 
  rowvec beta2(npred2);
  rowvec gamma(2);
  rowvec gamma2(2);  
  unsigned pos=0;
  for (unsigned i=0; i<ny0; i++) {
    mu0(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny1; i++) {
    mu1(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny2; i++) {
    mu2(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny0; i++) {
    lambda0(i) = Theta[pos];
    pos++;
  }
  lambda1(0) = 1;
  for (unsigned i=1; i<ny1; i++) {
    lambda1(i) = Theta[pos];
    pos++;
  }
  lambda2(0) = 1;
  for (unsigned i=1; i<ny2; i++) {
    lambda2(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred0; i++) {
    beta0(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred1; i++) {
    beta1(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred2; i++) {
    beta2(i) = Theta[pos];
    pos++;
  }
  gamma(0) = Theta[pos]; gamma(1) = Theta[pos+1];
  gamma2(0) = Theta[pos+2]; gamma2(1) = Theta[pos+3];

  // cerr << "mu0=" << mu0 << endl;
  // cerr << "mu1=" << mu1 << endl;
  // cerr << "mu2=" << mu2 << endl;
  // cerr << "lambda0=" << lambda0 << endl;
  // cerr << "lambda1=" << lambda1 << endl;
  // cerr << "lambda2=" << lambda2 << endl;
  // cerr << "beta0=" << beta0 << endl;
  // cerr << "beta1=" << beta1 << endl;
  // cerr << "beta2=" << beta2 << endl;
  // cerr << "gamma=" << gamma << endl;
  // cerr << "gamma2=" << gamma2 << endl;
  
  mat lap(nobs,4);
  for (unsigned i=0; i<nobs; i++) {
    rowvec newlap = laNRb(Data.row(i), iS, detS,
			  mu0, mu1, mu2, 
			  lambda0, lambda1, lambda2, 
			  beta0,beta1, beta2, gamma, gamma2,
			  Dtol,niter,lambda);
    lap.row(i) = newlap;
  }

  List  res;
  res["indiv"] = lap;
  res["logLik"] = sum(lap.col(0)) + (3-V.nrow())*log(2.0*datum::pi)*nobs/2;
  res["norm0"] = (3-V.nrow())*log(2*datum::pi)/2;
  return res;
}
//----------------------
float tmVisThreshC1_MixtureModeling2::differenceGamma (int i) {
	return gamma1(i)-gamma2(i);
}
//----------------------
float tmVisThreshC1_MixtureModeling2::gamma (int i) {
	return gamma1(i)+gamma2(i);
}
Пример #6
0
void mlalign_TKF91(mlalign_Nucleotide *as, size_t na, mlalign_Nucleotide *bs,
                   size_t nb, double lambda, double mu, double tau, double pi[mlalign_NUMBER_OF_BASES],
                   mlalign_Site *alignment, size_t *n, double *score) {

  /***********************/
  /* initialize matrices */
  /***********************/

  size_t rows = na + 1;
  size_t cols = nb + 1;
  auto idxM = diagonalizedIndexer(rows, cols, VECSIZE);
  auto idxA = identityIndexer(na);
  auto idxB = identityIndexer(nb);
  auto idxP1 = identityIndexer(mlalign_NUMBER_OF_BASES);
  auto idxP2 = rowMajorIndexer(mlalign_NUMBER_OF_BASES, mlalign_NUMBER_OF_BASES);
  auto idx2 = identityIndexer(2);


  // Allocate enough bytes for the matrices and properly align that.
  // We won't use vector because
  //  1) it initializes every element to 0
  //  2) has some extra payload we won't need (e.g. capacity and size for bounds checks)
  //  3) we don't resize
  const size_t doubles_per_matrix = to_next_multiple(idxM(rows - 1, cols - 1) + 1, VECSIZE);
  std::unique_ptr<double[]> buffer(new double[3 * doubles_per_matrix + VECSIZE]);
  auto M0 = reinterpret_cast<double*>(
          to_next_multiple(
                  reinterpret_cast<size_t>(buffer.get()),
                  VECSIZE * sizeof(double)));
  auto M1 = M0 + doubles_per_matrix;
  auto M2 = M1 + doubles_per_matrix;
  assert(M0 - buffer.get() < static_cast<std::ptrdiff_t>(VECSIZE));

  //
  // Memoization
  //
  const double beta = (1 - std::exp((lambda - mu) * tau)) / (mu - lambda * std::exp((lambda - mu) * tau));
  const double delta = 1 / (1 - pi[0] * pi[0] - pi[1] * pi[1] - pi[2] * pi[2] - pi[3] * pi[3]);
  const double lambda_div_mu = lambda / mu;
  const double lambda_mul_beta = lambda * beta;
  double p_desc_1 = p_desc(1, beta, lambda, mu, tau);
  double M0_factor[mlalign_NUMBER_OF_BASES];
  double M1_factor[mlalign_NUMBER_OF_BASES * mlalign_NUMBER_OF_BASES];
  double M2_factor[mlalign_NUMBER_OF_BASES];
  double p_desc_inv_n[2];

  for (size_t i = 0; i < 2; ++i) {
    p_desc_inv_n[idx2(i)] = p_desc_inv(i, beta, lambda, mu, tau);
  }

  for (size_t i = 0; i < mlalign_NUMBER_OF_BASES; ++i) {
    const auto a = static_cast<mlalign_Nucleotide>(i);
    M0_factor[idxP1(a)] = std::log(lambda_div_mu * pi[idxP1(a)] * p_desc_inv_n[idx2(0)]);
  }

  for (size_t i = 0; i < mlalign_NUMBER_OF_BASES; ++i) {
    for (size_t j = 0; j < mlalign_NUMBER_OF_BASES; ++j) {
      const auto a = static_cast<mlalign_Nucleotide>(i);
      const auto b = static_cast<mlalign_Nucleotide>(j);
      M1_factor[idxP2(a, b)] = std::log(lambda_div_mu * pi[idxP1(a)]
                                 * std::max(p_trans(a, b, delta, pi, tau) * p_desc_1, pi[idxP1(b)] * p_desc_inv_n[idx2(1)]));
    }
  }

  for (size_t i = 0; i < mlalign_NUMBER_OF_BASES; ++i) {
    const auto b = static_cast<mlalign_Nucleotide>(i);
    M2_factor[idxP1(b)] = std::log(pi[idxP1(b)] * lambda_mul_beta);
  }

  size_t ix = idxM(0, 0); // We'll reuse ix throughout this function for caching idx calculations
  M0[ix] = -std::numeric_limits<double>::max();
  M1[ix] = std::log(gamma2(0, lambda, mu) * zeta(1, beta, lambda));
  M2[ix] = -std::numeric_limits<double>::max();

  double accum = 0.0;
  for (size_t i = 1; i < rows; i++) {
    ix = idxM(i, 0);
    accum += std::log(pi[idxP1(as[idxA(i-1)])] * p_desc_inv_n[idx2(0)]);

    M0[ix] = std::log(gamma2(i, lambda, mu) * zeta(i, beta, lambda)) + accum;
    M1[ix] = -std::numeric_limits<double>::max();
    M2[ix] = -std::numeric_limits<double>::max();
  }

  accum = 0.0;
  for (size_t j = 1; j < cols; j++) {
    ix = idxM(0, j);
    accum += std::log(pi[idxP1(bs[idxB(j-1)])]);

    M0[ix] = -std::numeric_limits<double>::max();
    M1[ix] = -std::numeric_limits<double>::max();
    M2[ix] = std::log(gamma2(0, lambda, mu) * zeta(j + 1, beta, lambda)) + accum;
  }

  /****************/
  /* DP algorithm */
  /****************/

  // TODO: Implement these in circular queues.
  size_t top[3] = { 0, 0, SIZE_MAX };
  size_t bottom[3] { 1, 0, SIZE_MAX };
  // This is tricky. We store the corrected offsets for diagonals offset -1 and -2 (7, 3 resp.) and the
  // uncorrected (e.g. not aligned) offset for the current diagonal (which is 7 + 2 = 9).
  // We inititialize with the values for diagonal 2, 1 and 0, we start at diagonal = 2 anyway.
  size_t diagonal_offsets[3] = { 2*VECSIZE + 1, 2*VECSIZE - 1, VECSIZE - 1 };
  const size_t number_of_diagonals = rows + cols - 1;
  for (size_t diagonal = 2; diagonal < number_of_diagonals; ++diagonal) {

    // Topmost and bottommost row index of the diagonal,
    // skipping the already initialized first row and column (diagonal - 1 for that reason).
    // It's helpful for intuition to visualize this (rows=7, cols=6):
    //
    //   3  7 11 15 19
    //   8 12 16 20 24
    //   5 17 21 25 32
    //  18 22 26 33 40
    //  23 27 34 41 44
    //  28 35 42 45 48
    //  36 43 46 49 52
    //
    // diagonal             | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
    // bottom_without_first | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 6 |
    // top_without_first    | 1 | 1 | 1 | 1 | 2 | 3 | 4 | 5 |
    //
    // We will then iterate over the diagonal through the indices
    // [top_without_first, bottom_without_first] inclusive. Column
    // indices are easily computed from the diagonal and row index.
    // We start with diagonal = 2, e.g. the third diagonal, because
    // it's the first containing uninitialized values.
    //
    const size_t bottom_without_first = std::min(diagonal - 1, rows - 1);
    const size_t top_without_first = diagonal - std::min(diagonal - 1, cols - 1);

    std::rotate(top, top + 2, top + 3); // This pushes all elements on further back
    std::rotate(bottom, bottom + 2, bottom + 3);
    bottom[0] = std::min(diagonal, rows - 1);
    top[0] = diagonal - std::min(diagonal, cols - 1);
    const size_t length_of_diagonal = bottom[0] + 1 - top[0];

    // We have to correct the diagonal offset for the alignment rules layed out in diagonalizedIndexer.
    //    1. If the diagonal starts in the first row (top[0]=0), then the offset must have alignment -1.
    //    2. If the diagonal doesn't start in the first row, then the offset must have alignment 0.
    diagonal_offsets[0] += top[0] == 0
                  ? VECSIZE - 1 - diagonal_offsets[0] % VECSIZE
                  : (VECSIZE - diagonal_offsets[0] % VECSIZE) % VECSIZE;

    assert((top[0] == 0 && diagonal_offsets[0] % VECSIZE == VECSIZE - 1)
           || (top[0] != 0 && diagonal_offsets[0] % VECSIZE == 0));

    // INDEX EXPLANATIONS
    // row_offset   offset of the row where the current SIMD vector begins
    // i            index into the SIMD vector
    // col          index of the column where the currently processed vector element is located in the DP matrix
    // row          index of the row where the currently processed vector element is located in the DP matrix
    
    // Step in vector size over diagonal entries
    for (size_t row_offset = top_without_first; row_offset <= bottom_without_first; row_offset += VECSIZE) {


      // Copy the factors values from the lookuptable into the vector
      // Apparently it is not better to copy into temp memory and the use loaddvec, but it is faster to just use the [] operator.
      dvec factors[3];
      for (size_t i = 0; i < VECSIZE; ++i) {
        const size_t row = row_offset + i;
        const size_t col = diagonal - row;

        if (row > bottom_without_first) {
          // We would load from somewhere out of the matrix, so we just leave the
          // other vector elements untouched
          break;
        }

        const mlalign_Nucleotide a = as[idxA(row - 1)];
        const mlalign_Nucleotide b = bs[idxB(col - 1)];

        factors[0][i] = M0_factor[idxP1(a)];
        factors[1][i] = M1_factor[idxP2(a, b)];
        factors[2][i] = M2_factor[idxP1(b)];
      }

      // Compute the indexes of the top, left and top left cells and load them.
      const size_t ix_top = diagonal_offsets[1] + row_offset - 1 - top[1];
      assert(ix_top == idxM(row_offset - 1, diagonal - row_offset));
      const dvec max_top[3] = {
              loaddvec(M0 + ix_top),
              loaddvec(M1 + ix_top),
              loaddvec(M2 + ix_top),
      };

      const size_t ix_topleft = diagonal_offsets[2] + row_offset - 1 - top[2];
      assert(ix_topleft == idxM(row_offset - 1, diagonal - row_offset - 1));
      const dvec max_topleft[3] = {
              loaddvec(M0 + ix_topleft),
              loaddvec(M1 + ix_topleft),
              loaddvec(M2 + ix_topleft),
      };

      // Against all symmetry M0 isn't part of the formula.
      const size_t ix_left = ix_top + 1;
      assert(ix_left == idxM(row_offset, diagonal - row_offset - 1));
      const dvec max_left[2] = {
              loaddvec(M1 + ix_left),
              loaddvec(M2 + ix_left),
      };

      // Maxima for each cells on top/topleft/left of the calculated cell
      const dvec mt = maxdvec(max_top[0], maxdvec(max_top[1], max_top[2]));
      const dvec mtl = maxdvec(max_topleft[0], maxdvec(max_topleft[1], max_topleft[2]));
      const dvec ml = maxdvec(max_left[0], max_left[1]);

      // Vectorised add
      const dvec m0v = factors[0] + mt;
      const dvec m1v = factors[1] + mtl;
      const dvec m2v = factors[2] + ml;

      // Write back to matrix
      const size_t occupied_vector_elements = std::min(bottom_without_first + 1 - row_offset, VECSIZE);
      ix = diagonal_offsets[0] + row_offset - top[0];
      assert(ix % VECSIZE == 0);
      assert(ix == idxM(row_offset, diagonal - row_offset));
      storedvec(M0 + ix, m0v, occupied_vector_elements);
      storedvec(M1 + ix, m1v, occupied_vector_elements);
      storedvec(M2 + ix, m2v, occupied_vector_elements);
    }

    std::rotate(diagonal_offsets, diagonal_offsets + 2, diagonal_offsets + 3);
    diagonal_offsets[0] = diagonal_offsets[1] + length_of_diagonal;
  }

  /****************/
  /* Backtracking */
  /****************/

  ix = idxM(na, nb);
  *n = 0;
  *score = std::exp(std::max({M0[ix], M1[ix], M2[ix]}));
  size_t cur = max_idx({M0[ix], M1[ix], M2[ix]});

  for (size_t i = na, j = nb; i > 0 || j > 0;) {
    mlalign_Site site = {mlalign_Gap, mlalign_Gap};
    switch (cur) {
      case 0: // insert
        assert(i > 0);
        site.a = as[--i];
        site.b = mlalign_Gap;

        ix = idxM(i, j);
        cur = max_idx({M0[ix], M1[ix], M2[ix]});
        break;
      case 1: // substitution
        assert(i > 0);
        assert(j > 0);
        site.a = as[--i];
        site.b = bs[--j];

        ix = idxM(i, j);
        cur = max_idx({M0[ix], M1[ix], M2[ix]});
        break;
      case 2: // deletion
        assert(j > 0);
        site.a = mlalign_Gap;
        site.b = bs[--j];

        ix = idxM(i, j);
        cur = max_idx({M1[ix], M2[ix]}) + 1;
        break;
      default:
        assert(0);
    }

    alignment[(*n)++] = site; // Doesn't get any scarier
  }

  // The alignment is reversed, so we have to undo that.
  for (size_t i = 0; i < (*n) / 2; ++i) {
    std::swap(alignment[i], alignment[*n - i - 1]);
  }
}