/*please excuse the multiple uses of the same letters: A,D, etc.*/ void assignDownWeightsUp(edge *etest, node *vtest, node *va, edge *back, node *cprev, double oldD_AB, double coeff, double **A, double ***swapWeights) { edge *par, *sib, *skew; double D_AC, D_BD, D_AB, D_CD; par = etest->tail->parentEdge; skew = siblingEdge(etest); if (NULL == back) /*first recursive call*/ { if (NULL == par) return; else /*start the process of assigning weights recursively*/ { assignDownWeightsUp(par,vtest,va,etest,va,A[va->index][vtest->index],0.5,A,swapWeights); assignDownWeightsSkew(skew,vtest,va,etest,va,A[va->index][vtest->index],0.5,A,swapWeights); } } else /*second or later recursive call*/ { sib = siblingEdge(back); D_BD = A[vtest->index][etest->head->index]; /*straightforward*/ D_CD = A[sib->head->index][etest->head->index]; /*this one too*/ D_AC = A[sib->head->index][back->head->index] + coeff*(A[sib->head->index][va->index] - A[sib->head->index][vtest->index]); D_AB = 0.5*(oldD_AB + A[vtest->index][cprev->index]); swapWeights[0][vtest->index][etest->head->index] = swapWeights[0][vtest->index][back->head->index] + (D_AC + D_BD - D_AB - D_CD); if (NULL != par) { assignDownWeightsUp(par,vtest,va,etest,sib->head,D_AB,0.5*coeff,A,swapWeights); assignDownWeightsSkew(skew,vtest,va,etest,sib->head,D_AB,0.5*coeff,A,swapWeights); } } }
/* Assigns values to array swapWeights * swapWeights[0][j][k] will be the value of removing the tree below the * edge whose head node has index j and reattaching it to split the edge * whose head has the index k * swapWeights[1][j][k] will be the value of removing the tree above the * edge whose head node has index j and reattaching it to split the edge * whose head has the index k */ void assignSPRWeights (node *vtest, double **A, double ***swapWeights) { edge *etest, *left, *right, *sib, *par; etest = vtest->parentEdge; left = vtest->leftEdge; right = vtest->rightEdge; par = etest->tail->parentEdge; sib = siblingEdge (etest); if (NULL != par) assignDownWeightsUp (par, vtest, sib->head, NULL, NULL, 0.0, 1.0, A, swapWeights); if (NULL != sib) assignDownWeightsSkew (sib, vtest, sib->tail, NULL, NULL, 0.0, 1.0, A, swapWeights); /* Assigns values for moving subtree rooted at vtest, starting with * edge parental to tail of edge parental to vtest */ if (NULL != left) { assignUpWeights (left, vtest, right->head, NULL, NULL, 0.0, 1.0, A, swapWeights); assignUpWeights (right, vtest, left->head, NULL, NULL, 0.0, 1.0, A, swapWeights); } return; }