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