2 // forester -- software libraries and applications
3 // for genomics and evolutionary biology research.
5 // Copyright (C) 2010 Christian M Zmasek
6 // Copyright (C) 2010 Sanford-Burnham Medical Research Institute
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 // Contact: phylosoft @ gmail . com
24 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
26 package org.forester.evoinference.distance;
28 import org.forester.evoinference.matrix.distance.BasicSymmetricalDistanceMatrix;
29 import org.forester.evoinference.matrix.distance.DistanceMatrix;
30 import org.forester.evoinference.matrix.distance.DistanceMatrix;
31 import org.forester.msa.Msa;
33 public final class PairwiseDistanceCalculator {
35 public static final double DEFAULT_VALUE_FOR_TOO_LARGE_DISTANCE_FOR_KIMURA_FORMULA = 10; // Felsenstein uses -1
36 private final Msa _msa;
37 private final double _value_for_too_large_distance_for_kimura_formula;
39 private PairwiseDistanceCalculator( final Msa msa, final double value_for_too_large_distance_for_kimura_formula ) {
41 _value_for_too_large_distance_for_kimura_formula = value_for_too_large_distance_for_kimura_formula;
44 private double calcFractionalDissimilarity( final int row_1, final int row_2 ) {
45 final int length = _msa.getLength();
47 for( int col = 0; col < length; ++col ) {
48 if ( _msa.getResidueAt( row_1, col ) != _msa.getResidueAt( row_2, col ) ) {
52 return ( double ) nd / length;
63 private double calcKimuraDistance( final int row_1, final int row_2 ) {
64 final double p = calcFractionalDissimilarity( row_1, row_2 );
65 final double dp = 1 - p - ( 0.2 * p * p );
67 return _value_for_too_large_distance_for_kimura_formula;
70 return 0; // Too avoid -0.
72 return -Math.log( dp );
75 private double calcPoissonDistance( final int row_1, final int row_2 ) {
76 final double p = calcFractionalDissimilarity( row_1, row_2 );
77 final double dp = 1 - p;
79 return _value_for_too_large_distance_for_kimura_formula;
82 return 0; // Too avoid -0.
84 return -Math.log( dp );
87 private DistanceMatrix calcKimuraDistances() {
88 final int s = _msa.getNumberOfSequences();
89 final DistanceMatrix d = new BasicSymmetricalDistanceMatrix( s );
90 copyIdentifiers( s, d );
91 calcKimuraDistances( s, d );
95 private DistanceMatrix calcPoissonDistances() {
96 final int s = _msa.getNumberOfSequences();
97 final DistanceMatrix d = new BasicSymmetricalDistanceMatrix( s );
98 copyIdentifiers( s, d );
99 calcPoissonDistances( s, d );
103 private DistanceMatrix calcFractionalDissimilarities() {
104 final int s = _msa.getNumberOfSequences();
105 final DistanceMatrix d = new BasicSymmetricalDistanceMatrix( s );
106 copyIdentifiers( s, d );
107 calcFractionalDissimilarities( s, d );
111 private void calcKimuraDistances( final int s, final DistanceMatrix d ) {
112 for( int i = 1; i < s; i++ ) {
113 for( int j = 0; j < i; j++ ) {
114 d.setValue( i, j, calcKimuraDistance( i, j ) );
119 private void calcPoissonDistances( final int s, final DistanceMatrix d ) {
120 for( int i = 1; i < s; i++ ) {
121 for( int j = 0; j < i; j++ ) {
122 d.setValue( i, j, calcPoissonDistance( i, j ) );
127 private void calcFractionalDissimilarities( final int s, final DistanceMatrix d ) {
128 for( int i = 1; i < s; i++ ) {
129 for( int j = 0; j < i; j++ ) {
130 d.setValue( i, j, calcFractionalDissimilarity( i, j ) );
136 public Object clone() throws CloneNotSupportedException {
137 throw new CloneNotSupportedException();
140 private void copyIdentifiers( final int s, final DistanceMatrix d ) {
141 for( int i = 0; i < s; i++ ) {
142 d.setIdentifier( i, _msa.getIdentifier( i ) );
146 public static DistanceMatrix calcFractionalDissimilarities( final Msa msa ) {
147 return new PairwiseDistanceCalculator( msa, DEFAULT_VALUE_FOR_TOO_LARGE_DISTANCE_FOR_KIMURA_FORMULA )
148 .calcFractionalDissimilarities();
151 public static DistanceMatrix calcPoissonDistances( final Msa msa ) {
152 return new PairwiseDistanceCalculator( msa, DEFAULT_VALUE_FOR_TOO_LARGE_DISTANCE_FOR_KIMURA_FORMULA )
153 .calcPoissonDistances();
156 public static DistanceMatrix calcKimuraDistances( final Msa msa ) {
157 return new PairwiseDistanceCalculator( msa, DEFAULT_VALUE_FOR_TOO_LARGE_DISTANCE_FOR_KIMURA_FORMULA )
158 .calcKimuraDistances();
161 public static DistanceMatrix calcKimuraDistances( final Msa msa,
162 final double value_for_too_large_distance_for_kimura_formula ) {
163 return new PairwiseDistanceCalculator( msa, value_for_too_large_distance_for_kimura_formula )
164 .calcKimuraDistances();
167 public enum PWD_DISTANCE_METHOD {
168 KIMURA_DISTANCE, POISSON_DISTANCE, FRACTIONAL_DISSIMILARITY;