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