@@ -5130,7 +5130,7 @@ void cmaple::Tree::refreshUpperLR(const Index node_index,
51305130 PhyloNode& node,
51315131 const Index neighbor_index,
51325132 std::unique_ptr<SeqRegions>& replaced_regions,
5133- const SeqRegions& parent_upper_lr_lh) {
5133+ const std::unique_ptr< SeqRegions> & parent_upper_lr_lh) {
51345134 // recalculate the upper left/right lh of the current node
51355135 std::unique_ptr<SeqRegions> new_upper_lr_lh = nullptr ;
51365136 PhyloNode& neighbor = nodes[neighbor_index.getVectorIndex ()];
@@ -5139,13 +5139,96 @@ void cmaple::Tree::refreshUpperLR(const Index node_index,
51395139 // model, threshold_prob);
51405140 // parent_upper_lr_lh.mergeUpperLower<num_states>(new_upper_lr_lh,
51415141 // node->length, *lower_lh, next_node->length, aln, model, threshold_prob);
5142- parent_upper_lr_lh. mergeUpperLower <num_states>(
5142+ parent_upper_lr_lh-> mergeUpperLower <num_states>(
51435143 new_upper_lr_lh, node.getUpperLength (), *lower_lh,
51445144 neighbor.getUpperLength (), aln, model, params->threshold_prob );
51455145
51465146 // if the upper left/right lh is null -> try to increase the branch length
51475147 if (!new_upper_lr_lh) {
5148- if (neighbor.getUpperLength () <= 0 ) // next_node->length <= 0)
5148+ // update the latest version 0.7.1
5149+ if ((neighbor.getUpperLength () <= 0 ) && node.getUpperLength () <= 0 )
5150+ {
5151+ stack<Index> node_stack;
5152+ stack<Index> node_stack_unused;
5153+
5154+ // handle case where neighbor is the left child
5155+ if (node.getNeighborIndex (LEFT) == neighbor_index)
5156+ {
5157+ updateZeroBlength<num_states>(node_index, node, node_stack_unused);
5158+
5159+ if (node.getUpperLength () <= 0 )
5160+ {
5161+ updateZeroBlength<num_states>(neighbor_index, neighbor, node_stack_unused);
5162+
5163+ // update neighbor's side
5164+ neighbor.setOutdated (true );
5165+ node_stack.push (Index (neighbor_index.getVectorIndex (), TOP));
5166+ }
5167+ else
5168+ {
5169+ // update vector of regions at mid-branch point
5170+ bool update_blength = true ;
5171+ updateMidBranchLh<num_states>(node_index, node, parent_upper_lr_lh, node_stack_unused,
5172+ update_blength);
5173+
5174+ // update parent's side
5175+ const Index parent_index = node.getNeighborIndex (TOP);
5176+ PhyloNode& parent_node = nodes[parent_index.getVectorIndex ()];
5177+ parent_node.setOutdated (true );
5178+ node_stack.push (parent_index);
5179+ }
5180+ }
5181+ // handle case where neighbor is the right child
5182+ else
5183+ {
5184+ updateZeroBlength<num_states>(neighbor_index, neighbor, node_stack_unused);
5185+
5186+ if (neighbor.getUpperLength () <= 0 )
5187+ {
5188+ updateZeroBlength<num_states>(node_index, node, node_stack_unused);
5189+
5190+ // update parent's side
5191+ const Index parent_index = node.getNeighborIndex (TOP);
5192+ PhyloNode& parent_node = nodes[parent_index.getVectorIndex ()];
5193+ parent_node.setOutdated (true );
5194+ node_stack.push (parent_index);
5195+
5196+ // update vector of regions at mid-branch point
5197+ bool update_blength = true ;
5198+ updateMidBranchLh<num_states>(node_index, node, parent_upper_lr_lh, node_stack_unused,
5199+ update_blength);
5200+
5201+ // update partial lh up left/right of the current node which becomes outdated because the branch length of this node has changed
5202+ const Index other_neighbor_index = node.getNeighborIndex (LEFT);
5203+ PhyloNode& other_neighbor = nodes[other_neighbor_index.getVectorIndex ()];
5204+ const std::unique_ptr<SeqRegions>& other_neighbor_lower_lh = other_neighbor.getPartialLh (
5205+ TOP);
5206+ parent_upper_lr_lh->mergeUpperLower <num_states>(
5207+ node.getPartialLh (RIGHT), node.getUpperLength (), *other_neighbor_lower_lh,
5208+ other_neighbor.getUpperLength (), aln, model, params->threshold_prob );
5209+ }
5210+ else
5211+ {
5212+ // update neighbor's side
5213+ neighbor.setOutdated (true );
5214+ node_stack.push (Index (neighbor_index.getVectorIndex (), TOP));
5215+
5216+ }
5217+ }
5218+
5219+ // update partial lh up left/right of the current node
5220+ parent_upper_lr_lh->mergeUpperLower <num_states>(
5221+ replaced_regions, node.getUpperLength (), *lower_lh,
5222+ neighbor.getUpperLength (), aln, model, params->threshold_prob );
5223+
5224+ updatePartialLh<num_states>(node_stack);
5225+ } else {
5226+ throw std::logic_error (
5227+ " Strange, inconsistent upper left/right lh "
5228+ " creation in refreshAllNonLowerLhs()" );
5229+ }
5230+ // --- before 0.7.1 ---
5231+ /* if (neighbor.getUpperLength() <= 0) // next_node->length <= 0)
51495232 {
51505233 stack<Index> node_stack;
51515234 // updateZeroBlength<num_states>(next_node->neighbor, node_stack,
@@ -5162,7 +5245,8 @@ void cmaple::Tree::refreshUpperLR(const Index node_index,
51625245 throw std::logic_error(
51635246 "Strange, inconsistent upper left/right lh "
51645247 "creation in refreshAllNonLowerLhs()");
5165- }
5248+ }*/
5249+ // --- end before 0.7.1 ---
51665250 }
51675251 // otherwise, everything is good -> update upper left/right lh of the
51685252 // current node
@@ -5230,13 +5314,13 @@ void cmaple::Tree::refreshNonLowerLhsFromParent(Index& node_index,
52305314 // refreshUpperLR(node, next_node_2, next_node_1->partial_lh,
52315315 // *parent_upper_lr_lh);
52325316 refreshUpperLR<num_states>(node_index, node, neighbor_2_index,
5233- node.getPartialLh (RIGHT), * parent_upper_lr_lh);
5317+ node.getPartialLh (RIGHT), parent_upper_lr_lh);
52345318
52355319 // recalculate the SECOND upper left/right lh of the current node
52365320 // refreshUpperLR(node, next_node_1, next_node_2->partial_lh,
52375321 // *parent_upper_lr_lh);
52385322 refreshUpperLR<num_states>(node_index, node, neighbor_1_index,
5239- node.getPartialLh (LEFT), * parent_upper_lr_lh);
5323+ node.getPartialLh (LEFT), parent_upper_lr_lh);
52405324
52415325 // NHANLT: LOGS FOR DEBUGGING
52425326 /* if (params->debug)
0 commit comments