예제 #1
0
void Annotator::update_color(MeshBundle<DefaultMesh>::Ptr m,const arma::uvec& label)
{
    assert(m->mesh_.n_vertices()==label.size());
    uint32_t* c = (uint32_t*)m->custom_color_.vertex_colors();
    #pragma omp parallel for
    for(int i=0;i<label.size();++i)
    {
        assert( l2c_.find(int(label(i))) != l2c_.end() );
        c[i] = l2c_[ int(label(i)) ];
    }
}
예제 #2
0
	/**
         * Add a random local matrix and rhs spanning over given rows and columns.
         * 
         */
	void add(arma::uvec rows, arma::uvec cols) {
          
            arma::mat loc_mat=arma::randu<arma::mat>(rows.size(), cols.size());
            arma::vec loc_rhs=arma::randu<arma::vec>(rows.size());
            // apply to full system
            full_matrix_.submat(rows, cols)+=loc_mat;
            full_rhs_.elem(rows)+=loc_rhs;
            // apply to fixture system
            arma::vec row_sol=dirichlet_values_.elem(rows);
            arma::vec col_sol=dirichlet_values_.elem(cols);
            
            
            auto i_rows=arma::conv_to<std::vector<int> >::from(
                          arma::conv_to<arma::ivec>::from(rows)%dirichlet_.elem(rows));
            auto i_cols=arma::conv_to<std::vector<int> >::from(
                          arma::conv_to<arma::ivec>::from(cols)%dirichlet_.elem(cols));
            
            //cout << "i_rows\n" << arma::ivec(i_rows);
            //cout << "i_cols\n" << arma::ivec(i_cols);
            this->set_values(i_rows, i_cols, loc_mat, loc_rhs, row_sol, col_sol);            
            
            
            // check consistency
            double eps=4*arma::datum::eps;
            // zero dirichlet rows and cols
            //cout << "Dirich rows:\n" << dirichlet_rows_;
            //cout << "matrix_:\n" << matrix_;
            EXPECT_TRUE( arma::norm(matrix_.submat(dirichlet_rows_, non_dirichlet_rows_), "inf") < eps);
            
            EXPECT_TRUE( arma::norm(matrix_.submat(non_dirichlet_rows_, dirichlet_rows_), "inf") < eps);
            
            auto dirich_submat = matrix_.submat(dirichlet_rows_, dirichlet_rows_);
            EXPECT_TRUE( arma::norm( dirich_submat - arma::diagmat(dirich_submat), "inf") < eps );
            
            /*
            // full check
            arma::mat reduced_matrix_=full_matrix_;
            auto dirich_cols=reduced_matrix_.submat(arma::span::all, dirichlet_rows_);
            arma::vec reduced_rhs_=full_rhs_ - dirich_cols *dirichlet_values_;
            dirich_cols.zeros();
            
            reduced_matrix_.submat(dirichlet_rows_, arma::span::all).zeros();
            reduced_matrix_.submat(dirichlet_rows_, dirichlet_rows_) = dirich_submat;
            reduced_rhs_.subvec(dirichlet_rows_)=dirich_submat*dirichlet_values_;
            
            EXPECT_TRUE( arma::all( abs(matrix_ - reduced_matrix_)<eps ) );
            EXPECT_TRUE( arma::all( abs(rhs_ - reduced_rhs_)<eps ) );
            */
	}
예제 #3
0
파일: random.hpp 프로젝트: YaweiZhao/mlpack
/**
 * Obtains no more than maxNumSamples distinct samples. Each sample belongs to
 * [loInclusive, hiExclusive).
 *
 * @param loInclusive The lower bound (inclusive).
 * @param hiExclusive The high bound (exclusive).
 * @param maxNumSamples The maximum number of samples to obtain.
 * @param distinctSamples The samples that will be obtained.
 */
