I was comparing MPL function performance with the Java version. I set the parameter to match Java version, and it is much faster (8.8h to 18 minutes; great!). The results agree on all the tree cases (r=0), but disagree on all the r=1 cases, and the distance to the ground truth is slightly worse with PhyNetPy. I used Claude to help me summarize some differences in the two versions' implementations:
- What "1 iteration" actually does:
Java "round" = pick a topology move + run a Brent line search on each affected branch (_maxTryPerBranch = 100 Brent iters per branch) to find a locally-optimal branch length under that topology, then accept/reject.
PhyNetPy "iter" = pick ONE proposal from {SPR, ChangeNodeHeight, ChangeInheritanceProb, AddRetic, RemoveRetic, FlipRetic, RelocateRetic, ChangeReticSource, ChangeReticDest}, perturb, accept/reject. No bundled Brent line search.
- Branch-length optimization is different.
Java: no separate "optimize node heights" move — branch lengths are tuned by Brent during every round. Only optimizes internal edges.
PhyNetPy: has ChangeNodeHeight as an explicit move competing for selection probability with topology moves. Roughly only ~1/9 of iterations actually move branch lengths. PhyNetPy seems to optimize all edges, including leaf edges.
It would be nice to see what causes the distance to be slightly worse for r=1.
I was comparing MPL function performance with the Java version. I set the parameter to match Java version, and it is much faster (8.8h to 18 minutes; great!). The results agree on all the tree cases (r=0), but disagree on all the r=1 cases, and the distance to the ground truth is slightly worse with PhyNetPy. I used Claude to help me summarize some differences in the two versions' implementations:
Java "round" = pick a topology move + run a Brent line search on each affected branch (_maxTryPerBranch = 100 Brent iters per branch) to find a locally-optimal branch length under that topology, then accept/reject.
PhyNetPy "iter" = pick ONE proposal from {SPR, ChangeNodeHeight, ChangeInheritanceProb, AddRetic, RemoveRetic, FlipRetic, RelocateRetic, ChangeReticSource, ChangeReticDest}, perturb, accept/reject. No bundled Brent line search.
Java: no separate "optimize node heights" move — branch lengths are tuned by Brent during every round. Only optimizes internal edges.
PhyNetPy: has ChangeNodeHeight as an explicit move competing for selection probability with topology moves. Roughly only ~1/9 of iterations actually move branch lengths. PhyNetPy seems to optimize all edges, including leaf edges.
It would be nice to see what causes the distance to be slightly worse for r=1.