Skip to content

Commit c5a127c

Browse files
committed
use new getArgument(re, im) dealing with numerical precision
1 parent 425fc8b commit c5a127c

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

src/main/java/fr/jmmc/jmcs/util/NumberUtils.java

+33-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@
4848
public final class NumberUtils {
4949

5050
/** Smallest positive number used in double comparisons (rounding). */
51-
public final static double EPSILON = 1e-6d;
51+
public final static double EPSILON = 1e-6;
52+
/* PI and PI/2 constants */
53+
public final static double PI = Math.PI;
54+
public final static double PI_HALF = PI / 2.0;
55+
/** Typical scale precision in re/im comparisons (rounding). */
56+
public static final double ARG_EPSILON = Math.ulp(1.0);
5257
/* shared Double instances */
5358
/** shared Double = NaN instance */
5459
public final static Double DBL_NAN = Double.valueOf(Double.NaN);
@@ -61,6 +66,33 @@ public final class NumberUtils {
6166
/** scientific formatter */
6267
private final static NumberFormat _fmtScience = new DecimalFormat("0.0##E0");
6368

69+
public static double getArgumentInDegrees(final double re, final double im) {
70+
return Math.toDegrees(getArgument(re, im));
71+
}
72+
73+
public static double getArgument(final double re, final double im) {
74+
// check |re| == 0
75+
final double normRe = Math.abs(re);
76+
if (normRe == 0.0) {
77+
return (im >= 0.0) ? PI_HALF : -PI_HALF;
78+
}
79+
// check |im| == 0
80+
final double normIm = Math.abs(im);
81+
if (normIm == 0.0) {
82+
return (re >= 0.0) ? 0.0 : PI;
83+
}
84+
final double epsilon = ARG_EPSILON * (normRe + normIm);
85+
// check |re| << |im| or |im| << |re|
86+
if (normIm <= epsilon) {
87+
return (re >= 0.0) ? 0.0 : PI;
88+
}
89+
// check |im| << |re|
90+
if (normRe <= epsilon) {
91+
return (im >= 0.0) ? PI_HALF : -PI_HALF;
92+
}
93+
return Math.atan2(im, re);
94+
}
95+
6496
/**
6597
* Private constructor
6698
*/

src/main/java/fr/jmmc/oitools/model/OIT3.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
******************************************************************************/
2020
package fr.jmmc.oitools.model;
2121

22+
import fr.jmmc.jmcs.util.NumberUtils;
2223
import fr.jmmc.oitools.OIFitsConstants;
2324
import fr.jmmc.oitools.meta.ArrayColumnMeta;
2425
import static fr.jmmc.oitools.meta.CellMeta.NO_STR_VALUES;
@@ -437,13 +438,13 @@ public double[] getPosAngle() {
437438

438439
switch (j) {
439440
case 1: // AB
440-
angle[i] = Math.atan2(u1coord[i], v1coord[i]);
441+
angle[i] = NumberUtils.getArgument(v1coord[i], u1coord[i]);
441442
break;
442443
case 2: // BC
443-
angle[i] = Math.atan2(u2coord[i], v2coord[i]);
444+
angle[i] = NumberUtils.getArgument(v2coord[i], u2coord[i]);
444445
break;
445446
case 3: // AC
446-
angle[i] = Math.atan2(u3, v3);
447+
angle[i] = NumberUtils.getArgument(v3, u3);
447448
break;
448449
default:
449450
angle[i] = 0d;

src/main/java/fr/jmmc/oitools/model/OIVis.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
******************************************************************************/
2020
package fr.jmmc.oitools.model;
2121

22+
import fr.jmmc.jmcs.util.NumberUtils;
2223
import fr.jmmc.oitools.OIFitsConstants;
2324
import fr.jmmc.oitools.meta.ArrayColumnMeta;
2425
import static fr.jmmc.oitools.meta.CellMeta.NO_STR_VALUES;
@@ -578,7 +579,7 @@ public double[] getPosAngle() {
578579
final double[] vcoord = getVCoord();
579580

580581
for (int i = 0, j; i < nRows; i++) {
581-
angle[i] = Math.toDegrees(Math.atan2(ucoord[i], vcoord[i]));
582+
angle[i] = NumberUtils.getArgumentInDegrees(vcoord[i], ucoord[i]);
582583
}
583584

584585
this.setColumnDerivedValue(OIFitsConstants.COLUMN_POS_ANGLE, angle);

src/main/java/fr/jmmc/oitools/model/OIVis2.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
******************************************************************************/
2020
package fr.jmmc.oitools.model;
2121

22+
import fr.jmmc.jmcs.util.NumberUtils;
2223
import fr.jmmc.oitools.OIFitsConstants;
2324
import fr.jmmc.oitools.meta.ArrayColumnMeta;
2425
import static fr.jmmc.oitools.meta.CellMeta.NO_STR_VALUES;
@@ -391,7 +392,7 @@ public double[] getPosAngle() {
391392
final double[] vcoord = getVCoord();
392393

393394
for (int i = 0, j; i < nRows; i++) {
394-
angle[i] = Math.toDegrees(Math.atan2(ucoord[i], vcoord[i]));
395+
angle[i] = NumberUtils.getArgumentInDegrees(vcoord[i], ucoord[i]);
395396
}
396397

397398
this.setColumnDerivedValue(OIFitsConstants.COLUMN_POS_ANGLE, angle);

src/main/java/fr/jmmc/oitools/processing/BeamEstimator.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
******************************************************************************/
44
package fr.jmmc.oitools.processing;
55

6+
import fr.jmmc.jmcs.util.NumberUtils;
67
import fr.jmmc.oitools.model.IndexMask;
78
import fr.jmmc.oitools.model.OIData;
89
import fr.jmmc.oitools.model.OIFitsFile;
@@ -276,7 +277,7 @@ private static BeamInfo computeBeam(final double[] covMatrix) {
276277
final double rx = Math.toDegrees(SCALE_FACTOR / Math.sqrt(results.ev1)) * DEG_IN_MILLI_ARCSEC;
277278
final double ry = Math.toDegrees(SCALE_FACTOR / Math.sqrt(results.ev2)) * DEG_IN_MILLI_ARCSEC;
278279

279-
double angle = Math.toDegrees(Math.atan2(results.vec1[0], results.vec1[1]));
280+
double angle = NumberUtils.getArgumentInDegrees(results.vec1[1], results.vec1[0]);
280281

281282
// correct angle in range [-90; 90] as collinearity !
282283
if (angle < -90.0) {

0 commit comments

Comments
 (0)