11#include < RcppArmadillo.h>
2-
32#include < Rcpp.h>
43using namespace Rcpp ;
54
@@ -25,36 +24,6 @@ arma::uvec table_cpp(arma::uvec x) {
2524 return counts;
2625}
2726
28- // ----------------------------------------------------------------------------|
29- // Remove row i and column i from a matrix
30- // ----------------------------------------------------------------------------|
31- arma::mat remove_row_col_matrix (arma::mat X, arma::uword i) {
32- arma::uword n = X.n_rows ;
33-
34- // Handle special case of matrix with only two rows and columns
35- if (n == 2 ) {
36- if (i == 0 ) {
37- X = X (arma::span (1 , 1 ), arma::span (1 , 1 ));
38- } else {
39- X = X (arma::span (0 , 0 ), arma::span (0 , 0 ));
40- }
41- return X;
42- }
43-
44- // Remove row i
45- for (arma::uword j = i; j < n - 1 ; j++) {
46- X.row (j) = X (j+1 ); // Shift all rows below i up by one
47- }
48- X = X.rows (arma::span (0 , n - 2 )); // Remove last row
49-
50- // Remove column i
51- for (arma::uword j = i; j < n - 1 ; j++) {
52- X.col (j) = X.col (j+1 ); // Shift all columns right of i to the left by one
53- }
54- X = X.cols (arma::span (0 ,n-2 )); // Remove last column
55-
56- return X;
57- }
5827
5928// ----------------------------------------------------------------------------|
6029// Add a row and column to a matrix (and fill with beta variables)
@@ -236,10 +205,10 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
236205 double logmarg;
237206
238207 // Generate a randomized order using Rcpp's sample function
239- arma::ivec indices = Rcpp::sample (no_variables, no_variables);
208+ arma::uvec indices = arma::randperm (no_variables); // arma::randperm() Generate a vector with a random permutation of integers from 0 to no_variables-1
240209
241- for (arma::uword idx = 0 ; idx < no_variables; ++idx ) {
242- arma::uword node = indices (idx) - 1 ; // Convert to zero-based index
210+ for (arma::uword idx = 0 ; idx < no_variables; idx++ ) {
211+ arma::uword node = indices (idx);
243212 old = cluster_assign (node);
244213
245214 arma::uvec cluster_size = table_cpp (cluster_assign);
@@ -250,15 +219,15 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
250219
251220 // Cluster sizes without node
252221 arma::uvec cluster_size_node = cluster_size;
253- cluster_size_node (old) -= (1 + dirichlet_alpha);
254222
255223 // Compute probabilities for sampling process
256- arma::vec cluster_prob (no_clusters + 1 );
257- for (arma::uword c = 0 ; c <= no_clusters; c++) {
224+ arma::vec cluster_prob (no_clusters + 1 );
225+ for (arma::uword c = 0 ; c <= no_clusters; c++) {
258226 arma::uvec cluster_assign_tmp = cluster_assign;
259227 cluster_assign_tmp (node) = c;
260228
261- if (c < no_clusters) {
229+ if (c < no_clusters) {
230+ if (c != old){
262231 loglike = log_likelihood_mfm_sbm (cluster_assign_tmp,
263232 block_probs,
264233 indicator,
@@ -267,6 +236,11 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
267236
268237 prob = (static_cast <double >(dirichlet_alpha) + static_cast <double >(cluster_size_node (c))) *
269238 std::exp (loglike);
239+ }
240+ else { // if old group, the probability is set to 0.0
241+ prob = 0.0 ;
242+ }
243+
270244 } else {
271245 logmarg = log_marginal_mfm_sbm (cluster_assign_tmp,
272246 indicator,
@@ -283,21 +257,22 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
283257 cluster_prob (c) = prob;
284258 }
285259
286-
287260 // Choose the cluster number for node
288261 cluster = sample_cluster (cluster_prob);
289262
290- // Remove the empty cluster
263+ // if the sampled cluster is the new added cluster or the old one
291264 if (cluster == no_clusters) {
292- cluster_assign (node) = old;
293- } else {
265+ cluster_assign (node) = old; // new cluster takes the place of the older singleton but doesn't update probabilities, they are kept the same as the old ones
266+ } else { // otherwise remove old (singleton) empty cluster, redefine cluster_assign and block_probs
294267 cluster_assign (node) = cluster;
295268 for (arma::uword i = 0 ; i < no_variables; i++) {
296269 if (cluster_assign (i) > old) {
297270 cluster_assign (i) -= 1 ;
298271 }
299272 }
300- block_probs = remove_row_col_matrix (block_probs, old);
273+ // removing row and col index 'old' from block_probs
274+ block_probs.shed_row (old);
275+ block_probs.shed_col (old);
301276 }
302277 } else {
303278 // Cluster sizes without node
@@ -309,7 +284,6 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
309284 for (arma::uword c = 0 ; c <= no_clusters; c++) {
310285 arma::uvec cluster_assign_tmp = cluster_assign;
311286 cluster_assign_tmp (node) = c;
312-
313287 if (c < no_clusters) {
314288 loglike = log_likelihood_mfm_sbm (cluster_assign_tmp,
315289 block_probs,
@@ -329,7 +303,7 @@ arma::uvec block_allocations_mfm_sbm(arma::uvec cluster_assign,
329303
330304 prob = static_cast <double >(dirichlet_alpha) *
331305 std::exp (logmarg) *
332- std::exp (log_Vn (no_clusters) - log_Vn (no_clusters - 1 ));
306+ std::exp (log_Vn (no_clusters) - log_Vn (no_clusters- 1 ));
333307 }
334308
335309 cluster_prob (c) = prob;
0 commit comments