5b0e20aad9a4658213845a5bb43be3d4d238f54e
[jalview.git] / src / jalview / analysis / AverageDistanceTree.java
1 package jalview.analysis;
2
3 import jalview.api.analysis.ScoreModelI;
4 import jalview.api.analysis.SimilarityParamsI;
5 import jalview.datamodel.SequenceNode;
6 import jalview.viewmodel.AlignmentViewport;
7
8 public class AverageDistanceTree extends TreeBuilder
9 {
10   /**
11    * Constructor
12    * 
13    * @param av
14    * @param sm
15    * @param scoreParameters
16    */
17   public AverageDistanceTree(AlignmentViewport av, ScoreModelI sm,
18           SimilarityParamsI scoreParameters)
19   {
20     super(av, sm, scoreParameters);
21   }
22
23   /**
24    * Calculates and saves the distance between the combination of cluster(i) and
25    * cluster(j) and all other clusters. An average of the distances from
26    * cluster(i) and cluster(j) is calculated, weighted by the sizes of each
27    * cluster.
28    * 
29    * @param i
30    * @param j
31    */
32   @Override
33   protected void findClusterDistance(int i, int j)
34   {
35     int noi = clusters.elementAt(i).cardinality();
36     int noj = clusters.elementAt(j).cardinality();
37
38     // New distances from cluster i to others
39     double[] newdist = new double[noseqs];
40
41     for (int l = 0; l < noseqs; l++)
42     {
43       if ((l != i) && (l != j))
44       {
45         newdist[l] = ((distances.getValue(i, l) * noi) + (distances
46                 .getValue(j, l) * noj)) / (noi + noj);
47       }
48       else
49       {
50         newdist[l] = 0;
51       }
52     }
53
54     for (int ii = 0; ii < noseqs; ii++)
55     {
56       distances.setValue(i, ii, newdist[ii]);
57       distances.setValue(ii, i, newdist[ii]);
58     }
59   }
60
61   /**
62    * Returns the minimum distance between two clusters, and also sets the
63    * indices of the clusters in fields mini and minj
64    * 
65    * @return DOCUMENT ME!
66    */
67   @Override
68   protected double findMinDistance()
69   {
70     double min = Double.MAX_VALUE;
71
72     for (int i = 0; i < (noseqs - 1); i++)
73     {
74       for (int j = i + 1; j < noseqs; j++)
75       {
76         if (!done.get(i) && !done.get(j))
77         {
78           if (distances.getValue(i, j) < min)
79           {
80             mini = i;
81             minj = j;
82
83             min = distances.getValue(i, j);
84           }
85         }
86       }
87     }
88     return min;
89   }
90
91   /**
92    * DOCUMENT ME!
93    * 
94    * @param tmpi
95    *          DOCUMENT ME!
96    * @param tmpj
97    *          DOCUMENT ME!
98    * @param dist
99    *          DOCUMENT ME!
100    */
101   @Override
102   protected void findNewDistances(SequenceNode tmpi, SequenceNode tmpj,
103           double dist)
104   {
105     double ih = 0;
106     double jh = 0;
107
108     SequenceNode sni = tmpi;
109     SequenceNode snj = tmpj;
110
111     while (sni != null)
112     {
113       ih = ih + sni.dist;
114       sni = (SequenceNode) sni.left();
115     }
116
117     while (snj != null)
118     {
119       jh = jh + snj.dist;
120       snj = (SequenceNode) snj.left();
121     }
122
123     tmpi.dist = ((dist / 2) - ih);
124     tmpj.dist = ((dist / 2) - jh);
125   }
126
127 }