inline void ObtainDistinctSamples(const size_t loInclusive,
                                  const size_t hiExclusive,
                                  const size_t maxNumSamples,
                                  arma::uvec& distinctSamples)
{
  const size_t samplesRangeSize = hiExclusive - loInclusive;

  if (samplesRangeSize > maxNumSamples)
  {
    arma::Col<size_t> samples;

    samples.zeros(samplesRangeSize);

    for (size_t i = 0; i < maxNumSamples; i++)
      samples [ (size_t) math::RandInt(samplesRangeSize) ]++;

    distinctSamples = arma::find(samples > 0);

    if (loInclusive > 0)
      distinctSamples += loInclusive;
  }
  else
  {
    distinctSamples.set_size(samplesRangeSize);
    for (size_t i = 0; i < samplesRangeSize; i++)
      distinctSamples[i] = loInclusive + i;
  }
}
예제 #4
0
void SAC_Parallel_Plane::selectWithinDistance(arma::vec& coeff,double threshold,arma::uvec& inliers)
{
    // Check if the model is valid given the user constraints
    if (!isModelValid (coeff))
    {
      inliers.reset();
      return;
    }
    SAC_Plane::selectWithinDistance(coeff,threshold,inliers);
}
예제 #5
0
파일: svm_basic.cpp 프로젝트: gmum/gmum.r
void SVMConfiguration::setSparseData(
    arma::uvec rowptr,
    arma::uvec colind,
    arma::vec values,
    size_t nrow,
    size_t ncol,
    bool one_indexed
) {
    // rowind and colptr are one-indexed -- we are sad
    if (one_indexed) {
        for (size_t i=0; i < rowptr.size(); ++i) {
            rowptr[i] -= 1;
        }
        for (size_t i=0; i < colind.size(); ++i) {
            colind[i] -= 1;
        }
    }

    // THIS IS TRICKY:
    // we are using fact that CSR format for A is CSC format for A^T
    this->sparse_data = arma::sp_mat(colind, rowptr, values, ncol, nrow);
}
예제 #6
0
void InPatchGraphCut::applyToFrame(const arma::uvec& gc_label,const arma::uvec& label_indices)
{
    MeshBundle<DefaultMesh>& mesh = *meshes_[current_frame_];
    arma::uvec& label = labels_[current_frame_];
    arma::uvec patch_label;
    current_patch_graph_->sv2pix(gc_label,patch_label);
    if(patch_label.size()!=label_indices.size())std::logic_error("gc_label.size()!=label_indices.size()");
    arma::uvec new_patch_indices = arma::find( patch_label==0 );
    arma::uvec new_patch_value = label(label_indices);
    new_patch_value(new_patch_indices).fill(0);
    label(label_indices) = new_patch_value;
    mesh.custom_color_.fromlabel(label);
}
예제 #7
0
파일: VCA.cpp 프로젝트: sedarsky/Vespucci
///
/// \brief Vespucci::Math::DimensionReduction::VCA
/// Vertex Component Analysis
/// \param R The dataset
/// \param endmembers Number of endmembers to compute
/// \param indices Row indices of pure components.
/// \param endmember_spectra Spectra of pure components (note that these are in
/// columns, not rows as in spectra_)
/// \param projected_data Projected data
/// \param fractional_abundances Purity of a given spectrum relative to endmember
/// \return Convergeance (no actual test implemented...)
///
bool Vespucci::Math::DimensionReduction::VCA(const arma::mat &R, arma::uword p,
         arma::uvec &indices, arma::mat &endmember_spectra,
         arma::mat &projected_data, arma::mat &fractional_abundances)
{
//Initializations
    arma::uword L = R.n_rows;
    arma::uword N = R.n_cols;
    if (L == 0 || N == 0){
        std::cerr << "No data!" << std::endl;
        return false;
    }

    if (p > L){
        std::cerr << "wrong number of endmembers (" << p << ")!"<< std::endl;
        std::cerr << "set to 5 or one less than number of spectra" << std::endl;
        p = (L < 5? 5: L-1);
    }
//mat of SNR
    arma::mat r_m = mean(R, 1);
    arma::mat R_m = arma::repmat(r_m, 1, N); //the mean of each spectral band
    arma::mat R_o = R - R_m; //mean-center the data
    arma::mat Ud;
    arma::vec Sd;
    arma::mat Vd;
    //arma::svds(Ud, Sd, Vd, arma::sp_mat(R_o * R_o.t()/N), p);
    Vespucci::Math::DimensionReduction::svds(R_o*R_o.t()/N, p, Ud, Sd, Vd);
    arma::mat x_p;
    try{
    x_p = Ud.t() * R_o;
    }catch(std::exception e){
        std::cout << "Ud.t() * R_o" << std::endl;
    }

    double SNR = Vespucci::Math::DimensionReduction::estimate_snr(R, r_m, x_p);
    double SNR_th = 15 + 10*log10(p);

//Choose projective projection or projection to p-1 subspace
    arma::mat y;
    if (SNR < SNR_th){
        arma::uword d = p - 1;
        Ud = Ud.cols(0, d-1);
        projected_data = Ud * x_p.rows(0, d-1) + R_m; //in dimension L
        arma::mat x = x_p.rows(0, d-1);//x_p = trans(Ud)*R_o, p-dimensional subspace
        //following three lines are one in arma::matlab...
        arma::mat sum_squares = sum(pow(x, 2));
        double c = sum_squares.max();
        c = std::sqrt(c);
        y = arma::join_vert(x, c*arma::ones(1, N));
      }
    else{
        arma::uword d = p;
        Vespucci::Math::DimensionReduction::svds(R*R.t()/N, p, Ud, Sd, Vd);
        arma::svds(Ud, Sd, Vd, arma::sp_mat(R*R.t()/N), d);//R_o is a mean centered version...
        x_p = Ud.t() * R;
        projected_data = Ud * x_p.rows(0, d-1);
        arma::mat x = Ud.t() * R;
        arma::mat u = arma::mean(x, 1);
        y = x / arma::repmat(sum(x % arma::repmat(u, 1, N)), d, 1);
    }


    // The VCA algorithm
    arma::vec w;
    w.set_size(p);
    arma::vec f;
    arma::rowvec v;
    indices.set_size(p);
    //there are no fill functions for arma::uvecs
    for (arma::uword i = 0; i < p; ++i)
        indices(i) = 0;

    arma::mat A = arma::zeros(p, p);
    double v_max;
    double sum_squares;
    arma::uvec q1;
    A(p-1, 0) = 1;
    for (arma::uword i = 0; i < p; ++i){
        w.randu();
        f = w - A*arma::pinv(A)*w;
        sum_squares = sqrt(sum(square(f)));
        f /= sum_squares;
        v = f.t() * y;
        v_max = arma::max(abs(v));
        q1 = arma::find(abs(v) == v_max, 1);
        indices(i) = q1(0);
        A.col(i) = y.col(indices(i)); //same as x.col(indices(i));
    }
    endmember_spectra = projected_data.cols(indices);
    fractional_abundances = arma::trans(pinv(endmember_spectra) * projected_data);
    return true;
}
예제 #8
0
/* Metropolis-Hastings updates of mu 
* Updates are implemented simulateaneously for all biological genes
*/
arma::mat muUpdateNoSpikes(
    arma::vec const& mu0, 
    arma::vec const& prop_var, 
    arma::mat const& Counts,  
    arma::vec const& invdelta, 
    arma::vec const& nu, 
    arma::vec const& sum_bycell_all, 
    double const& s2_mu,
    int const& q0,
    int const& n,
    arma::vec & mu1,
    arma::vec & u,
    arma::vec & ind,
    double const& Constrain,
    int const& RefGene,
    arma::uvec const& ConstrainGene,
    arma::uvec const& NotConstrainGene,
    int const& ConstrainType)
{
  using arma::span;
  
  int nConstrainGene = ConstrainGene.size();
  int nNotConstrainGene = NotConstrainGene.size();
  
  // PROPOSAL STEP    
  mu1 = exp(arma::randn(q0) % sqrt(prop_var) + log(mu0));
  u = arma::randu(q0);
  
  // INITIALIZE MU
  double aux; double iAux;
  double sumAux = sum(log(mu0.elem(ConstrainGene))) - log(mu0(RefGene));
  
  // ACCEPT/REJECT STEP
  
  // Step 1: Computing the likelihood contribution of the acceptance rate 
  // Calculated in the same way for all genes, 
  // but the reference one (no need to be sequential)
  arma::vec log_aux = (log(mu1) - log(mu0)) % sum_bycell_all;
  for (int i=0; i < q0; i++) {
    if(i != RefGene) {
      for (int j=0; j < n; j++) {
        log_aux(i) -= ( Counts(i,j) + invdelta(i) ) * 
          log( ( nu(j)*mu1(i) + invdelta(i) ) / 
          ( nu(j)*mu0(i) + invdelta(i) ));
      }
    }
  }
  
  // Step 2: Computing prior component of the acceptance rate 
  
  // Step 2.1: For genes that are under the constrain (excluding the reference one)
  for (int i=0; i < nConstrainGene; i++) {
    iAux = ConstrainGene(i);
    if(iAux != RefGene) {
      aux = 0.5 * (ConstrainGene.size() * Constrain - (sumAux - log(mu0(iAux))));
      log_aux(iAux) -= (0.5 * 2 /s2_mu) * (pow(log(mu1(iAux)) - aux,2)); 
      log_aux(iAux) += (0.5 * 2 /s2_mu) * (pow(log(mu0(iAux)) - aux,2));
      // ACCEPT REJECT
      if((log(u(iAux)) < log_aux(iAux)) & (mu1(iAux) > 1e-3)) {
        ind(iAux) = 1; sumAux += log(mu1(iAux)) - log(mu0(iAux)); 
      }
      else{ind(iAux) = 0; mu1(iAux) = mu0(iAux); }      
    }
  }
  
  // Step 2.2: For the reference gene 
  ind(RefGene) = 1;
  mu1(RefGene) = exp(ConstrainGene.size() * Constrain - sumAux);
  
  // Step 2.3: For genes that are *not* under the constrain
  // Only relevant for a trimmed constrain
  if(ConstrainType == 2) {
    for (int i=0; i < nNotConstrainGene; i++) {
      iAux = NotConstrainGene(i);
      log_aux(iAux) -= (0.5/s2_mu) * (pow(log(mu1(iAux)),2) - pow(log(mu0(iAux)),2));
      // ACCEPT REJECT
      if((log(u(iAux)) < log_aux(iAux)) & (mu1(iAux) > 1e-3)) { ind(iAux) = 1; }
      else{ind(iAux) = 0; mu1(iAux) = mu0(iAux);}
    }
  }
  // OUTPUT
  return join_rows(mu1, ind);
}
예제 #9
0
List objectivex(const arma::mat& transition, const arma::cube& emission,
  const arma::vec& init, const arma::ucube& obs, const arma::umat& ANZ,
  const arma::ucube& BNZ, const arma::uvec& INZ, const arma::uvec& nSymbols,
  const arma::mat& coef, const arma::mat& X, arma::uvec& numberOfStates,
  unsigned int threads) {

  unsigned int q = coef.n_rows;
  arma::vec grad(
      arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ) + (numberOfStates.n_elem- 1) * q,
      arma::fill::zeros);
  arma::mat weights = exp(X * coef).t();
  if (!weights.is_finite()) {
    grad.fill(-arma::datum::inf);
    return List::create(Named("objective") = arma::datum::inf, Named("gradient") = wrap(grad));
  }

  weights.each_row() /= sum(weights, 0);

  arma::mat initk(emission.n_rows, obs.n_slices);

  for (unsigned int k = 0; k < obs.n_slices; k++) {
    initk.col(k) = init % reparma(weights.col(k), numberOfStates);
  }
  
  arma::uvec cumsumstate = arma::cumsum(numberOfStates);
  
  unsigned int error = 0;
  double ll = 0;
