diff --git a/.gitignore b/.gitignore index d43e5cd510d84f9c4320c56ecbf7777aca4ae97f..57f16fb67c1b1589981416b323d7a9debc728665 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,41 @@ -/bin -*.jar -.project -.classpath -export.jardesc +/build* +/workspace +setting.xml +release/ target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +icy.log + +### IntelliJ IDEA ### .idea/ +*.iws *.iml -.settings/ -**/.DS_Store \ No newline at end of file +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +**/.DS_Store +Icon? \ No newline at end of file diff --git a/pom.xml b/pom.xml index 433890d168979b9cfcf3eb45a0c3c208be3365e0..447f7e10337aa0d2cbaeea03574254748cf74cb0 100644 --- a/pom.xml +++ b/pom.xml @@ -7,11 +7,11 @@ <parent> <groupId>org.bioimageanalysis.icy</groupId> <artifactId>pom-icy</artifactId> - <version>2.2.0</version> + <version>3.0.0-a.1</version> </parent> <artifactId>nherve-matrix</artifactId> - <version>2.0.0</version> + <version>2.0.0-a.1</version> <name>NHerve Matrix</name> <description> @@ -22,7 +22,7 @@ <repositories> <repository> <id>icy</id> - <url>https://icy-nexus.pasteur.fr/repository/Icy/</url> + <url>https://nexus-icy.pasteur.cloud/repository/icy/</url> </repository> </repositories> </project> \ No newline at end of file diff --git a/src/main/java/plugins/nherve/matrix/CholeskyDecomposition.java b/src/main/java/plugins/nherve/matrix/CholeskyDecomposition.java index 398b51b74e00ad19c4fb8438e7c4c13c94997ff3..3d5d88d650ad54df7e64dc57147bd37e5d4e0000 100644 --- a/src/main/java/plugins/nherve/matrix/CholeskyDecomposition.java +++ b/src/main/java/plugins/nherve/matrix/CholeskyDecomposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,8 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.NotNull; + /** * Cholesky Decomposition. * <p> @@ -29,7 +31,6 @@ package plugins.nherve.matrix; * be queried by the isSPD() method. */ public class CholeskyDecomposition implements java.io.Serializable { - /** * Array for internal storage of decomposition. * @@ -51,16 +52,12 @@ public class CholeskyDecomposition implements java.io.Serializable { */ private boolean isspd; -/* ------------------------ - Constructor - * ------------------------ */ - /** * Cholesky algorithm for symmetric and positive definite matrix. * * @param Arg Square, symmetric matrix. */ - public CholeskyDecomposition(final Matrix Arg) { + public CholeskyDecomposition(final @NotNull Matrix Arg) { // Initialize. final double[][] A = Arg.getArray(); n = Arg.getRowDimension(); @@ -89,61 +86,6 @@ public class CholeskyDecomposition implements java.io.Serializable { } } -/* - \** Right Triangular Cholesky Decomposition. - <P> - For a symmetric, positive definite matrix A, the Right Cholesky - decomposition is an upper triangular matrix R so that A = R'*R. - This constructor computes R with the Fortran inspired column oriented - algorithm used in LINPACK and MATLAB. In Java, we suspect a row oriented, - lower triangular decomposition is faster. We have temporarily included - this constructor here until timing experiments confirm this suspicion. - *\ - - \** Array for internal storage of right triangular decomposition. **\ - private transient double[][] R; - - \** Cholesky algorithm for symmetric and positive definite matrix. - @param A Square, symmetric matrix. - @param rightflag Actual value ignored. - @return Structure to access R and isspd flag. - *\ - - public CholeskyDecomposition (Matrix Arg, int rightflag) { - // Initialize. - double[][] A = Arg.getArray(); - n = Arg.getColumnDimension(); - R = new double[n][n]; - isspd = (Arg.getColumnDimension() == n); - // Main loop. - for (int j = 0; j < n; j++) { - double d = 0.0; - for (int k = 0; k < j; k++) { - double s = A[k][j]; - for (int i = 0; i < k; i++) { - s = s - R[i][k]*R[i][j]; - } - R[k][j] = s = s/R[k][k]; - d = d + s*s; - isspd = isspd & (A[k][j] == A[j][k]); - } - d = A[j][j] - d; - isspd = isspd & (d > 0.0); - R[j][j] = Math.sqrt(Math.max(d,0.0)); - for (int k = j+1; k < n; k++) { - R[k][j] = 0.0; - } - } - } - - \** Return upper triangular factor. - @return R - *\ - - public Matrix getR () { - return new Matrix(R,n,n); - }*/ - /** * Is the matrix symmetric and positive definite? * @@ -170,7 +112,7 @@ public class CholeskyDecomposition implements java.io.Serializable { * @throws IllegalArgumentException Matrix row dimensions must agree. * @throws RuntimeException Matrix is not symmetric positive definite. */ - public Matrix solve(final Matrix B) { + public Matrix solve(final @NotNull Matrix B) { if (B.getRowDimension() != n) { throw new IllegalArgumentException("Matrix row dimensions must agree."); } diff --git a/src/main/java/plugins/nherve/matrix/EigenvalueDecomposition.java b/src/main/java/plugins/nherve/matrix/EigenvalueDecomposition.java index 369f589414666db670763696d78d49292c9789bb..c8b4f60271548246ee829fbf47241ee8ad698a3a 100644 --- a/src/main/java/plugins/nherve/matrix/EigenvalueDecomposition.java +++ b/src/main/java/plugins/nherve/matrix/EigenvalueDecomposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.NotNull; import plugins.nherve.matrix.util.Maths; /** @@ -37,7 +38,6 @@ import plugins.nherve.matrix.util.Maths; * A = V*D*inverse(V) depends upon V.cond(). **/ public class EigenvalueDecomposition implements java.io.Serializable { - /** * Row and column dimension (square matrix). * @@ -898,7 +898,7 @@ public class EigenvalueDecomposition implements java.io.Serializable { * * @param Arg Square matrix */ - public EigenvalueDecomposition(final Matrix Arg) { + public EigenvalueDecomposition(final @NotNull Matrix Arg) { final double[][] A = Arg.getArray(); n = Arg.getColumnDimension(); V = new double[n][n]; diff --git a/src/main/java/plugins/nherve/matrix/LUDecomposition.java b/src/main/java/plugins/nherve/matrix/LUDecomposition.java index 5cb67a0a44b6480641ba3261712374f49686e40c..c32987f53c2f1b13e73cceb695b1610b63ae2fbd 100644 --- a/src/main/java/plugins/nherve/matrix/LUDecomposition.java +++ b/src/main/java/plugins/nherve/matrix/LUDecomposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,8 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.NotNull; + /** * LU Decomposition. * <p> @@ -32,7 +34,6 @@ package plugins.nherve.matrix; * linear equations. This will fail if isNonsingular() returns false. */ public class LUDecomposition implements java.io.Serializable { - /** * Array for internal storage of decomposition. * @@ -73,7 +74,7 @@ public class LUDecomposition implements java.io.Serializable { * * @param A Rectangular matrix */ - public LUDecomposition(final Matrix A) { + public LUDecomposition(final @NotNull Matrix A) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. @@ -144,58 +145,6 @@ public class LUDecomposition implements java.io.Serializable { } } -/* - \** LU Decomposition, computed by Gaussian elimination. - <P> - This constructor computes L and U with the "daxpy"-based elimination - algorithm used in LINPACK and MATLAB. In Java, we suspect the dot-product, - Crout algorithm will be faster. We have temporarily included this - constructor until timing experiments confirm this suspicion. - <P> - @param A Rectangular matrix - @param linpackflag Use Gaussian elimination. Actual value ignored. - @return Structure to access L, U and piv. - *\ - - public LUDecomposition (Matrix A, int linpackflag) { - // Initialize. - LU = A.getArrayCopy(); - m = A.getRowDimension(); - n = A.getColumnDimension(); - piv = new int[m]; - for (int i = 0; i < m; i++) { - piv[i] = i; - } - pivsign = 1; - // Main loop. - for (int k = 0; k < n; k++) { - // Find pivot. - int p = k; - for (int i = k+1; i < m; i++) { - if (Math.abs(LU[i][k]) > Math.abs(LU[p][k])) { - p = i; - } - } - // Exchange if necessary. - if (p != k) { - for (int j = 0; j < n; j++) { - double t = LU[p][j]; LU[p][j] = LU[k][j]; LU[k][j] = t; - } - int t = piv[p]; piv[p] = piv[k]; piv[k] = t; - pivsign = -pivsign; - } - // Compute multipliers and eliminate k-th column. - if (LU[k][k] != 0.0) { - for (int i = k+1; i < m; i++) { - LU[i][k] /= LU[k][k]; - for (int j = k+1; j < n; j++) { - LU[i][j] -= LU[i][k]*LU[k][j]; - } - } - } - } - } */ - /** * Is the matrix nonsingular? * @@ -303,7 +252,7 @@ public class LUDecomposition implements java.io.Serializable { * @throws IllegalArgumentException Matrix row dimensions must agree. * @throws RuntimeException Matrix is singular. */ - public Matrix solve(final Matrix B) { + public Matrix solve(final @NotNull Matrix B) { if (B.getRowDimension() != m) { throw new IllegalArgumentException("Matrix row dimensions must agree."); } diff --git a/src/main/java/plugins/nherve/matrix/Matrix.java b/src/main/java/plugins/nherve/matrix/Matrix.java index b74d7746eac6a003c6f865764aaa4848a6cd44e0..a8305af3c0a0f5062e413c227faf92ec2c6cbea4 100644 --- a/src/main/java/plugins/nherve/matrix/Matrix.java +++ b/src/main/java/plugins/nherve/matrix/Matrix.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,8 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import plugins.nherve.matrix.util.Maths; import java.io.BufferedReader; @@ -76,7 +78,6 @@ import java.util.Vector; * @version 5 August 1998 */ public class Matrix implements Cloneable, java.io.Serializable { - /** * Array for internal storage of elements. * @@ -129,7 +130,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @throws IllegalArgumentException All rows must have the same length * @see #constructWithCopy */ - public Matrix(final double[][] A) { + public Matrix(final double @NotNull [] @NotNull [] A) { m = A.length; n = A[0].length; for (int i = 0; i < m; i++) { @@ -161,7 +162,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param m Number of rows. * @throws IllegalArgumentException Array length must be a multiple of m. */ - public Matrix(final double[] vals, final int m) { + public Matrix(final double @NotNull [] vals, final int m) { this.m = m; n = (m != 0 ? vals.length / m : 0); if (m * n != vals.length) { @@ -180,7 +181,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @return Construct a matrix from a copy of a 2-D array. * @throws IllegalArgumentException All rows must have the same length */ - public static Matrix constructWithCopy(final double[][] A) { + public static Matrix constructWithCopy(final double @NotNull [] @NotNull [] A) { final int m = A.length; final int n = A[0].length; final Matrix X = new Matrix(m, n); @@ -326,7 +327,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @return A(r ( :), c(:)) * @throws ArrayIndexOutOfBoundsException Submatrix indices */ - public Matrix getMatrix(final int[] r, final int[] c) { + public Matrix getMatrix(final int @NotNull [] r, final int @NotNull [] c) { final Matrix X = new Matrix(r.length, c.length); final double[][] B = X.getArray(); try { @@ -351,7 +352,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @return A(i0 : i1, c ( :)) * @throws ArrayIndexOutOfBoundsException Submatrix indices */ - public Matrix getMatrix(final int i0, final int i1, final int[] c) { + public Matrix getMatrix(final int i0, final int i1, final int @NotNull [] c) { final Matrix X = new Matrix(i1 - i0 + 1, c.length); final double[][] B = X.getArray(); try { @@ -376,7 +377,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @return A(r ( :), j0:j1) * @throws ArrayIndexOutOfBoundsException Submatrix indices */ - public Matrix getMatrix(final int[] r, final int j0, final int j1) { + public Matrix getMatrix(final int @NotNull [] r, final int j0, final int j1) { final Matrix X = new Matrix(r.length, j1 - j0 + 1); final double[][] B = X.getArray(); try { @@ -437,7 +438,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param X A(r(:),c(:)) * @throws ArrayIndexOutOfBoundsException Submatrix indices */ - public void setMatrix(final int[] r, final int[] c, final Matrix X) { + public void setMatrix(final int @NotNull [] r, final int[] c, final Matrix X) { try { for (int i = 0; i < r.length; i++) { for (int j = 0; j < c.length; j++) { @@ -459,7 +460,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param X A(r(:),j0:j1) * @throws ArrayIndexOutOfBoundsException Submatrix indices */ - public void setMatrix(final int[] r, final int j0, final int j1, final Matrix X) { + public void setMatrix(final int @NotNull [] r, final int j0, final int j1, final Matrix X) { try { for (int i = 0; i < r.length; i++) { for (int j = j0; j <= j1; j++) { @@ -793,7 +794,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @return Matrix product, A * B * @throws IllegalArgumentException Matrix inner dimensions must agree. */ - public Matrix times(final Matrix B) { + public Matrix times(final @NotNull Matrix B) { if (B.m != n) { throw new IllegalArgumentException("Matrix inner dimensions must agree."); } @@ -882,7 +883,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param B right hand side * @return solution if A is square, least squares solution otherwise. */ - public Matrix solveTranspose(final Matrix B) { + public Matrix solveTranspose(final @NotNull Matrix B) { return transpose().solve(B.transpose()); } @@ -978,6 +979,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param w Column width. * @param d Number of digits after the decimal. */ + @SuppressWarnings("UseOfSystemOutOrSystemErr") public void print(final int w, final int d) { print(new PrintWriter(System.out, true), w, d); } @@ -1010,6 +1012,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param width Field width for each column. * @see java.text.DecimalFormat#setDecimalFormatSymbols */ + @SuppressWarnings("UseOfSystemOutOrSystemErr") public void print(final NumberFormat format, final int width) { print(new PrintWriter(System.out, true), format, width); } @@ -1031,7 +1034,7 @@ public class Matrix implements Cloneable, java.io.Serializable { * @param width Column width. * @see java.text.DecimalFormat#setDecimalFormatSymbols */ - public void print(final PrintWriter output, final NumberFormat format, final int width) { + public void print(final @NotNull PrintWriter output, final NumberFormat format, final int width) { output.println(); // start on new line. for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { @@ -1055,7 +1058,9 @@ public class Matrix implements Cloneable, java.io.Serializable { * row appear on a single line, the last row is followed by a blank line. * @throws java.io.IOException IO Exception */ - public static Matrix read(final BufferedReader input) throws java.io.IOException { + @Contract("_ -> new") + @SuppressWarnings("StatementWithEmptyBody") + public static @NotNull Matrix read(final BufferedReader input) throws java.io.IOException { final StreamTokenizer tokenizer = getStreamTokenizer(input); final Vector<Double> v1 = new Vector<>(); @@ -1095,7 +1100,7 @@ public class Matrix implements Cloneable, java.io.Serializable { return new Matrix(A); } - private static StreamTokenizer getStreamTokenizer(final BufferedReader input) { + private static @NotNull StreamTokenizer getStreamTokenizer(final BufferedReader input) { final StreamTokenizer tokenizer = new StreamTokenizer(input); // Although StreamTokenizer will parse numbers, it doesn't recognize @@ -1114,7 +1119,8 @@ public class Matrix implements Cloneable, java.io.Serializable { /** * Check if size(A) == size(B) **/ - private void checkMatrixDimensions(final Matrix B) { + @Contract(pure = true) + private void checkMatrixDimensions(final @NotNull Matrix B) { if (B.m != m || B.n != n) { throw new IllegalArgumentException("Matrix dimensions must agree."); } diff --git a/src/main/java/plugins/nherve/matrix/NHerveMatrix.java b/src/main/java/plugins/nherve/matrix/NHerveMatrix.java index ee3d1c58add4805c8d7dd7b0765ca6571c60bd16..91d188df96b803cbfbe16bb0489138ec9d4ae6eb 100644 --- a/src/main/java/plugins/nherve/matrix/NHerveMatrix.java +++ b/src/main/java/plugins/nherve/matrix/NHerveMatrix.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,14 +18,18 @@ package plugins.nherve.matrix; -import icy.plugin.abstract_.Plugin; -import icy.plugin.interface_.PluginLibrary; +import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin; +import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon; +import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName; +import org.bioimageanalysis.icy.extension.plugin.interface_.PluginLibrary; /** * The Class NHerveMatrix. * * @author Nicolas HERVE - nicolas.herve@pasteur.fr */ +@IcyPluginName("NHerve Matrix") +@IcyPluginIcon(path = "/NHerveMatrix_icon.png") public class NHerveMatrix extends Plugin implements PluginLibrary { - + // } diff --git a/src/main/java/plugins/nherve/matrix/QRDecomposition.java b/src/main/java/plugins/nherve/matrix/QRDecomposition.java index 3ebfc3b086a50a93be1caf94dfc0f94d8c681c76..69d97a0802155e559abfdef1ed98d3356434ee48 100644 --- a/src/main/java/plugins/nherve/matrix/QRDecomposition.java +++ b/src/main/java/plugins/nherve/matrix/QRDecomposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.NotNull; import plugins.nherve.matrix.util.Maths; /** @@ -33,9 +34,7 @@ import plugins.nherve.matrix.util.Maths; * of simultaneous linear equations. This will fail if isFullRank() * returns false. */ - public class QRDecomposition implements java.io.Serializable { - /** * Array for internal storage of decomposition. * @@ -64,7 +63,7 @@ public class QRDecomposition implements java.io.Serializable { * * @param A Rectangular matrix */ - public QRDecomposition(final Matrix A) { + public QRDecomposition(final @NotNull Matrix A) { // Initialize. QR = A.getArrayCopy(); m = A.getRowDimension(); @@ -200,7 +199,7 @@ public class QRDecomposition implements java.io.Serializable { * @throws IllegalArgumentException Matrix row dimensions must agree. * @throws RuntimeException Matrix is rank deficient. */ - public Matrix solve(final Matrix B) { + public Matrix solve(final @NotNull Matrix B) { if (B.getRowDimension() != m) { throw new IllegalArgumentException("Matrix row dimensions must agree."); } diff --git a/src/main/java/plugins/nherve/matrix/SingularValueDecomposition.java b/src/main/java/plugins/nherve/matrix/SingularValueDecomposition.java index 633a44585f2eea925606a4d6f8fc081109d4597d..8bfbbe0e71546fd99ee793c9b2c5415155f5e88c 100644 --- a/src/main/java/plugins/nherve/matrix/SingularValueDecomposition.java +++ b/src/main/java/plugins/nherve/matrix/SingularValueDecomposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2023. Institut Pasteur. + * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ package plugins.nherve.matrix; +import org.jetbrains.annotations.NotNull; import plugins.nherve.matrix.util.Maths; /** @@ -34,9 +35,7 @@ import plugins.nherve.matrix.util.Maths; * never fail. The matrix condition number and the effective numerical * rank can be computed from this decomposition. */ - public class SingularValueDecomposition implements java.io.Serializable { - /** * Array for internal storage of U. * @@ -77,8 +76,7 @@ public class SingularValueDecomposition implements java.io.Serializable { * * @param Arg Rectangular matrix */ - public SingularValueDecomposition(final Matrix Arg) { - + public SingularValueDecomposition(final @NotNull Matrix Arg) { // Derived from LINPACK code. // Initialize. final double[][] A = Arg.getArrayCopy(); diff --git a/src/main/java/plugins/nherve/matrix/util/Maths.java b/src/main/java/plugins/nherve/matrix/util/Maths.java index e5cba8b484522027bbbb99cb613dc1ff2b90a1f9..81b6468770b0ce35d993a343adc7e25ff23b063b 100644 --- a/src/main/java/plugins/nherve/matrix/util/Maths.java +++ b/src/main/java/plugins/nherve/matrix/util/Maths.java @@ -1 +1 @@ -/* * Copyright (c) 2010-2023. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <https://www.gnu.org/licenses/>. */ package plugins.nherve.matrix.util; public class Maths { /** * @param a double * @param b double * @return sqrt(a ^ 2 + b ^ 2) without under/overflow. **/ public static double hypot(final double a, final double b) { double r; if (Math.abs(a) > Math.abs(b)) { r = b / a; r = Math.abs(a) * Math.sqrt(1 + r * r); } else if (b != 0) { r = a / b; r = Math.abs(b) * Math.sqrt(1 + r * r); } else { r = 0.0; } return r; } } \ No newline at end of file +/* * Copyright (c) 2010-2024. Institut Pasteur. * * This file is part of Icy. * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <https://www.gnu.org/licenses/>. */ package plugins.nherve.matrix.util; public class Maths { /** * @param a double * @param b double * @return sqrt(a ^ 2 + b ^ 2) without under/overflow. **/ public static double hypot(final double a, final double b) { double r; if (Math.abs(a) > Math.abs(b)) { r = b / a; r = Math.abs(a) * Math.sqrt(1 + r * r); } else if (b != 0) { r = a / b; r = Math.abs(b) * Math.sqrt(1 + r * r); } else { r = 0.0; } return r; } } \ No newline at end of file