inprogress
[jalview.git] / forester / java / src / org / forester / evoinference / TestPhylogenyReconstruction.java
1 // $Id:
2 // $
3 //
4 // FORESTER -- software libraries and applications
5 // for evolutionary biology research and applications.
6 //
7 // Copyright (C) 2008-2009 Christian M. Zmasek
8 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
9 // All rights reserved
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 //
25 // Contact: phylosoft @ gmail . com
26 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
27
28 package org.forester.evoinference;
29
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.StringWriter;
33 import java.util.Date;
34 import java.util.List;
35
36 import org.forester.evoinference.distance.NeighborJoining;
37 import org.forester.evoinference.distance.NeighborJoiningF;
38 import org.forester.evoinference.distance.NeighborJoiningR;
39 import org.forester.evoinference.distance.PairwiseDistanceCalculator;
40 import org.forester.evoinference.matrix.character.BasicCharacterStateMatrix;
41 import org.forester.evoinference.matrix.character.CharacterStateMatrix;
42 import org.forester.evoinference.matrix.character.CharacterStateMatrix.BinaryStates;
43 import org.forester.evoinference.matrix.character.CharacterStateMatrix.GainLossStates;
44 import org.forester.evoinference.matrix.distance.BasicSymmetricalDistanceMatrix;
45 import org.forester.evoinference.matrix.distance.DistanceMatrix;
46 import org.forester.evoinference.parsimony.DolloParsimony;
47 import org.forester.evoinference.parsimony.FitchParsimony;
48 import org.forester.io.parsers.GeneralMsaParser;
49 import org.forester.io.parsers.SymmetricalDistanceMatrixParser;
50 import org.forester.io.parsers.nhx.NHXParser;
51 import org.forester.msa.Msa;
52 import org.forester.phylogeny.Phylogeny;
53 import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;
54 import org.forester.phylogeny.factories.PhylogenyFactory;
55 import org.forester.util.ForesterUtil;
56
57 public class TestPhylogenyReconstruction {
58
59     private final static double ZERO_DIFF = 1.0E-9;
60
61     public static boolean isEqual( final double a, final double b ) {
62         return ( ( Math.abs( a - b ) ) < ZERO_DIFF );
63     }
64
65     public static boolean isUnequal( final double a, final double b ) {
66         return !isEqual( a, b );
67     }
68
69     public static void main( final String[] args ) {
70         //        System.out.println( "NJ" );
71         //        if ( testNeighborJoining() ) {
72         //            System.out.println( "  OK." );
73         //        }
74         //        else {
75         //            System.out.println( "  failed." );
76         //        }
77         System.out.println( "NJR" );
78         if ( testNeighborJoiningR() ) {
79             System.out.println( "  OK." );
80         }
81         else {
82             System.out.println( "  failed." );
83         }
84         //timeNeighborJoining();
85     }
86
87     public static boolean test( final File test_dir ) {
88         System.out.print( "  Basic symmetrical distance matrix: " );
89         if ( !testBasicSymmetricalDistanceMatrix() ) {
90             System.out.println( "failed." );
91             return false;
92         }
93         System.out.println( "OK." );
94         System.out.print( "  Basic character state matrix: " );
95         if ( !testBasicCharacterStateMatrix() ) {
96             System.out.println( "failed." );
97             return false;
98         }
99         System.out.println( "OK." );
100         System.out.print( "  Symmetrical distance matrix parser: " );
101         if ( !testSymmetricalDistanceMatrixParser() ) {
102             System.out.println( "failed." );
103             return false;
104         }
105         System.out.println( "OK." );
106         System.out.print( "  Distance Calculation: " );
107         if ( !testDistanceCalculationMethods( test_dir ) ) {
108             System.out.println( "failed." );
109             return false;
110         }
111         System.out.println( "OK." );
112         System.out.print( "  Neighbor Joining: " );
113         if ( !testNeighborJoining() ) {
114             System.out.println( "failed." );
115             return false;
116         }
117         System.out.println( "OK." );
118         System.out.print( "  Dollo Parsimony: " );
119         if ( !testDolloParsimony() ) {
120             System.out.println( "failed." );
121             return false;
122         }
123         System.out.println( "OK." );
124         System.out.print( "  Dollo Parsimony on non binary trees: " );
125         if ( !testDolloParsimonyOnNonBinaryTree() ) {
126             System.out.println( "failed." );
127             return false;
128         }
129         System.out.println( "OK." );
130         System.out.print( "  Fitch Parsimony: " );
131         if ( !testFitchParsimony() ) {
132             System.out.println( "failed." );
133             return false;
134         }
135         System.out.println( "OK." );
136         return true;
137     }
138
139     private static boolean testBasicCharacterStateMatrix() {
140         try {
141             final CharacterStateMatrix<String> matrix_0 = new BasicCharacterStateMatrix<String>( 4, 8 );
142             final CharacterStateMatrix<String> matrix_00 = new BasicCharacterStateMatrix<String>( 4, 8 );
143             matrix_0.setIdentifier( 0, "A" );
144             matrix_0.setIdentifier( 1, "B" );
145             matrix_0.setIdentifier( 2, "C" );
146             matrix_0.setIdentifier( 3, "D" );
147             matrix_0.setCharacter( 0, "0" );
148             matrix_0.setCharacter( 1, "1" );
149             matrix_0.setCharacter( 2, "2" );
150             matrix_0.setCharacter( 3, "3" );
151             matrix_0.setCharacter( 4, "4" );
152             matrix_0.setCharacter( 5, "5" );
153             matrix_0.setCharacter( 6, "6" );
154             matrix_0.setCharacter( 7, "7" );
155             matrix_00.setIdentifier( 0, "A" );
156             matrix_00.setIdentifier( 1, "B" );
157             matrix_00.setIdentifier( 2, "C" );
158             matrix_00.setIdentifier( 3, "D" );
159             matrix_00.setCharacter( 3, "3" );
160             matrix_00.setCharacter( 4, "4" );
161             if ( !matrix_0.getCharacter( 1 ).equals( "1" ) ) {
162                 return false;
163             }
164             if ( !matrix_0.getIdentifier( 0 ).equals( "A" ) ) {
165                 return false;
166             }
167             matrix_0.setState( 0, 0, "00" );
168             matrix_00.setState( 0, 0, "00" );
169             if ( !matrix_0.getState( 0, 0 ).equals( "00" ) ) {
170                 return false;
171             }
172             matrix_0.setState( 0, 1, "01" );
173             matrix_00.setState( 0, 1, "01" );
174             if ( !matrix_0.getState( 0, 1 ).equals( "01" ) ) {
175                 return false;
176             }
177             matrix_0.setState( 1, 1, "11" );
178             matrix_00.setState( 1, 1, "11" );
179             if ( !matrix_0.getState( 1, 1 ).equals( "11" ) ) {
180                 return false;
181             }
182             matrix_0.setState( 1, 0, "10" );
183             matrix_00.setState( 1, 0, "10" );
184             if ( !matrix_0.getState( 1, 0 ).equals( "10" ) ) {
185                 return false;
186             }
187             matrix_0.setState( 1, 2, "12" );
188             matrix_00.setState( 1, 2, "12" );
189             if ( !matrix_0.getState( 1, 2 ).equals( "12" ) ) {
190                 return false;
191             }
192             matrix_0.setState( 3, 7, "37" );
193             matrix_00.setState( 3, 7, "37" );
194             if ( !matrix_0.getState( 3, 7 ).equals( "37" ) ) {
195                 return false;
196             }
197             matrix_0.setState( 2, 6, "26" );
198             matrix_00.setState( 2, 6, "26" );
199             if ( !matrix_0.getState( 2, 6 ).equals( "26" ) ) {
200                 return false;
201             }
202             matrix_0.setState( "D", "3", "33" );
203             matrix_00.setState( "D", "3", "33" );
204             if ( !matrix_0.getState( 3, 3 ).equals( "33" ) ) {
205                 return false;
206             }
207             if ( !matrix_0.getState( "D", "3" ).equals( "33" ) ) {
208                 return false;
209             }
210             matrix_0.setState( "C", "4", "24" );
211             matrix_00.setState( "C", "4", "24" );
212             if ( !matrix_0.getState( 2, 4 ).equals( "24" ) ) {
213                 return false;
214             }
215             if ( !matrix_0.getState( "C", "4" ).equals( "24" ) ) {
216                 return false;
217             }
218             if ( matrix_0.isEmpty() ) {
219                 return false;
220             }
221             if ( matrix_0.getNumberOfIdentifiers() != 4 ) {
222                 return false;
223             }
224             if ( matrix_0.getNumberOfCharacters() != 8 ) {
225                 return false;
226             }
227             if ( !matrix_0.equals( matrix_0 ) ) {
228                 return false;
229             }
230             if ( !matrix_0.equals( matrix_00 ) ) {
231                 return false;
232             }
233             matrix_00.setState( "C", "4", "123" );
234             if ( matrix_0.equals( matrix_00 ) ) {
235                 return false;
236             }
237             final Integer[][] ints = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
238             final CharacterStateMatrix<Integer> matrix_000 = new BasicCharacterStateMatrix<Integer>( ints );
239             matrix_000.toString();
240             if ( matrix_000.getNumberOfCharacters() != 4 ) {
241                 return false;
242             }
243             if ( matrix_000.getNumberOfIdentifiers() != 3 ) {
244                 return false;
245             }
246             if ( matrix_000.getState( 0, 1 ) != 2 ) {
247                 return false;
248             }
249             if ( matrix_000.getState( 2, 3 ) != 12 ) {
250                 return false;
251             }
252             final Integer[][] ints0 = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
253             final CharacterStateMatrix<Integer> matrix_0000 = new BasicCharacterStateMatrix<Integer>( ints0 );
254             if ( !matrix_000.equals( matrix_0000 ) ) {
255                 return false;
256             }
257             final Integer[][] ints00 = { { 1, 2, 3, -4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
258             final CharacterStateMatrix<Integer> matrix_00000 = new BasicCharacterStateMatrix<Integer>( ints00 );
259             if ( matrix_000.equals( matrix_00000 ) ) {
260                 return false;
261             }
262             final CharacterStateMatrix<String> clone0 = matrix_0.copy();
263             final CharacterStateMatrix<String> clone00 = matrix_00.copy();
264             if ( !clone0.equals( matrix_0 ) ) {
265                 return false;
266             }
267             if ( !clone00.equals( matrix_00 ) ) {
268                 return false;
269             }
270             if ( clone00.equals( clone0 ) ) {
271                 return false;
272             }
273             final CharacterStateMatrix<String> pivot0 = matrix_0.pivot();
274             final CharacterStateMatrix<String> pivot00 = matrix_00.pivot();
275             if ( !pivot0.getState( 1, 0 ).equals( "01" ) ) {
276                 return false;
277             }
278             if ( !pivot0.getState( 6, 2 ).equals( "26" ) ) {
279                 return false;
280             }
281             if ( !matrix_0.getState( 2, 6 ).equals( "26" ) ) {
282                 return false;
283             }
284             final CharacterStateMatrix<String> pivotpivot00 = pivot00.pivot();
285             if ( !pivotpivot00.equals( matrix_00 ) ) {
286                 return false;
287             }
288             final CharacterStateMatrix<BinaryStates> nex = new BasicCharacterStateMatrix<BinaryStates>( 4, 3 );
289             nex.setIdentifier( 0, "amphioxus" );
290             nex.setIdentifier( 1, "sponge" );
291             nex.setIdentifier( 2, "sea_anemone" );
292             nex.setIdentifier( 3, "cobra" );
293             nex.setCharacter( 0, "notch" );
294             nex.setCharacter( 1, "homeobox" );
295             nex.setCharacter( 2, "wnt" );
296             nex.setState( 0, 0, BinaryStates.ABSENT );
297             nex.setState( 0, 1, BinaryStates.ABSENT );
298             nex.setState( 0, 2, BinaryStates.ABSENT );
299             nex.setState( 1, 0, BinaryStates.PRESENT );
300             nex.setState( 1, 1, BinaryStates.PRESENT );
301             nex.setState( 1, 2, BinaryStates.ABSENT );
302             nex.setState( 2, 0, BinaryStates.PRESENT );
303             nex.setState( 2, 1, BinaryStates.PRESENT );
304             nex.setState( 2, 2, BinaryStates.PRESENT );
305             nex.setState( 3, 0, BinaryStates.PRESENT );
306             nex.setState( 3, 1, BinaryStates.ABSENT );
307             nex.setState( 3, 2, BinaryStates.ABSENT );
308             StringWriter w = new StringWriter();
309             nex.toWriter( w, CharacterStateMatrix.Format.NEXUS_BINARY );
310             //System.out.println( w.getBuffer().toString() );
311             w = new StringWriter();
312             nex.pivot().toWriter( w, CharacterStateMatrix.Format.NEXUS_BINARY );
313             //System.out.println( w.getBuffer().toString() );
314         }
315         catch ( final Exception e ) {
316             e.printStackTrace( System.out );
317             return false;
318         }
319         return true;
320     }
321
322     private static boolean testBasicSymmetricalDistanceMatrix() {
323         try {
324             final DistanceMatrix matrix_0 = new BasicSymmetricalDistanceMatrix( 4 );
325             matrix_0.setIdentifier( 0, "A" );
326             matrix_0.setIdentifier( 1, "B" );
327             matrix_0.setIdentifier( 2, "C" );
328             matrix_0.setIdentifier( 3, "0123456789012" );
329             matrix_0.setValue( 1, 0, 0.00001 );
330             matrix_0.setValue( 0, 2, 0.0000009 );
331             matrix_0.setValue( 3, 0, 3.0 );
332             matrix_0.setValue( 1, 2, 4.0 );
333             matrix_0.setValue( 3, 1, 5.0 );
334             matrix_0.setValue( 2, 3, 6.0 );
335             if ( !matrix_0.getIdentifier( 0 ).equals( "A" ) ) {
336                 return false;
337             }
338             if ( !matrix_0.getIdentifier( 1 ).equals( "B" ) ) {
339                 return false;
340             }
341             if ( !matrix_0.getIdentifier( 2 ).equals( "C" ) ) {
342                 return false;
343             }
344             if ( !matrix_0.getIdentifier( 3 ).equals( "0123456789012" ) ) {
345                 return false;
346             }
347             if ( matrix_0.getSize() != 4 ) {
348                 return false;
349             }
350             if ( !isEqual( matrix_0.getValue( 0, 0 ), 0.0 ) ) {
351                 return false;
352             }
353             if ( !isEqual( matrix_0.getValue( 3, 3 ), 0.0 ) ) {
354                 return false;
355             }
356             if ( !isEqual( matrix_0.getValue( 0, 1 ), 0.00001 ) ) {
357                 return false;
358             }
359             if ( !isEqual( matrix_0.getValue( 0, 2 ), 0.0000009 ) ) {
360                 return false;
361             }
362             if ( !isEqual( matrix_0.getValue( 0, 3 ), 3 ) ) {
363                 return false;
364             }
365             if ( !isEqual( matrix_0.getValue( 1, 0 ), 0.00001 ) ) {
366                 return false;
367             }
368             if ( !isEqual( matrix_0.getValue( 1, 2 ), 4 ) ) {
369                 return false;
370             }
371             if ( !isEqual( matrix_0.getValue( 1, 3 ), 5 ) ) {
372                 return false;
373             }
374             if ( !isEqual( matrix_0.getValue( 2, 0 ), 0.0000009 ) ) {
375                 return false;
376             }
377             if ( !isEqual( matrix_0.getValue( 2, 1 ), 4 ) ) {
378                 return false;
379             }
380             if ( !isEqual( matrix_0.getValue( 2, 3 ), 6 ) ) {
381                 return false;
382             }
383             if ( !isEqual( matrix_0.getValue( 3, 0 ), 3 ) ) {
384                 return false;
385             }
386             if ( !isEqual( matrix_0.getValue( 3, 1 ), 5 ) ) {
387                 return false;
388             }
389             if ( !isEqual( matrix_0.getValue( 3, 2 ), 6 ) ) {
390                 return false;
391             }
392             final StringBuffer matrix_0_phylip = new StringBuffer();
393             matrix_0_phylip.append( "    4" );
394             matrix_0_phylip.append( ForesterUtil.LINE_SEPARATOR );
395             matrix_0_phylip.append( "A           0.000000  0.000010  0.000001  3.000000" );
396             matrix_0_phylip.append( ForesterUtil.LINE_SEPARATOR );
397             matrix_0_phylip.append( "B           0.000010  0.000000  4.000000  5.000000" );
398             matrix_0_phylip.append( ForesterUtil.LINE_SEPARATOR );
399             matrix_0_phylip.append( "C           0.000001  4.000000  0.000000  6.000000" );
400             matrix_0_phylip.append( ForesterUtil.LINE_SEPARATOR );
401             matrix_0_phylip.append( "0123456789  3.000000  5.000000  6.000000  0.000000" );
402             if ( !matrix_0_phylip.toString()
403                     .equals( matrix_0.toStringBuffer( DistanceMatrix.Format.PHYLIP ).toString() ) ) {
404                 return false;
405             }
406         }
407         catch ( final Exception e ) {
408             e.printStackTrace( System.out );
409             return false;
410         }
411         return true;
412     }
413
414     private static boolean testDistanceCalculationMethods( final File test_dir ) {
415         try {
416             final Msa msa0 = GeneralMsaParser.parse( new FileInputStream( test_dir + ForesterUtil.FILE_SEPARATOR
417                     + "bcl.aln" ) );
418             final BasicSymmetricalDistanceMatrix pwd0 = PairwiseDistanceCalculator.calcKimuraDistances( msa0 );
419             if ( pwd0.getSize() != 120 ) {
420                 return false;
421             }
422             for( int i = 0; i < pwd0.getSize(); ++i ) {
423                 if ( !isEqual( pwd0.getValue( i, i ), 0.0 ) ) {
424                     return false;
425                 }
426             }
427         }
428         catch ( final Exception e ) {
429             e.printStackTrace( System.out );
430             return false;
431         }
432         return true;
433     }
434
435     private static boolean testDolloParsimony() {
436         try {
437             final BinaryStates PRESENT = BinaryStates.PRESENT;
438             final BinaryStates ABSENT = BinaryStates.ABSENT;
439             final GainLossStates UNCHANGED_PRESENT = GainLossStates.UNCHANGED_PRESENT;
440             final DolloParsimony dollo1 = DolloParsimony.createInstance();
441             final PhylogenyFactory factory1 = ParserBasedPhylogenyFactory.getInstance();
442             final String p1_str = "((((((a,b)ab,c)ac,d)ad,(e,f)ef)af,(g,h)gh)ah,i)r";
443             final Phylogeny p1 = factory1.create( p1_str, new NHXParser() )[ 0 ];
444             CharacterStateMatrix<CharacterStateMatrix.BinaryStates> m1 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 9,
445                                                                                                                                            1 );
446             m1.setIdentifier( 0, "a" );
447             m1.setIdentifier( 1, "b" );
448             m1.setIdentifier( 2, "c" );
449             m1.setIdentifier( 3, "d" );
450             m1.setIdentifier( 4, "e" );
451             m1.setIdentifier( 5, "f" );
452             m1.setIdentifier( 6, "g" );
453             m1.setIdentifier( 7, "h" );
454             m1.setIdentifier( 8, "i" );
455             m1.setCharacter( 0, "0" );
456             m1.setState( "a", "0", PRESENT );
457             m1.setState( "b", "0", ABSENT );
458             m1.setState( "c", "0", PRESENT );
459             m1.setState( "d", "0", ABSENT );
460             m1.setState( "e", "0", ABSENT );
461             m1.setState( "f", "0", ABSENT );
462             m1.setState( "g", "0", ABSENT );
463             m1.setState( "h", "0", ABSENT );
464             m1.setState( "i", "0", ABSENT );
465             dollo1.execute( p1, m1 );
466             if ( dollo1.getTotalGains() != 1 ) {
467                 return false;
468             }
469             if ( dollo1.getTotalLosses() != 1 ) {
470                 return false;
471             }
472             if ( dollo1.getTotalUnchanged() != 15 ) {
473                 return false;
474             }
475             m1.setState( "b", "0", PRESENT );
476             dollo1.execute( p1, m1 );
477             if ( dollo1.getTotalGains() != 1 ) {
478                 return false;
479             }
480             if ( dollo1.getTotalLosses() != 0 ) {
481                 return false;
482             }
483             if ( dollo1.getTotalUnchanged() != 16 ) {
484                 return false;
485             }
486             m1.setState( "b", "0", ABSENT );
487             m1.setState( "e", "0", PRESENT );
488             dollo1.execute( p1, m1 );
489             if ( dollo1.getTotalGains() != 1 ) {
490                 return false;
491             }
492             if ( dollo1.getTotalLosses() != 3 ) {
493                 return false;
494             }
495             if ( dollo1.getTotalUnchanged() != 13 ) {
496                 return false;
497             }
498             m1.setState( "a", "0", ABSENT );
499             m1.setState( "c", "0", ABSENT );
500             m1.setState( "g", "0", PRESENT );
501             dollo1.setReturnInternalStates( true );
502             dollo1.setReturnGainLossMatrix( true );
503             dollo1.execute( p1, m1 );
504             if ( dollo1.getTotalGains() != 1 ) {
505                 return false;
506             }
507             if ( dollo1.getTotalLosses() != 3 ) {
508                 return false;
509             }
510             if ( dollo1.getTotalUnchanged() != 13 ) {
511                 return false;
512             }
513             final DolloParsimony dollo2 = DolloParsimony.createInstance();
514             final PhylogenyFactory factory2 = ParserBasedPhylogenyFactory.getInstance();
515             final String p2_str = "((((((a,b)ab,c)ac,d)ad,(e,f)ef)af,(g,h,i)gi)ai,((j,k,l)jl,(m,n,o)mo,(p,q,r)pr)jr)root";
516             final Phylogeny p2 = factory2.create( p2_str, new NHXParser() )[ 0 ];
517             final CharacterStateMatrix<CharacterStateMatrix.BinaryStates> m2 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 18,
518                                                                                                                                                  4 );
519             m2.setIdentifier( 0, "a" );
520             m2.setIdentifier( 1, "b" );
521             m2.setIdentifier( 2, "c" );
522             m2.setIdentifier( 3, "d" );
523             m2.setIdentifier( 4, "e" );
524             m2.setIdentifier( 5, "f" );
525             m2.setIdentifier( 6, "g" );
526             m2.setIdentifier( 7, "h" );
527             m2.setIdentifier( 8, "i" );
528             m2.setIdentifier( 9, "j" );
529             m2.setIdentifier( 10, "k" );
530             m2.setIdentifier( 11, "l" );
531             m2.setIdentifier( 12, "m" );
532             m2.setIdentifier( 13, "n" );
533             m2.setIdentifier( 14, "o" );
534             m2.setIdentifier( 15, "p" );
535             m2.setIdentifier( 16, "q" );
536             m2.setIdentifier( 17, "r" );
537             m2.setCharacter( 0, "0" );
538             m2.setCharacter( 1, "1" );
539             m2.setCharacter( 2, "2" );
540             m2.setCharacter( 3, "3" );
541             m2.setState( "a", "0", PRESENT );
542             m2.setState( "b", "0", ABSENT );
543             m2.setState( "c", "0", PRESENT );
544             m2.setState( "d", "0", ABSENT );
545             m2.setState( "e", "0", ABSENT );
546             m2.setState( "f", "0", ABSENT );
547             m2.setState( "g", "0", ABSENT );
548             m2.setState( "h", "0", ABSENT );
549             m2.setState( "i", "0", ABSENT );
550             m2.setState( "j", "0", ABSENT );
551             m2.setState( "k", "0", ABSENT );
552             m2.setState( "l", "0", ABSENT );
553             m2.setState( "m", "0", ABSENT );
554             m2.setState( "n", "0", ABSENT );
555             m2.setState( "o", "0", ABSENT );
556             m2.setState( "p", "0", ABSENT );
557             m2.setState( "q", "0", ABSENT );
558             m2.setState( "r", "0", ABSENT );
559             m2.setState( "a", "1", PRESENT );
560             m2.setState( "b", "1", ABSENT );
561             m2.setState( "c", "1", PRESENT );
562             m2.setState( "d", "1", ABSENT );
563             m2.setState( "e", "1", ABSENT );
564             m2.setState( "f", "1", ABSENT );
565             m2.setState( "g", "1", PRESENT );
566             m2.setState( "h", "1", ABSENT );
567             m2.setState( "i", "1", ABSENT );
568             m2.setState( "j", "1", PRESENT );
569             m2.setState( "k", "1", ABSENT );
570             m2.setState( "l", "1", ABSENT );
571             m2.setState( "m", "1", PRESENT );
572             m2.setState( "n", "1", ABSENT );
573             m2.setState( "o", "1", ABSENT );
574             m2.setState( "p", "1", ABSENT );
575             m2.setState( "q", "1", ABSENT );
576             m2.setState( "r", "1", ABSENT );
577             m2.setState( "a", "2", ABSENT );
578             m2.setState( "b", "2", ABSENT );
579             m2.setState( "c", "2", ABSENT );
580             m2.setState( "d", "2", ABSENT );
581             m2.setState( "e", "2", ABSENT );
582             m2.setState( "f", "2", ABSENT );
583             m2.setState( "g", "2", ABSENT );
584             m2.setState( "h", "2", ABSENT );
585             m2.setState( "i", "2", ABSENT );
586             m2.setState( "j", "2", PRESENT );
587             m2.setState( "k", "2", ABSENT );
588             m2.setState( "l", "2", ABSENT );
589             m2.setState( "m", "2", PRESENT );
590             m2.setState( "n", "2", ABSENT );
591             m2.setState( "o", "2", ABSENT );
592             m2.setState( "p", "2", PRESENT );
593             m2.setState( "q", "2", ABSENT );
594             m2.setState( "r", "2", ABSENT );
595             m2.setState( "a", "3", ABSENT );
596             m2.setState( "b", "3", ABSENT );
597             m2.setState( "c", "3", PRESENT );
598             m2.setState( "d", "3", ABSENT );
599             m2.setState( "e", "3", ABSENT );
600             m2.setState( "f", "3", ABSENT );
601             m2.setState( "g", "3", PRESENT );
602             m2.setState( "h", "3", ABSENT );
603             m2.setState( "i", "3", ABSENT );
604             m2.setState( "j", "3", ABSENT );
605             m2.setState( "k", "3", ABSENT );
606             m2.setState( "l", "3", ABSENT );
607             m2.setState( "m", "3", ABSENT );
608             m2.setState( "n", "3", ABSENT );
609             m2.setState( "o", "3", ABSENT );
610             m2.setState( "p", "3", ABSENT );
611             m2.setState( "q", "3", ABSENT );
612             m2.setState( "r", "3", ABSENT );
613             dollo2.setReturnInternalStates( true );
614             dollo2.setReturnGainLossMatrix( true );
615             dollo2.execute( p2, m2 );
616             final CharacterStateMatrix<BinaryStates> i_m = dollo2.getInternalStatesMatrix();
617             final CharacterStateMatrix<GainLossStates> gl_m = dollo2.getGainLossMatrix();
618             if ( dollo2.getTotalGains() != 3 ) {
619                 return false;
620             }
621             if ( dollo2.getTotalLosses() != 22 ) {
622                 return false;
623             }
624             if ( dollo2.getTotalUnchanged() != 95 ) {
625                 return false;
626             }
627             if ( i_m.getState( "ab", "0" ) != PRESENT ) {
628                 return false;
629             }
630             if ( i_m.getState( "ac", "0" ) != PRESENT ) {
631                 return false;
632             }
633             if ( i_m.getState( "ad", "0" ) != ABSENT ) {
634                 return false;
635             }
636             if ( i_m.getState( "af", "0" ) != ABSENT ) {
637                 return false;
638             }
639             if ( i_m.getState( "ef", "0" ) != ABSENT ) {
640                 return false;
641             }
642             if ( i_m.getState( "ai", "0" ) != ABSENT ) {
643                 return false;
644             }
645             if ( i_m.getState( "gi", "0" ) != ABSENT ) {
646                 return false;
647             }
648             if ( i_m.getState( "jl", "0" ) != ABSENT ) {
649                 return false;
650             }
651             if ( i_m.getState( "mo", "0" ) != ABSENT ) {
652                 return false;
653             }
654             if ( i_m.getState( "pr", "0" ) != ABSENT ) {
655                 return false;
656             }
657             if ( i_m.getState( "jr", "0" ) != ABSENT ) {
658                 return false;
659             }
660             if ( i_m.getState( "root", "0" ) != ABSENT ) {
661                 return false;
662             }
663             if ( i_m.getState( "ab", "1" ) != PRESENT ) {
664                 return false;
665             }
666             if ( i_m.getState( "ac", "1" ) != PRESENT ) {
667                 return false;
668             }
669             if ( i_m.getState( "ad", "1" ) != PRESENT ) {
670                 return false;
671             }
672             if ( i_m.getState( "af", "1" ) != PRESENT ) {
673                 return false;
674             }
675             if ( i_m.getState( "ef", "1" ) != ABSENT ) {
676                 return false;
677             }
678             if ( i_m.getState( "ai", "1" ) != PRESENT ) {
679                 return false;
680             }
681             if ( i_m.getState( "gi", "1" ) != PRESENT ) {
682                 return false;
683             }
684             if ( i_m.getState( "jl", "1" ) != PRESENT ) {
685                 return false;
686             }
687             if ( i_m.getState( "mo", "1" ) != PRESENT ) {
688                 return false;
689             }
690             if ( i_m.getState( "pr", "1" ) != ABSENT ) {
691                 return false;
692             }
693             if ( i_m.getState( "jr", "1" ) != PRESENT ) {
694                 return false;
695             }
696             if ( i_m.getState( "root", "1" ) != PRESENT ) {
697                 return false;
698             }
699             if ( i_m.getState( "ab", "2" ) != ABSENT ) {
700                 return false;
701             }
702             if ( i_m.getState( "ac", "2" ) != ABSENT ) {
703                 return false;
704             }
705             if ( i_m.getState( "ad", "2" ) != ABSENT ) {
706                 return false;
707             }
708             if ( i_m.getState( "af", "2" ) != ABSENT ) {
709                 return false;
710             }
711             if ( i_m.getState( "ef", "2" ) != ABSENT ) {
712                 return false;
713             }
714             if ( i_m.getState( "ai", "2" ) != ABSENT ) {
715                 return false;
716             }
717             if ( i_m.getState( "gi", "2" ) != ABSENT ) {
718                 return false;
719             }
720             if ( i_m.getState( "jl", "2" ) != PRESENT ) {
721                 return false;
722             }
723             if ( i_m.getState( "mo", "2" ) != PRESENT ) {
724                 return false;
725             }
726             if ( i_m.getState( "pr", "2" ) != PRESENT ) {
727                 return false;
728             }
729             if ( i_m.getState( "jr", "2" ) != PRESENT ) {
730                 return false;
731             }
732             if ( i_m.getState( "root", "2" ) != ABSENT ) {
733                 return false;
734             }
735             if ( i_m.getState( "ab", "3" ) != ABSENT ) {
736                 return false;
737             }
738             if ( i_m.getState( "ac", "3" ) != PRESENT ) {
739                 return false;
740             }
741             if ( i_m.getState( "ad", "3" ) != PRESENT ) {
742                 return false;
743             }
744             if ( i_m.getState( "af", "3" ) != PRESENT ) {
745                 return false;
746             }
747             if ( i_m.getState( "ef", "3" ) != ABSENT ) {
748                 return false;
749             }
750             if ( i_m.getState( "ai", "3" ) != PRESENT ) {
751                 return false;
752             }
753             if ( i_m.getState( "gi", "3" ) != PRESENT ) {
754                 return false;
755             }
756             if ( i_m.getState( "jl", "3" ) != ABSENT ) {
757                 return false;
758             }
759             if ( i_m.getState( "mo", "3" ) != ABSENT ) {
760                 return false;
761             }
762             if ( i_m.getState( "pr", "3" ) != ABSENT ) {
763                 return false;
764             }
765             if ( i_m.getState( "jr", "3" ) != ABSENT ) {
766                 return false;
767             }
768             if ( i_m.getState( "root", "3" ) != ABSENT ) {
769                 return false;
770             }
771             if ( gl_m.getState( "a", "0" ) != UNCHANGED_PRESENT ) {
772                 return false;
773             }
774             final DolloParsimony dollo9 = DolloParsimony.createInstance();
775             final PhylogenyFactory factory9 = ParserBasedPhylogenyFactory.getInstance();
776             final String p9_str = "((((((a,b)ab,c)ac,d)ad,(e,f)ef)af,(g,h)gh)ah,i)r";
777             final Phylogeny p9 = factory9.create( p9_str, new NHXParser() )[ 0 ];
778             m1 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 9, 3 );
779             m1.setIdentifier( 0, "a" );
780             m1.setIdentifier( 1, "b" );
781             m1.setIdentifier( 2, "c" );
782             m1.setIdentifier( 3, "d" );
783             m1.setIdentifier( 4, "e" );
784             m1.setIdentifier( 5, "f" );
785             m1.setIdentifier( 6, "g" );
786             m1.setIdentifier( 7, "h" );
787             m1.setIdentifier( 8, "i" );
788             m1.setState( 0, 0, PRESENT );
789             m1.setState( 1, 0, ABSENT );
790             m1.setState( 2, 0, PRESENT );
791             m1.setState( 3, 0, ABSENT );
792             m1.setState( 4, 0, ABSENT );
793             m1.setState( 5, 0, ABSENT );
794             m1.setState( 6, 0, ABSENT );
795             m1.setState( 7, 0, ABSENT );
796             m1.setState( 8, 0, ABSENT );
797             m1.setState( 0, 1, PRESENT );
798             m1.setState( 1, 1, PRESENT );
799             m1.setState( 2, 1, PRESENT );
800             m1.setState( 3, 1, PRESENT );
801             m1.setState( 4, 1, ABSENT );
802             m1.setState( 5, 1, ABSENT );
803             m1.setState( 6, 1, ABSENT );
804             m1.setState( 7, 1, ABSENT );
805             m1.setState( 8, 1, ABSENT );
806             m1.setState( 0, 2, PRESENT );
807             m1.setState( 1, 2, ABSENT );
808             m1.setState( 2, 2, ABSENT );
809             m1.setState( 3, 2, ABSENT );
810             m1.setState( 4, 2, ABSENT );
811             m1.setState( 5, 2, ABSENT );
812             m1.setState( 6, 2, ABSENT );
813             m1.setState( 7, 2, PRESENT );
814             m1.setState( 8, 2, ABSENT );
815             dollo9.execute( p9, m1 );
816             if ( dollo9.getTotalGains() != 3 ) {
817                 return false;
818             }
819             if ( dollo9.getTotalLosses() != 6 ) {
820                 return false;
821             }
822             final DolloParsimony dollo10 = DolloParsimony.createInstance();
823             final PhylogenyFactory factory10 = ParserBasedPhylogenyFactory.getInstance();
824             final String p10_str = "((((((a,b)ab,c)ac,d)ad,(e,f)ef)af,(g,h)gh)ah,i)r";
825             final Phylogeny p10 = factory10.create( p10_str, new NHXParser() )[ 0 ];
826             final CharacterStateMatrix<CharacterStateMatrix.BinaryStates> m10 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 9,
827                                                                                                                                                   1 );
828             m10.setIdentifier( 0, "a" );
829             m10.setIdentifier( 1, "b" );
830             m10.setIdentifier( 2, "c" );
831             m10.setIdentifier( 3, "d" );
832             m10.setIdentifier( 4, "e" );
833             m10.setIdentifier( 5, "f" );
834             m10.setIdentifier( 6, "g" );
835             m10.setIdentifier( 7, "h" );
836             m10.setIdentifier( 8, "i" );
837             m10.setState( 0, 0, PRESENT );
838             m10.setState( 1, 0, ABSENT );
839             m10.setState( 2, 0, PRESENT );
840             m10.setState( 3, 0, ABSENT );
841             m10.setState( 4, 0, ABSENT );
842             m10.setState( 5, 0, ABSENT );
843             m10.setState( 6, 0, ABSENT );
844             m10.setState( 7, 0, ABSENT );
845             m10.setState( 8, 0, ABSENT );
846             dollo10.execute( p10, m10 );
847             if ( dollo10.getTotalGains() != 1 ) {
848                 return false;
849             }
850             if ( dollo10.getTotalLosses() != 1 ) {
851                 return false;
852             }
853         }
854         catch ( final Exception e ) {
855             e.printStackTrace( System.out );
856             return false;
857         }
858         return true;
859     }
860
861     private static boolean testDolloParsimonyOnNonBinaryTree() {
862         try {
863             final BinaryStates PRESENT = BinaryStates.PRESENT;
864             final BinaryStates ABSENT = BinaryStates.ABSENT;
865             final DolloParsimony dollo1 = DolloParsimony.createInstance();
866             final PhylogenyFactory factory1 = ParserBasedPhylogenyFactory.getInstance();
867             final String p1_str = "((((((a,b,y)aby,c)ac,d)ad,(e,f)ef)af,(g,h)gh)ah,i)r";
868             final Phylogeny p1 = factory1.create( p1_str, new NHXParser() )[ 0 ];
869             final CharacterStateMatrix<CharacterStateMatrix.BinaryStates> m1 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 10,
870                                                                                                                                                  1 );
871             m1.setIdentifier( 0, "a" );
872             m1.setIdentifier( 1, "b" );
873             m1.setIdentifier( 2, "y" );
874             m1.setIdentifier( 3, "c" );
875             m1.setIdentifier( 4, "d" );
876             m1.setIdentifier( 5, "e" );
877             m1.setIdentifier( 6, "f" );
878             m1.setIdentifier( 7, "g" );
879             m1.setIdentifier( 8, "h" );
880             m1.setIdentifier( 9, "i" );
881             m1.setCharacter( 0, "0" );
882             m1.setState( "a", "0", PRESENT );
883             m1.setState( "b", "0", ABSENT );
884             m1.setState( "y", "0", PRESENT );
885             m1.setState( "c", "0", PRESENT );
886             m1.setState( "d", "0", ABSENT );
887             m1.setState( "e", "0", ABSENT );
888             m1.setState( "f", "0", ABSENT );
889             m1.setState( "g", "0", ABSENT );
890             m1.setState( "h", "0", ABSENT );
891             m1.setState( "i", "0", ABSENT );
892             dollo1.execute( p1, m1 );
893             if ( dollo1.getTotalGains() != 1 ) {
894                 return false;
895             }
896             if ( dollo1.getTotalLosses() != 1 ) {
897                 return false;
898             }
899             if ( dollo1.getTotalUnchanged() != 16 ) {
900                 return false;
901             }
902             m1.setState( "b", "0", PRESENT );
903             dollo1.execute( p1, m1 );
904             if ( dollo1.getTotalGains() != 1 ) {
905                 return false;
906             }
907             if ( dollo1.getTotalLosses() != 0 ) {
908                 return false;
909             }
910             if ( dollo1.getTotalUnchanged() != 17 ) {
911                 return false;
912             }
913             m1.setState( "a", "0", ABSENT );
914             m1.setState( "b", "0", ABSENT );
915             dollo1.execute( p1, m1 );
916             if ( dollo1.getTotalGains() != 1 ) {
917                 return false;
918             }
919             if ( dollo1.getTotalLosses() != 2 ) {
920                 return false;
921             }
922             if ( dollo1.getTotalUnchanged() != 15 ) {
923                 return false;
924             }
925             m1.setState( "y", "0", ABSENT );
926             dollo1.execute( p1, m1 );
927             if ( dollo1.getTotalGains() != 1 ) {
928                 return false;
929             }
930             if ( dollo1.getTotalLosses() != 0 ) {
931                 return false;
932             }
933             if ( dollo1.getTotalUnchanged() != 17 ) {
934                 return false;
935             }
936             final DolloParsimony dollo2 = DolloParsimony.createInstance();
937             final PhylogenyFactory factory2 = ParserBasedPhylogenyFactory.getInstance();
938             final String p2_str = "((((((a,b,y)aby,c,d)cad,e,f)af,(g,h)gh)ah,i))r";
939             final Phylogeny p2 = factory2.create( p2_str, new NHXParser() )[ 0 ];
940             final CharacterStateMatrix<CharacterStateMatrix.BinaryStates> m2 = new BasicCharacterStateMatrix<CharacterStateMatrix.BinaryStates>( 10,
941                                                                                                                                                  1 );
942             m2.setIdentifier( 0, "a" );
943             m2.setIdentifier( 1, "b" );
944             m2.setIdentifier( 2, "y" );
945             m2.setIdentifier( 3, "c" );
946             m2.setIdentifier( 4, "d" );
947             m2.setIdentifier( 5, "e" );
948             m2.setIdentifier( 6, "f" );
949             m2.setIdentifier( 7, "g" );
950             m2.setIdentifier( 8, "h" );
951             m2.setIdentifier( 9, "i" );
952             m2.setCharacter( 0, "0" );
953             m2.setState( "a", "0", PRESENT );
954             m2.setState( "b", "0", ABSENT );
955             m2.setState( "y", "0", PRESENT );
956             m2.setState( "c", "0", PRESENT );
957             m2.setState( "d", "0", ABSENT );
958             m2.setState( "e", "0", ABSENT );
959             m2.setState( "f", "0", ABSENT );
960             m2.setState( "g", "0", ABSENT );
961             m2.setState( "h", "0", ABSENT );
962             m2.setState( "i", "0", ABSENT );
963             dollo2.setReturnInternalStates( true );
964             dollo2.execute( p2, m2 );
965             CharacterStateMatrix<BinaryStates> i_m2 = dollo2.getInternalStatesMatrix();
966             if ( i_m2.getState( "aby", "0" ) != PRESENT ) {
967                 return false;
968             }
969             if ( i_m2.getState( "cad", "0" ) != PRESENT ) {
970                 return false;
971             }
972             if ( i_m2.getState( "af", "0" ) != ABSENT ) {
973                 return false;
974             }
975             if ( i_m2.getState( "gh", "0" ) != ABSENT ) {
976                 return false;
977             }
978             if ( i_m2.getState( "ah", "0" ) != ABSENT ) {
979                 return false;
980             }
981             if ( i_m2.getState( "r", "0" ) != ABSENT ) {
982                 return false;
983             }
984             if ( dollo2.getTotalGains() != 1 ) {
985                 return false;
986             }
987             if ( dollo2.getTotalLosses() != 2 ) {
988                 return false;
989             }
990             if ( dollo2.getTotalUnchanged() != 14 ) {
991                 return false;
992             }
993             m2.setState( "b", "0", PRESENT );
994             dollo2.execute( p2, m2 );
995             if ( dollo2.getTotalGains() != 1 ) {
996                 return false;
997             }
998             if ( dollo2.getTotalLosses() != 1 ) {
999                 return false;
1000             }
1001             if ( dollo2.getTotalUnchanged() != 15 ) {
1002                 return false;
1003             }
1004             m2.setState( "a", "0", ABSENT );
1005             m2.setState( "b", "0", ABSENT );
1006             dollo2.execute( p2, m2 );
1007             if ( dollo2.getTotalGains() != 1 ) {
1008                 return false;
1009             }
1010             if ( dollo2.getTotalLosses() != 3 ) {
1011                 return false;
1012             }
1013             if ( dollo2.getTotalUnchanged() != 13 ) {
1014                 return false;
1015             }
1016             m2.setState( "y", "0", ABSENT );
1017             dollo2.execute( p2, m2 );
1018             if ( dollo2.getTotalGains() != 1 ) {
1019                 return false;
1020             }
1021             if ( dollo2.getTotalLosses() != 0 ) {
1022                 return false;
1023             }
1024             if ( dollo2.getTotalUnchanged() != 16 ) {
1025                 return false;
1026             }
1027             m2.setState( "c", "0", ABSENT );
1028             dollo2.execute( p2, m2 );
1029             if ( dollo2.getTotalGains() != 0 ) {
1030                 return false;
1031             }
1032             if ( dollo2.getTotalLosses() != 0 ) {
1033                 return false;
1034             }
1035             if ( dollo2.getTotalUnchanged() != 17 ) {
1036                 return false;
1037             }
1038             m2.setState( "y", "0", PRESENT );
1039             m2.setState( "e", "0", PRESENT );
1040             dollo2.execute( p2, m2 );
1041             if ( dollo2.getTotalGains() != 1 ) {
1042                 return false;
1043             }
1044             if ( dollo2.getTotalLosses() != 5 ) {
1045                 return false;
1046             }
1047             if ( dollo2.getTotalUnchanged() != 11 ) {
1048                 return false;
1049             }
1050             i_m2 = dollo2.getInternalStatesMatrix();
1051             if ( i_m2.getState( "aby", "0" ) != PRESENT ) {
1052                 return false;
1053             }
1054             if ( i_m2.getState( "cad", "0" ) != PRESENT ) {
1055                 return false;
1056             }
1057             if ( i_m2.getState( "af", "0" ) != PRESENT ) {
1058                 return false;
1059             }
1060             if ( i_m2.getState( "gh", "0" ) != ABSENT ) {
1061                 return false;
1062             }
1063             if ( i_m2.getState( "ah", "0" ) != ABSENT ) {
1064                 return false;
1065             }
1066             if ( i_m2.getState( "r", "0" ) != ABSENT ) {
1067                 return false;
1068             }
1069         }
1070         catch ( final Exception e ) {
1071             e.printStackTrace( System.out );
1072             return false;
1073         }
1074         return true;
1075     }
1076
1077     private static boolean testFitchParsimony() {
1078         try {
1079             final BinaryStates PRESENT = BinaryStates.PRESENT;
1080             final BinaryStates ABSENT = BinaryStates.ABSENT;
1081             final GainLossStates GAIN = GainLossStates.GAIN;
1082             final GainLossStates LOSS = GainLossStates.LOSS;
1083             final GainLossStates UNCHANGED_PRESENT = GainLossStates.UNCHANGED_PRESENT;
1084             final GainLossStates UNCHANGED_ABSENT = GainLossStates.UNCHANGED_ABSENT;
1085             final FitchParsimony<String> fitch1 = new FitchParsimony<String>();
1086             final PhylogenyFactory factory1 = ParserBasedPhylogenyFactory.getInstance();
1087             final String p1_str = "((((((a,b)ab,c)ac,d)ad,(e,f)ef)af,(g,h,i)gi)ai,((j,k,l)jl,(m,n,o)mo,(p,q,r)pr)jr)root";
1088             final Phylogeny p1 = factory1.create( p1_str, new NHXParser() )[ 0 ];
1089             final CharacterStateMatrix<String> m1 = new BasicCharacterStateMatrix<String>( 18, 1 );
1090             m1.setIdentifier( 0, "a" );
1091             m1.setIdentifier( 1, "b" );
1092             m1.setIdentifier( 2, "c" );
1093             m1.setIdentifier( 3, "d" );
1094             m1.setIdentifier( 4, "e" );
1095             m1.setIdentifier( 5, "f" );
1096             m1.setIdentifier( 6, "g" );
1097             m1.setIdentifier( 7, "h" );
1098             m1.setIdentifier( 8, "i" );
1099             m1.setIdentifier( 9, "j" );
1100             m1.setIdentifier( 10, "k" );
1101             m1.setIdentifier( 11, "l" );
1102             m1.setIdentifier( 12, "m" );
1103             m1.setIdentifier( 13, "n" );
1104             m1.setIdentifier( 14, "o" );
1105             m1.setIdentifier( 15, "p" );
1106             m1.setIdentifier( 16, "q" );
1107             m1.setIdentifier( 17, "r" );
1108             m1.setCharacter( 0, "0" );
1109             m1.setState( "a", "0", "A" );
1110             m1.setState( "b", "0", "A" );
1111             m1.setState( "c", "0", "B" );
1112             m1.setState( "d", "0", "C" );
1113             m1.setState( "e", "0", "D" );
1114             m1.setState( "f", "0", "A" );
1115             m1.setState( "g", "0", "A" );
1116             m1.setState( "h", "0", "B" );
1117             m1.setState( "i", "0", "C" );
1118             m1.setState( "j", "0", "A" );
1119             m1.setState( "k", "0", "B" );
1120             m1.setState( "l", "0", "C" );
1121             m1.setState( "m", "0", "B" );
1122             m1.setState( "n", "0", "B" );
1123             m1.setState( "o", "0", "B" );
1124             m1.setState( "p", "0", "A" );
1125             m1.setState( "q", "0", "C" );
1126             m1.setState( "r", "0", "D" );
1127             fitch1.setReturnInternalStates( true );
1128             fitch1.setReturnGainLossMatrix( false );
1129             fitch1.setRandomize( false );
1130             fitch1.execute( p1, m1 );
1131             final CharacterStateMatrix<String> i_m = fitch1.getInternalStatesMatrix();
1132             final CharacterStateMatrix<List<String>> i_m_all = fitch1.getInternalStatesMatrixPriorToTraceback();
1133             if ( fitch1.getCost() != 10 ) {
1134                 return false;
1135             }
1136             if ( !i_m.getState( "ab", "0" ).equals( "A" ) ) {
1137                 return false;
1138             }
1139             if ( !i_m.getState( "ac", "0" ).equals( "A" ) ) {
1140                 return false;
1141             }
1142             if ( !i_m.getState( "ad", "0" ).equals( "A" ) ) {
1143                 return false;
1144             }
1145             if ( !i_m.getState( "ef", "0" ).equals( "A" ) ) {
1146                 return false;
1147             }
1148             if ( !i_m.getState( "ai", "0" ).equals( "A" ) ) {
1149                 return false;
1150             }
1151             if ( !i_m.getState( "gi", "0" ).equals( "A" ) ) {
1152                 return false;
1153             }
1154             if ( !i_m.getState( "jl", "0" ).equals( "A" ) ) {
1155                 return false;
1156             }
1157             if ( !i_m.getState( "mo", "0" ).equals( "B" ) ) {
1158                 return false;
1159             }
1160             if ( !i_m.getState( "pr", "0" ).equals( "A" ) ) {
1161                 return false;
1162             }
1163             if ( i_m_all.getState( "ab", "0" ).size() != 1 ) {
1164                 return false;
1165             }
1166             if ( !i_m_all.getState( "ab", "0" ).contains( "A" ) ) {
1167                 return false;
1168             }
1169             if ( i_m_all.getState( "ac", "0" ).size() != 2 ) {
1170                 return false;
1171             }
1172             if ( !i_m_all.getState( "ac", "0" ).contains( "A" ) ) {
1173                 return false;
1174             }
1175             if ( !i_m_all.getState( "ac", "0" ).contains( "B" ) ) {
1176                 return false;
1177             }
1178             if ( i_m_all.getState( "ad", "0" ).size() != 3 ) {
1179                 return false;
1180             }
1181             if ( !i_m_all.getState( "ad", "0" ).contains( "A" ) ) {
1182                 return false;
1183             }
1184             if ( !i_m_all.getState( "ad", "0" ).contains( "B" ) ) {
1185                 return false;
1186             }
1187             if ( !i_m_all.getState( "ad", "0" ).contains( "C" ) ) {
1188                 return false;
1189             }
1190             if ( i_m_all.getState( "af", "0" ).size() != 1 ) {
1191                 return false;
1192             }
1193             if ( !i_m_all.getState( "af", "0" ).contains( "A" ) ) {
1194                 return false;
1195             }
1196             if ( i_m_all.getState( "ef", "0" ).size() != 2 ) {
1197                 return false;
1198             }
1199             if ( !i_m_all.getState( "ef", "0" ).contains( "A" ) ) {
1200                 return false;
1201             }
1202             if ( !i_m_all.getState( "ef", "0" ).contains( "D" ) ) {
1203                 return false;
1204             }
1205             if ( i_m_all.getState( "gi", "0" ).size() != 3 ) {
1206                 return false;
1207             }
1208             if ( !i_m_all.getState( "gi", "0" ).contains( "A" ) ) {
1209                 return false;
1210             }
1211             if ( !i_m_all.getState( "gi", "0" ).contains( "B" ) ) {
1212                 return false;
1213             }
1214             if ( !i_m_all.getState( "gi", "0" ).contains( "C" ) ) {
1215                 return false;
1216             }
1217             if ( i_m_all.getState( "ai", "0" ).size() != 1 ) {
1218                 return false;
1219             }
1220             if ( !i_m_all.getState( "ai", "0" ).contains( "A" ) ) {
1221                 return false;
1222             }
1223             if ( i_m_all.getState( "jl", "0" ).size() != 3 ) {
1224                 return false;
1225             }
1226             if ( !i_m_all.getState( "jl", "0" ).contains( "A" ) ) {
1227                 return false;
1228             }
1229             if ( !i_m_all.getState( "jl", "0" ).contains( "B" ) ) {
1230                 return false;
1231             }
1232             if ( !i_m_all.getState( "jl", "0" ).contains( "C" ) ) {
1233                 return false;
1234             }
1235             if ( i_m_all.getState( "mo", "0" ).size() != 1 ) {
1236                 return false;
1237             }
1238             if ( !i_m_all.getState( "mo", "0" ).contains( "B" ) ) {
1239                 return false;
1240             }
1241             if ( i_m_all.getState( "pr", "0" ).size() != 3 ) {
1242                 return false;
1243             }
1244             if ( !i_m_all.getState( "pr", "0" ).contains( "A" ) ) {
1245                 return false;
1246             }
1247             if ( !i_m_all.getState( "pr", "0" ).contains( "C" ) ) {
1248                 return false;
1249             }
1250             if ( !i_m_all.getState( "pr", "0" ).contains( "D" ) ) {
1251                 return false;
1252             }
1253             if ( i_m_all.getState( "jr", "0" ).size() != 4 ) {
1254                 return false;
1255             }
1256             if ( !i_m_all.getState( "jr", "0" ).contains( "A" ) ) {
1257                 return false;
1258             }
1259             if ( !i_m_all.getState( "jr", "0" ).contains( "B" ) ) {
1260                 return false;
1261             }
1262             if ( !i_m_all.getState( "jr", "0" ).contains( "C" ) ) {
1263                 return false;
1264             }
1265             if ( !i_m_all.getState( "jr", "0" ).contains( "D" ) ) {
1266                 return false;
1267             }
1268             final FitchParsimony<String> fitch2 = new FitchParsimony<String>();
1269             final PhylogenyFactory factory2 = ParserBasedPhylogenyFactory.getInstance();
1270             final String p2_str = "((a,b)ab,(c,(d,e)de)cde)r";
1271             final Phylogeny p2 = factory2.create( p2_str, new NHXParser() )[ 0 ];
1272             final CharacterStateMatrix<String> m2 = new BasicCharacterStateMatrix<String>( 5, 1 );
1273             m2.setIdentifier( 0, "a" );
1274             m2.setIdentifier( 1, "b" );
1275             m2.setIdentifier( 2, "c" );
1276             m2.setIdentifier( 3, "d" );
1277             m2.setIdentifier( 4, "e" );
1278             m2.setCharacter( 0, "0" );
1279             m2.setState( "a", "0", "C" );
1280             m2.setState( "b", "0", "A" );
1281             m2.setState( "c", "0", "C" );
1282             m2.setState( "d", "0", "A" );
1283             m2.setState( "e", "0", "G" );
1284             fitch2.setReturnInternalStates( true );
1285             fitch2.setReturnGainLossMatrix( false );
1286             fitch2.execute( p2, m2 );
1287             final CharacterStateMatrix<String> i_m2 = fitch2.getInternalStatesMatrix();
1288             final CharacterStateMatrix<List<String>> i_m_all2 = fitch2.getInternalStatesMatrixPriorToTraceback();
1289             if ( fitch2.getCost() != 3 ) {
1290                 return false;
1291             }
1292             if ( !i_m2.getState( "ab", "0" ).equals( "A" ) ) {
1293                 return false;
1294             }
1295             if ( !i_m2.getState( "de", "0" ).equals( "A" ) ) {
1296                 return false;
1297             }
1298             if ( !i_m2.getState( "cde", "0" ).equals( "A" ) ) {
1299                 return false;
1300             }
1301             if ( !i_m2.getState( "r", "0" ).equals( "A" ) ) {
1302                 return false;
1303             }
1304             if ( i_m_all2.getState( "cde", "0" ).size() != 3 ) {
1305                 return false;
1306             }
1307             if ( !i_m_all2.getState( "cde", "0" ).contains( "A" ) ) {
1308                 return false;
1309             }
1310             if ( !i_m_all2.getState( "cde", "0" ).contains( "C" ) ) {
1311                 return false;
1312             }
1313             if ( !i_m_all2.getState( "cde", "0" ).contains( "G" ) ) {
1314                 return false;
1315             }
1316             if ( i_m_all2.getState( "ab", "0" ).size() != 2 ) {
1317                 return false;
1318             }
1319             if ( !i_m_all2.getState( "ab", "0" ).contains( "A" ) ) {
1320                 return false;
1321             }
1322             if ( !i_m_all2.getState( "ab", "0" ).contains( "C" ) ) {
1323                 return false;
1324             }
1325             fitch2.setReturnInternalStates( true );
1326             fitch2.setReturnGainLossMatrix( false );
1327             fitch2.setUseLast( true );
1328             fitch2.execute( p2, m2 );
1329             final CharacterStateMatrix<String> i_m21 = fitch2.getInternalStatesMatrix();
1330             final CharacterStateMatrix<List<String>> i_m_all21 = fitch2.getInternalStatesMatrixPriorToTraceback();
1331             if ( fitch2.getCost() != 3 ) {
1332                 return false;
1333             }
1334             if ( !i_m21.getState( "ab", "0" ).equals( "C" ) ) {
1335                 return false;
1336             }
1337             if ( !i_m21.getState( "de", "0" ).equals( "G" ) ) {
1338                 return false;
1339             }
1340             if ( !i_m21.getState( "cde", "0" ).equals( "C" ) ) {
1341                 return false;
1342             }
1343             if ( !i_m21.getState( "r", "0" ).equals( "C" ) ) {
1344                 return false;
1345             }
1346             if ( i_m_all21.getState( "cde", "0" ).size() != 3 ) {
1347                 return false;
1348             }
1349             if ( !i_m_all21.getState( "cde", "0" ).contains( "A" ) ) {
1350                 return false;
1351             }
1352             if ( !i_m_all21.getState( "cde", "0" ).contains( "C" ) ) {
1353                 return false;
1354             }
1355             if ( !i_m_all21.getState( "cde", "0" ).contains( "G" ) ) {
1356                 return false;
1357             }
1358             final FitchParsimony<String> fitch3 = new FitchParsimony<String>();
1359             final PhylogenyFactory factory3 = ParserBasedPhylogenyFactory.getInstance();
1360             final String p3_str = "(((a,b)ab,((c,d)cd,e)cde)abcde,f)r";
1361             final Phylogeny p3 = factory3.create( p3_str, new NHXParser() )[ 0 ];
1362             final CharacterStateMatrix<String> m3 = new BasicCharacterStateMatrix<String>( 6, 1 );
1363             m3.setIdentifier( 0, "a" );
1364             m3.setIdentifier( 1, "b" );
1365             m3.setIdentifier( 2, "c" );
1366             m3.setIdentifier( 3, "d" );
1367             m3.setIdentifier( 4, "e" );
1368             m3.setIdentifier( 5, "f" );
1369             m3.setCharacter( 0, "0" );
1370             m3.setState( "a", "0", "C" );
1371             m3.setState( "b", "0", "U" );
1372             m3.setState( "c", "0", "G" );
1373             m3.setState( "d", "0", "U" );
1374             m3.setState( "e", "0", "A" );
1375             m3.setState( "f", "0", "A" );
1376             fitch3.setReturnInternalStates( true );
1377             fitch3.setReturnGainLossMatrix( false );
1378             fitch3.execute( p3, m3 );
1379             final CharacterStateMatrix<String> i_m3 = fitch3.getInternalStatesMatrix();
1380             final CharacterStateMatrix<List<String>> i_m_all3 = fitch3.getInternalStatesMatrixPriorToTraceback();
1381             if ( fitch3.getCost() != 4 ) {
1382                 return false;
1383             }
1384             if ( !i_m3.getState( "ab", "0" ).equals( "U" ) ) {
1385                 return false;
1386             }
1387             if ( !i_m3.getState( "cd", "0" ).equals( "U" ) ) {
1388                 return false;
1389             }
1390             if ( !i_m3.getState( "cde", "0" ).equals( "U" ) ) {
1391                 return false;
1392             }
1393             if ( !i_m3.getState( "abcde", "0" ).equals( "U" ) ) {
1394                 return false;
1395             }
1396             if ( !i_m3.getState( "r", "0" ).equals( "A" ) ) {
1397                 return false;
1398             }
1399             if ( i_m_all3.getState( "cde", "0" ).size() != 3 ) {
1400                 return false;
1401             }
1402             if ( !i_m_all3.getState( "cde", "0" ).contains( "A" ) ) {
1403                 return false;
1404             }
1405             if ( !i_m_all3.getState( "cde", "0" ).contains( "G" ) ) {
1406                 return false;
1407             }
1408             if ( !i_m_all3.getState( "cde", "0" ).contains( "U" ) ) {
1409                 return false;
1410             }
1411             if ( i_m_all3.getState( "ab", "0" ).size() != 2 ) {
1412                 return false;
1413             }
1414             if ( !i_m_all3.getState( "ab", "0" ).contains( "C" ) ) {
1415                 return false;
1416             }
1417             if ( !i_m_all3.getState( "ab", "0" ).contains( "U" ) ) {
1418                 return false;
1419             }
1420             if ( i_m_all3.getState( "cd", "0" ).size() != 2 ) {
1421                 return false;
1422             }
1423             if ( !i_m_all3.getState( "cd", "0" ).contains( "G" ) ) {
1424                 return false;
1425             }
1426             if ( !i_m_all3.getState( "cd", "0" ).contains( "U" ) ) {
1427                 return false;
1428             }
1429             if ( i_m_all3.getState( "abcde", "0" ).size() != 1 ) {
1430                 return false;
1431             }
1432             if ( !i_m_all3.getState( "abcde", "0" ).contains( "U" ) ) {
1433                 return false;
1434             }
1435             if ( i_m_all3.getState( "r", "0" ).size() != 2 ) {
1436                 return false;
1437             }
1438             if ( !i_m_all3.getState( "r", "0" ).contains( "A" ) ) {
1439                 return false;
1440             }
1441             if ( !i_m_all3.getState( "r", "0" ).contains( "U" ) ) {
1442                 return false;
1443             }
1444             final FitchParsimony<BinaryStates> fitch4 = new FitchParsimony<BinaryStates>();
1445             final PhylogenyFactory factory4 = ParserBasedPhylogenyFactory.getInstance();
1446             final String p4_str = "(((a,b)ab,((c,d)cd,e)cde)abcde,f)r";
1447             final Phylogeny p4 = factory4.create( p4_str, new NHXParser() )[ 0 ];
1448             final CharacterStateMatrix<BinaryStates> m4 = new BasicCharacterStateMatrix<BinaryStates>( 6, 1 );
1449             m4.setIdentifier( 0, "a" );
1450             m4.setIdentifier( 1, "b" );
1451             m4.setIdentifier( 2, "c" );
1452             m4.setIdentifier( 3, "d" );
1453             m4.setIdentifier( 4, "e" );
1454             m4.setIdentifier( 5, "f" );
1455             m4.setCharacter( 0, "0" );
1456             m4.setState( "a", "0", PRESENT );
1457             m4.setState( "b", "0", ABSENT );
1458             m4.setState( "c", "0", PRESENT );
1459             m4.setState( "d", "0", PRESENT );
1460             m4.setState( "e", "0", ABSENT );
1461             m4.setState( "f", "0", ABSENT );
1462             fitch4.setReturnInternalStates( true );
1463             fitch4.setReturnGainLossMatrix( true );
1464             fitch4.execute( p4, m4 );
1465             final CharacterStateMatrix<GainLossStates> gl_m_4 = fitch4.getGainLossMatrix();
1466             if ( fitch4.getCost() != 2 ) {
1467                 return false;
1468             }
1469             if ( fitch4.getTotalLosses() != 0 ) {
1470                 return false;
1471             }
1472             if ( fitch4.getTotalGains() != 2 ) {
1473                 return false;
1474             }
1475             if ( fitch4.getTotalUnchanged() != 9 ) {
1476                 return false;
1477             }
1478             if ( gl_m_4.getState( "a", "0" ) != GAIN ) {
1479                 return false;
1480             }
1481             if ( gl_m_4.getState( "b", "0" ) != UNCHANGED_ABSENT ) {
1482                 return false;
1483             }
1484             if ( gl_m_4.getState( "ab", "0" ) != UNCHANGED_ABSENT ) {
1485                 return false;
1486             }
1487             if ( gl_m_4.getState( "cd", "0" ) != GAIN ) {
1488                 return false;
1489             }
1490             if ( gl_m_4.getState( "r", "0" ) != UNCHANGED_ABSENT ) {
1491                 return false;
1492             }
1493             final FitchParsimony<BinaryStates> fitch5 = new FitchParsimony<BinaryStates>();
1494             final PhylogenyFactory factory5 = ParserBasedPhylogenyFactory.getInstance();
1495             final String p5_str = "(((a,b)ab,((c,d)cd,e)cde)abcde,f)r";
1496             final Phylogeny p5 = factory5.create( p5_str, new NHXParser() )[ 0 ];
1497             final CharacterStateMatrix<BinaryStates> m5 = new BasicCharacterStateMatrix<BinaryStates>( 6, 1 );
1498             m5.setIdentifier( 0, "a" );
1499             m5.setIdentifier( 1, "b" );
1500             m5.setIdentifier( 2, "c" );
1501             m5.setIdentifier( 3, "d" );
1502             m5.setIdentifier( 4, "e" );
1503             m5.setIdentifier( 5, "f" );
1504             m5.setCharacter( 0, "0" );
1505             m5.setState( "a", "0", PRESENT );
1506             m5.setState( "b", "0", ABSENT );
1507             m5.setState( "c", "0", PRESENT );
1508             m5.setState( "d", "0", ABSENT );
1509             m5.setState( "e", "0", PRESENT );
1510             m5.setState( "f", "0", ABSENT );
1511             fitch5.setReturnInternalStates( true );
1512             fitch5.setReturnGainLossMatrix( true );
1513             fitch5.execute( p5, m5 );
1514             final CharacterStateMatrix<GainLossStates> gl_m_5 = fitch5.getGainLossMatrix();
1515             if ( fitch5.getCost() != 3 ) {
1516                 return false;
1517             }
1518             if ( fitch5.getTotalLosses() != 2 ) {
1519                 return false;
1520             }
1521             if ( fitch5.getTotalGains() != 1 ) {
1522                 return false;
1523             }
1524             if ( fitch5.getTotalUnchanged() != 8 ) {
1525                 return false;
1526             }
1527             if ( gl_m_5.getState( "abcde", "0" ) != GAIN ) {
1528                 return false;
1529             }
1530             if ( gl_m_5.getState( "a", "0" ) != UNCHANGED_PRESENT ) {
1531                 return false;
1532             }
1533             if ( gl_m_5.getState( "b", "0" ) != LOSS ) {
1534                 return false;
1535             }
1536             if ( gl_m_5.getState( "d", "0" ) != LOSS ) {
1537                 return false;
1538             }
1539             if ( gl_m_5.getState( "r", "0" ) != UNCHANGED_ABSENT ) {
1540                 return false;
1541             }
1542             final FitchParsimony<BinaryStates> fitch6 = new FitchParsimony<BinaryStates>();
1543             final PhylogenyFactory factory6 = ParserBasedPhylogenyFactory.getInstance();
1544             final String p6_str = "(((a,b)ab,((c,d)cd,e)cde)abcde,f)r";
1545             final Phylogeny p6 = factory6.create( p6_str, new NHXParser() )[ 0 ];
1546             final CharacterStateMatrix<BinaryStates> m6 = new BasicCharacterStateMatrix<BinaryStates>( 6, 1 );
1547             m6.setIdentifier( 0, "a" );
1548             m6.setIdentifier( 1, "b" );
1549             m6.setIdentifier( 2, "c" );
1550             m6.setIdentifier( 3, "d" );
1551             m6.setIdentifier( 4, "e" );
1552             m6.setIdentifier( 5, "f" );
1553             m6.setCharacter( 0, "0" );
1554             m6.setState( "a", "0", PRESENT );
1555             m6.setState( "b", "0", ABSENT );
1556             m6.setState( "c", "0", PRESENT );
1557             m6.setState( "d", "0", PRESENT );
1558             m6.setState( "e", "0", ABSENT );
1559             m6.setState( "f", "0", PRESENT );
1560             fitch6.setReturnInternalStates( true );
1561             fitch6.setReturnGainLossMatrix( true );
1562             fitch6.execute( p6, m6 );
1563             final CharacterStateMatrix<GainLossStates> gl_m_6 = fitch6.getGainLossMatrix();
1564             if ( fitch6.getCost() != 2 ) {
1565                 return false;
1566             }
1567             if ( fitch6.getTotalLosses() != 2 ) {
1568                 return false;
1569             }
1570             if ( fitch6.getTotalGains() != 0 ) {
1571                 return false;
1572             }
1573             if ( fitch6.getTotalUnchanged() != 9 ) {
1574                 return false;
1575             }
1576             if ( gl_m_6.getState( "abcde", "0" ) != UNCHANGED_PRESENT ) {
1577                 return false;
1578             }
1579             if ( gl_m_6.getState( "r", "0" ) != UNCHANGED_PRESENT ) {
1580                 return false;
1581             }
1582             if ( gl_m_6.getState( "b", "0" ) != LOSS ) {
1583                 return false;
1584             }
1585             if ( gl_m_6.getState( "e", "0" ) != LOSS ) {
1586                 return false;
1587             }
1588             final FitchParsimony<BinaryStates> fitch7 = new FitchParsimony<BinaryStates>();
1589             final PhylogenyFactory factory7 = ParserBasedPhylogenyFactory.getInstance();
1590             final String p7_str = "(((a,b)ab,(c,d)cd)abcd,((e,f)ef,(g,h)gh)efgh)r";
1591             final Phylogeny p7 = factory7.create( p7_str, new NHXParser() )[ 0 ];
1592             final CharacterStateMatrix<BinaryStates> m7 = new BasicCharacterStateMatrix<BinaryStates>( 8, 1 );
1593             m7.setIdentifier( 0, "a" );
1594             m7.setIdentifier( 1, "b" );
1595             m7.setIdentifier( 2, "c" );
1596             m7.setIdentifier( 3, "d" );
1597             m7.setIdentifier( 4, "e" );
1598             m7.setIdentifier( 5, "f" );
1599             m7.setIdentifier( 6, "g" );
1600             m7.setIdentifier( 7, "h" );
1601             m7.setCharacter( 0, "0" );
1602             m7.setState( "a", "0", PRESENT );
1603             m7.setState( "b", "0", ABSENT );
1604             m7.setState( "c", "0", PRESENT );
1605             m7.setState( "d", "0", ABSENT );
1606             m7.setState( "e", "0", PRESENT );
1607             m7.setState( "f", "0", ABSENT );
1608             m7.setState( "g", "0", PRESENT );
1609             m7.setState( "h", "0", ABSENT );
1610             fitch7.setReturnInternalStates( true );
1611             fitch7.setReturnGainLossMatrix( true );
1612             fitch7.execute( p7, m7 );
1613             final CharacterStateMatrix<GainLossStates> gl_m_7 = fitch7.getGainLossMatrix();
1614             if ( fitch7.getCost() != 4 ) {
1615                 return false;
1616             }
1617             if ( fitch7.getTotalLosses() != 0 ) {
1618                 return false;
1619             }
1620             if ( fitch7.getTotalGains() != 4 ) {
1621                 return false;
1622             }
1623             if ( fitch7.getTotalUnchanged() != 11 ) {
1624                 return false;
1625             }
1626             if ( gl_m_7.getState( "a", "0" ) != GAIN ) {
1627                 return false;
1628             }
1629             if ( gl_m_7.getState( "c", "0" ) != GAIN ) {
1630                 return false;
1631             }
1632             if ( gl_m_7.getState( "e", "0" ) != GAIN ) {
1633                 return false;
1634             }
1635             if ( gl_m_7.getState( "g", "0" ) != GAIN ) {
1636                 return false;
1637             }
1638             if ( gl_m_7.getState( "r", "0" ) != UNCHANGED_ABSENT ) {
1639                 return false;
1640             }
1641             fitch7.setReturnInternalStates( true );
1642             fitch7.setReturnGainLossMatrix( true );
1643             fitch7.setUseLast( true );
1644             fitch7.execute( p7, m7 );
1645             final CharacterStateMatrix<GainLossStates> gl_m_71 = fitch7.getGainLossMatrix();
1646             if ( fitch7.getCost() != 4 ) {
1647                 return false;
1648             }
1649             if ( fitch7.getTotalLosses() != 4 ) {
1650                 return false;
1651             }
1652             if ( fitch7.getTotalGains() != 0 ) {
1653                 return false;
1654             }
1655             if ( fitch7.getTotalUnchanged() != 11 ) {
1656                 return false;
1657             }
1658             if ( gl_m_71.getState( "b", "0" ) != LOSS ) {
1659                 return false;
1660             }
1661             if ( gl_m_71.getState( "d", "0" ) != LOSS ) {
1662                 return false;
1663             }
1664             if ( gl_m_71.getState( "f", "0" ) != LOSS ) {
1665                 return false;
1666             }
1667             if ( gl_m_71.getState( "h", "0" ) != LOSS ) {
1668                 return false;
1669             }
1670             if ( gl_m_71.getState( "r", "0" ) != UNCHANGED_PRESENT ) {
1671                 return false;
1672             }
1673             final FitchParsimony<BinaryStates> fitch8 = new FitchParsimony<BinaryStates>();
1674             final PhylogenyFactory factory8 = ParserBasedPhylogenyFactory.getInstance();
1675             final String p8_str = "(((a,b)ab,(c,d)cd)abcd,((e,f)ef,(g,h)gh)efgh)r";
1676             final Phylogeny p8 = factory8.create( p8_str, new NHXParser() )[ 0 ];
1677             final CharacterStateMatrix<BinaryStates> m8 = new BasicCharacterStateMatrix<BinaryStates>( 8, 1 );
1678             m8.setIdentifier( 0, "a" );
1679             m8.setIdentifier( 1, "b" );
1680             m8.setIdentifier( 2, "c" );
1681             m8.setIdentifier( 3, "d" );
1682             m8.setIdentifier( 4, "e" );
1683             m8.setIdentifier( 5, "f" );
1684             m8.setIdentifier( 6, "g" );
1685             m8.setIdentifier( 7, "h" );
1686             m8.setCharacter( 0, "0" );
1687             m8.setState( "a", "0", PRESENT );
1688             m8.setState( "b", "0", PRESENT );
1689             m8.setState( "c", "0", PRESENT );
1690             m8.setState( "d", "0", ABSENT );
1691             m8.setState( "e", "0", ABSENT );
1692             m8.setState( "f", "0", ABSENT );
1693             m8.setState( "g", "0", ABSENT );
1694             m8.setState( "h", "0", ABSENT );
1695             fitch8.setReturnInternalStates( true );
1696             fitch8.setReturnGainLossMatrix( true );
1697             fitch8.execute( p8, m8 );
1698             final CharacterStateMatrix<GainLossStates> gl_m_8 = fitch8.getGainLossMatrix();
1699             if ( fitch8.getCost() != 2 ) {
1700                 return false;
1701             }
1702             if ( fitch8.getTotalLosses() != 1 ) {
1703                 return false;
1704             }
1705             if ( fitch8.getTotalGains() != 1 ) {
1706                 return false;
1707             }
1708             if ( fitch8.getTotalUnchanged() != 13 ) {
1709                 return false;
1710             }
1711             if ( gl_m_8.getState( "d", "0" ) != LOSS ) {
1712                 return false;
1713             }
1714             if ( gl_m_8.getState( "abcd", "0" ) != GAIN ) {
1715                 return false;
1716             }
1717             final FitchParsimony<BinaryStates> fitch9 = new FitchParsimony<BinaryStates>();
1718             final PhylogenyFactory factory9 = ParserBasedPhylogenyFactory.getInstance();
1719             final String p9_str = "(((a,b)ab,c)abc,d)abcd";
1720             final Phylogeny p9 = factory9.create( p9_str, new NHXParser() )[ 0 ];
1721             final CharacterStateMatrix<BinaryStates> m9 = new BasicCharacterStateMatrix<BinaryStates>( 4, 1 );
1722             m9.setIdentifier( 0, "a" );
1723             m9.setIdentifier( 1, "b" );
1724             m9.setIdentifier( 2, "c" );
1725             m9.setIdentifier( 3, "d" );
1726             m9.setCharacter( 0, "0" );
1727             m9.setState( "a", "0", PRESENT );
1728             m9.setState( "b", "0", ABSENT );
1729             m9.setState( "c", "0", PRESENT );
1730             m9.setState( "d", "0", ABSENT );
1731             fitch9.setReturnInternalStates( true );
1732             fitch9.setReturnGainLossMatrix( true );
1733             fitch9.setUseLast( false );
1734             fitch9.execute( p9, m9 );
1735             final CharacterStateMatrix<GainLossStates> gl_m_9a = fitch9.getGainLossMatrix();
1736             if ( fitch9.getCost() != 2 ) {
1737                 return false;
1738             }
1739             if ( fitch9.getTotalLosses() != 1 ) {
1740                 return false;
1741             }
1742             if ( fitch9.getTotalGains() != 1 ) {
1743                 return false;
1744             }
1745             if ( fitch9.getTotalUnchanged() != 5 ) {
1746                 return false;
1747             }
1748             if ( gl_m_9a.getState( "a", "0" ) != UNCHANGED_PRESENT ) {
1749                 return false;
1750             }
1751             if ( gl_m_9a.getState( "b", "0" ) != LOSS ) {
1752                 return false;
1753             }
1754             if ( gl_m_9a.getState( "c", "0" ) != UNCHANGED_PRESENT ) {
1755                 return false;
1756             }
1757             if ( gl_m_9a.getState( "d", "0" ) != UNCHANGED_ABSENT ) {
1758                 return false;
1759             }
1760             if ( gl_m_9a.getState( "ab", "0" ) != UNCHANGED_PRESENT ) {
1761                 return false;
1762             }
1763             if ( gl_m_9a.getState( "abc", "0" ) != GAIN ) {
1764                 return false;
1765             }
1766             if ( gl_m_9a.getState( "abcd", "0" ) != UNCHANGED_ABSENT ) {
1767                 return false;
1768             }
1769             fitch9.setUseLast( true );
1770             fitch9.execute( p9, m9 );
1771             final CharacterStateMatrix<GainLossStates> gl_m_9b = fitch9.getGainLossMatrix();
1772             if ( fitch9.getCost() != 2 ) {
1773                 return false;
1774             }
1775             if ( fitch9.getTotalLosses() != 2 ) {
1776                 return false;
1777             }
1778             if ( fitch9.getTotalGains() != 0 ) {
1779                 return false;
1780             }
1781             if ( fitch9.getTotalUnchanged() != 5 ) {
1782                 return false;
1783             }
1784             if ( gl_m_9b.getState( "a", "0" ) != UNCHANGED_PRESENT ) {
1785                 return false;
1786             }
1787             if ( gl_m_9b.getState( "b", "0" ) != LOSS ) {
1788                 return false;
1789             }
1790             if ( gl_m_9b.getState( "c", "0" ) != UNCHANGED_PRESENT ) {
1791                 return false;
1792             }
1793             if ( gl_m_9b.getState( "d", "0" ) != LOSS ) {
1794                 return false;
1795             }
1796             if ( gl_m_9b.getState( "ab", "0" ) != UNCHANGED_PRESENT ) {
1797                 return false;
1798             }
1799             if ( gl_m_9b.getState( "abc", "0" ) != UNCHANGED_PRESENT ) {
1800                 return false;
1801             }
1802             if ( gl_m_9b.getState( "abcd", "0" ) != UNCHANGED_PRESENT ) {
1803                 return false;
1804             }
1805             fitch9.setUseLast( false );
1806             fitch9.setRandomize( true );
1807             fitch9.setRandomNumberSeed( 8722445 );
1808             fitch9.execute( p9, m9 );
1809             fitch9.getGainLossMatrix();
1810             if ( fitch9.getCost() != 2 ) {
1811                 return false;
1812             }
1813             if ( fitch9.getTotalLosses() != 1 ) {
1814                 return false;
1815             }
1816             if ( fitch9.getTotalGains() != 1 ) {
1817                 return false;
1818             }
1819             if ( fitch9.getTotalUnchanged() != 5 ) {
1820                 return false;
1821             }
1822             final FitchParsimony<BinaryStates> fitch10 = new FitchParsimony<BinaryStates>();
1823             final PhylogenyFactory factory10 = ParserBasedPhylogenyFactory.getInstance();
1824             final String p10_str = "((((a,b)ab,c)abc,d)abcd,e)abcde";
1825             final Phylogeny p10 = factory10.create( p10_str, new NHXParser() )[ 0 ];
1826             final CharacterStateMatrix<BinaryStates> m10 = new BasicCharacterStateMatrix<BinaryStates>( 5, 1 );
1827             m10.setIdentifier( 0, "a" );
1828             m10.setIdentifier( 1, "b" );
1829             m10.setIdentifier( 2, "c" );
1830             m10.setIdentifier( 3, "d" );
1831             m10.setIdentifier( 4, "e" );
1832             m10.setCharacter( 0, "0" );
1833             m10.setState( "a", "0", PRESENT );
1834             m10.setState( "b", "0", ABSENT );
1835             m10.setState( "c", "0", ABSENT );
1836             m10.setState( "d", "0", PRESENT );
1837             m10.setState( "e", "0", ABSENT );
1838             fitch10.setReturnInternalStates( true );
1839             fitch10.setReturnGainLossMatrix( true );
1840             fitch10.setUseLast( false );
1841             fitch10.execute( p10, m10 );
1842             final CharacterStateMatrix<GainLossStates> gl_m_10a = fitch10.getGainLossMatrix();
1843             if ( fitch10.getCost() != 2 ) {
1844                 return false;
1845             }
1846             if ( fitch10.getTotalLosses() != 0 ) {
1847                 return false;
1848             }
1849             if ( fitch10.getTotalGains() != 2 ) {
1850                 return false;
1851             }
1852             if ( fitch10.getTotalUnchanged() != 7 ) {
1853                 return false;
1854             }
1855             if ( gl_m_10a.getState( "a", "0" ) != GAIN ) {
1856                 return false;
1857             }
1858             if ( gl_m_10a.getState( "b", "0" ) != UNCHANGED_ABSENT ) {
1859                 return false;
1860             }
1861             if ( gl_m_10a.getState( "c", "0" ) != UNCHANGED_ABSENT ) {
1862                 return false;
1863             }
1864             if ( gl_m_10a.getState( "d", "0" ) != GAIN ) {
1865                 return false;
1866             }
1867             if ( gl_m_10a.getState( "e", "0" ) != UNCHANGED_ABSENT ) {
1868                 return false;
1869             }
1870             if ( gl_m_10a.getState( "ab", "0" ) != UNCHANGED_ABSENT ) {
1871                 return false;
1872             }
1873             if ( gl_m_10a.getState( "abc", "0" ) != UNCHANGED_ABSENT ) {
1874                 return false;
1875             }
1876             if ( gl_m_10a.getState( "abcd", "0" ) != UNCHANGED_ABSENT ) {
1877                 return false;
1878             }
1879             if ( gl_m_10a.getState( "abcde", "0" ) != UNCHANGED_ABSENT ) {
1880                 return false;
1881             }
1882             fitch10.setUseLast( true );
1883             fitch10.execute( p10, m10 );
1884             final CharacterStateMatrix<GainLossStates> gl_m_10b = fitch10.getGainLossMatrix();
1885             if ( fitch10.getCost() != 2 ) {
1886                 return false;
1887             }
1888             if ( fitch10.getTotalLosses() != 0 ) {
1889                 return false;
1890             }
1891             if ( fitch10.getTotalGains() != 2 ) {
1892                 return false;
1893             }
1894             if ( fitch10.getTotalUnchanged() != 7 ) {
1895                 return false;
1896             }
1897             if ( gl_m_10b.getState( "a", "0" ) != GAIN ) {
1898                 return false;
1899             }
1900             if ( gl_m_10b.getState( "b", "0" ) != UNCHANGED_ABSENT ) {
1901                 return false;
1902             }
1903             if ( gl_m_10b.getState( "c", "0" ) != UNCHANGED_ABSENT ) {
1904                 return false;
1905             }
1906             if ( gl_m_10b.getState( "d", "0" ) != GAIN ) {
1907                 return false;
1908             }
1909             if ( gl_m_10b.getState( "e", "0" ) != UNCHANGED_ABSENT ) {
1910                 return false;
1911             }
1912             if ( gl_m_10b.getState( "ab", "0" ) != UNCHANGED_ABSENT ) {
1913                 return false;
1914             }
1915             if ( gl_m_10b.getState( "abc", "0" ) != UNCHANGED_ABSENT ) {
1916                 return false;
1917             }
1918             if ( gl_m_10b.getState( "abcd", "0" ) != UNCHANGED_ABSENT ) {
1919                 return false;
1920             }
1921             if ( gl_m_10b.getState( "abcde", "0" ) != UNCHANGED_ABSENT ) {
1922                 return false;
1923             }
1924         }
1925         catch ( final Exception e ) {
1926             e.printStackTrace( System.out );
1927             return false;
1928         }
1929         return true;
1930     }
1931
1932     private static boolean testNeighborJoining() {
1933         try {
1934             NeighborJoining nj = NeighborJoining.createInstance();
1935             final BasicSymmetricalDistanceMatrix m0 = new BasicSymmetricalDistanceMatrix( 4 );
1936             m0.setIdentifier( 0, "A" );
1937             m0.setIdentifier( 1, "B" );
1938             m0.setIdentifier( 2, "C" );
1939             m0.setIdentifier( 3, "D" );
1940             m0.setRow( "5 ", 1 );
1941             m0.setRow( "3 6 ", 2 );
1942             m0.setRow( "7.5 10.5 5.5", 3 );
1943             final Phylogeny p0 = nj.execute( m0 );
1944             p0.reRoot( p0.getNode( "D" ) );
1945             if ( isUnequal( p0.getNode( "A" ).getDistanceToParent(), 1 ) ) {
1946                 return false;
1947             }
1948             if ( isUnequal( p0.getNode( "B" ).getDistanceToParent(), 4 ) ) {
1949                 return false;
1950             }
1951             if ( isUnequal( p0.getNode( "C" ).getDistanceToParent(), 0.5 ) ) {
1952                 return false;
1953             }
1954             if ( isUnequal( p0.getNode( "D" ).getDistanceToParent(), 2.5 ) ) {
1955                 return false;
1956             }
1957             if ( isUnequal( p0.getNode( "A" ).getParent().getDistanceToParent(), 1.5 ) ) {
1958                 return false;
1959             }
1960             if ( isUnequal( p0.getNode( "A" ).getParent().getParent().getDistanceToParent(), 2.5 ) ) {
1961                 return false;
1962             }
1963             nj = NeighborJoining.createInstance();
1964             final BasicSymmetricalDistanceMatrix m00 = new BasicSymmetricalDistanceMatrix( 4 );
1965             m00.setIdentifier( 0, "A" );
1966             m00.setIdentifier( 1, "B" );
1967             m00.setIdentifier( 2, "C" );
1968             m00.setIdentifier( 3, "D" );
1969             m00.setRow( "2.01 ", 1 );
1970             m00.setRow( "3 3.01 ", 2 );
1971             m00.setRow( "3.01 3.02 1.01", 3 );
1972             final Phylogeny p00 = nj.execute( m00 );
1973             p00.reRoot( p00.getNode( "D" ) );
1974             if ( isUnequal( p00.getNode( "A" ).getDistanceToParent(), 1 ) ) {
1975                 return false;
1976             }
1977             if ( isUnequal( p00.getNode( "B" ).getDistanceToParent(), 1.01 ) ) {
1978                 return false;
1979             }
1980             if ( isUnequal( p00.getNode( "C" ).getDistanceToParent(), 0.5 ) ) {
1981                 return false;
1982             }
1983             if ( isUnequal( p00.getNode( "D" ).getDistanceToParent(), 0.255 ) ) {
1984                 return false;
1985             }
1986             if ( isUnequal( p00.getNode( "A" ).getParent().getDistanceToParent(), 1.5 ) ) {
1987                 return false;
1988             }
1989             if ( isUnequal( p00.getNode( "A" ).getParent().getParent().getDistanceToParent(), 0.255 ) ) {
1990                 return false;
1991             }
1992             BasicSymmetricalDistanceMatrix m = new BasicSymmetricalDistanceMatrix( 6 );
1993             m.setRow( "5", 1 );
1994             m.setRow( "4 7", 2 );
1995             m.setRow( "7 10 7", 3 );
1996             m.setRow( "6 9 6 5", 4 );
1997             m.setRow( "8 11 8 9 8", 5 );
1998             m.setIdentifier( 0, "A" );
1999             m.setIdentifier( 1, "B" );
2000             m.setIdentifier( 2, "C" );
2001             m.setIdentifier( 3, "D" );
2002             m.setIdentifier( 4, "E" );
2003             m.setIdentifier( 5, "F" );
2004             nj = NeighborJoining.createInstance();
2005             final Phylogeny p1 = nj.execute( m );
2006             p1.reRoot( p1.getNode( "F" ) );
2007             if ( isUnequal( p1.getNode( "A" ).getDistanceToParent(), 1 ) ) {
2008                 return false;
2009             }
2010             if ( isUnequal( p1.getNode( "B" ).getDistanceToParent(), 4 ) ) {
2011                 return false;
2012             }
2013             if ( isUnequal( p1.getNode( "C" ).getDistanceToParent(), 2 ) ) {
2014                 return false;
2015             }
2016             if ( isUnequal( p1.getNode( "D" ).getDistanceToParent(), 3 ) ) {
2017                 return false;
2018             }
2019             if ( isUnequal( p1.getNode( "E" ).getDistanceToParent(), 2 ) ) {
2020                 return false;
2021             }
2022             if ( isUnequal( p1.getNode( "F" ).getDistanceToParent(), 2.5 ) ) {
2023                 return false;
2024             }
2025             if ( isUnequal( p1.getNode( "A" ).getParent().getDistanceToParent(), 1 ) ) {
2026                 return false;
2027             }
2028             if ( isUnequal( p1.getNode( "A" ).getParent().getParent().getDistanceToParent(), 1 ) ) {
2029                 return false;
2030             }
2031             if ( isUnequal( p1.getNode( "A" ).getParent().getParent().getParent().getDistanceToParent(), 2.5 ) ) {
2032                 return false;
2033             }
2034             if ( isUnequal( p1.getNode( "B" ).getParent().getDistanceToParent(), 1 ) ) {
2035                 return false;
2036             }
2037             if ( isUnequal( p1.getNode( "D" ).getParent().getDistanceToParent(), 1 ) ) {
2038                 return false;
2039             }
2040             if ( isUnequal( p1.getNode( "E" ).getParent().getDistanceToParent(), 1 ) ) {
2041                 return false;
2042             }
2043             m = new BasicSymmetricalDistanceMatrix( 7 );
2044             m.setIdentifier( 0, "Bovine" );
2045             m.setIdentifier( 1, "Mouse" );
2046             m.setIdentifier( 2, "Gibbon" );
2047             m.setIdentifier( 3, "Orang" );
2048             m.setIdentifier( 4, "Gorilla" );
2049             m.setIdentifier( 5, "Chimp" );
2050             m.setIdentifier( 6, "Human" );
2051             m.setRow( "0.00000 1.68660 1.71980 1.66060 1.52430 1.60430 1.59050", 0 );
2052             m.setRow( "1.68660 0.00000 1.52320 1.48410 1.44650 1.43890 1.46290", 1 );
2053             m.setRow( "1.71980 1.52320 0.00000 0.71150 0.59580 0.61790 0.55830", 2 );
2054             m.setRow( "1.66060 1.48410 0.71150 0.00000 0.46310 0.50610 0.47100", 3 );
2055             m.setRow( "1.52430 1.44650 0.59580 0.46310 0.00000 0.34840 0.30830", 4 );
2056             m.setRow( "1.60430 1.43890 0.61790 0.50610 0.34840 0.00000 0.26920", 5 );
2057             m.setRow( "1.59050 1.46290 0.55830 0.47100 0.30830 0.26920 0.00000", 6 );
2058             //NeighborJoiningR njr = NeighborJoiningR.createInstance( true, 6 );
2059             nj = NeighborJoining.createInstance( true, 6 );
2060             final Phylogeny p2 = nj.execute( m );
2061             //  Archaeopteryx.createApplication( p2 );
2062             p2.reRoot( p2.getNode( "Bovine" ) );
2063             if ( isUnequal( p2.getNode( "Chimp" ).getDistanceToParent(), 0.151675 ) ) {
2064                 return false;
2065             }
2066             if ( isUnequal( p2.getNode( "Human" ).getDistanceToParent(), 0.117525 ) ) {
2067                 return false;
2068             }
2069             if ( isUnequal( p2.getNode( "Gorilla" ).getDistanceToParent(), 0.153932 ) ) {
2070                 return false;
2071             }
2072             if ( isUnequal( p2.getNode( "Orang" ).getDistanceToParent(), 0.284694 ) ) {
2073                 return false;
2074             }
2075             if ( isUnequal( p2.getNode( "Gibbon" ).getDistanceToParent(), 0.357931 ) ) {
2076                 return false;
2077             }
2078             if ( isUnequal( p2.getNode( "Mouse" ).getDistanceToParent(), 0.76891 ) ) {
2079                 return false;
2080             }
2081             if ( isUnequal( p2.getNode( "Bovine" ).getDistanceToParent(), 0.458845 ) ) {
2082                 return false;
2083             }
2084             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getDistanceToParent(), 0.039819 ) ) {
2085                 return false;
2086             }
2087             if ( isUnequal( p2.getNode( "Human" ).getParent().getDistanceToParent(), 0.039819 ) ) {
2088                 return false;
2089             }
2090             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getDistanceToParent(), 0.026956 ) ) {
2091                 return false;
2092             }
2093             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getDistanceToParent(), 0.046481 ) ) {
2094                 return false;
2095             }
2096             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getParent().getDistanceToParent(),
2097                             0.420269 ) ) {
2098                 return false;
2099             }
2100             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getParent().getParent()
2101                     .getDistanceToParent(), 0.458845 ) ) {
2102                 return false;
2103             }
2104             m = new BasicSymmetricalDistanceMatrix( 4 );
2105             m.setIdentifier( 0, "A" );
2106             m.setIdentifier( 1, "B" );
2107             m.setIdentifier( 2, "C" );
2108             m.setIdentifier( 3, "D" );
2109             m.setRow( "0.00 0.95 0.17 0.98", 0 );
2110             m.setRow( "0.95 0.00 1.02 1.83", 1 );
2111             m.setRow( "0.17 1.02 0.00 1.01", 2 );
2112             m.setRow( "0.98 1.83 1.01 0.00", 3 );
2113             final Phylogeny p3 = nj.execute( m );
2114             p3.reRoot( p3.getNode( "C" ) );
2115             if ( isUnequal( p3.getNode( "A" ).getDistanceToParent(), 0.05 ) ) {
2116                 return false;
2117             }
2118             if ( isUnequal( p3.getNode( "B" ).getDistanceToParent(), 0.90 ) ) {
2119                 return false;
2120             }
2121             if ( !isEqual( p3.getNode( "C" ).getDistanceToParent(), 0.05 ) ) {
2122                 return false;
2123             }
2124             if ( !isEqual( p3.getNode( "D" ).getDistanceToParent(), 0.91 ) ) {
2125                 return false;
2126             }
2127             if ( isUnequal( p3.getNode( "A" ).getParent().getDistanceToParent(), 0.02 ) ) {
2128                 return false;
2129             }
2130             if ( isUnequal( p3.getNode( "A" ).getParent().getParent().getDistanceToParent(), 0.05 ) ) {
2131                 return false;
2132             }
2133             //
2134             NeighborJoiningF njf = NeighborJoiningF.createInstance();
2135             final BasicSymmetricalDistanceMatrix m0f = new BasicSymmetricalDistanceMatrix( 4 );
2136             m0f.setIdentifier( 0, "A" );
2137             m0f.setIdentifier( 1, "B" );
2138             m0f.setIdentifier( 2, "C" );
2139             m0f.setIdentifier( 3, "D" );
2140             m0f.setRow( "5 ", 1 );
2141             m0f.setRow( "3 6 ", 2 );
2142             m0f.setRow( "7.5 10.5 5.5", 3 );
2143             final Phylogeny p0f = njf.execute( m0f );
2144             p0f.reRoot( p0f.getNode( "D" ) );
2145             if ( isUnequal( p0f.getNode( "A" ).getDistanceToParent(), 1 ) ) {
2146                 return false;
2147             }
2148             if ( isUnequal( p0f.getNode( "B" ).getDistanceToParent(), 4 ) ) {
2149                 return false;
2150             }
2151             if ( isUnequal( p0f.getNode( "C" ).getDistanceToParent(), 0.5 ) ) {
2152                 return false;
2153             }
2154             if ( isUnequal( p0f.getNode( "D" ).getDistanceToParent(), 2.5 ) ) {
2155                 return false;
2156             }
2157             if ( isUnequal( p0f.getNode( "A" ).getParent().getDistanceToParent(), 1.5 ) ) {
2158                 return false;
2159             }
2160             if ( isUnequal( p0f.getNode( "A" ).getParent().getParent().getDistanceToParent(), 2.5 ) ) {
2161                 return false;
2162             }
2163             //
2164             m = new BasicSymmetricalDistanceMatrix( 7 );
2165             m.setIdentifier( 0, "Bovine" );
2166             m.setIdentifier( 1, "Mouse" );
2167             m.setIdentifier( 2, "Gibbon" );
2168             m.setIdentifier( 3, "Orang" );
2169             m.setIdentifier( 4, "Gorilla" );
2170             m.setIdentifier( 5, "Chimp" );
2171             m.setIdentifier( 6, "Human" );
2172             m.setRow( "0.00000 1.68660 1.71980 1.66060 1.52430 1.60430 1.59050", 0 );
2173             m.setRow( "1.68660 0.00000 1.52320 1.48410 1.44650 1.43890 1.46290", 1 );
2174             m.setRow( "1.71980 1.52320 0.00000 0.71150 0.59580 0.61790 0.55830", 2 );
2175             m.setRow( "1.66060 1.48410 0.71150 0.00000 0.46310 0.50610 0.47100", 3 );
2176             m.setRow( "1.52430 1.44650 0.59580 0.46310 0.00000 0.34840 0.30830", 4 );
2177             m.setRow( "1.60430 1.43890 0.61790 0.50610 0.34840 0.00000 0.26920", 5 );
2178             m.setRow( "1.59050 1.46290 0.55830 0.47100 0.30830 0.26920 0.00000", 6 );
2179             njf = NeighborJoiningF.createInstance( false, 5 );
2180             final Phylogeny p2f = njf.execute( m );
2181             p2f.reRoot( p2f.getNode( "Bovine" ) );
2182             if ( isUnequal( p2f.getNode( "Chimp" ).getDistanceToParent(), 0.15168 ) ) {
2183                 return false;
2184             }
2185             if ( isUnequal( p2f.getNode( "Human" ).getDistanceToParent(), 0.11752 ) ) {
2186                 return false;
2187             }
2188             if ( isUnequal( p2f.getNode( "Gorilla" ).getDistanceToParent(), 0.15393 ) ) {
2189                 return false;
2190             }
2191             if ( isUnequal( p2f.getNode( "Orang" ).getDistanceToParent(), 0.28469 ) ) {
2192                 return false;
2193             }
2194             if ( isUnequal( p2f.getNode( "Gibbon" ).getDistanceToParent(), 0.35793 ) ) {
2195                 return false;
2196             }
2197             if ( isUnequal( p2f.getNode( "Mouse" ).getDistanceToParent(), 0.76891 ) ) {
2198                 return false;
2199             }
2200             if ( isUnequal( p2f.getNode( "Bovine" ).getDistanceToParent(), 0.458845 ) ) {
2201                 return false;
2202             }
2203             if ( isUnequal( p2f.getNode( "Chimp" ).getParent().getDistanceToParent(), 0.03982 ) ) {
2204                 return false;
2205             }
2206             if ( isUnequal( p2f.getNode( "Human" ).getParent().getDistanceToParent(), 0.03982 ) ) {
2207                 return false;
2208             }
2209             if ( isUnequal( p2f.getNode( "Chimp" ).getParent().getParent().getDistanceToParent(), 0.02696 ) ) {
2210                 return false;
2211             }
2212             if ( isUnequal( p2f.getNode( "Chimp" ).getParent().getParent().getParent().getDistanceToParent(), 0.04648 ) ) {
2213                 return false;
2214             }
2215             if ( isUnequal( p2f.getNode( "Chimp" ).getParent().getParent().getParent().getParent()
2216                     .getDistanceToParent(), 0.42027 ) ) {
2217                 return false;
2218             }
2219             if ( isUnequal( p2f.getNode( "Chimp" ).getParent().getParent().getParent().getParent().getParent()
2220                     .getDistanceToParent(), 0.458845 ) ) {
2221                 return false;
2222             }
2223         }
2224         catch ( final Exception e ) {
2225             e.printStackTrace( System.out );
2226             return false;
2227         }
2228         return true;
2229     }
2230
2231     private static boolean testNeighborJoiningR() {
2232         try {
2233             final NeighborJoiningR nj = NeighborJoiningR.createInstance();
2234             //            final BasicSymmetricalDistanceMatrix m0 = new BasicSymmetricalDistanceMatrix( 4 );
2235             //            m0.setIdentifier( 0, "A" );
2236             //            m0.setIdentifier( 1, "B" );
2237             //            m0.setIdentifier( 2, "C" );
2238             //            m0.setIdentifier( 3, "D" );
2239             //            m0.setRow( "5 ", 1 );
2240             //            m0.setRow( "3 6 ", 2 );
2241             //            m0.setRow( "7.5 10.5 5.5", 3 );
2242             //            final Phylogeny p0 = nj.execute( m0 );
2243             //            p0.reRoot( p0.getNode( "D" ) );
2244             //            //  Archaeopteryx.createApplication( p0 );
2245             //            if ( isUnequal( p0.getNode( "A" ).getDistanceToParent(), 1 ) ) {
2246             //                return false;
2247             //            }
2248             //            if ( isUnequal( p0.getNode( "B" ).getDistanceToParent(), 4 ) ) {
2249             //                return false;
2250             //            }
2251             //            if ( isUnequal( p0.getNode( "C" ).getDistanceToParent(), 0.5 ) ) {
2252             //                return false;
2253             //            }
2254             //            if ( isUnequal( p0.getNode( "D" ).getDistanceToParent(), 2.5 ) ) {
2255             //                return false;
2256             //            }
2257             //            if ( isUnequal( p0.getNode( "A" ).getParent().getDistanceToParent(), 1.5 ) ) {
2258             //                return false;
2259             //            }
2260             //            if ( isUnequal( p0.getNode( "A" ).getParent().getParent().getDistanceToParent(), 2.5 ) ) {
2261             //                return false;
2262             //            }
2263             BasicSymmetricalDistanceMatrix m = new BasicSymmetricalDistanceMatrix( 6 );
2264             //            m.setRow( "5", 1 );
2265             //            m.setRow( "4 7", 2 );
2266             //            m.setRow( "7 10 7", 3 );
2267             //            m.setRow( "6 9 6 5", 4 );
2268             //            m.setRow( "8 11 8 9 8", 5 );
2269             //            m.setIdentifier( 0, "A" );
2270             //            m.setIdentifier( 1, "B" );
2271             //            m.setIdentifier( 2, "C" );
2272             //            m.setIdentifier( 3, "D" );
2273             //            m.setIdentifier( 4, "E" );
2274             //            m.setIdentifier( 5, "F" );
2275             //            nj = NeighborJoiningR.createInstance();
2276             //            final Phylogeny p1 = nj.execute( m );
2277             //            p1.reRoot( p1.getNode( "F" ) );
2278             //            Archaeopteryx.createApplication( p1 );
2279             //            if ( isUnequal( p1.getNode( "A" ).getDistanceToParent(), 1 ) ) {
2280             //                return false;
2281             //            }
2282             //            if ( isUnequal( p1.getNode( "B" ).getDistanceToParent(), 4 ) ) {
2283             //                return false;
2284             //            }
2285             //            if ( isUnequal( p1.getNode( "C" ).getDistanceToParent(), 2 ) ) {
2286             //                return false;
2287             //            }
2288             //            if ( isUnequal( p1.getNode( "D" ).getDistanceToParent(), 3 ) ) {
2289             //                return false;
2290             //            }
2291             //            if ( isUnequal( p1.getNode( "E" ).getDistanceToParent(), 2 ) ) {
2292             //                return false;
2293             //            }
2294             //            if ( isUnequal( p1.getNode( "F" ).getDistanceToParent(), 2.5 ) ) {
2295             //                return false;
2296             //            }
2297             //            if ( isUnequal( p1.getNode( "A" ).getParent().getDistanceToParent(), 1 ) ) {
2298             //                return false;
2299             //            }
2300             //            if ( isUnequal( p1.getNode( "A" ).getParent().getParent().getDistanceToParent(), 1 ) ) {
2301             //                return false;
2302             //            }
2303             //            if ( isUnequal( p1.getNode( "A" ).getParent().getParent().getParent().getDistanceToParent(), 2.5 ) ) {
2304             //                return false;
2305             //            }
2306             //            if ( isUnequal( p1.getNode( "B" ).getParent().getDistanceToParent(), 1 ) ) {
2307             //                return false;
2308             //            }
2309             //            if ( isUnequal( p1.getNode( "D" ).getParent().getDistanceToParent(), 1 ) ) {
2310             //                return false;
2311             //            }
2312             //            if ( isUnequal( p1.getNode( "E" ).getParent().getDistanceToParent(), 1 ) ) {
2313             //                return false;
2314             //            }
2315             ///////////////
2316             m = new BasicSymmetricalDistanceMatrix( 7 );
2317             m.setIdentifier( 0, "Bovine" );
2318             m.setIdentifier( 1, "Mouse" );
2319             m.setIdentifier( 2, "Gibbon" );
2320             m.setIdentifier( 3, "Orang" );
2321             m.setIdentifier( 4, "Gorilla" );
2322             m.setIdentifier( 5, "Chimp" );
2323             m.setIdentifier( 6, "Human" );
2324             m.setRow( "0.00000 1.68660 1.71980 1.66060 1.52430 1.60430 1.59050", 0 );
2325             m.setRow( "1.68660 0.00000 1.52320 1.48410 1.44650 1.43890 1.46290", 1 );
2326             m.setRow( "1.71980 1.52320 0.00000 0.71150 0.59580 0.61790 0.55830", 2 );
2327             m.setRow( "1.66060 1.48410 0.71150 0.00000 0.46310 0.50610 0.47100", 3 );
2328             m.setRow( "1.52430 1.44650 0.59580 0.46310 0.00000 0.34840 0.30830", 4 );
2329             m.setRow( "1.60430 1.43890 0.61790 0.50610 0.34840 0.00000 0.26920", 5 );
2330             m.setRow( "1.59050 1.46290 0.55830 0.47100 0.30830 0.26920 0.00000", 6 );
2331             final NeighborJoiningR njr = NeighborJoiningR.createInstance( true, 6 );
2332             //nj = NeighborJoining.createInstance( true, 6 );
2333             final Phylogeny p2 = njr.execute( m );
2334             //  Archaeopteryx.createApplication( p2 );
2335             p2.reRoot( p2.getNode( "Bovine" ) );
2336             if ( isUnequal( p2.getNode( "Chimp" ).getDistanceToParent(), 0.151675 ) ) {
2337                 return false;
2338             }
2339             if ( isUnequal( p2.getNode( "Human" ).getDistanceToParent(), 0.117525 ) ) {
2340                 return false;
2341             }
2342             if ( isUnequal( p2.getNode( "Gorilla" ).getDistanceToParent(), 0.153932 ) ) {
2343                 return false;
2344             }
2345             if ( isUnequal( p2.getNode( "Orang" ).getDistanceToParent(), 0.284694 ) ) {
2346                 return false;
2347             }
2348             if ( isUnequal( p2.getNode( "Gibbon" ).getDistanceToParent(), 0.357931 ) ) {
2349                 return false;
2350             }
2351             if ( isUnequal( p2.getNode( "Mouse" ).getDistanceToParent(), 0.76891 ) ) {
2352                 return false;
2353             }
2354             if ( isUnequal( p2.getNode( "Bovine" ).getDistanceToParent(), 0.458845 ) ) {
2355                 return false;
2356             }
2357             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getDistanceToParent(), 0.039819 ) ) {
2358                 return false;
2359             }
2360             if ( isUnequal( p2.getNode( "Human" ).getParent().getDistanceToParent(), 0.039819 ) ) {
2361                 return false;
2362             }
2363             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getDistanceToParent(), 0.026956 ) ) {
2364                 return false;
2365             }
2366             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getDistanceToParent(), 0.046481 ) ) {
2367                 return false;
2368             }
2369             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getParent().getDistanceToParent(),
2370                             0.420269 ) ) {
2371                 return false;
2372             }
2373             if ( isUnequal( p2.getNode( "Chimp" ).getParent().getParent().getParent().getParent().getParent()
2374                     .getDistanceToParent(), 0.458845 ) ) {
2375                 return false;
2376             }
2377         }
2378         catch ( final Exception e ) {
2379             e.printStackTrace( System.out );
2380             return false;
2381         }
2382         return true;
2383     }
2384
2385     private static boolean testSymmetricalDistanceMatrixParser() {
2386         try {
2387             final String l = ForesterUtil.getLineSeparator();
2388             StringBuffer source = new StringBuffer();
2389             source.append( " 4" + l );
2390             source.append( "A 0 0 0 0" + l );
2391             source.append( "B 1 0 0 0" + l );
2392             source.append( "C 2 4 0 0" + l );
2393             source.append( "D 3 5 6 0" + l );
2394             source.append( l );
2395             source.append( " 4" + l );
2396             source.append( "A 0   11  12  13" + l );
2397             source.append( "B 11  0   14  15" + l );
2398             source.append( "C 12  14  0   16" + l );
2399             source.append( "D 13  15  16  0" + l );
2400             source.append( l );
2401             source.append( l );
2402             source.append( "     " + l );
2403             source.append( " 4" + l );
2404             source.append( " A        0     " + l );
2405             source.append( " B            21 0" + l );
2406             source.append( " C            22 24    0  " + l );
2407             source.append( " # 2 222 2 2 " + l );
2408             source.append( " D            23 25 26 0" + l );
2409             source.append( l );
2410             source.append( l );
2411             source.append( "     " + l );
2412             final SymmetricalDistanceMatrixParser p0 = SymmetricalDistanceMatrixParser.createInstance();
2413             final DistanceMatrix[] ma0 = p0.parse( source.toString() );
2414             if ( ma0.length != 3 ) {
2415                 return false;
2416             }
2417             if ( !isEqual( ma0[ 0 ].getValue( 0, 0 ), 0 ) ) {
2418                 return false;
2419             }
2420             if ( !isEqual( ma0[ 0 ].getValue( 1, 0 ), 1 ) ) {
2421                 return false;
2422             }
2423             if ( !isEqual( ma0[ 0 ].getValue( 2, 0 ), 2 ) ) {
2424                 return false;
2425             }
2426             if ( !isEqual( ma0[ 0 ].getValue( 3, 0 ), 3 ) ) {
2427                 return false;
2428             }
2429             if ( !isEqual( ma0[ 0 ].getValue( 0, 1 ), 1 ) ) {
2430                 return false;
2431             }
2432             if ( !isEqual( ma0[ 0 ].getValue( 1, 1 ), 0 ) ) {
2433                 return false;
2434             }
2435             if ( !isEqual( ma0[ 0 ].getValue( 2, 1 ), 4 ) ) {
2436                 return false;
2437             }
2438             if ( !isEqual( ma0[ 0 ].getValue( 3, 1 ), 5 ) ) {
2439                 return false;
2440             }
2441             if ( !isEqual( ma0[ 1 ].getValue( 0, 0 ), 0 ) ) {
2442                 return false;
2443             }
2444             if ( !isEqual( ma0[ 1 ].getValue( 1, 0 ), 11 ) ) {
2445                 return false;
2446             }
2447             if ( !isEqual( ma0[ 1 ].getValue( 2, 0 ), 12 ) ) {
2448                 return false;
2449             }
2450             if ( !isEqual( ma0[ 1 ].getValue( 3, 0 ), 13 ) ) {
2451                 return false;
2452             }
2453             if ( !isEqual( ma0[ 1 ].getValue( 0, 1 ), 11 ) ) {
2454                 return false;
2455             }
2456             if ( !isEqual( ma0[ 1 ].getValue( 1, 1 ), 0 ) ) {
2457                 return false;
2458             }
2459             if ( !isEqual( ma0[ 1 ].getValue( 2, 1 ), 14 ) ) {
2460                 return false;
2461             }
2462             if ( !isEqual( ma0[ 1 ].getValue( 3, 1 ), 15 ) ) {
2463                 return false;
2464             }
2465             if ( !isEqual( ma0[ 2 ].getValue( 0, 0 ), 0 ) ) {
2466                 return false;
2467             }
2468             if ( !isEqual( ma0[ 2 ].getValue( 1, 0 ), 21 ) ) {
2469                 return false;
2470             }
2471             if ( !isEqual( ma0[ 2 ].getValue( 2, 0 ), 22 ) ) {
2472                 return false;
2473             }
2474             if ( !isEqual( ma0[ 2 ].getValue( 3, 0 ), 23 ) ) {
2475                 return false;
2476             }
2477             if ( !isEqual( ma0[ 2 ].getValue( 0, 1 ), 21 ) ) {
2478                 return false;
2479             }
2480             if ( !isEqual( ma0[ 2 ].getValue( 1, 1 ), 0 ) ) {
2481                 return false;
2482             }
2483             if ( !isEqual( ma0[ 2 ].getValue( 2, 1 ), 24 ) ) {
2484                 return false;
2485             }
2486             if ( !isEqual( ma0[ 2 ].getValue( 3, 1 ), 25 ) ) {
2487                 return false;
2488             }
2489             source = new StringBuffer();
2490             source.append( "A 0 0 0 0" + l );
2491             source.append( "B 1 0 0 0" + l );
2492             source.append( "C 2 4 0 0" + l );
2493             source.append( "D 3 5 6 0" + l );
2494             source.append( " " + l );
2495             source.append( "A 0   11  12  13" + l );
2496             source.append( "B 11  0   14  15" + l );
2497             source.append( "C 12  14  0   16" + l );
2498             source.append( "D 13  15  16  0" + l );
2499             source.append( l );
2500             source.append( " A        0     " + l );
2501             source.append( " B            21 0" + l );
2502             source.append( " C            22 24    0  " + l );
2503             source.append( " # 2 222 2 2 " + l );
2504             source.append( " D            23 25 26 0" + l );
2505             final DistanceMatrix[] ma1 = p0.parse( source.toString() );
2506             if ( ma1.length != 3 ) {
2507                 return false;
2508             }
2509             if ( !isEqual( ma1[ 0 ].getValue( 0, 0 ), 0 ) ) {
2510                 return false;
2511             }
2512             if ( !isEqual( ma1[ 0 ].getValue( 1, 0 ), 1 ) ) {
2513                 return false;
2514             }
2515             if ( !isEqual( ma1[ 0 ].getValue( 2, 0 ), 2 ) ) {
2516                 return false;
2517             }
2518             if ( !isEqual( ma1[ 0 ].getValue( 3, 0 ), 3 ) ) {
2519                 return false;
2520             }
2521             if ( !isEqual( ma1[ 0 ].getValue( 0, 1 ), 1 ) ) {
2522                 return false;
2523             }
2524             if ( !isEqual( ma1[ 0 ].getValue( 1, 1 ), 0 ) ) {
2525                 return false;
2526             }
2527             if ( !isEqual( ma1[ 0 ].getValue( 2, 1 ), 4 ) ) {
2528                 return false;
2529             }
2530             if ( !isEqual( ma1[ 0 ].getValue( 3, 1 ), 5 ) ) {
2531                 return false;
2532             }
2533             if ( !isEqual( ma1[ 1 ].getValue( 0, 0 ), 0 ) ) {
2534                 return false;
2535             }
2536             if ( !isEqual( ma1[ 1 ].getValue( 1, 0 ), 11 ) ) {
2537                 return false;
2538             }
2539             if ( !isEqual( ma1[ 1 ].getValue( 2, 0 ), 12 ) ) {
2540                 return false;
2541             }
2542             if ( !isEqual( ma1[ 1 ].getValue( 3, 0 ), 13 ) ) {
2543                 return false;
2544             }
2545             if ( !isEqual( ma1[ 1 ].getValue( 0, 1 ), 11 ) ) {
2546                 return false;
2547             }
2548             if ( !isEqual( ma1[ 1 ].getValue( 1, 1 ), 0 ) ) {
2549                 return false;
2550             }
2551             if ( !isEqual( ma1[ 1 ].getValue( 2, 1 ), 14 ) ) {
2552                 return false;
2553             }
2554             if ( !isEqual( ma1[ 1 ].getValue( 3, 1 ), 15 ) ) {
2555                 return false;
2556             }
2557             if ( !isEqual( ma1[ 2 ].getValue( 0, 0 ), 0 ) ) {
2558                 return false;
2559             }
2560             if ( !isEqual( ma1[ 2 ].getValue( 1, 0 ), 21 ) ) {
2561                 return false;
2562             }
2563             if ( !isEqual( ma1[ 2 ].getValue( 2, 0 ), 22 ) ) {
2564                 return false;
2565             }
2566             if ( !isEqual( ma1[ 2 ].getValue( 3, 0 ), 23 ) ) {
2567                 return false;
2568             }
2569             if ( !isEqual( ma1[ 2 ].getValue( 0, 1 ), 21 ) ) {
2570                 return false;
2571             }
2572             if ( !isEqual( ma1[ 2 ].getValue( 1, 1 ), 0 ) ) {
2573                 return false;
2574             }
2575             if ( !isEqual( ma1[ 2 ].getValue( 2, 1 ), 24 ) ) {
2576                 return false;
2577             }
2578             if ( !isEqual( ma1[ 2 ].getValue( 3, 1 ), 25 ) ) {
2579                 return false;
2580             }
2581             source = new StringBuffer();
2582             source.append( "A 0" + l );
2583             source.append( "B 10 0" + l );
2584             final DistanceMatrix[] ma2 = p0.parse( source.toString() );
2585             if ( ma2.length != 1 ) {
2586                 return false;
2587             }
2588             if ( !isEqual( ma2[ 0 ].getValue( 0, 1 ), 10 ) ) {
2589                 return false;
2590             }
2591             source = new StringBuffer();
2592             source.append( " " + l );
2593             source.append( "#" + l );
2594             final DistanceMatrix[] ma3 = p0.parse( source.toString() );
2595             if ( ma3.length != 0 ) {
2596                 return false;
2597             }
2598             source = new StringBuffer();
2599             source.append( " " + l );
2600             source.append( "A 0   11  12  13" + l );
2601             source.append( "B     0   14  15" + l );
2602             source.append( "C         0   16" + l );
2603             source.append( "D              0" + l );
2604             source.append( l );
2605             source.append( "A 0 21  22  23" + l );
2606             source.append( "B 0 24  25" + l );
2607             source.append( "C 0 26" + l );
2608             source.append( "D 0" + l );
2609             p0.setInputMatrixType( SymmetricalDistanceMatrixParser.InputMatrixType.UPPER_TRIANGLE );
2610             final DistanceMatrix[] ma4 = p0.parse( source );
2611             if ( ma4.length != 2 ) {
2612                 return false;
2613             }
2614             if ( !isEqual( ma4[ 0 ].getValue( 0, 0 ), 0 ) ) {
2615                 return false;
2616             }
2617             if ( !isEqual( ma4[ 0 ].getValue( 1, 0 ), 11 ) ) {
2618                 return false;
2619             }
2620             if ( !isEqual( ma4[ 0 ].getValue( 2, 0 ), 12 ) ) {
2621                 return false;
2622             }
2623             if ( !isEqual( ma4[ 0 ].getValue( 3, 0 ), 13 ) ) {
2624                 return false;
2625             }
2626             if ( !isEqual( ma4[ 0 ].getValue( 0, 1 ), 11 ) ) {
2627                 return false;
2628             }
2629             if ( !isEqual( ma4[ 0 ].getValue( 1, 1 ), 0 ) ) {
2630                 return false;
2631             }
2632             if ( !isEqual( ma4[ 0 ].getValue( 2, 1 ), 14 ) ) {
2633                 return false;
2634             }
2635             if ( !isEqual( ma4[ 0 ].getValue( 3, 1 ), 15 ) ) {
2636                 return false;
2637             }
2638             if ( !isEqual( ma4[ 0 ].getValue( 0, 2 ), 12 ) ) {
2639                 return false;
2640             }
2641             if ( !isEqual( ma4[ 0 ].getValue( 1, 2 ), 14 ) ) {
2642                 return false;
2643             }
2644             if ( !isEqual( ma4[ 0 ].getValue( 2, 2 ), 0 ) ) {
2645                 return false;
2646             }
2647             if ( !isEqual( ma4[ 0 ].getValue( 3, 2 ), 16 ) ) {
2648                 return false;
2649             }
2650             if ( !isEqual( ma4[ 0 ].getValue( 0, 3 ), 13 ) ) {
2651                 return false;
2652             }
2653             if ( !isEqual( ma4[ 0 ].getValue( 1, 3 ), 15 ) ) {
2654                 return false;
2655             }
2656             if ( !isEqual( ma4[ 0 ].getValue( 2, 3 ), 16 ) ) {
2657                 return false;
2658             }
2659             if ( !isEqual( ma4[ 0 ].getValue( 3, 3 ), 0 ) ) {
2660                 return false;
2661             }
2662             source = new StringBuffer();
2663             source.append( " 4 " + l );
2664             source.append( "A 0   11  12  13" + l );
2665             source.append( "B     0   14  15" + l );
2666             source.append( "C         0   16" + l );
2667             source.append( "D              0" + l );
2668             source.append( " 4" + l );
2669             source.append( "A 0 21  22  23" + l );
2670             source.append( "B 0 24  25" + l );
2671             source.append( "C 0 26" + l );
2672             source.append( "D 0" + l );
2673             source.append( "     " + l );
2674             source.append( " 4" + l );
2675             source.append( "A 0 21  22  23" + l );
2676             source.append( "B 0 24  25" + l );
2677             source.append( "C 0 26" + l );
2678             source.append( "D 0" + l );
2679             source.append( l );
2680             source.append( "A 0 21  22  23" + l );
2681             source.append( "B 0 24  25" + l );
2682             source.append( "C 0 26" + l );
2683             source.append( "D 0" + l );
2684             p0.setInputMatrixType( SymmetricalDistanceMatrixParser.InputMatrixType.UPPER_TRIANGLE );
2685             final DistanceMatrix[] ma5 = p0.parse( source );
2686             if ( ma5.length != 4 ) {
2687                 return false;
2688             }
2689             if ( !isEqual( ma5[ 0 ].getValue( 0, 0 ), 0 ) ) {
2690                 return false;
2691             }
2692             if ( !isEqual( ma5[ 0 ].getValue( 1, 0 ), 11 ) ) {
2693                 return false;
2694             }
2695             if ( !isEqual( ma5[ 0 ].getValue( 2, 0 ), 12 ) ) {
2696                 return false;
2697             }
2698             if ( !isEqual( ma5[ 0 ].getValue( 3, 0 ), 13 ) ) {
2699                 return false;
2700             }
2701             if ( !isEqual( ma5[ 0 ].getValue( 0, 1 ), 11 ) ) {
2702                 return false;
2703             }
2704             if ( !isEqual( ma5[ 0 ].getValue( 1, 1 ), 0 ) ) {
2705                 return false;
2706             }
2707             if ( !isEqual( ma5[ 0 ].getValue( 2, 1 ), 14 ) ) {
2708                 return false;
2709             }
2710             if ( !isEqual( ma5[ 0 ].getValue( 3, 1 ), 15 ) ) {
2711                 return false;
2712             }
2713             if ( !isEqual( ma5[ 0 ].getValue( 0, 2 ), 12 ) ) {
2714                 return false;
2715             }
2716             if ( !isEqual( ma5[ 0 ].getValue( 1, 2 ), 14 ) ) {
2717                 return false;
2718             }
2719             if ( !isEqual( ma5[ 0 ].getValue( 2, 2 ), 0 ) ) {
2720                 return false;
2721             }
2722             if ( !isEqual( ma5[ 0 ].getValue( 3, 2 ), 16 ) ) {
2723                 return false;
2724             }
2725             if ( !isEqual( ma5[ 0 ].getValue( 0, 3 ), 13 ) ) {
2726                 return false;
2727             }
2728             if ( !isEqual( ma5[ 0 ].getValue( 1, 3 ), 15 ) ) {
2729                 return false;
2730             }
2731             if ( !isEqual( ma5[ 0 ].getValue( 2, 3 ), 16 ) ) {
2732                 return false;
2733             }
2734             if ( !isEqual( ma5[ 0 ].getValue( 3, 3 ), 0 ) ) {
2735                 return false;
2736             }
2737         }
2738         catch ( final Exception e ) {
2739             e.printStackTrace( System.out );
2740             return false;
2741         }
2742         return true;
2743     }
2744
2745     private static void timeNeighborJoining() {
2746         final NeighborJoiningF njf = NeighborJoiningF.createInstance();
2747         for( int n = 3; n <= 9; ++n ) {
2748             final int x = ( int ) Math.pow( 2, n );
2749             final BasicSymmetricalDistanceMatrix mt = new BasicSymmetricalDistanceMatrix( x );
2750             mt.randomize( new Date().getTime() );
2751             final long start_time = new Date().getTime();
2752             njf.execute( mt );
2753             System.out.println( "Size: " + x + " -> " + ( new Date().getTime() - start_time ) + "ms" );
2754         }
2755         final NeighborJoining nj = NeighborJoining.createInstance();
2756         for( int n = 3; n <= 9; ++n ) {
2757             final int x = ( int ) Math.pow( 2, n );
2758             final BasicSymmetricalDistanceMatrix mt = new BasicSymmetricalDistanceMatrix( x );
2759             mt.randomize( new Date().getTime() );
2760             final long start_time = new Date().getTime();
2761             nj.execute( mt );
2762             System.out.println( "Size: " + x + " -> " + ( new Date().getTime() - start_time ) + "ms" );
2763         }
2764     }
2765 }