#pragma omp parallel for if(obs.n_slices >= threads) schedule(static) reduction(+:ll) num_threads(threads)       \
  default(none) shared(q, grad, nSymbols, ANZ, BNZ, INZ,                                                         \
    numberOfStates, cumsumstate, obs, init, initk, X, weights, transition, emission, error)
    for (unsigned int k = 0; k < obs.n_slices; k++) {
      if (error == 0) {
        arma::mat alpha(emission.n_rows, obs.n_cols); //m,n
        arma::vec scales(obs.n_cols); //n
        arma::sp_mat sp_trans(transition);
        uvForward(sp_trans.t(), emission, initk.col(k), obs.slice(k), alpha, scales);
        arma::mat beta(emission.n_rows, obs.n_cols); //m,n
        uvBackward(sp_trans, emission, obs.slice(k), beta, scales);

        int countgrad = 0;
        arma::vec grad_k(grad.n_elem, arma::fill::zeros);
        // transitionMatrix
        if (arma::accu(ANZ) > 0) {

          for (unsigned int jj = 0; jj < numberOfStates.n_elem; jj++) {
            arma::vec gradArow(numberOfStates(jj));
            arma::mat gradA(numberOfStates(jj), numberOfStates(jj));
            int ind_jj = cumsumstate(jj) - numberOfStates(jj);

            for (unsigned int i = 0; i < numberOfStates(jj); i++) {
              arma::uvec ind = arma::find(ANZ.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1));

              if (ind.n_elem > 0) {
                gradArow.zeros();
                gradA.eye();
                gradA.each_row() -= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1);
                gradA.each_col() %= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1).t();


                for (unsigned int j = 0; j < numberOfStates(jj); j++) {
                  for (unsigned int t = 0; t < (obs.n_cols - 1); t++) {
                    double tmp = alpha(ind_jj + i, t);
                    for (unsigned int r = 0; r < obs.n_rows; r++) {
                      tmp *= emission(ind_jj + j, obs(r, t + 1, k), r);
                    }
                    gradArow(j) += tmp * beta(ind_jj + j, t + 1);
                  }

                }

                gradArow = gradA * gradArow;
                grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradArow.rows(ind);
                countgrad += ind.n_elem;
              }
            }
          }
        }
        if (arma::accu(BNZ) > 0) {
          // emissionMatrix
          for (unsigned int r = 0; r < obs.n_rows; r++) {
            arma::vec gradBrow(nSymbols(r));
            arma::mat gradB(nSymbols(r), nSymbols(r));
            for (unsigned int i = 0; i < emission.n_rows; i++) {
              arma::uvec ind = arma::find(BNZ.slice(r).row(i));
              if (ind.n_elem > 0) {
                gradBrow.zeros();
                gradB.eye();
                gradB.each_row() -= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1);
                gradB.each_col() %= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1).t();
                for (unsigned int j = 0; j < nSymbols(r); j++) {
                  if (obs(r, 0, k) == j) {
                    double tmp = initk(i, k);
                    for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) {
                      if (r2 != r) {
                        tmp *= emission(i, obs(r2, 0, k), r2);
                      }
                    }
                    gradBrow(j) += tmp * beta(i, 0);
                  }
                  for (unsigned int t = 0; t < (obs.n_cols - 1); t++) {
                    if (obs(r, t + 1, k) == j) {
                      double tmp = beta(i, t + 1);
                      for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) {
                        if (r2 != r) {
                          tmp *= emission(i, obs(r2, t + 1, k), r2);
                        }
                      }
                      gradBrow(j) += arma::dot(alpha.col(t), transition.col(i)) * tmp;
                    }
                  }

                }
                gradBrow = gradB * gradBrow;
                grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradBrow.rows(ind);
                countgrad += ind.n_elem;

              }
            }
          }
        }
        if (arma::accu(INZ) > 0) {
          for (unsigned int i = 0; i < numberOfStates.n_elem; i++) {
            int ind_i = cumsumstate(i) - numberOfStates(i);
            arma::uvec ind = arma::find(
              INZ.subvec(ind_i, cumsumstate(i) - 1));
            if (ind.n_elem > 0) {
              arma::vec gradIrow(numberOfStates(i), arma::fill::zeros);
              for (unsigned int j = 0; j < numberOfStates(i); j++) {
                double tmp = weights(i, k);
                for (unsigned int r = 0; r < obs.n_rows; r++) {
                  tmp *= emission(ind_i + j, obs(r, 0, k), r);
                }
                gradIrow(j) += tmp * beta(ind_i + j, 0);

              }
              arma::mat gradI(numberOfStates(i), numberOfStates(i), arma::fill::zeros);
              gradI.eye();
              gradI.each_row() -= init.subvec(ind_i, cumsumstate(i) - 1).t();
              gradI.each_col() %= init.subvec(ind_i, cumsumstate(i) - 1);
              gradIrow = gradI * gradIrow;
              grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradIrow.rows(ind);
              countgrad += ind.n_elem;
            }
          }
        }
        for (unsigned int jj = 1; jj < numberOfStates.n_elem; jj++) {
          unsigned int ind_jj = (cumsumstate(jj) - numberOfStates(jj));

          for (unsigned int j = 0; j < emission.n_rows; j++) {
            double tmp = 1.0;
            for (unsigned int r = 0; r < obs.n_rows; r++) {
              tmp *= emission(j, obs(r, 0, k), r);
            }
            if ((j >= ind_jj) & (j < cumsumstate(jj))) {
              grad_k.subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) += tmp
              * beta(j, 0) * initk(j, k) * X.row(k).t() * (1.0 - weights(jj, k));
            } else {
              grad_k.subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) -= tmp
              * beta(j, 0) * initk(j, k) * X.row(k).t() * weights(jj, k);
            }
          }

        }
        if (!scales.is_finite() || !beta.is_finite()) {
#pragma omp atomic
          error++;
        } else {
          ll -= arma::sum(log(scales));
#pragma omp critical
          grad += grad_k;
        }
      }
    }
    if(error > 0){
      ll = -arma::datum::inf;
      grad.fill(-arma::datum::inf);
    }
    return List::create(Named("objective") = -ll, Named("gradient") = wrap(-grad));
}
예제 #10
0
inline TR TrX(const T1& rho1, arma::uvec sys, arma::uvec dim) {
  const auto& p = as_Mat(rho1);

  bool checkV = true;
  if (p.n_cols == 1)
    checkV = false;

#ifndef QICLIB_NO_DEBUG
  if (p.n_elem == 0)
    throw Exception("qic::TrX", Exception::type::ZERO_SIZE);

  if (checkV)
    if (p.n_rows != p.n_cols)
      throw Exception("qic::TrX",
                      Exception::type::MATRIX_NOT_SQUARE_OR_CVECTOR);

  if (dim.n_elem == 0 || arma::any(dim == 0))
    throw Exception("qic::TrX", Exception::type::INVALID_DIMS);

  if (arma::prod(dim) != p.n_rows)
    throw Exception("qic::TrX", Exception::type::DIMS_MISMATCH_MATRIX);

  if (dim.n_elem < sys.n_elem || arma::any(sys == 0) ||
      arma::any(sys > dim.n_elem) ||
      sys.n_elem != arma::find_unique(sys, false).eval().n_elem)
    throw Exception("qic::TrX", Exception::type::INVALID_SUBSYS);
#endif

  if (sys.n_elem == dim.n_elem)
    return {arma::trace(p)};
  
  _internal::dim_collapse_sys(dim, sys);
  const arma::uword n = dim.n_elem;
  const arma::uword m = sys.n_elem;

  arma::uvec keep(n - m);
  arma::uword keep_count(0);
  for (arma::uword run = 0; run < n; ++run) {
    if (!arma::any(sys == run + 1)) {
      keep.at(keep_count) = run + 1;
      ++keep_count;
    }
  }

  arma::uword dimtrace = arma::prod(dim(sys - 1));
  arma::uword dimkeep = p.n_rows / dimtrace;

  arma::uvec product(n, arma::fill::ones);
  for (arma::sword i = n - 2; i > -1; --i)
    product.at(i) = product.at(i + 1) * dim.at(i + 1);

  arma::uvec productr(n - m, arma::fill::ones);
  for (arma::sword i = n - m - 2; i > -1; --i)
    productr.at(i) = productr.at(i + 1) * dim.at(keep.at(i + 1) - 1);

  arma::Mat<trait::eT<T1> > tr_p(dimkeep, dimkeep, arma::fill::zeros);

  const arma::uword loop_no = 2 * n;
  arma::uword* loop_counter = new arma::uword[loop_no + 1];
  arma::uword* MAX = new arma::uword[loop_no + 1];

  for (arma::uword i = 0; i < n; ++i) {
    MAX[i] = dim.at(i);
    if (arma::any(sys == (i + 1)))
      MAX[i + n] = 1;
    else
      MAX[i + n] = dim.at(i);
  }
  MAX[loop_no] = 2;

  for (arma::uword i = 0; i < loop_no + 1; ++i) loop_counter[i] = 0;

  arma::uword p1 = 0;

  while (loop_counter[loop_no] == 0) {
    arma::uword I(0), J(0), K(0), L(0), n_to_k(0);

    for (arma::uword i = 0; i < n; ++i) {
      if (arma::any(sys == i + 1)) {
        I += product.at(i) * loop_counter[i];
        J += product.at(i) * loop_counter[i];

      } else {
        I += product.at(i) * loop_counter[i];
        J += product.at(i) * loop_counter[i + n];
      }

      if (arma::any(keep == i + 1)) {
        K += productr.at(n_to_k) * loop_counter[i];
        L += productr.at(n_to_k) * loop_counter[i + n];
        ++n_to_k;
      }
    }

    tr_p.at(K, L) += checkV ? p.at(I, J) : p.at(I) * std::conj(p.at(J));

    ++loop_counter[0];
    while (loop_counter[p1] == MAX[p1]) {
      loop_counter[p1] = 0;
      loop_counter[++p1]++;
      if (loop_counter[p1] != MAX[p1])
        p1 = 0;
    }
  }
  delete[] loop_counter;
  delete[] MAX;
  return tr_p;
}
예제 #11
0
inline TR sysperm(const T1& rho1, const arma::uvec& sys,
                   const arma::uvec& dim) {
  const auto& p = as_Mat(rho1);
  const arma::uword n = dim.n_elem;

  bool checkV = true;
  if (p.n_cols == 1)
    checkV = false;

#ifndef QICLIB_NO_DEBUG
  if (p.n_elem == 0)
    throw Exception("qic::sysperm", Exception::type::ZERO_SIZE);

  if (checkV)
    if (p.n_rows != p.n_cols)
      throw Exception("qic::sysperm",
                      Exception::type::MATRIX_NOT_SQUARE_OR_CVECTOR);

  if (dim.n_elem == 0 || arma::any(dim == 0))
    throw Exception("qic::sysperm", Exception::type::INVALID_DIMS);

  if (arma::prod(dim) != p.n_rows)
    throw Exception("qic::sysperm", Exception::type::DIMS_MISMATCH_MATRIX);

  if (n != sys.n_elem || arma::any(sys == 0) || arma::any(sys > n) ||
      sys.n_elem != arma::unique(sys).eval().n_elem)
    throw Exception("qic::sysperm", Exception::type::PERM_INVALID);
#endif

  arma::uword product[_internal::MAXQDIT];
  product[n-1] = 1;
  for (arma::sword i = n - 2; i >= 0; --i)
    product[i] = product[i + 1] * dim.at(i + 1);

  arma::uword productr[_internal::MAXQDIT];
  productr[n-1] = 1;
  for (arma::sword i = n - 2; i >= 0; --i)
    productr[i] = productr[i + 1] * dim.at(sys.at(i + 1) - 1);

  if (checkV) {
    arma::Mat<trait::eT<T1> > p_r(p.n_rows, p.n_cols, arma::fill::zeros);

    const arma::uword loop_no = 2 * n;
    constexpr auto loop_no_buffer = 2 * _internal::MAXQDIT + 1;
    arma::uword loop_counter[loop_no_buffer] = {0};
    arma::uword MAX[loop_no_buffer];

    for (arma::uword i = 0; i < n; ++i) {
      MAX[i] = dim.at(i);
      MAX[i + n] = dim.at(i);
    }
    MAX[loop_no] = 2;

    arma::uword p1 = 0;

    while (loop_counter[loop_no] == 0) {
      arma::uword I(0), J(0), K(0), L(0);
      for (arma::uword i = 0; i < n; ++i) {
        I += product[i] * loop_counter[i];
        J += product[i] * loop_counter[i + n];
        K += productr[i] * loop_counter[sys.at(i) - 1];
        L += productr[i] * loop_counter[sys.at(i) + n - 1];
      }

      p_r.at(K, L) = p.at(I, J);

      ++loop_counter[0];
      while (loop_counter[p1] == MAX[p1]) {
        loop_counter[p1] = 0;
        loop_counter[++p1]++;
        if (loop_counter[p1] != MAX[p1])
          p1 = 0;
      }
    }
    return p_r;

  } else {
    arma::Col<trait::eT<T1> > p_r(p.n_rows, arma::fill::zeros);

    const arma::uword loop_no = n;
    constexpr auto loop_no_buffer = _internal::MAXQDIT + 1;
    arma::uword loop_counter[loop_no_buffer] = {0};
    arma::uword MAX[loop_no_buffer];

    for (arma::uword i = 0; i < n; ++i) MAX[i] = dim.at(i);
    MAX[loop_no] = 2;

    for (arma::uword i = 0; i < loop_no + 1; ++i) loop_counter[i] = 0;

    arma::uword p1 = 0;

    while (loop_counter[loop_no] == 0) {
      arma::uword I(0), K(0);
      for (arma::uword i = 0; i < n; ++i) {
        I += product[i] * loop_counter[i];
        K += productr[i] * loop_counter[sys.at(i) - 1];
      }

      p_r.at(K) = p.at(I);

      ++loop_counter[0];
      while (loop_counter[p1] == MAX[p1]) {
        loop_counter[p1] = 0;
        loop_counter[++p1]++;
        if (loop_counter[p1] != MAX[p1])
          p1 = 0;
      }
    }

    return p_r;
  }
}
예제 #12
0
TR discord3_reg(const T1& rho1, arma::uword nodal, arma::uvec dim) {
  const auto& rho = as_Mat(rho1);
  arma::uword party_no = dim.n_elem;
  arma::uword dim1 = arma::prod(dim);

#ifndef QICLIB_NO_DEBUG
  if (rho.n_elem == 0)
    throw Exception("qic::discord3_reg", Exception::type::ZERO_SIZE);

  if (rho.n_rows != rho.n_cols)
    throw Exception("qic::discord3_reg", Exception::type::MATRIX_NOT_SQUARE);

  if (any(dim == 0))
    throw Exception("qic::discord3_reg", Exception::type::INVALID_DIMS);

  if (dim1 != rho.n_rows)
    throw Exception("qic::discord3_reg", Exception::type::DIMS_MISMATCH_MATRIX);

  if (nodal <= 0 || nodal > party_no)
    throw Exception("qic::discord3_reg", "Invalid measured party index");

  if (dim(nodal - 1) != 3)
    throw Exception("qic::discord3_reg", "Measured party is not qutrit");
#endif

  arma::uvec party = arma::zeros<arma::uvec>(party_no);
  for (arma::uword i = 0; i < party_no; ++i) party.at(i) = i + 1;

  arma::uvec rest = party;
  rest.shed_row(nodal - 1);

  auto rho_A = TrX(rho, rest, dim);
  auto rho_B = TrX(rho, {nodal}, dim);

  auto S_A = entropy(rho_A);
  auto S_B = entropy(rho_B);
  auto S_A_B = entropy(rho);
  auto I1 = S_A + S_B - S_A_B;

  dim1 /= 3;
  arma::uword dim2(1);
  for (arma::uword i = 0; i < nodal - 1; ++i) dim2 *= dim.at(i);
  arma::uword dim3(1);
  for (arma::uword i = nodal; i < party_no; ++i) dim3 *= dim.at(i);

  arma::Mat<trait::pT<T1> > eye2 =
    arma::eye<arma::Mat<trait::pT<T1> > >(dim1, dim1);
  arma::Mat<trait::pT<T1> > eye3 =
    arma::eye<arma::Mat<trait::pT<T1> > >(dim2, dim2);
  arma::Mat<trait::pT<T1> > eye4 =
    arma::eye<arma::Mat<trait::pT<T1> > >(dim3, dim3);

  typename arma::Col<trait::pT<T1> >::template fixed<3> disc;

  for (arma::uword i = 0; i < 3; ++i) {
    arma::Mat<std::complex<trait::pT<T1> > > proj1 =
      SPM<trait::pT<T1> >::get_instance().proj3.at(0, i + 1);

    arma::Mat<std::complex<trait::pT<T1> > > proj2 =
      SPM<trait::pT<T1> >::get_instance().proj3.at(1, i + 1);

    arma::Mat<std::complex<trait::pT<T1> > > proj3 =
      SPM<trait::pT<T1> >::get_instance().proj3.at(2, i + 1);

    if (nodal == 1) {
      proj1 = kron(proj1, eye2);
      proj2 = kron(proj2, eye2);
      proj3 = kron(proj3, eye2);
    } else if (party_no == nodal) {
      proj1 = kron(eye2, proj1);
      proj2 = kron(eye2, proj2);
      proj3 = kron(eye2, proj3);
    } else {
      proj1 = kron(kron(eye3, proj1), eye4);
      proj2 = kron(kron(eye3, proj2), eye4);
      proj3 = kron(kron(eye3, proj3), eye4);
    }

    arma::Mat<std::complex<trait::pT<T1> > > rho_1 = (proj1 * rho * proj1);
    arma::Mat<std::complex<trait::pT<T1> > > rho_2 = (proj2 * rho * proj2);
    arma::Mat<std::complex<trait::pT<T1> > > rho_3 = (proj3 * rho * proj3);

    trait::pT<T1> p1 = std::real(arma::trace(rho_1));
    trait::pT<T1> p2 = std::real(arma::trace(rho_2));
    trait::pT<T1> p3 = std::real(arma::trace(rho_3));

    trait::pT<T1> S_max = 0.0;
    if (p1 > _precision::eps<trait::pT<T1> >::value) {
      rho_1 /= p1;
      S_max += p1 * entropy(rho_1);
    }
    if (p2 > _precision::eps<trait::pT<T1> >::value) {
      rho_2 /= p2;
      S_max += p2 * entropy(rho_2);
    }
    if (p3 > _precision::eps<trait::pT<T1> >::value) {
      rho_3 /= p3;
      S_max += p3 * entropy(rho_3);
    }
    disc.at(i) = I1 - (S_B - S_max);
  }

  return disc;
}
예제 #13
0
void PZStability::real_imag_idx(arma::uvec & idxr, arma::uvec & idxi) const {
  if(!cplx) {
    ERROR_INFO();
    throw std::runtime_error("Should not call real_imag_idx for purely real calculation!\n");
  }
  
  // Count amount of parameters
  size_t nreal=0, nimag=0;
  if(cancheck) {
    nreal+=oa*va;
    nimag+=oa*va;
    if(!restr) {
      nreal+=ob*vb;
      nimag+=ob*vb;
    }
  }
  if(oocheck) {
    nreal+=oa*(oa-1)/2;
    if(cplx)
      nimag+=oa*(oa+1)/2;
    
    if(!restr) {
      nreal+=ob*(ob-1)/2;
      if(cplx)
	nimag+=ob*(ob+1)/2;
    }
  }

  // Sanity check
  if(nreal+nimag != count_params()) {
    ERROR_INFO();
    throw std::runtime_error("Parameter count is wrong!\n");
  }
  
  // Parameter indices
  idxr.zeros(nreal);
  idxi.zeros(nimag);
  
  // Fill indices.
  size_t ir=0, ii=0;
  
  // Offset
  size_t ioff=0;
  
  if(cancheck) {
    // First are the real parameters
    for(size_t irot=0;irot<oa*va;irot++) {
      idxr(ir++)=irot;
    }
    ioff+=oa*va;
    // followed by the imaginary parameters
    for(size_t irot=0;irot<oa*va;irot++)
      idxi(ii++)=irot+ioff;
    ioff+=oa*va;
    
    if(!restr) {
      // and then again the real parameters
      for(size_t irot=0;irot<ob*vb;irot++)
	idxr(ir++)=irot + ioff;
      ioff+=ob*vb;
      // followed by the imaginary parameters
      for(size_t irot=0;irot<ob*vb;irot++)
	idxi(ii++)=irot + ioff;
      ioff+=ob*vb;
    }
  }
    
  if(oocheck) {
    // First are the real parameters
    for(size_t irot=0;irot<oa*(oa-1)/2;irot++) {
      idxr(ir++)=irot+ioff;
    }
    ioff+=oa*(oa-1)/2;
    // and then the imaginary parameters
    for(size_t irot=0;irot<oa*(oa+1)/2;irot++)
      idxi(ii++)=irot + ioff;
    ioff+=oa*(oa+1)/2;

    if(!restr) {
      // First are the real parameters
      for(size_t irot=0;irot<ob*(ob-1)/2;irot++) {
	idxr(ir++)=irot+ioff;
      }
      ioff+=ob*(ob-1)/2;
      // and then the imaginary parameters
      for(size_t irot=0;irot<ob*(ob+1)/2;irot++)
	idxi(ii++)=irot + ioff;
      ioff+=ob*(ob+1)/2;
    }
  }

  // Sanity check
  arma::uvec idx(nreal+nimag);
  idx.subvec(0,nreal-1)=idxr;
  idx.subvec(nreal,nreal+nimag-1)=idxi;
  idx=arma::sort(idx,"ascending");
  for(size_t i=0;i<idx.n_elem;i++)
    if(idx(i)!=i) {
      std::ostringstream oss;
      oss << "Element " << i << " of compound index is wrong: " << idx(i) << "!\n";
      throw std::runtime_error(oss.str());
    }
}
예제 #14
0
bool Partition(arma::mat &A, arma::uvec &label, int &nGroups){

	// to do
	int N = A.n_rows;
	arma::uvec parent(N);
	arma::uvec rank;

	for (int i = 0; i < N; i++){
		parent(i) = i;
	}
	rank.zeros(N, 1);
	arma::uvec ori_parent(parent);

	for (int i = 0; i < N; i++){
		// check equal items
		for (int j = 0; j < N; j++){
			if (A(i, j) == 0){
				continue;
			}

			// find root of node i and compress path
			int root_i = Find(parent, i);

			// find root of node j and compress path
			int root_j = Find(parent, j);

			// union both trees
			if (root_j != root_i){
				if (rank(root_j) < rank(root_i)){
					parent(root_j) = root_i;
				}
				else if (rank(root_i) < rank(root_j)){
					parent(root_i) = root_j;
				}
				else{
					parent(root_j) = root_i;
					rank(root_i) = rank(root_i) + 1;
				}
			}
		}
	}

	//parent.print("parent:");
	//rank.print("rank:");

	// label each element
	arma::uvec flag = parent == ori_parent;
	nGroups = arma::sum(flag);
	label.zeros(N,1);

	// matlab: label(flag) = 1:nGroups
	int t = 1;
	for (int i = 0; i < N; i++){
		if (flag(i)){
			label(i) = t++;
		}
	}
	//label.print("label");


	int root_i;
	for (int i = 0; i < N; i++){
		if (parent(i) == i){
			continue;
		}

		// find root of node i
		root_i = Find(parent, i);
		label(i) = label(root_i);
	}

	//label.print("label:");
	//cout << "nGroups:" << nGroups << endl;

	return true;
}