/* Takes two lists sorted in increasing order, and splices their nodes together to make one big sorted list which is returned. */ struct node* SortedMerge(struct node* a, struct node* b) { struct node dummy; // a dummy first node to hang the result on struct node* tail = &dummy; // Points to the last result node -- // so tail->next is the place to add // new nodes to the result. dummy.next = NULL; while (1) { if (a == NULL) { // if either list runs out, use the other list tail->next = b; break; } else if (b == NULL) { tail->next = a; break; } if (a->data <= b->data) { MoveNode(&(tail->next), &a); } else { MoveNode(&(tail->next), &b); } tail = tail->next; } return(dummy.next); }
int main(int argc, char *arg[]) { struct node* listA = NULL; Push(&listA, 3); Push(&listA, 2); Push(&listA, 1); struct node* listB = NULL; Push(&listB, 6); Push(&listB, 5); Push(&listB, 4); printf("List A\n"); PrintList(listA); printf("List B\n"); PrintList(listB); MoveNode(&listA, &listB); printf("List A\n"); PrintList(listA); printf("List B\n"); PrintList(listB); MoveNode(&listA, &listB); printf("List A\n"); PrintList(listA); printf("List B\n"); PrintList(listB); }
// Swaps positions of nodes in the list void GaTreeBase::SwapNodes(GaTreeNodeBase* node1, GaTreeNodeBase* node2) { GaTreeNodeBase* parent1 = node1->GetParent(); GaTreeNodeBase* parent2 = node2->GetParent(); // get positions of nodes in their parent's children list int position1 = parent1->GetChildren()->GetPosition( node1 ); int position2 = parent2->GetChildren()->GetPosition( node2 ); // move the first node MoveNode( node1, parent2, position2 ); try { // move the second node MoveNode( node2, parent1, position1 ); } catch( ... ) { // if moveing second node fails - place back the first node MoveNode( node1, parent1, position1 ); throw; } }
struct Node* Merge(struct Node *a, struct Node *b) { struct Node dummy; struct Node* tail = NULL; tail = &dummy; dummy.next = NULL; while(1){ if (a == NULL){ tail->next = b; break; }else if (b == NULL){ tail->next = a; break; } if (a->data <= b->data){ MoveNode(&(tail->next), &a); } else{ MoveNode(&(tail->next), &b); } tail=tail->next; } return (dummy.next); }
struct node *ShuffleMerge (struct node *a, struct node *b) { struct node *temp = NULL; struct node **tpos = &temp; struct node *aa = a; struct node *bb = b; while (1) { if (aa == 0) { *tpos = bb; break; } else if (bb == 0) { *tpos = aa; break; } MoveNode(tpos, &aa); tpos = &((*tpos)->next); MoveNode(tpos, &bb); tpos = &((*tpos)->next); } return temp; }
bool OperCFThread::Move(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath) { if (list->Count()<=0) return true; FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); FSStat st; int ret_error; int r = destFs->Stat(__destPath, &st, &ret_error, Info()); if (r == -2) return false; if (list->Count()>1) { //если файлов >1 то копировать можно только в каталог if (r) { RedMessage( _LT("Can't move files, bad destination directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!st.IsDir()) { RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } for (FSNode *node = list->First(); node; node = node->next) { srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); //printf("MOVE '%s'\n", srcPath.GetUtf8()); if (!MoveNode(srcFs, srcPath, node, destFs, destPath)) return false; } } else { // 1 element if (r && !destFs->IsENOENT(ret_error)) { RedMessage( _LT("Can't move to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!r && st.IsDir()) destPath.SetItemStr(destPos, list->First()->Name()); FSNode *node = list->First(); srcPath.SetItemStr(srcPos, list->First()->Name()); if (!MoveNode(srcFs, srcPath, list->First(), destFs, destPath)) return false; } return true; }
void AlternatingSplit(struct node* source,struct node** aRef, struct node** bRef) { while(source != NULL) { MoveNode(aRef, &source); if(source != NULL) MoveNode(bRef, &source); } print_linked_list("aRef", aRef); print_linked_list("bRef", bRef); }
void AlternatingSplit( struct node* source, struct node** aRef, struct node** bRef ) { struct node* a = NULL; struct node* b = NULL; struct node* current = source; while ( current != NULL ) { MoveNode( &a, ¤t ); if ( current != NULL ) { MoveNode( &b, ¤t ); } } *aRef = a; *bRef = b; }
/* Given the source list, split its nodes into two shorter lists. If we number the elements 0, 1, 2, ... then all the even elements should go in the first list, and all the odd elements in the second. The elements in the new lists may be in any order. */ void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef) { struct node* a = NULL; // Split the nodes to these 'a' and 'b' lists struct node* b = NULL; struct node* current = source; while (current != NULL) { MoveNode(&a, ¤t); // Move a node to 'a' if (current != NULL) { MoveNode(&b, ¤t); // Move a node to 'b' } } *aRef = a; *bRef = b; }
void AlternatingSplit (struct node *source, struct node **aRef, struct node **bRef) { struct node *temp = source; struct node *a = NULL; struct node *b = NULL; while (temp != 0) { MoveNode(&a , &temp); if (temp != 0) MoveNode(&b, &temp); } *aRef = a; *bRef = b; }
// 11 — MoveNode() void MoveNodeTest() { struct node* a = BuildOneTwoThree(); // the list {1, 2, 3} struct node* b = BuildOneTwoThree(); MoveNode(&a, &b); // a == {1, 1, 2, 3} // b == {2, 3} }
static void Reverse2(struct node** headRef) { struct node* result = NULL; struct node* current = *headRef; while (current != NULL) { MoveNode(&result, ¤t); } *headRef = result; }
void MoveNodeTest() { struct node* a = BuildOneTwoThree(); struct node* b = BuildOneTwoThree(); display(a); display(b); MoveNode(&a, &b); display(a); display(b); }
void AlternatingSplit2(struct node* source, struct node** aRef, struct node** bRef) { struct node aDummy; struct node* aTail = &aDummy; // points to the last node in 'a' struct node bDummy; struct node* bTail = &bDummy; // points to the last node in 'b' struct node* current = source; aDummy.next = NULL; bDummy.next = NULL; while (current != NULL) { MoveNode(&(aTail->next), ¤t); // add at 'a' tail aTail = aTail->next; // advance the 'a' tail if (current != NULL) { MoveNode(&(bTail->next), ¤t); bTail = bTail->next; } } *aRef = aDummy.next; *bRef = bDummy.next; }
// SuffleMerge() — Local References // Uses a local reference to get rid of the dummy nodes entirely. struct node* ShuffleMerge3(struct node* a, struct node* b) { struct node* result = NULL; struct node** lastPtrRef = &result; while (1) { if (a==NULL) { *lastPtrRef = b; break; } else if (b==NULL) { *lastPtrRef = a; break; } else { MoveNode(lastPtrRef, &a); lastPtrRef = &((*lastPtrRef)->next); MoveNode(lastPtrRef, &b); lastPtrRef = &((*lastPtrRef)->next); } } return(result); }
void AlternatingSplit2(struct node* source, struct node** aRef, struct node** bRef){ struct node dummy_a; struct node* pa = &dummy_a; struct node dummy_b; struct node* pb = &dummy_b; struct node* current = source; pa->next = NULL; pb->next = NULL; while(current != NULL){ MoveNode(&(pa->next), ¤t); pa = pa->next; if (current != NULL){ MoveNode(&(pb->next), ¤t); pb = pb->next; } } *aRef = dummy_a.next; *bRef = dummy_b.next; }
// SuffleMerge() — Dummy Node Using MoveNode() // Basically the same as above, but use MoveNode(). struct node* ShuffleMerge2(struct node* a, struct node* b) { struct node dummy; struct node* tail = &dummy; dummy.next = NULL; while (1) { if (a==NULL) { tail->next = b; break; } else if (b==NULL) { tail->next = a; break; } else { MoveNode(&(tail->next), &a); tail = tail->next; MoveNode(&(tail->next), &b); tail = tail->next; } } return(dummy.next); }
struct node* SortedMerge(struct node* a, struct node* b) { struct node dummy; struct node *head = &dummy; dummy.next = NULL; while(1) { print_linked_list("a",&a); print_linked_list("b",&b); print_linked_list("head",&dummy.next); if(a == NULL) { head->next = b; break; } if(b == NULL) { head->next = a; break; } if(a->data <= b->data) { printf("a <= b\n"); MoveNode(&head->next, &a); } else { printf("a > b\n"); MoveNode(&head->next, &b); } head = head->next; } return dummy.next; }
/*----------Sorted Merge------------*/ struct node* SortedMerge(struct node* a, struct node *b){ struct node* merged = NULL; while(( a != NULL) || (b != NULL)) { if((a != NULL) && (b != NULL)) { if(a->data < b->data) MoveNode(&merged, &a); else if(a->data > b->data) MoveNode(&merged, &b); else { MoveNode(&merged, &b); a = a->next; } } else if(a != NULL) MoveNode(&merged, &a); else if(b != NULL) MoveNode(&merged, &b); } return merged; }
struct node* SortedMerge2(struct node* a, struct node* b) { struct node* result = NULL; struct node** lastPtrRef = &result; // point to the last result pointer while (1) { if (a==NULL) { *lastPtrRef = b; break; } else if (b==NULL) { *lastPtrRef = a; break; } if (a->data <= b->data) { MoveNode(lastPtrRef, &a); } else { MoveNode(lastPtrRef, &b); } lastPtrRef = &((*lastPtrRef)->next); // tricky: advance to point to // the next ".next" field } return(result); }
Node* MergeLists(Node *a, Node* b) { /* a dummy first node to hang the result on */ Node dummy; /* tail points to the last result node */ Node* tail = &dummy; /* so tail->next is the place to add new nodes to the result. */ dummy.next = NULL; while(1) { if(a == NULL) { /* if either list runs out, use the other list */ tail->next = b; break; } else if (b == NULL) { tail->next = a; break; } if (a->data <= b->data) { MoveNode(&(tail->next), &a); } else { MoveNode(&(tail->next), &b); } tail = tail->next; } return(dummy.next); }
/* * @func: split the origianal list into two list in alternating way. Given the source list, split its nodes into two shorter lists. If we number the elements 0, 1, 2, ... then all the even elements should go in the first list, and all the odd elements in the second. The elements in the new lists may be in any order. */ void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef){ // here is error case, In order to return the pointer, // the address of node must be passed into MoveNode(). struct node* current = source; while (current != NULL){ MoveNode(bRef, ¤t); if (current->next != NULL){ MoveNode(aRef, &(source->next)); } current = current->next->next; } // here is correct version. but, the lists are reverse order. struct node* a = NULL; struct node* b = NULL; while (current != NULL){ MoveNode(&a, ¤t); if (current != NULL){ MoveNode(&b, ¤t); } *aRef = a; *bRef = b; } }
struct node* ShuffleMerge(struct node* a, struct node* b) { struct node dummy; struct node *head = &dummy; dummy.next = NULL; while((a != NULL) || (b != NULL)) { if(a != NULL) { MoveNode(&head->next, &a); head = head->next; } if(b != NULL) { MoveNode(&head->next, &b); head = head->next; } } return dummy.next; }
void TurretManager::UpdateNodes() { for (int i = nodes.size() - 1; i >= 0; i--) { auto node = nodes[i]; node->MoveNode(orbit01Angle, orbit02Angle); if (node->GetTrue()) { nodes[i]->AddTag("Construct"); AddTurretButtons(); //if (node->GetOrbit() == 1) //CreateTurret(node->GetOrbitPos() + 1, node->GetOrbit(), node->GetOrbitPos()); //else //CreateTurret(1, node->GetOrbit(), node->GetOrbitPos()); //RemoveChild(node); //nodes.erase(nodes.begin() + i); Not necessary anymore since we can just hide the nodes UI = true; } } }
/** * @brief 新たな候補手を一手設定します。 */ void MoveNodeList::add_move(Move move) { m_nodeList.push_back(MoveNode(move)); }
/* --------------------------------------------------------------------- Do a Monte Carlo step for the prediction of missing links. Each "step" involves nnod independent attempts to move a single node. --------------------------------------------------------------------- */ void LSMCStepMB_OD(int factor, double *H, double linC, struct node_gra **nlist, struct group **glist, struct group *part, int nnod, int **G2G, int *n2gList, double **LogChooseList, int LogChooseListSize, double *LogFactList, int LogFactListSize, double *HarmonicList, gsl_rng *gen) { double dH; struct group *g, *oldg, *newg; int dice, oldgnum, newgnum, n2g, oldg2g, newg2g, ng, noldg, nnewg; struct node_gra *node; int n2oldg, n2newg, newg2oldg, oldg2oldg, newg2newg; int r, l; int i, j, ngroup=nnod; int move; int effectng=0; for (move=0; move<nnod*factor; move++) { /* Choose node and destination group */ dice = floor(gsl_rng_uniform(gen) * (double)nnod); node = nlist[dice]; oldgnum = node->inGroup; do { newgnum = floor(gsl_rng_uniform(gen) * (double)nnod); } while (newgnum == oldgnum); oldg = glist[oldgnum]; newg = glist[newgnum]; /* Calculate the change of energy */ dH = 0.0; noldg = oldg->size; nnewg = newg->size; if (noldg == 1) /* number of groups would decrease by one */ dH -= linC; if (nnewg == 0) /* number of groups would increase by one */ dH += linC; n2oldg = NLinksToGroup(node, oldg); n2newg = NLinksToGroup(node, newg); newg2oldg = NG2GLinks(newg, oldg); oldg2oldg = oldg->inlinks; newg2newg = newg->inlinks; g = part; effectng = 0; while ((g = g->next) != NULL) { if (g->size > 0) { /* group is not empty */ effectng++; n2gList[g->label] = NLinksToGroup(node, g); if (g->label == oldg->label) { /* old conf, oldg-oldg */ r = noldg * (noldg - 1) / 2; l = oldg2oldg; dH -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-oldg */ r = (noldg - 1) * (noldg - 2) / 2; l = oldg2oldg - n2oldg; dH += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-oldg */ r = nnewg * noldg; l = newg2oldg; dH -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-oldg */ r = (nnewg + 1) * (noldg - 1); l = newg2oldg + n2oldg - n2newg; dH += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } else if (g->label == newg->label) { /* old conf, newg-newg */ r = nnewg * (nnewg - 1) / 2; l = newg2newg; dH -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-newg */ r = (nnewg + 1) * nnewg / 2; l = newg2newg + n2newg; dH += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } else { n2g = n2gList[g->label]; oldg2g = G2G[oldg->label][g->label]; newg2g = G2G[newg->label][g->label]; ng = g->size; /* old conf, oldg-g */ r = noldg * ng; l = oldg2g; dH -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-g */ r = (noldg - 1) * ng; l = oldg2g - n2g; dH += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-g */ r = nnewg * ng; l = newg2g; dH -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-g */ r = (nnewg + 1) * ng; l = newg2g + n2g; dH += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } } else { /* group is empty */ n2gList[g->label] = 0.0; } } /* Labeled-groups sampling correction */ if (noldg == 1 && nnewg != 0) { // effectng would decrease by one dH -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dH += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize); dH += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1); } else if (noldg != 1 && nnewg == 0) { // effectng would increase by one dH -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dH += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize); dH += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1); } /* Metropolis rule */ if ((dH <= 0.0) || (gsl_rng_uniform(gen) < exp(-dH))) { /* accept move */ MoveNode(node, oldg, newg); *H += dH; /* update G2G */ for (i=0; i<nnod; i++) { G2G[i][oldgnum] -= n2gList[i]; G2G[oldgnum][i] = G2G[i][oldgnum]; G2G[i][newgnum] += n2gList[i]; G2G[newgnum][i] = G2G[i][newgnum]; } } } /* nnod moves completed: done! */ }
/* --------------------------------------------------------------------- Do a Gibbs Monte Carlo step for the prediction of missing links. --------------------------------------------------------------------- */ void GibbsLinkScoreStepMB_OD(double *H, double linC, struct node_gra **nlist, struct group **glist, struct group *part, int nnod, int **G2G, int *n2gList, double **LogChooseList, int LogChooseListSize, double *LogFactList, int LogFactListSize, double *HarmonicList, gsl_rng *gen) { double *dH; struct group *g, *oldg, *newg; int oldgnum, newgnum, n2g, oldg2g, newg2g, ng, noldg, nnewg; struct node_gra *node; int n2oldg, n2newg, newg2oldg, oldg2oldg, newg2newg; int r, l; int i, j, ngroup=nnod; int move; int effectng; /* Shortlist of groups. Groups not in this list are empty for sure. Note that, during a step, we may have to add groups to this list (groups that were initially empty but got filled) but we never remove groups from it (even if they loose all their nodes during a step). slgXsize is the size of slgX. */ int *slg=NULL; int slgn, slgsize, isinlist; int newgn, target; double dice, norm, dHempty, cum; double Href; /* Preliminaries */ dH = allocate_d_vec(nnod); slg = allocate_i_vec(nnod); // Shortlist of groups slgsize = 0; g = part; while ((g=g->next) != NULL) if (g->size > 0) slg[slgsize++] = g->label; /* Steps */ for (move=0; move<nnod; move++) { node = nlist[move]; oldgnum = node->inGroup; oldg = glist[oldgnum]; norm = 0.0; /* Loop over destination groups */ for (newgn=0; newgn<slgsize; newgn++) { newgnum = slg[newgn]; newg = glist[newgnum]; if (newgnum != oldgnum) { /* Calculate the change of energy */ dH[newgnum] = 0.0; noldg = oldg->size; nnewg = newg->size; if (noldg == 1) /* number of groups would decrease by one */ dH[newgnum] -= linC; if (nnewg == 0) /* number of groups would increase by one */ dH[newgnum] += linC; n2oldg = NLinksToGroup(node, oldg); n2newg = NLinksToGroup(node, newg); newg2oldg = NG2GLinks(newg, oldg); oldg2oldg = oldg->inlinks; newg2newg = newg->inlinks; effectng = 0; for (slgn=0; slgn<slgsize; slgn++) { g = glist[slg[slgn]]; if (g->size > 0) { /* group is not empty */ effectng++; n2gList[g->label] = NLinksToGroup(node, g); if (g->label == oldg->label) { /* old conf, oldg-oldg */ r = noldg * (noldg - 1) / 2; l = oldg2oldg; dH[newgnum] -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-olg */ r = (noldg - 1) * (noldg - 2) / 2; l = oldg2oldg - n2oldg; dH[newgnum] += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-oldg */ r = nnewg * noldg; l = newg2oldg; dH[newgnum] -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-oldg */ r = (nnewg + 1) * (noldg - 1); l = newg2oldg + n2oldg - n2newg; dH[newgnum] += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } else if (g->label == newg->label) { /* old conf, newg-newg */ r = nnewg * (nnewg - 1) / 2; l = newg2newg; dH[newgnum] -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-olg */ r = (nnewg + 1) * nnewg / 2; l = newg2newg + n2newg; dH[newgnum] += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } else { n2g = n2gList[g->label]; oldg2g = G2G[oldg->label][g->label]; newg2g = G2G[newg->label][g->label]; ng = g->size; /* old conf, oldg-g */ r = noldg * ng; l = oldg2g; dH[newgnum] -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-g */ r = (noldg - 1) * ng; l = oldg2g - n2g; dH[newgnum] += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-g */ r = nnewg * ng; l = newg2g; dH[newgnum] -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-g */ r = (nnewg + 1) * ng; l = newg2g + n2g; dH[newgnum] += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } } else { /* group is empty */ n2gList[g->label] = 0.0; } } /* Labeled-groups sampling correction */ if (noldg == 1 && nnewg != 0) { // effectng would decrease by one dH[newgnum] -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dH[newgnum] += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize); dH[newgnum] += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1); } else if (noldg != 1 && nnewg == 0) { // effectng would increase by one dH[newgnum] -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dH[newgnum] += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize); dH[newgnum] += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1); } } else { // oldg and newg are the same: nothing changes dH[newgnum] = 0.0; } norm += exp(-dH[newgnum]); } /** Calculate the change of energy to go to an empty group **/ dHempty = 0.0; nnewg = 0; if (noldg == 1) /* number of groups would decrease by one */ dHempty -= linC; if (nnewg == 0) /* number of groups would increase by one */ dHempty += linC; n2newg = 0; newg2oldg = 0; newg2newg = 0; for (slgn=0; slgn<slgsize; slgn++) { g = glist[slg[slgn]]; if (g->size > 0) { /* group is not empty */ if (g->label == oldg->label) { /* old conf, oldg-oldg */ r = noldg * (noldg - 1) / 2; l = oldg2oldg; dHempty -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-olg */ r = (noldg - 1) * (noldg - 2) / 2; l = oldg2oldg - n2oldg; dHempty += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-oldg */ r = nnewg * noldg; l = newg2oldg; dHempty -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-oldg */ r = (nnewg + 1) * (noldg - 1); l = newg2oldg + n2oldg - n2newg; dHempty += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } else { n2g = n2gList[g->label]; oldg2g = G2G[oldg->label][g->label]; newg2g = 0; ng = g->size; /* old conf, oldg-g */ r = noldg * ng; l = oldg2g; dHempty -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, oldg-g */ r = (noldg - 1) * ng; l = oldg2g - n2g; dHempty += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* old conf, newg-g */ r = nnewg * ng; l = newg2g; dHempty -= log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/ /* new conf, newg-g */ r = (nnewg + 1) * ng; l = newg2g + n2g; dHempty += log(r + 1) + FastLogChoose(r, l, LogChooseList, LogChooseListSize); /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/ } } } /* Labeled-groups sampling correction */ if (noldg == 1 && nnewg != 0) { // effectng would decrease by one dHempty -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dHempty += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize); dHempty += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1); } else if (noldg != 1 && nnewg == 0) { // effectng would increase by one dHempty -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize); dHempty += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize); dHempty += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1); } norm += exp(-dHempty) * (double)(nnod - slgsize); /** CHOOSE THE MOVE **/ dice = norm * gsl_rng_uniform(gen); if (dice > (norm - (double)(nnod - slgsize) * exp(-dHempty))) { /* Select an empty group */ newg = GetEmptyGroup(part); newgnum = newg->label; dH[newgnum] = dHempty; } else { /* Select group in shortlist */ target = 0; cum = 0.0; while (cum < dice) { cum += exp(-dH[slg[target++]]); } newgnum = slg[target - 1]; newg = glist[newgnum]; } /* MAKE THE MOVE AND UPDATE MATRICES */ MoveNode(node, oldg, newg); *H += dH[newgnum]; /* update G2G */ for (slgn=0; slgn<slgsize; slgn++) { G2G[slg[slgn]][oldgnum] -= n2gList[slg[slgn]]; G2G[oldgnum][slg[slgn]] = G2G[slg[slgn]][oldgnum]; G2G[slg[slgn]][newgnum] += n2gList[slg[slgn]]; G2G[newgnum][slg[slgn]] = G2G[slg[slgn]][newgnum]; } /* Add newg to shortlist (if it's not there already!) */ isinlist = 0; for (slgn=0; slgn<slgsize; slgn++) if (newgnum == slg[slgn]) isinlist = 1; if (isinlist == 0) slg[slgsize++] = newgnum; } /* nnod moves completed: done! */ free_i_vec(slg); free_d_vec(dH); }