fn iterate_cnm_communities()

in src/dachshund/algorithms/cnm_communities.rs [160:265]


    fn iterate_cnm_communities(
        &self,
        state: CNMCommunityIntermediaryState,
    ) -> CNMCommunityIntermediaryState {
        let mut communities = state.communities;
        let mut degree_map = state.degree_map;
        let mut delta_q_bmap = state.delta_q_bmap;
        let mut delta_q_maxheap = state.delta_q_maxheap;
        let mut maxh = state.maxh;
        let num_edges = state.num_edges;

        // find largest delta_q_ij
        let (_largest_delta_q_ij, i, j) = maxh.pop().unwrap().tuple();

        // we will create community j from communities i and j
        let com_i: Community = communities.remove(&i).unwrap();
        let com_j: &mut Community = communities.get_mut(&j).unwrap();
        com_j.extend(com_i);

        // get communities to which com_i, com_j are connected
        let neighbors_i: HashMap<usize, f64> = delta_q_bmap.remove(&i).unwrap();
        let neighbors_j: HashMap<usize, f64> = delta_q_bmap.remove(&j).unwrap();
        let mut all_neighbors: HashSet<usize> = neighbors_i.keys().copied().collect();

        all_neighbors.extend(neighbors_j.keys().copied());
        all_neighbors.remove(&i);
        all_neighbors.remove(&j);

        let mut new_delta_qjk_map: HashMap<usize, f64> = HashMap::new();
        let mut new_community_maxheap: CNMCommunityMergeInstructionHeap = BinaryHeap::new();
        for k in all_neighbors {
            let delta_qik: Option<&f64> = neighbors_i.get(&k);
            let delta_qjk: Option<&f64> = neighbors_j.get(&k);

            /* Get new delta_qjk */
            let new_delta_qjk = match delta_qik {
                Some(x) => match delta_qjk {
                    Some(y) => x + y,
                    None => {
                        x - (degree_map[&j] as f64 / num_edges as f64)
                            * (degree_map[&k] as f64 / (2 * num_edges) as f64)
                    }
                },
                None => {
                    delta_qjk.unwrap()
                        - (degree_map[&i] as f64 / num_edges as f64)
                            * (degree_map[&k] as f64 / (2 * num_edges) as f64)
                }
            };
            new_delta_qjk_map.insert(k, new_delta_qjk);

            /* Update the binary maps for k */
            let neighbors_k: &mut HashMap<usize, f64> = delta_q_bmap.get_mut(&k).unwrap();
            if delta_qik.is_some() {
                neighbors_k.remove(&i);
            }
            neighbors_k.insert(j, new_delta_qjk);

            /* Update the binary heap for k */
            let old_maxheap: CNMCommunityMergeInstructionHeap = delta_q_maxheap.remove(&k).unwrap();
            let mut new_maxheap: CNMCommunityMergeInstructionHeap =
                BinaryHeap::with_capacity(old_maxheap.len());
            for el in old_maxheap.into_iter_sorted() {
                let ll = el.j;

                if ll != i {
                    if ll == j {
                        new_maxheap.push(CNMCommunityMergeInstruction::new(
                            OrderedFloat(new_delta_qjk),
                            k,
                            ll,
                        ));
                    } else {
                        new_maxheap.push(el);
                    }
                }
            }
            delta_q_maxheap.insert(k, new_maxheap);
            new_community_maxheap.push(CNMCommunityMergeInstruction::new(
                OrderedFloat(new_delta_qjk),
                j,
                k,
            ));
        }
        // adding the new_delta_qjk map for the newly created community
        delta_q_bmap.insert(j, new_delta_qjk_map);
        delta_q_bmap.remove(&i);
        // updating the delta_q_maxheap
        delta_q_maxheap.insert(j, new_community_maxheap);
        delta_q_maxheap.remove(&i);

        // updating the degree map
        let new_degree = degree_map[&i] + degree_map[&j];
        degree_map.insert(j, new_degree);
        degree_map.remove(&i);

        maxh = self.get_max_maxheap(&delta_q_maxheap);
        CNMCommunityIntermediaryState {
            communities,
            degree_map,
            delta_q_bmap,
            delta_q_maxheap,
            maxh,
            num_edges,
        }
    }