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)) ]; } }
/** * 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 ) ); */ }
/** * 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; } }
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); }
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); }
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); }
/// /// \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; }
/* 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); }
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)); }
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; }
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; } }
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; }
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()); } }
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; }