1
// FreeInternalNode.java
3
// (c) 1999-2004 PAL Development Core Team
5
// This package may be distributed under the
6
// terms of the Lesser GNU General Public License (LGPL)
8
package pal.treesearch;
11
* <p>Title: FreeInternalNode </p>
12
* <p>Description: A free internal node has three FreeBranches connected to it. </p>
13
* @author Matthew Goode
21
public class FreeInternalNode implements FreeNode {
22
private final FreeBranch[] connections_ = new FreeBranch[3];
23
private final FreeBranch[] markConnections_ = new FreeBranch[3];
25
private final PatternInfo[] patternInfos_;
26
private final boolean[] patternsValid_;
28
private static final int[] LEFT_LOOKUP = { 1 , 0, 0 };
29
private static final int[] RIGHT_LOOKUP = { 2 , 2, 1 };
31
// private final int index_;
32
private final UnconstrainedLikelihoodModel.Internal calculator_;
33
private boolean topologyChangedSinceLastFlat_ = true;
34
private boolean topologyChangedSincleLastExtended_ = true;
37
public FreeInternalNode(Node i, FreeBranch parentFreeBranch, GeneralConstructionTool tool, GeneralConstraintGroupManager.Store store) {
38
this.connections_[0] = parentFreeBranch;
39
this.connections_[1] = new FreeBranch(i.getChild(0),this, tool,store);
40
this.connections_[2] = new FreeBranch(i.getChild(1),this, tool,store);
41
this.patternsValid_ = new boolean[] { false, false, false};
43
this.calculator_ = tool.allocateNewFreeInternalCalculator();
44
final int numberOfSites = tool.getNumberOfSites();
45
this.patternInfos_ = new PatternInfo[] {
46
new PatternInfo( numberOfSites, true ),
47
new PatternInfo( numberOfSites, true ),
48
new PatternInfo( numberOfSites, true )
56
markConnections_[0] = connections_[0];
57
markConnections_[1] = connections_[1];
58
markConnections_[2] = connections_[2];
60
public void undoToMark() {
61
connections_[0] = markConnections_[0];
62
connections_[1] = markConnections_[1];
63
connections_[2] = markConnections_[2];
66
private final void topologyChanged() {
67
this.topologyChangedSinceLastFlat_ = true;
68
this.topologyChangedSincleLastExtended_ = true;
70
public boolean hasDirectConnection(FreeBranch c) {
71
for(int i = 0 ; i < connections_.length ; i++) {
72
if(connections_[i]==c) { return true; }
77
public boolean hasConnection(FreeBranch c, FreeBranch caller) {
78
for(int i = 0 ; i < connections_.length ; i++) {
79
if((connections_[i]==c)||(connections_[i]!=caller&&connections_[i].hasConnection(c,this))) {
86
// public final int getIndex() { return index_; }
87
public void testLikelihood(FreeBranch caller, GeneralConstructionTool tool) {
88
for(int i = 0 ; i < connections_.length ; i++) {
89
if(connections_[i]!=caller) {
90
connections_[i].testLikelihood(this,tool);
94
public void setConnectingBranches(FreeBranch[] store, int number){
96
throw new IllegalArgumentException("Must be three connections not:"+number);
98
System.arraycopy(store,0,connections_,0,3);
101
//Interchange related
102
public FreeBranch getLeftBranch(FreeBranch caller) {
103
return connections_[LEFT_LOOKUP[getCallerIndex(caller)]];
106
public FreeBranch getRightBranch(FreeBranch caller) {
107
return connections_[RIGHT_LOOKUP[getCallerIndex(caller)]];
109
public FreeBranch extract(FreeBranch caller) {
110
int callerIndex = getCallerIndex(caller);
111
FreeBranch left = connections_[LEFT_LOOKUP[callerIndex]];
112
FreeBranch right = connections_[RIGHT_LOOKUP[callerIndex]];
113
FreeNode rightNode = right.getOther(this);
114
left.swapNode(this,rightNode);
115
rightNode.swapConnection(right,left);
119
public void swapConnection(FreeBranch original, FreeNode nodeToReplace, FreeBranch newConnection) {
120
int index = getCallerIndex(original);
121
connections_[index] = newConnection;
122
newConnection.swapNode(nodeToReplace,this);
123
original.swapNode(this,nodeToReplace);
125
nodeToReplace.swapConnection(newConnection,original);
128
public void swapConnection(FreeBranch original,FreeBranch newConnection) {
129
int index = getCallerIndex(original);
130
connections_[index] = newConnection;
133
public PatternInfo getPatternInfo(GeneralConstructionTool tool, FreeBranch caller) {
134
return getPatternInfo( tool, getCallerIndex(caller));
137
private final PatternInfo getPatternInfo(final GeneralConstructionTool tool, final int callerIndex) {
139
if(!patternsValid_[callerIndex]) {
141
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
142
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
143
final FreeNode left = leftConnection.getOther(this);
144
final FreeNode right = rightConnection.getOther(this);
145
final PatternInfo leftPattern= left.getPatternInfo(tool,leftConnection);
146
final PatternInfo rightPattern= right.getPatternInfo(tool,rightConnection);
147
tool.build(patternInfos_[callerIndex],leftPattern, rightPattern);
148
patternsValid_[callerIndex] = true;
150
return patternInfos_[callerIndex];
153
public Node buildPALNodeES(double branchLength, FreeBranch caller) {
154
final int callerIndex = getCallerIndex(caller);
155
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
156
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
157
Node[] children = new Node[] {
158
leftConnection.buildPALNodeES(this), rightConnection.buildPALNodeES(this)
160
return NodeFactory.createNodeBranchLength(branchLength,children);
162
public Node buildPALNodeBase(double branchLength, FreeBranch caller) {
163
final int callerIndex = getCallerIndex(caller);
164
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
165
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
166
Node[] children = new Node[] {
167
leftConnection.buildPALNodeBase(this), rightConnection.buildPALNodeBase(this)
169
return NodeFactory.createNodeBranchLength(branchLength,children);
172
public String toString(FreeBranch caller) {
173
StringBuffer sb = new StringBuffer();
174
boolean printed = false;
175
for(int i = 0 ; i < connections_.length ; i++) {
176
if(connections_[i]!=caller) {
181
sb.append(connections_[i].toString(this));
184
return sb.toString();
187
public void getAllComponents(ArrayList store, Class componentType) {
188
getAllComponents(store, componentType, null);
190
public void getAllComponents(ArrayList store, Class componentType, FreeBranch caller) {
191
if(componentType.isAssignableFrom(getClass())) { store.add(this); }
192
for(int i = 0 ; i < connections_.length ; i++) {
193
if(connections_[i]!=caller) {
194
connections_[i].getAllComponents(store,componentType, this);
202
private final int getCallerIndex(FreeBranch caller) {
204
throw new IllegalArgumentException("getCallerIndex() called on null object");
206
if(caller==connections_[0]) { return 0; }
207
if(caller==connections_[1]) { return 1; }
208
if(caller==connections_[2]) { return 2; }
209
throw new IllegalArgumentException("Unknown caller");
214
public ConditionalProbabilityStore getLeftExtendedConditionalProbabilities( FreeBranch callingConnection, UnconstrainedLikelihoodModel.External external, ConditionalProbabilityStore resultStore, GeneralConstructionTool tool) {
215
final int callerIndex = getCallerIndex(callingConnection);
216
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
217
return leftConnection.getExtendedConditionalProbabilities(this,external, resultStore,tool);
219
public ConditionalProbabilityStore getRightExtendedConditionalProbabilities( FreeBranch callingConnection, UnconstrainedLikelihoodModel.External external, ConditionalProbabilityStore resultStore, GeneralConstructionTool tool) {
220
final int callerIndex = getCallerIndex(callingConnection);
221
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
222
return rightConnection.getExtendedConditionalProbabilities( this, external, resultStore,tool);
224
public PatternInfo getLeftPatternInfo(GeneralConstructionTool tool, FreeBranch caller) {
225
final int callerIndex = getCallerIndex(caller);
226
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
227
final FreeNode other = leftConnection.getOther(this);
228
return other.getPatternInfo(tool, leftConnection);
231
public PatternInfo getRightPatternInfo(GeneralConstructionTool tool, FreeBranch caller) {
232
final int callerIndex = getCallerIndex(caller);
233
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
234
final FreeNode other = rightConnection.getOther(this);
235
return other.getPatternInfo(tool, rightConnection);
239
public ConditionalProbabilityStore getFlatConditionalProbabilities( final FreeBranch callerConnection, UnconstrainedLikelihoodModel.External externalCalculator, ConditionalProbabilityStore resultStore, GeneralConstructionTool tool) {
240
final int callerIndex = getCallerIndex(callerConnection);
241
final PatternInfo pi = getPatternInfo(tool, callerIndex);
242
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
243
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
245
externalCalculator.calculateFlat(
247
leftConnection.getExtendedConditionalProbabilities(this,tool),
248
rightConnection.getExtendedConditionalProbabilities(this,tool),
254
public ConditionalProbabilityStore getFlatConditionalProbabilities( final FreeBranch callerConnection, GeneralConstructionTool tool) {
255
final int callerIndex = getCallerIndex(callerConnection);
256
final PatternInfo pi = getPatternInfo(tool, callerIndex);
257
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
258
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
259
final boolean childrenChanged = topologyChangedSinceLastFlat_;
260
topologyChangedSinceLastFlat_ = false;
261
return calculator_.calculateFlat( pi,
262
leftConnection.getExtendedConditionalProbabilities(this,tool),
263
rightConnection.getExtendedConditionalProbabilities(this,tool)
266
public ConditionalProbabilityStore getExtendedConditionalProbabilities( final double distance, final FreeBranch callerConnection, UnconstrainedLikelihoodModel.External externalCalculator, ConditionalProbabilityStore resultStore, final GeneralConstructionTool tool) {
267
final int callerIndex = getCallerIndex(callerConnection);
268
final PatternInfo pi = getPatternInfo(tool, callerIndex);
269
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
270
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
273
externalCalculator.calculateExtended(
275
leftConnection.getExtendedConditionalProbabilities(this,tool),
276
rightConnection.getExtendedConditionalProbabilities(this,tool),
281
public ConditionalProbabilityStore getExtendedConditionalProbabilities( final double distance, final FreeBranch callerConnection, GeneralConstructionTool tool) {
282
final int callerIndex = getCallerIndex(callerConnection);
283
final PatternInfo pi = getPatternInfo(tool, callerIndex);
284
final FreeBranch leftConnection = connections_[LEFT_LOOKUP[callerIndex]];
285
final FreeBranch rightConnection = connections_[RIGHT_LOOKUP[callerIndex]];
286
final boolean childrenChanged = topologyChangedSincleLastExtended_;
287
topologyChangedSincleLastExtended_ = false;
288
return calculator_.calculateExtended(
290
leftConnection.getExtendedConditionalProbabilities(this,tool),
291
rightConnection.getExtendedConditionalProbabilities( this,tool)