4fde68a023e080034dbb3639eb662ecf2a445131
[jalview.git] / src / jalview / math / MiscMath.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.math;
22
23 import java.lang.Math;
24 import java.util.Arrays;
25
26 /**
27  * A collection of miscellaneous mathematical operations
28  * @AUTHOR MorellThomas
29  */
30 public class MiscMath
31 {
32   /**
33   * calculates the mean of an array 
34   *
35   * @param m ~ array
36   * @return
37   * TODO whats with nans??
38   */
39   public static double mean(double[] m)
40   {
41     double sum = 0;
42     for (int i = 0; i < m.length; i++)
43     {
44       if (!Double.isNaN(m[i]))
45       {
46         sum += m[i];
47       }
48     }
49     return sum / m.length;
50   }
51
52   /**
53   * calculates the square root of each element in an array
54   *
55   * @param m ~ array
56   *
57   * @return
58   * TODO
59   * make general with function passed -> apply function to each element
60   */
61   public static double[] sqrt(double[] m)
62   {
63     double[] sqrts = new double[m.length];
64     for (int i = 0; i < m.length; i++)
65     {
66       sqrts[i] = Math.sqrt(m[i]);
67     }
68     return sqrts;
69   }
70
71   /**
72   * calculate element wise multiplication of two arrays
73   *
74   * @param a ~ array
75   * @param b ~ array
76   *
77   * @return
78   */
79   public static double[] elementwiseMultiply(byte[] a, double[] b) throws RuntimeException
80   {
81     if (a.length != b.length)
82     {
83       throw new SameLengthException(a.length, b.length);
84     }
85     double[] result = new double[a.length];
86     for (int i = 0; i < a.length; i++)
87     {
88       result[i] = a[i] * b[i];
89     }
90     return result;
91   }
92   public static double[] elementwiseMultiply(double[] a, double[] b) throws RuntimeException
93   {
94     if (a.length != b.length)
95     {
96       throw new SameLengthException(a.length, b.length);
97     }
98     double[] result = new double[a.length];
99     for (int i = 0; i < a.length; i++)
100     {
101       result[i] = a[i] * b[i];
102     }
103     return result;
104   }
105   public static byte[] elementwiseMultiply(byte[] a, byte[] b) throws RuntimeException
106   {
107     if (a.length != b.length)
108     {
109       throw new SameLengthException(a.length, b.length);
110     }
111     byte[] result = new byte[a.length];
112     for (int i = 0; i < a.length; i++)
113     {
114       result[i] = (byte) (a[i] * b[i]);
115     }
116     return result;
117   }
118
119   /**
120   * calculate element wise division of two arrays
121   *
122   * @param a ~ array
123   * @param b ~ array
124   *
125   * @return
126   */
127   public static double[] elementwiseDivide(double[] a, double[] b) throws RuntimeException
128   {
129     if (a.length != b.length)
130     {
131       throw new SameLengthException(a.length, b.length);
132     }
133     double[] result = new double[a.length];
134     for (int i = 0; i < a.length; i++)
135     {
136       result[i] = a[i] / b[i];
137     }
138     return result;
139   }
140
141   /**
142   * returns true if two arrays are element wise within a tolerance
143   *
144   * @param a ~ array
145   * @param b ~ array
146   * @param rtol ~ relative tolerance
147   * @param atol ~ absolute tolerance
148   * @param equalNAN ~ whether NaN at the same position return true
149   *
150   * @return
151   */
152   public static boolean allClose(double[] a, double[] b, double rtol, double atol, boolean equalNAN)
153   {
154     boolean areEqual = true;
155     for (int i = 0; i < a.length; i++)
156     {
157       if (equalNAN && (Double.isNaN(a[i]) && Double.isNaN(b[i])))
158       {
159         continue;
160       }
161       if (Math.abs(a[i] - b[i]) > (atol + rtol * Math.abs(b[i])))
162       {
163         areEqual = false;
164         break;
165       }
166     }
167     return areEqual;
168   }
169
170   /**
171   * returns the index of the maximum and the maximum value of an array
172   * 
173   * @pararm a ~ array
174   *
175   * @returns
176   */
177   public static int[] findMax(int[] a)
178   {
179     int max = 0;
180     int maxIndex = 0;
181     for (int i = 0; i < a.length; i++)
182     {
183       if (a[i] > max)
184       {
185         max = a[i];
186         maxIndex = i;
187       }
188     }
189     return new int[]{maxIndex, max};
190   }
191 }