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