$darkmode
DENOPTIM
MathUtils.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.no> and
4 * Marco Foscato <marco.foscato@uib.no>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20package denoptim.utils;
21
22import java.math.BigDecimal;
23import java.math.RoundingMode;
24import java.util.ArrayList;
25import java.util.Collection;
26import java.util.List;
27
28import javax.vecmath.Point3d;
29import javax.vecmath.Vector3d;
30
31import denoptim.constants.DENOPTIMConstants;
32
38public class MathUtils
39{
40
41//------------------------------------------------------------------------------
42
51 public static double calculateAngle (double[] a, double[] b)
52 {
53 double alen = length(a);
54 double blen = length(b);
55 double abdot = computeDotProduct(a, b);
56 double angle = Math.acos(abdot/(alen*blen));
57 return Math.toDegrees(angle);
58 }
59
60//------------------------------------------------------------------------------
67 public static void norm(double[] d, double[] ret)
68 {
69 double length;
70 length = length(d);
71 ret[0] = d[0] / length;
72 ret[1] = d[1] / length;
73 ret[2] = d[2] / length;
74 }
75
76//------------------------------------------------------------------------------
77
86 public static Vector3d normDist(Point3d p1, Point3d p2)
87 {
88 Vector3d v = new Vector3d(p1.x - p2.x,
89 p1.y - p2.y,
90 p1.z - p2.z);
91 v.normalize();
92 return v;
93 }
94
95//------------------------------------------------------------------------------
102 public static double[] scale(double[] d, double a)
103 {
104 double[] scaled = new double[3];
105 scaled[0] = d[0] * a;
106 scaled[1] = d[1] * a;
107 scaled[2] = d[2] * a;
108 return scaled;
109 }
110
111//------------------------------------------------------------------------------
119 public static void scalar(double[] d, double a, double[] ret)
120 {
121 ret[0] = d[0] * a;
122 ret[1] = d[1] * a;
123 ret[2] = d[2] * a;
124 }
125
126//------------------------------------------------------------------------------
127
134 public static double length (double[] v)
135 {
136 return Math.sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
137 }
138
139//------------------------------------------------------------------------------
140
148 public static double computeDotProduct (double[] v0, double[] v1)
149 {
150 return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
151 }
152
153//------------------------------------------------------------------------------
154
162 public static double[] computeCrossProduct (double[] v0, double[] v1)
163 {
164 double[] crossProduct = new double[3];
165 crossProduct[0] = v0[1] * v1[2] - v0[2] * v1[1];
166 crossProduct[1] = v0[2] * v1[0] - v0[0] * v1[2];
167 crossProduct[2] = v0[0] * v1[1] - v0[1] * v1[0];
168 return crossProduct;
169 }
170
171//------------------------------------------------------------------------------
172
180 public static double[] subtract (double[] v0, double[] v1)
181 {
182 double[] res = new double[3];
183 res[0] = v0[0] - v1[0];
184 res[1] = v0[1] - v1[1];
185 res[2] = v0[2] - v1[2];
186 return res;
187 }
188
189//------------------------------------------------------------------------------
190
198 public static double[] add (double[] v0, double[] v1)
199 {
200 double[] res = new double[3];
201 res[0] = v0[0] + v1[0];
202 res[1] = v0[1] + v1[1];
203 res[2] = v0[2] + v1[2];
204 return res;
205 }
206
207//------------------------------------------------------------------------------
208
218 public static double computeDihedralAngle(Point3d p0, Point3d p1,
219 Point3d p2, Point3d p3)
220 {
221 double[] v0 = new double[] {p0.x, p0.y, p0.z};
222 double[] v1 = new double[] {p1.x, p1.y, p1.z};
223 double[] v2 = new double[] {p2.x, p2.y, p2.z};
224 double[] v3 = new double[] {p3.x, p3.y, p3.z};
225
226 return computeDihedralAngle(v0, v1, v2, v3);
227 }
228
229//------------------------------------------------------------------------------
230
241 public static double computeDihedralAngle (double[] v0, double[] v1,
242 double[] v2, double[] v3)
243 {
244 double[] r1 = subtract(v1, v0);
245 double[] r2 = subtract(v2, v1);
246 double[] r3 = subtract(v3, v2);
247
248 double[] n1 = computeCrossProduct(r1, r2);
249 double[] n2 = computeCrossProduct(r2, r3);
250
251 double psin = computeDotProduct(n1, r3) *
252 Math.sqrt(computeDotProduct(r2, r2));
253 double pcos = computeDotProduct(n1, n2);
254
255 return Math.toDegrees(Math.atan2(psin, pcos));
256 }
257
258//------------------------------------------------------------------------------
259
260 public static double log2(double x)
261 {
262 return Math.log(x)/Math.log(2);
263 }
264
265
266//------------------------------------------------------------------------------
267
268 public static double roundValue(double val, int decimalPlaces)
269 {
270 BigDecimal bd = new BigDecimal(val);
271 bd = bd.setScale(decimalPlaces, RoundingMode.UP);
272 return bd.doubleValue();
273 }
274
275//------------------------------------------------------------------------------
276
284 public static double angle(Point3d a, Point3d b, Point3d c)
285 {
286 double xba = a.x - b.x;
287 double xbc = c.x - b.x;
288 double yba = a.y - b.y;
289 double ybc = c.y - b.y;
290 double zba = a.z - b.z;
291 double zbc = c.z - b.z;
292
293 double ba = Math.sqrt(xba*xba + yba*yba + zba*zba);
294 double bc = Math.sqrt(xbc*xbc + ybc*ybc + zbc*zbc);
295
296 double dot = xba*xbc + yba*ybc + zba*zbc;
297 dot /= (ba * bc);
298
299 double angle;
300 if (dot < 0.0 &&
301 Math.abs(Math.abs(dot)-1.0) < DENOPTIMConstants.FLOATCOMPARISONTOLERANCE)
302 {
303 angle = 180.0;
304 }
305 else
306 {
307 angle = Math.toDegrees(Math.acos(dot));
308 }
309
310 return angle;
311 }
312
313//------------------------------------------------------------------------------
314
324 public static double getAngle(double[] A, double[] B, double[] C)
325 {
326 double[] vBA = {A[0]-B[0], A[1]-B[1], A[2]-B[2]}; // Vector from B to A
327 double[] vBC = {C[0]-B[0], C[1]-B[1], C[2]-B[2]}; // Vector from B to C
328
329 return calculateAngle(vBA, vBC);
330 }
331
332
333//------------------------------------------------------------------------------
334
342 public static double distance(Point3d a, Point3d b)
343 {
344 double dx = a.x - b.x, dy = a.y - b.y, dz = a.z - b.z;
345 return Math.sqrt(dx*dx + dy*dy + dz*dz);
346 }
347
348//------------------------------------------------------------------------------
349
350 private static final double[] tp1 = new double[3];
351 private static final double[] tp2 = new double[3];
352 private static final double[] tp3 = new double[3];
353 private static final double[] tp4 = new double[3];
354
363 public static double torsion(Point3d p1, Point3d p2, Point3d p3, Point3d p4)
364 {
365 p1.get(tp1);
366 p2.get(tp2);
367 p3.get(tp3);
368 p4.get(tp4);
369
371 }
372
373//------------------------------------------------------------------------------
374
380 public static double sum(double[] a)
381 {
382 double sum = 0.0;
383 for (double v : a) {
384 sum += v;
385 }
386 return sum;
387 }
388
389//------------------------------------------------------------------------------
390
396 public static double mean(double[] a)
397 {
398 if (a.length == 0)
399 return Double.NaN;
400 double sum = sum(a);
401 return sum / a.length;
402 }
403
404//------------------------------------------------------------------------------
405
406 public static double mean(List<Double> vals)
407 {
408 double[] arr = new double[vals.size()];
409 for (int i=0; i<vals.size(); i++)
410 {
411 arr[i] = vals.get(i);
412 }
413
414 return mean(arr);
415 }
416
417//------------------------------------------------------------------------------
418
426 public static Vector3d getNormalDirection(Vector3d vecA)
427 {
428 Vector3d normalDir = new Vector3d();
429 ArrayList<Vector3d> candidates = new ArrayList<>();
430 candidates.add(new Vector3d(1.0, 0.0, 0.0));
431 candidates.add(new Vector3d(0.0, 1.0, 0.0));
432 candidates.add(new Vector3d(0.0, 0.0, 1.0));
433 candidates.add(new Vector3d(1.0/Math.sqrt(2.0),
434 1.0/Math.sqrt(2.0),
435 0.0));
436 candidates.add(new Vector3d(1.0/Math.sqrt(2.0),
437 0.0,
438 1.0/Math.sqrt(2.0)));
439 candidates.add(new Vector3d(0.0,
440 1.0/Math.sqrt(2.0),
441 1.0/Math.sqrt(2.0)));
442
443 for (Vector3d candidate : candidates) {
444 double res = vecA.dot(candidate);
445 if (Math.abs(res) > 0.1 && Math.abs(res) < 0.9) {
446 normalDir.cross(vecA, candidate);
447 break;
448 }
449 }
450 normalDir.normalize();
451
452 return normalDir;
453 }
454
455//------------------------------------------------------------------------------
456
457 public static double[] centroidOf(Collection<double[]> points, int dimension)
458 {
459 double[] centroid = new double[dimension];
460 for (double[] point : points)
461 {
462 for (int i = 0; i < centroid.length; i++)
463 {
464 centroid[i] += point[i];
465 }
466 }
467 for (int i = 0; i < centroid.length; i++)
468 {
469 centroid[i] /= points.size();
470 }
471 return centroid;
472 }
473
474//------------------------------------------------------------------------------
475}
General set of constants used in DENOPTIM.
static final double FLOATCOMPARISONTOLERANCE
Smallest difference for comparison of double and float numbers.
Some useful math operations.
Definition: MathUtils.java:39
static Vector3d normDist(Point3d p1, Point3d p2)
Get normalized distance between two point.
Definition: MathUtils.java:86
static double sum(double[] a)
Return sum of all values in array.
Definition: MathUtils.java:380
static double computeDihedralAngle(double[] v0, double[] v1, double[] v2, double[] v3)
Compute the dihedral angle.
Definition: MathUtils.java:241
static double computeDotProduct(double[] v0, double[] v1)
Compute the dot product (a scalar) between two vectors.
Definition: MathUtils.java:148
static double angle(Point3d a, Point3d b, Point3d c)
Calculate the angle between the 3 points.
Definition: MathUtils.java:284
static final double[] tp3
Definition: MathUtils.java:352
static double log2(double x)
Definition: MathUtils.java:260
static double length(double[] v)
Return the norm of a vector.
Definition: MathUtils.java:134
static double mean(List< Double > vals)
Definition: MathUtils.java:406
static double[] add(double[] v0, double[] v1)
Perform vector addition.
Definition: MathUtils.java:198
static final double[] tp4
Definition: MathUtils.java:353
static double roundValue(double val, int decimalPlaces)
Definition: MathUtils.java:268
static void scalar(double[] d, double a, double[] ret)
Scales a vector.
Definition: MathUtils.java:119
static double getAngle(double[] A, double[] B, double[] C)
Calculates angle (in degrees) between vectors BA and BC.
Definition: MathUtils.java:324
static final double[] tp1
Definition: MathUtils.java:350
static double[] subtract(double[] v0, double[] v1)
Perform vector subtraction.
Definition: MathUtils.java:180
static final double[] tp2
Definition: MathUtils.java:351
static double calculateAngle(double[] a, double[] b)
compute the angle between two vectors a & b of same length
Definition: MathUtils.java:51
static double computeDihedralAngle(Point3d p0, Point3d p1, Point3d p2, Point3d p3)
Compute the dihedral angle.
Definition: MathUtils.java:218
static double[] scale(double[] d, double a)
Scales a vector.
Definition: MathUtils.java:102
static void norm(double[] d, double[] ret)
Normalizes a vector.
Definition: MathUtils.java:67
static double torsion(Point3d p1, Point3d p2, Point3d p3, Point3d p4)
Calculate the torsion angle between the 4 points.
Definition: MathUtils.java:363
static double distance(Point3d a, Point3d b)
Calculates distance between point a and point b.
Definition: MathUtils.java:342
static double[] centroidOf(Collection< double[]> points, int dimension)
Definition: MathUtils.java:457
static double[] computeCrossProduct(double[] v0, double[] v1)
Compute the cross product of two vectors.
Definition: MathUtils.java:162
static Vector3d getNormalDirection(Vector3d vecA)
Generate a vector that is perpendicular to the given one.
Definition: MathUtils.java:426
static double mean(double[] a)
Calculate mean value.
Definition: MathUtils.java:396