From de72c475903cd16d27e838e83a77944464890f08 Mon Sep 17 00:00:00 2001
From: Cyrille Valladeau <cyrille.valladeau@c-s.fr>
Date: Mon, 21 Mar 2011 19:48:32 +0100
Subject: [PATCH] ENH : supress Hermitian Analysis class

---
 .../otbHermitianEigenAnalysis.h               | 342 ------
 .../otbHermitianEigenAnalysis.txx             | 983 ------------------
 .../otbReciprocalHAlphaImageFilter.h          | 157 ++-
 Testing/Code/SARPolarimetry/CMakeLists.txt    |   5 -
 .../otbHermitianEigenAnalysisTest.cxx         |  41 +
 .../otbReciprocalHAlphaImageFilter.cxx        |   5 +-
 .../otbSARPolarimetryTests2.cxx               |   1 -
 7 files changed, 145 insertions(+), 1389 deletions(-)
 delete mode 100644 Code/SARPolarimetry/otbHermitianEigenAnalysis.h
 delete mode 100644 Code/SARPolarimetry/otbHermitianEigenAnalysis.txx

diff --git a/Code/SARPolarimetry/otbHermitianEigenAnalysis.h b/Code/SARPolarimetry/otbHermitianEigenAnalysis.h
deleted file mode 100644
index 16001824ae..0000000000
--- a/Code/SARPolarimetry/otbHermitianEigenAnalysis.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef __otbHermitianEigenAnalysis_h
-#define __otbHermitianEigenAnalysis_h
-
-#include "itkMacro.h"
-#include "itkVector.h"
-#include "itkArray2D.h"
-
-namespace otb
-{
-  
-/** \class HermitianEigenAnalysis
- * \brief Find Eigen values of a real 2D symmetric matrix. It
- * serves as a thread safe alternative to the class:
- * vnl_symmetric_eigensystem, which uses netlib routines.
- *
- * The class is templated over the input matrix, (which is expected to provide
- * access to its elements with the [][] operator), matrix to store eigen
- * values, (must provide write operations on its elements with the [] operator),
- * EigenMatrix to store eigen vectors (must provide write access to its elements
- * with the [][] operator).
- *
- * The SetOrderEigenValues() method can be used to order eigen values (and their
- * corresponding eigen vectors if computed) in ascending order. This is the
- * default ordering scheme. Eigen vectors and values can be obtained without
- * ordering by calling SetOrderEigenValues(false)
- *
- * The SetOrderEigenMagnitudes() method can be used to order eigen values (and
- * their corresponding eigen vectors if computed) by magnitude in ascending order.
- *
- * The user of this class is explicitly supposed to set the dimension of the
- * 2D matrix using the SetDimension() method.
- *
- * The class contains routines taken from netlib sources. (www.netlib.org).
- * netlib/tql1.c
- * netlib/tql2.c
- * netlib/tred1.c
- * netlib/tred2.c
- *
- * Reference:
- *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
- *     wilkinson.
- *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
- *
- * \ingroup SARPolarimetry
- */
-
-template < typename TMatrix, typename TVector, typename TEigenMatrix=TMatrix >
-class HermitianEigenAnalysis
-{
-public:
-  typedef enum {
-    OrderByValue=1,
-    OrderByMagnitude,
-    DoNotOrder
-  }EigenValueOrderType;
-
-  typedef itk::Vector<float, 2> ComplexVectorType;
-  typedef itk::Vector<ComplexVectorType, 3> HermitianVectorType;
-  typedef itk::Vector<HermitianVectorType, 3> HermitianMatrixType;
- 
-  
-  HermitianEigenAnalysis():
-      m_Dimension(0),
-      m_Order(0),
-      m_OrderEigenValues(OrderByValue)
-    {};
-  
-  HermitianEigenAnalysis( const unsigned int dimension ):
-      m_Dimension(dimension),
-      m_Order(dimension),
-      m_OrderEigenValues(OrderByValue)
-    {};
-
-  virtual ~HermitianEigenAnalysis() {};
-
-  typedef TMatrix      MatrixType;
-  typedef TEigenMatrix EigenMatrixType;
-  typedef TVector      VectorType;
-
-  
-
-
-  /** Compute Eigen values of A
-   * A is any type that overloads the [][] operator and contains the
-   * symmetric matrix. In practice only the upper triangle of the
-   * matrix will be accessed. (Both itk::Matrix and vnl_matrix
-   * overload [][] operator.)
-   *
-   * 'EigenValues' is any type that overloads the []   operator and will contain
-   * the eigen values.
-   *
-   * No size checking is performed. A is expected to be a square matrix of size
-   * m_Dimension.  'EigenValues' is expected to be of length m_Dimension.
-   * The matrix is not checked to see if it is symmetric.
-   */
-  unsigned int ComputeEigenValues(
-              const TMatrix  & A,
-              TVector        & EigenValues) const;
-              
-  /** Compute Eigen values and vectors of A
-   * A is any type that overloads the [][] operator and contains the
-   * symmetric matrix. In practice only the upper triangle of the
-   * matrix will be accessed. (Both itk::Matrix and vnl_matrix
-   * overload [][] operator.)
-   *
-   * 'EigenValues' is any type that overloads the []   operator and will contain
-   * the eigen values.
-   *
-   * 'EigenVectors' is any type that provides access to its elements with the
-   * [][] operator. It is expected be of size m_Dimension * m_Dimension.
-   *
-   * No size checking is performed. A is expected to be a square matrix of size
-   * m_Dimension.  'EigenValues' is expected to be of length m_Dimension.
-   * The matrix is not checked to see if it is symmetric.
-   *
-   * Each row of the matrix 'EigenVectors' represents an eigen vector. (unlike MATLAB
-   * where the columns of the [EigenVectors, EigenValues] = eig(A) contains the
-   * eigenvectors).
-   */
-  unsigned int ComputeEigenValuesAndVectors(
-              const TMatrix  & A,
-              TVector        & EigenValues,
-              TEigenMatrix   & EigenVectors ) const;
-
-  
-  /** Matrix order. Defaults to matrix dimension if not set **/
-  void SetOrder(const unsigned int n)
-    {
-    m_Order = n;
-    }
-  
-  /** Get the Matrix order. Will be 0 unless explicitly set, or unless a
-   * call to SetDimension has been made in which case it will be the
-   * matrix dimension. */
-  unsigned int GetOrder() const { return m_Order; }
-
-  /** Set/Get methods to order the eigen values in ascending order.
-   * This is the default. ie lambda_1 < lambda_2 < ....
-   */
-  void SetOrderEigenValues( const bool b )
-    {
-    if (b) { m_OrderEigenValues = OrderByValue;     }
-    else   { m_OrderEigenValues = DoNotOrder;       }
-    }
-  bool GetOrderEigenValues() const { return (m_OrderEigenValues == OrderByValue); }
-
-  /** Set/Get methods to order the eigen value magnitudes in ascending order.
-   * In other words, |lambda_1| < |lambda_2| < .....
-   */
-  void SetOrderEigenMagnitudes( const bool b )
-    {
-    if (b) { m_OrderEigenValues = OrderByMagnitude; }
-    else   { m_OrderEigenValues = DoNotOrder;       }
-    }
-  bool GetOrderEigenMagnitudes() const { return (m_OrderEigenValues == OrderByMagnitude); }
-
-  /** Set the dimension of the input matrix A. A is a square matrix of
-   * size m_Dimension. */
-  void SetDimension( const unsigned int n )
-    {
-    m_Dimension = n;
-    if (m_Order == 0 )
-      {
-      m_Order = m_Dimension;
-      }
-    }
-  
-  /** Get Matrix dimension, Will be 0 unless explicitly set by a
-   * call to SetDimension. */
-  unsigned int GetDimension() const { return m_Dimension; }
-
-
-private:
-  unsigned int m_Dimension;
-  unsigned int m_Order;
-  EigenValueOrderType         m_OrderEigenValues;
-
- 
-  /** Reduces a real symmetric matrix to a symmetric tridiagonal matrix using
-   *  orthogonal similarity transformations.
-   *  'inputMatrix' contains the real symmetric input matrix. Only the lower
-   *  triangle of the matrix need be supplied. The upper triangle is unaltered.
-   *  'd' contains the diagonal elements of the tridiagonal matrix.
-   *  'e' contains the subdiagonal elements of the tridiagonal matrix in its
-   *  last n-1 positions.  e(1) is set to zero.
-   *  'e2' contains the squares of the corresponding elements of e.
-   *  'e2' may coincide with e if the squares are not needed.
-   *  questions and comments should be directed to burton s. garbow.
-   *  mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tred1.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary].
-   *  Reference:
-   *  num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson.
-   *    handbook for auto. comp., vol.ii-linear algebra, 212-226(1971).    */
-  void ReduceToTridiagonalMatrix(double *inputMatrix, VectorType &d,
-                                 double *e, double *e2) const;
-
-
-  
-  /** Reduces a real symmetric matrix to a symmetric tridiagonal matrix using
-   *  and accumulating orthogonal similarity transformations.
-   *  'inputMatrix' contains the real symmetric input matrix. Only the lower
-   *  triangle of the matrix need be supplied. The upper triangle is unaltered.
-   *  'diagonalElements' will contains the diagonal elements of the tridiagonal
-   *  matrix.
-   *  'subDiagonalElements' will contain the subdiagonal elements of the tridiagonal
-   *  matrix in its last n-1 positions.  subDiagonalElements(1) is set to zero.
-   *  'transformMatrix' contains the orthogonal transformation matrix produced
-   *  in the reduction.
-   *
-   *  questions and comments should be directed to burton s. garbow.
-   *  mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tred2.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary].
-   *  Reference:
-   *  num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson.
-   *    handbook for auto. comp., vol.ii-linear algebra, 212-226(1971).    */
-  void ReduceToTridiagonalMatrixAndGetTransformation(
-                  double *inputMatrix, VectorType &diagonalElements,
-                  double *subDiagonalElements, double *transformMatrix) const;
-  
-
-  
-  /* Finds the eigenvalues of a symmetric tridiagonal matrix by the ql method.
-   *
-   * On input:
-   * 'd' contains the diagonal elements of the input matrix.
-   * 'e' contains the subdiagonal elements of the input matrix
-   * in its last n-1 positions.  e(1) is arbitrary.
-   * On Output:
-   * 'd' contains the eigenvalues.
-   * 'e' has been destroyed.
-   *
-   * Returns:
-   *          zero       for normal return,
-   *          j          if the j-th eigenvalue has not been
-   *                     determined after 30 iterations.
-   *
-   *
-   * Reference
-   *     this subroutine is a translation of the algol procedure tql1,
-   *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
-   *     wilkinson.
-   *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
-   *
-   *     Questions and comments should be directed to burton s. garbow,
-   *     mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tql1.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary]                      */
-  unsigned int ComputeEigenValuesUsingQL(
-                         VectorType &d, double *e) const;
-
-  
-  /* Finds the eigenvalues and eigenvectors of a symmetric tridiagonal matrix
-   * by the ql method.
-   *
-   * On input:
-   * 'd' contains the diagonal elements of the input matrix.
-   * 'e' contains the subdiagonal elements of the input matrix
-   * in its last n-1 positions.  e(1) is arbitrary.
-   * 'z' contains the transformation matrix produced in the reduction by
-   * ReduceToTridiagonalMatrixAndGetTransformation(), if performed. If the
-   * eigenvectors of the tridiagonal matrix are desired, z must contain
-   * the identity matrix.
-
-   * On Output:
-   * 'd' contains the eigenvalues.
-   * 'e' has been destroyed.
-   * 'z' contains orthonormal eigenvectors of the symmetric tridiagonal
-   * (or full) matrix.
-   *
-   * Returns:
-   *          zero       for normal return,
-   *          j          if the j-th eigenvalue has not been
-   *                     determined after 1000 iterations.
-   *
-   * Reference
-   *     this subroutine is a translation of the algol procedure tql1,
-   *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
-   *     wilkinson.
-   *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
-   *
-   *     Questions and comments should be directed to burton s. garbow,
-   *     mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tql2.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary]
-   */
-  unsigned int ComputeEigenValuesAndVectorsUsingQL(
-                                   VectorType &d, double *e, double *z) const;
-  
-};
-
-template< typename TMatrix, typename TVector, typename TEigenMatrix >
-std::ostream & operator<<(std::ostream& os,
-    const HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix > &s)
-{
-  os << "[ClassType: HermitianEigenAnalysis]" << std::endl;
-  os << "  Dimension : " << s.GetDimension() << std::endl;
-  os << "  Order : " << s.GetOrder() << std::endl;
-  os << "  OrderEigenValues: " << s.GetOrderEigenValues() << std::endl;
-  os << "  OrderEigenMagnitudes: " << s.GetOrderEigenMagnitudes() << std::endl;
-  return os;
-}
-
-} // end namespace otb
-
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "otbHermitianEigenAnalysis.txx"
-#endif
-
-#endif
-
diff --git a/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx b/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx
deleted file mode 100644
index 04d32590c9..0000000000
--- a/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx
+++ /dev/null
@@ -1,983 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-
-#ifndef __otbHermitianEigenAnalysis_txx
-#define __otbHermitianEigenAnalysis_txx
-
-#include "otbHermitianEigenAnalysis.h"
-#include "vnl/vnl_math.h"
-
-namespace otb
-{
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValues(const TMatrix  & A,
-                         TVector  & D) const
-{
-  double *workArea1 = new double[ m_Dimension ];
-
-  // Copy the input matrix
-  double *inputMatrix = new double [ m_Dimension * m_Dimension ];
-  
-  unsigned int k = 0;
-
-  for( unsigned int row=0; row < m_Dimension; row++ )
-    {
-    for( unsigned int col=0; col < m_Dimension; col++ )
-      {
-      inputMatrix[k++] = A(row, col);
-      }
-    }
-
-  ReduceToTridiagonalMatrix( inputMatrix, D, workArea1, workArea1 );
-  const unsigned int eigenErrIndex =
-          ComputeEigenValuesUsingQL( D, workArea1 );
-  
-  delete[] workArea1;
-  delete[] inputMatrix;
-
-  return eigenErrIndex; //index of eigen value that could not be computed
-}
-
-
-/*******************************************************************************
-Routine  : diagonalisation
-Authors  : Eric POTTIER, Laurent FERRO-FAMIL
-Creation : 01/2002
-Update   :
-*-------------------------------------------------------------------------------
-Description :  Computes the eigenvectors and eigenvalues of a N*N hermitian
-matrix (with N < 10)
-*-------------------------------------------------------------------------------
-Inputs arguments :
-MatrixDim : Dimension of the Hermitian Matrix (N)
-HermitianMatrix : N*N*2 complex hermitian matrix
-Returned values  :
-EigenVect : N*N*2 complex eigenvector matrix
-EigenVal  : N elements eigenvalue real vector
-*******************************************************************************/
-
-static void HermitianDiagonalisation( float HM[3][3][2], float EigenVect[3][3][2], float EigenVal[3])
-{
-
-    double a[10][10][2], v[10][10][2], d[10], b[10], z[10];
-    double w[2], s[2], c[2], titi[2], gc[2], hc[2];
-    double sm, tresh, x, toto, e, f, g, h, r, d1, d2;
-    int n, p, q, ii, i, j, k;
-
-    //n = MatrixDim;
-    n=3;
-   
-  
-
-    for (i = 1; i < n + 1; i++)
-      {
-        for (j = 1; j < n + 1; j++)
-          {
-            a[i][j][0] = HM[i - 1][j - 1][0];
-            a[i][j][1] = HM[i - 1][j - 1][1];
-            v[i][j][0] = 0.;
-            v[i][j][1] = 0.;
-          }
-        v[i][i][0] = 1.;
-        v[i][i][1] = 0.;
-      }
-
-    for (p = 1; p < n + 1; p++)
-      {
-        d[p] = a[p][p][0];
-        b[p] = d[p];
-        z[p] = 0.;
-      }
-
-    for (ii = 1; ii < 1000 * n * n; ii++)
-      {
-        sm = 0.;
-        for (p = 1; p < n; p++)
-          {
-            for (q = p + 1; q < n + 1; q++)
-              {
-                sm = sm + 2. * sqrt(a[p][q][0] * a[p][q][0] + a[p][q][1] * a[p][q][1]);
-              }
-          }
-        sm = sm / (n * (n - 1));
-        if (sm < 1.E-16)
-          {
-            goto Sortie;
-          }
-        tresh = 1.E-17;
-        if (ii < 4)
-          {
-            tresh = (long) 0.2 *sm / (n * n);
-          }
-        x = -1.E-15;
-        for (i = 1; i < n; i++)
-          {
-            for (j = i + 1; j < n + 1; j++)
-              {
-                toto = sqrt(a[i][j][0] * a[i][j][0] + a[i][j][1] * a[i][j][1]);
-                if (x < toto)
-                  {
-                    x = toto;
-                    p = i;
-                    q = j;
-                  }
-              }
-          }
-        toto = sqrt(a[p][q][0] * a[p][q][0] + a[p][q][1] * a[p][q][1]);
-        if (toto > tresh)
-          {
-            e = d[p] - d[q];
-            w[0] = a[p][q][0];
-            w[1] = a[p][q][1];
-            g = sqrt(w[0] * w[0] + w[1] * w[1]);
-            g = g * g;
-            f = sqrt(e * e + 4. * g);
-            d1 = e + f;
-            d2 = e - f;
-            if (fabs(d2) > fabs(d1))
-              {
-                d1 = d2;
-              }
-            r = fabs(d1) / sqrt(d1 * d1 + 4. * g);
-            s[0] = r;
-            s[1] = 0.;
-            titi[0] = 2. * r / d1;
-            titi[1] = 0.;
-            c[0] = titi[0] * w[0] - titi[1] * w[1];
-            c[1] = titi[0] * w[1] + titi[1] * w[0];
-            r = sqrt(s[0] * s[0] + s[1] * s[1]);
-            r = r * r;
-            h = (d1 / 2. + 2. * g / d1) * r;
-            d[p] = d[p] - h;
-            z[p] = z[p] - h;
-            d[q] = d[q] + h;
-            z[q] = z[q] + h;
-            a[p][q][0] = 0.;
-            a[p][q][1] = 0.;
-            
-            for (j = 1; j < p; j++)
-              {
-                gc[0] = a[j][p][0];
-                gc[1] = a[j][p][1];
-                hc[0] = a[j][q][0];
-                hc[1] = a[j][q][1];
-                a[j][p][0] = c[0] * gc[0] - c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                a[j][p][1] = c[0] * gc[1] + c[1] * gc[0] - s[0] * hc[1] + s[1] * hc[0];
-                a[j][q][0] = s[0] * gc[0] - s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                a[j][q][1] = s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-            for (j = p + 1; j < q; j++)
-              {
-                gc[0] = a[p][j][0];
-                gc[1] = a[p][j][1];
-                hc[0] = a[j][q][0];
-                hc[1] = a[j][q][1];
-                a[p][j][0] = c[0] * gc[0] + c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                a[p][j][1] = c[0] * gc[1] - c[1] * gc[0] + s[0] * hc[1] - s[1] * hc[0];
-                a[j][q][0] = s[0] * gc[0] + s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                a[j][q][1] = -s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-            for (j = q + 1; j < n + 1; j++)
-              {
-                gc[0] = a[p][j][0];
-                gc[1] = a[p][j][1];
-                hc[0] = a[q][j][0];
-                hc[1] = a[q][j][1];
-                a[p][j][0] = c[0] * gc[0] + c[1] * gc[1] - s[0] * hc[0] + s[1] * hc[1];
-                a[p][j][1] = c[0] * gc[1] - c[1] * gc[0] - s[0] * hc[1] - s[1] * hc[0];
-                a[q][j][0] = s[0] * gc[0] + s[1] * gc[1] + c[0] * hc[0] - c[1] * hc[1];
-                a[q][j][1] = s[0] * gc[1] - s[1] * gc[0] + c[0] * hc[1] + c[1] * hc[0];
-              }
-            for (j = 1; j < n + 1; j++)
-              {
-                gc[0] = v[j][p][0];
-                gc[1] = v[j][p][1];
-                hc[0] = v[j][q][0];
-                hc[1] = v[j][q][1];
-                v[j][p][0] = c[0] * gc[0] - c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                v[j][p][1] = c[0] * gc[1] + c[1] * gc[0] - s[0] * hc[1] + s[1] * hc[0];
-                v[j][q][0] = s[0] * gc[0] - s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                v[j][q][1] = s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-          }
-      }
-    
- Sortie:
-    
-    for (k = 1; k < n + 1; k++)
-      {
-        d[k] = 0;
-        for (i = 1; i < n + 1; i++)
-          {
-            for (j = 1; j < n + 1; j++)
-              {
-                d[k] = d[k] + v[i][k][0] * (HM[i - 1][j - 1][0] * v[j][k][0] - HM[i - 1][j - 1][1] * v[j][k][1]);
-                d[k] = d[k] + v[i][k][1] * (HM[i - 1][j - 1][0] * v[j][k][1] + HM[i - 1][j - 1][1] * v[j][k][0]);
-              }
-          }
-      }
-    
-    for (i = 1; i < n + 1; i++)
-      {
-        for (j = i + 1; j < n + 1; j++)
-          {
-            if (d[j] > d[i])
-              {
-                x = d[i];
-                d[i] = d[j];
-                d[j] = x;
-                for (k = 1; k < n + 1; k++)
-                  {
-                    c[0] = v[k][i][0];
-                    c[1] = v[k][i][1];
-                    v[k][i][0] = v[k][j][0];
-                    v[k][i][1] = v[k][j][1];
-                    v[k][j][0] = c[0];
-                    v[k][j][1] = c[1];
-                  }
-              }
-          }
-      }
-    
-    for (i = 0; i < n; i++)
-      {
-        EigenVal[i] = d[i + 1];
-        for (j = 0; j < n; j++)
-          {
-            EigenVect[i][j][0] = v[i + 1][j + 1][0];
-            EigenVect[i][j][1] = v[i + 1][j + 1][1];
-          }
-      }
-    
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesAndVectors(
-            const TMatrix  & T,
-            TVector        & EigenValues,
-            TEigenMatrix   & EigenVectors ) const
-{
-  // double *workArea1 = new double[ m_Dimension ];
-//   double *workArea2 = new double [ m_Dimension * m_Dimension ];
-
-  // Copy the input matrix
- 
-  unsigned int k = 0;
-  
-  float HM[3][3][2];
-
-
-// Passage de la matrice T T1....T9  une matrice 3*3*2 compatible avec la methode HermitianDiagonalisation
-
-
-  HM[0][0][0]=T[0];    HM[0][0][1]=0.;
-  HM[0][1][0]=T[3];    HM[0][1][1]=-T[4];
-  HM[0][2][0]=T[5];    HM[0][2][1]=-T[6];
-  HM[1][0][0]=T[3];    HM[1][0][1]=T[4];
-  HM[1][1][0]=T[1];    HM[1][1][1]=0.;
-  HM[1][2][0]=T[7];    HM[1][2][1]=-T[8];
-  HM[2][0][0]=T[5];    HM[2][0][1]=T[6];
-  HM[2][1][0]=T[7];    HM[2][1][1]=T[8];
-  HM[2][2][0]=T[2];    HM[2][2][1]=0.;
-
- 
-
-
-  //Acrobatie pour convectir EigenVectors en un float *** et EigenValues en float*
-
-  float eigenVect[3][3][2];
- float eigenVal[3];
-
-  for (int i=0; i<3; i++)
-    for (int j=0; j<3; j++)
-      {
-       eigenVect[i][j][0]=0.;
-       eigenVect[i][j][1]=0.;
-      }
-
-  for (int i=0; i<3; i++)
-    eigenVal[i]=0.;
-    
-  
-  
-  HermitianDiagonalisation( HM, eigenVect, eigenVal);
-
-  
-  //std::cout << HM[0][0][0] << " " << HM[0][1][0]<<"+j"<<HM[0][1][1] << " " << HM[0][2][0]<<"+j"<<HM[0][2][1]<<std::endl;
-  //std::cout << HM[1][0][0]<<"+j"<<HM[1][0][1] << " " << HM[1][1][0] << " " << HM[1][2][0]<<"+j"<<HM[1][2][1]<<std::endl;
-  //std::cout << HM[2][0][0]<<"+j"<<HM[2][0][1] << " " << HM[2][1][0]<<"+j"<< HM[2][1][1] << " " <<HM[2][2][0]<<std::endl;
-  //std::cout << "Valeurs propres : " << eigenVal[0] << "...." << eigenVal[1] <<  "...." << eigenVal[2] << std::endl<< std::endl;
-   
-  
-  // Recuperation des sorties
-  for (int i=0; i<3; i++)
-    for (int j=0; j<3; j++)
-       {
-          EigenVectors[i][2*j]=eigenVect[i][j][0];
-          EigenVectors[i][2*j+1]=eigenVect[i][j][1];
-       }
-  
-
-  for (int i=0; i<3; i++)
-    EigenValues[i]=eigenVal[i];
-   
-  
-  
-
- 
-  int eigenErrIndex=0;
-  return eigenErrIndex; //index of eigen value that could not be computed
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-void
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ReduceToTridiagonalMatrix(double * a, VectorType &d,
-                          double *e, double *e2) const
-{
-  double d__1;
-
-  /* Local variables */
-  double f, g, h;
-  int i, j, k, l;
-  double scale;
-  
-  for (i = 0; i < static_cast< int >(m_Order); ++i)
-    {
-    d[i] = a[m_Order-1 + i * m_Dimension];
-    a[m_Order-1 + i * m_Dimension] = a[i + i * m_Dimension];
-    }
-
-
-  for (i = m_Order-1; i >= 0; --i)
-    {
-    l = i - 1;
-    h = 0.;
-    scale = 0.;
-
-    /*     .......... scale row (algol tol then not needed) .......... */
-    for (k = 0; k <= l; ++k)
-      {
-      scale += vnl_math_abs(d[k]);
-      }
-    if (scale == 0.)
-      {
-      for (j = 0; j <= l; ++j)
-        {
-        d[j] = a[l + j * m_Dimension];
-        a[l + j * m_Dimension] = a[i + j * m_Dimension];
-        a[i + j * m_Dimension] = 0.;
-        }
-        e[i] = 0.;
-        e2[i] = 0.;
-        continue;
-      }
-    for (k = 0; k <= l; ++k)
-      {
-      d[k] /= scale;
-      h += d[k] * d[k];
-      }
-
-    e2[i] = scale * scale * h;
-    f = d[l];
-    d__1 = vcl_sqrt(h);
-    g = (-1.0) * vnl_math_sgn0(f) * vnl_math_abs(d__1);
-    e[i] = scale * g;
-    h -= f * g;
-    d[l] = f - g;
-    if (l != 0)
-      {
-
-      /*     .......... form a*u .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] = 0.;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j] + a[j + j * m_Dimension] * f;
-
-        for (k = j+1; k <= l; ++k)
-          {
-          g += a[k + j * m_Dimension] * d[k];
-          e[k] += a[k + j * m_Dimension] * f;
-          }
-        e[j] = g;
-        }
-    
-      /*     .......... form p .......... */
-      f = 0.;
-
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] /= h;
-        f += e[j] * d[j];
-        }
-
-      h = f / (h + h);
-      /*     .......... form q .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] -= h * d[j];
-        }
-
-      /*     .......... form reduced a .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j];
-
-        for (k = j; k <= l; ++k)
-          {
-          a[k + j * m_Dimension] = a[k + j * m_Dimension] - f * e[k] - g * d[k];
-          }
-        }
-      }
-
-    for (j = 0; j <= l; ++j)
-      {
-      f = d[j];
-      d[j] = a[l + j * m_Dimension];
-      a[l + j * m_Dimension] = a[i + j * m_Dimension];
-      a[i + j * m_Dimension] = f * scale;
-      }
-    }
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-void
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ReduceToTridiagonalMatrixAndGetTransformation(double * a, VectorType &d,
-                                              double *e, double *z) const
-{
-  double d__1;
-
-  /* Local variables */
-  double f, g, h;
-  unsigned int i, j, k, l;
-  double scale, hh;
-
-  for (i = 0; i < m_Order; ++i)
-    {
-    for (j = i; j < m_Order; ++j)
-      {
-      z[j + i * m_Dimension] = a[j + i * m_Dimension];
-      }
-    d[i] = a[m_Order -1 + i * m_Dimension];
-    }
-
-  for (i = m_Order-1; i > 0; --i)
-    {
-    l = i - 1;
-    h = 0.0;
-    scale = 0.0;
-    
-    /*     .......... scale row (algol tol then not needed) .......... */
-    for (k = 0; k <= l; ++k)
-      {
-      scale += vnl_math_abs(d[k]);
-      }
-    if (scale == 0.0)
-      {
-      e[i] = d[l];
-
-      for (j = 0; j <= l; ++j)
-        {
-        d[j] = z[l + j * m_Dimension];
-        z[i + j * m_Dimension] = 0.0;
-        z[j + i * m_Dimension] = 0.0;
-        }
-      }
-    else
-      {
-      for (k = 0; k <= l; ++k)
-        {
-        d[k] /= scale;
-        h += d[k] * d[k];
-        }
-
-      f = d[l];
-      d__1 = vcl_sqrt(h);
-      g = (-1.0) * vnl_math_sgn0(f) * vnl_math_abs(d__1);
-      e[i] = scale * g;
-      h -= f * g;
-      d[l] = f - g;
-      
-      /*     .......... form a*u .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] = 0.0;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        z[j + i * m_Dimension] = f;
-        g = e[j] + z[j + j * m_Dimension] * f;
-
-        for (k = j+1; k <= l; ++k)
-          {
-          g += z[k + j * m_Dimension] * d[k];
-          e[k] += z[k + j * m_Dimension] * f;
-          }
-
-          e[j] = g;
-        }
-      
-      /*     .......... form p .......... */
-      f = 0.0;
-
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] /= h;
-        f += e[j] * d[j];
-        }
-
-      hh = f / (h + h);
-      
-      /*     .......... form q .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] -= hh * d[j];
-        }
-
-      /*     .......... form reduced a .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j];
-
-        for (k = j; k <= l; ++k)
-          {
-          z[k + j * m_Dimension] = z[k + j * m_Dimension] - f * e[k] - g * d[k];
-          }
-
-        d[j] = z[l + j * m_Dimension];
-        z[i + j * m_Dimension] = 0.0;
-        }
-      }
-
-    d[i] = h;
-    }
-
-  /*     .......... accumulation of transformation matrices .......... */
-  for (i = 1; i < m_Order; ++i)
-    {
-    l = i - 1;
-    z[m_Order-1 + l * m_Dimension] = z[l + l * m_Dimension];
-    z[l + l * m_Dimension] = 1.0;
-    h = d[i];
-    if (h != 0.0)
-      {
-      for (k = 0; k <= l; ++k)
-        {
-        d[k] = z[k + i * m_Dimension] / h;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        g = 0.0;
-
-        for (k = 0; k <= l; ++k)
-          {
-          g += z[k + i * m_Dimension] * z[k + j * m_Dimension];
-          }
-
-        for (k = 0; k <= l; ++k)
-          {
-          z[k + j * m_Dimension] -= g * d[k];
-          }
-        }
-      }
-    
-    for (k = 0; k <= l; ++k)
-      {
-      z[k + i * m_Dimension] = 0.0;
-      }
-    
-    }
-    
-  for (i = 0; i < m_Order; ++i)
-    {
-    d[i] = z[m_Order-1 + i * m_Dimension];
-    z[m_Order-1 + i * m_Dimension] = 0.0;
-    }
-
-  z[m_Order-1 + (m_Order-1) * m_Dimension] = 1.0;
-  e[0] = 0.0;
-
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesUsingQL(VectorType &d, double *e) const
-{
-  
-  const double c_b10 = 1.0;
-
-  /* Local variables */
-  double c, f, g, h;
-  unsigned int i, j, l, m;
-  double p, r, s, c2, c3=0.0;
-  double s2=0.0;
-  double dl1, el1;
-  double tst1, tst2;
-
-  unsigned int ierr = 0;
-  if (m_Order == 1) {
-       return 1;
-  }
-
-  for (i = 1; i < m_Order; ++i) {
-      e[i-1] = e[i];
-  }
-
-  f = 0.;
-  tst1 = 0.;
-  e[m_Order-1] = 0.;
-
-  for (l = 0; l < m_Order; ++l)
-    {
-    j = 0;
-    h = vnl_math_abs(d[l]) + vnl_math_abs(e[l]);
-    if (tst1 < h)
-      {
-      tst1 = h;
-      }
-    /*     .......... look for small sub-diagonal element .......... */
-    for (m = l; m < m_Order; ++m)
-      {
-      tst2 = tst1 + vnl_math_abs(e[m]);
-      if (tst2 == tst1)
-        {
-        break;
-        }
-      /*     .......... e(n) is always zero, so there is no exit */
-      /*                through the bottom of the loop .......... */
-      }
-
-    if (m != l)
-      {
-    
-      do
-        {
-        if (j == 30)
-          {
-          /*     .......... set error -- no convergence to an */
-          /*                eigenvalue after 30 iterations .......... */
-          ierr = l+1;
-          return ierr;
-          }
-        ++j;
-        /*     .......... form shift .......... */
-        g = d[l];
-        p = (d[l+1] - g) / (e[l] * 2.);
-        r = vnl_math_hypot(p, c_b10);
-        d[l] = e[l] / (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        d[l+1] = e[l] * (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        dl1 = d[l+1];
-        h = g - d[l];
-
-        for (i = l+2; i < m_Order; ++i)
-        {
-            d[i] -= h;
-        }
-
-        f += h;
-        /*     .......... ql transformation .......... */
-        p = d[m];
-        c = 1.;
-        c2 = c;
-        el1 = e[l+1];
-        s = 0.;
-        for (i = m-1; i >= l; --i)
-          {
-          c3 = c2;
-          c2 = c;
-          s2 = s;
-          g = c * e[i];
-          h = c * p;
-          r = vnl_math_hypot(p, e[i]);
-          e[i+1] = s * r;
-          s = e[i] / r;
-          c = p / r;
-          p = c * d[i] - s * g;
-          d[i+1] = h + s * (c * g + s * d[i]);
-          if( i == l )
-            {
-            break;
-            }
-          }
-
-        p = -s * s2 * c3 * el1 * e[l] / dl1;
-        e[l] = s * p;
-        d[l] = c * p;
-        tst2 = tst1 + vnl_math_abs(e[l]);
-        } while (tst2 > tst1);
-      }
-
-    p = d[l] + f;
- 
-    if( m_OrderEigenValues == OrderByValue )
-      {
-      // Order by value
-      for (i = l; i > 0; --i)
-        {
-        if (p >= d[i-1])
-          break;
-        d[i] = d[i-1];
-        }
-      d[i] = p;
-      }
-    else if( m_OrderEigenValues == OrderByMagnitude )
-      {
-      // Order by magnitude.. make eigen values positive
-      for (i = l; i > 0; --i)
-        {
-        if (vnl_math_abs(p) >= vnl_math_abs(d[i-1]))
-          break;
-        d[i] = vnl_math_abs(d[i-1]);
-        }
-      d[i] = vnl_math_abs(p);
-      }
-    else
-      {
-      d[l] = p;
-      }
-    }
-
-  return ierr;    //ierr'th eigen value that couldn't be computed
-  
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesAndVectorsUsingQL(VectorType &d, double *e, double *z) const
-{
-  
-  const double c_b10 = 1.0;
-
-  /* Local variables */
-  double c, f, g, h;
-  unsigned int i, j, k, l, m;
-  double p, r, s, c2, c3=0.0;
-  double s2=0.0;
-  double dl1, el1;
-  double tst1, tst2;
-
-  unsigned int ierr = 0;
-  if (m_Order == 1)
-    {
-    return 1;
-    }
-
-  for (i = 1; i < m_Order; ++i)
-    {
-    e[i - 1] = e[i];
-    }
-
-  f = 0.0;
-  tst1 = 0.;
-  e[m_Order-1] = 0.;
-
-  for (l = 0; l < m_Order; ++l)
-    {
-    j = 0;
-    h = vnl_math_abs(d[l]) + vnl_math_abs(e[l]);
-    if (tst1 < h)
-      {
-      tst1 = h;
-      }
-    
-    /*     .......... look for small sub-diagonal element .......... */
-    for (m = l; m < m_Order; ++m)
-      {
-      tst2 = tst1 + vnl_math_abs(e[m]);
-      if (tst2 == tst1)
-        {
-        break;
-        }
-      
-      /*     .......... e(n) is always zero, so there is no exit */
-      /*                through the bottom of the loop .......... */
-      }
-
-    if (m != l)
-      {
-      do
-        {
-          
-        if (j == 1000)
-          {
-          /*     .......... set error -- no convergence to an */
-          /*                eigenvalue after 1000 iterations .......... */
-          ierr = l+1;
-          return ierr;
-          }
-        ++j;
-        /*     .......... form shift .......... */
-        g = d[l];
-        p = (d[l+1] - g) / (e[l] * 2.);
-        r = vnl_math_hypot(p, c_b10);
-        d[l] = e[l] / (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        d[l+1] = e[l] * (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        dl1 = d[l+1];
-        h = g - d[l];
-
-        for (i = l+2; i < m_Order; ++i)
-          {
-          d[i] -= h;
-        }
-
-        f += h;
-        /*     .......... ql transformation .......... */
-        p = d[m];
-        c = 1.0;
-        c2 = c;
-        el1 = e[l+1];
-        s = 0.;
-        
-        for (i = m-1; i >= l; --i)
-          {
-          c3 = c2;
-          c2 = c;
-          s2 = s;
-          g = c * e[i];
-          h = c * p;
-          r = vnl_math_hypot(p, e[i]);
-          e[i + 1] = s * r;
-          s = e[i] / r;
-          c = p / r;
-          p = c * d[i] - s * g;
-          d[i + 1] = h + s * (c * g + s * d[i]);
-          
-          /*     .......... form vector .......... */
-          for (k = 0; k < m_Order; ++k)
-            {
-            h = z[k + (i + 1) * m_Dimension];
-            z[k + (i + 1) * m_Dimension] = s * z[k + i * m_Dimension] + c * h;
-            z[k + i * m_Dimension] = c * z[k + i * m_Dimension] - s * h;
-            }
-          if( i == l )
-            {
-            break;
-            }
-          }
-
-        p = -s * s2 * c3 * el1 * e[l] / dl1;
-        e[l] = s * p;
-        d[l] = c * p;
-        tst2 = tst1 + vnl_math_abs(e[l]);
-        } while (tst2 > tst1);
-  
-      }
-
-    d[l] += f;
-    }
-  
-  /*     .......... order eigenvalues and eigenvectors .......... */
-  if( m_OrderEigenValues == OrderByValue )
-    {
-    // Order by value
-    for (i = 0; i < m_Order-1; ++i)
-      {
-      k = i;
-      p = d[i];
-
-      for (j = i+1; j < m_Order; ++j)
-        {
-        if (d[j] >= p)
-          {
-          continue;
-          }
-        k = j;
-        p = d[j];
-      }
-
-      if (k == i)
-        {
-        continue;
-        }
-      d[k] = d[i];
-      d[i] = p;
-
-      for (j = 0; j < m_Order; ++j)
-        {
-        p = z[j + i * m_Dimension];
-        z[j + i * m_Dimension] = z[j + k * m_Dimension];
-        z[j + k * m_Dimension] = p;
-        }
-      }
-    }
-  else if( m_OrderEigenValues == OrderByMagnitude )
-    {
-    // Order by magnitude
-    for (i = 0; i < m_Order-1; ++i)
-      {
-      k = i;
-      p = d[i];
-
-      for (j = i+1; j < m_Order; ++j)
-        {
-        if (vnl_math_abs(d[j]) >= vnl_math_abs(p))
-          {
-          continue;
-          }
-        k = j;
-        p = d[j];
-      }
-
-      if (k == i)
-        {
-        continue;
-        }
-      d[k] = vnl_math_abs(d[i]);
-      d[i] = vnl_math_abs(p);
-
-      for (j = 0; j < m_Order; ++j)
-        {
-        p = z[j + i * m_Dimension];
-        z[j + i * m_Dimension] = z[j + k * m_Dimension];
-        z[j + k * m_Dimension] = p;
-        }
-      }
-    }
- 
-  
-  return ierr;
-}
-
-
-}  // end namespace otb
- 
-#endif
- 
diff --git a/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h b/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
index 18292eca3b..5a18300e3d 100644
--- a/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
+++ b/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
@@ -20,9 +20,9 @@
 #define __ReciprocalHAlphaImageFilter_h
 
 #include "otbUnaryFunctorImageFilter.h"
-#include "otbHermitianEigenAnalysis.h"
 #include "itkVector.h"
 #include "otbMath.h"
+#include "vnl/algo/vnl_complex_eigensystem.h"
 
 namespace otb
  {
@@ -44,60 +44,108 @@ template< class TInput, class TOutput>
 class ReciprocalHAlphaFunctor
 {
 public:
-  typedef typename std::complex <double>         ComplexType;
-  typedef typename TOutput::ValueType              OutputValueType;
-
-  /** CoherencyMatrix type **/
-  typedef itk::Vector<double, 9> CoherencyMatrixType;
-
-  /** Vector type used to store eigenvalues. */
-  typedef itk::Vector<double, 3> EigenvalueType;
-
-  /** Matrix type used to store eigenvectors. */
-  typedef itk::Vector<float, 2> VectorType;
-  typedef itk::Vector<VectorType, 3> EigenVectorFirstComposantType;
-  typedef itk::Vector<VectorType, 3> EigenVectorType; // eigenvector type (real part, imaginary part)
-  typedef itk::Vector<itk::Vector<float, 6>, 3> EigenMatrixType;
-  typedef itk::Image<EigenVectorType, 2> EigenVectorImageType;
-  typedef itk::Image<double, 2> EigenValueImageType;
-
-  typedef itk::Vector<double, 3> OutputVectorType;
-
-  typedef itk::Vector<float, 2> ComplexVectorType;
-  typedef itk::Vector<ComplexVectorType, 3> HermitianVectorType;
-  typedef itk::Vector<HermitianVectorType, 3> HermitianMatrixType;
-  typedef otb::HermitianEigenAnalysis<CoherencyMatrixType, EigenvalueType, EigenMatrixType> HermitianAnalysisType;
-
-
+  typedef typename std::complex<double> ComplexType;
+  typedef vnl_matrix<ComplexType>       VNLMatrixType;
+  typedef vnl_vector<ComplexType>       VNLVectorType;
+  typedef vnl_vector<double>            VNLDoubleVectorType;
+  typedef typename TOutput::ValueType   OutputValueType;
+  
+  
   inline TOutput operator()( const TInput & Coherency ) const
     {
     TOutput result;
     result.SetSize(m_NumberOfComponentsPerPixel);
  
-    CoherencyMatrixType T;
-    EigenvalueType eigenValues;
-    EigenMatrixType eigenVectors;
-    HermitianAnalysisType HermitianAnalysis;
-
-    T[0] = static_cast<double>(Coherency[0].real());
-    T[1] = static_cast<double>(Coherency[3].real());
-    T[2] = static_cast<double>(Coherency[5].real());
-    T[3] = static_cast<double>(Coherency[1].real());
-    T[4] = static_cast<double>(Coherency[1].imag());
-    T[5] = static_cast<double>(Coherency[2].real());
-    T[6] = static_cast<double>(Coherency[2].imag());
-    T[7] = static_cast<double>(Coherency[4].real());
-    T[8] = static_cast<double>(Coherency[4].imag());
-    HermitianAnalysis.ComputeEigenValuesAndVectors(T, eigenValues, eigenVectors);
-
+    double T0 = static_cast<double>(Coherency[0].real());
+    double T1 = static_cast<double>(Coherency[3].real());
+    double T2 = static_cast<double>(Coherency[5].real());
+    double T3 = static_cast<double>(Coherency[1].real());
+    double T4 = static_cast<double>(Coherency[1].imag());
+    double T5 = static_cast<double>(Coherency[2].real());
+    double T6 = static_cast<double>(Coherency[2].imag());
+    double T7 = static_cast<double>(Coherency[4].real());
+    double T8 = static_cast<double>(Coherency[4].imag());
+    
+    VNLMatrixType vnlMat(3, 3, 0.);
+    vnlMat[0][0] = ComplexType(T0,  0.);
+    vnlMat[0][1] = std::conj(ComplexType(Coherency[1]));
+    vnlMat[0][2] = std::conj(ComplexType(Coherency[2]));
+    vnlMat[1][0] = ComplexType(Coherency[1]);
+    vnlMat[1][1] = ComplexType(T1,  0.);
+    vnlMat[1][2] = std::conj(ComplexType(Coherency[4]));
+    vnlMat[2][0] = ComplexType(Coherency[2]);
+    vnlMat[2][1] = ComplexType(Coherency[4]);
+    vnlMat[2][2] = ComplexType(T2,  0.);
+    
+    // Only compute the left symetry to respect the previous Hermitian Analisys code
+    vnl_complex_eigensystem syst(vnlMat, false, true);
+    const VNLMatrixType eigenVectors( syst.L );
+    const VNLVectorType eigenValues(syst.W);
+    
     // Entropy estimation
     double  totalEigenValues(0.0);
     double  p[3];
     double entropy;
     double alpha;
     double anisotropy;
+    
+
+    // Sort eigne values and adapt eigen vectors first component
+    VNLDoubleVectorType sortedRealEigenValues(3, eigenValues[0].real());
+    VNLVectorType sortedEigenVectors(3, eigenVectors[0][0]);
+    
+    if( (eigenValues[1].real() >= eigenValues[0].real()) && (eigenValues[1].real() >= eigenValues[2].real()) )
+      { 
+        sortedRealEigenValues[0] = eigenValues[1].real();
+        sortedEigenVectors[0] = eigenVectors[1][0];
+        if( sortedRealEigenValues[2] >= eigenValues[0].real() )
+          {
+            sortedRealEigenValues[1] = eigenValues[2].real();
+            sortedEigenVectors[1] = eigenVectors[2][0];
+          }
+        else
+          {
+            sortedRealEigenValues[2] = eigenValues[2].real();
+            sortedEigenVectors[2] = eigenVectors[2][0];
+            //init do that sortedRealEigenValues[0] = eigenValues[1].real();
+          }
+      }
+    else if( (eigenValues[2].real() >= eigenValues[0].real()) && (eigenValues[2].real() >= eigenValues[1].real()) )
+     { 
+        sortedRealEigenValues[0] = eigenValues[2].real();
+        sortedEigenVectors[0] = eigenVectors[2][0];
+        if( sortedRealEigenValues[1] >= eigenValues[0].real() )
+          {
+            sortedRealEigenValues[1] = eigenValues[1].real();
+            sortedEigenVectors[1] = eigenVectors[1][0];
+          }
+        else
+          {
+            sortedRealEigenValues[2] = eigenValues[1].real();
+            sortedEigenVectors[2] = eigenVectors[1][0];
+            //init do that sortedRealEigenValues[0] = eigenValues[1].real();
+          }
+      }
+    else
+      {
+        if( eigenValues[1].real() >= eigenValues[2].real() )
+          {
+            sortedRealEigenValues[1] = eigenValues[1].real();
+            sortedRealEigenValues[2] = eigenValues[2].real();
+            sortedEigenVectors[1] = eigenVectors[1][0];
+            sortedEigenVectors[2] = eigenVectors[2][0];
+          }
+        else
+          {
+            sortedRealEigenValues[1] = eigenValues[2].real();
+            sortedRealEigenValues[2] = eigenValues[1].real();
+            sortedEigenVectors[1] = eigenVectors[2][0];
+            sortedEigenVectors[2] = eigenVectors[1][0];
+          }
+      }
 
-    totalEigenValues = static_cast<double>( eigenValues[0] + eigenValues[1] + eigenValues[2]);
+ 
+    totalEigenValues = sortedRealEigenValues[0] + sortedRealEigenValues[1] + sortedRealEigenValues[2];
     if (totalEigenValues <m_Epsilon)
       {
         totalEigenValues = m_Epsilon;
@@ -105,12 +153,7 @@ public:
 
     for (unsigned int k = 0; k < 3; k++)
       {
-        if (eigenValues[k] <0.)
-          {
-            eigenValues[k] = 0.;
-          }
-
-        p[k] = static_cast<double>(eigenValues[k]) / totalEigenValues;
+        p[k] = std::max(sortedRealEigenValues[k], 0.) / totalEigenValues;
       }
 
     if ( (p[0] < m_Epsilon) || (p[1] < m_Epsilon) || (p[2] < m_Epsilon) )
@@ -129,7 +172,7 @@ public:
 
     for(unsigned int k = 0; k < 3; k++)
       {
-         p[k] = eigenValues[k] / totalEigenValues;
+         p[k] = sortedRealEigenValues[k] / totalEigenValues;
 
          if (p[k] < 0.)
            {
@@ -142,13 +185,13 @@ public:
            }
       }
 
-    val0=sqrt(static_cast<double>(eigenVectors[0][0]*eigenVectors[0][0]) + static_cast<double>(eigenVectors[0][1]*eigenVectors[0][1]));
+    val0 = std::abs(sortedEigenVectors[0]);
     a0=acos(vcl_abs(val0)) * CONST_180_PI;
 
-    val1=sqrt(static_cast<double>(eigenVectors[0][2]*eigenVectors[0][2]) + static_cast<double>(eigenVectors[0][3]*eigenVectors[0][3]));
+    val1 = std::abs(sortedEigenVectors[1]);
     a1=acos(vcl_abs(val1)) * CONST_180_PI;
 
-    val2=sqrt(static_cast<double>(eigenVectors[0][4]*eigenVectors[0][4]) + static_cast<double>(eigenVectors[0][5]*eigenVectors[0][5]));
+    val2= std::abs(sortedEigenVectors[2]);
     a2=acos(vcl_abs(val2)) * CONST_180_PI;
 
     alpha=p[0]*a0 + p[1]*a1 + p[2]*a2;
@@ -159,11 +202,11 @@ public:
       }
 
     // Anisotropy estimation
-    anisotropy=(eigenValues[1] - eigenValues[2])/(eigenValues[1] + eigenValues[2]+m_Epsilon);
+    anisotropy=(sortedRealEigenValues[1] - sortedRealEigenValues[2])/(sortedRealEigenValues[1] + sortedRealEigenValues[2] + m_Epsilon);
 
-    result[0] = entropy;
-    result[1] = alpha;
-    result[2] = anisotropy;
+    result[0] = static_cast<OutputValueType>(entropy);
+    result[1] = static_cast<OutputValueType>(alpha);
+    result[2] = static_cast<OutputValueType>(anisotropy);
 
     return result;
     }
diff --git a/Testing/Code/SARPolarimetry/CMakeLists.txt b/Testing/Code/SARPolarimetry/CMakeLists.txt
index 654b91338e..c291daf45d 100644
--- a/Testing/Code/SARPolarimetry/CMakeLists.txt
+++ b/Testing/Code/SARPolarimetry/CMakeLists.txt
@@ -373,10 +373,6 @@ ADD_TEST(saTvMuellerToCovarianceImageFilter ${SARPOLARIMETRY_TESTS2}
         ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
         ${TEMP}/saTvMuellerToMLCImageFilter.tif
 	)
-# Hermitian eigen analysis class
-ADD_TEST(saTvHermitianEigenAnalysisTest ${SARPOLARIMETRY_TESTS2}
-		otbHermitianEigenAnalysisTest
-)
 
 # Polarimetric Data
 ADD_TEST(saTuPolarimetricDataNew ${SARPOLARIMETRY_TESTS2}
@@ -430,7 +426,6 @@ otbMuellerToPolarisationDegreeAndPowerImageFilterNew.cxx
 otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx
 otbMuellerToCovarianceImageFilterNew.cxx
 otbMuellerToCovarianceImageFilter.cxx
-otbHermitianEigenAnalysisTest.cxx
 otbPolarimetricData.cxx
 )
 
diff --git a/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx b/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
index d21ca4c3dd..62a756f674 100644
--- a/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
+++ b/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
@@ -26,6 +26,8 @@
 #include "otbVectorImage.h"
 #include "otbHermitianEigenAnalysis.h"
 #include "itkVariableLengthVector.h"
+#include "vnl/algo/vnl_complex_eigensystem.h"
+#include <complex>
 
 
 int otbHermitianEigenAnalysisTest(int argc, char * argv[])
@@ -37,6 +39,7 @@ int otbHermitianEigenAnalysisTest(int argc, char * argv[])
   typedef otb::HermitianEigenAnalysis<MatrixType, EigenvalueType, EigenMatrixType> FilterType;
 
   EigenMatrixType resEigVal;
+
   itk::Vector<float, 6> temp;
   temp[0] = 0.162793;
   temp[1] = -0.432753;
@@ -115,5 +118,43 @@ int otbHermitianEigenAnalysisTest(int argc, char * argv[])
     return EXIT_FAILURE;
   }
 
+  std::cout<<"Values: "<<vect<<std::endl;
+  std::cout<<"Vectors: "<<eigVal<<std::endl;
+
+
+  typedef std::complex<double> ComplexType;
+  vnl_matrix<ComplexType> vnlMat(3,3,0);
+  vnlMat[0][0] = ComplexType(0., 0.);
+  vnlMat[0][1] = ComplexType(1.5, 2.);
+  vnlMat[0][2] = ComplexType(2.5, 3.);
+  vnlMat[1][0] = ComplexType(1.5, -2.);
+  vnlMat[1][1] = ComplexType(0.5, 0.);
+  vnlMat[1][2] = ComplexType(3.5, 4.);
+  vnlMat[2][0] = ComplexType(2.5, -3.);
+  vnlMat[2][1] = ComplexType(3.5, -4.);
+  vnlMat[2][2] = ComplexType(1., 0.);
+
+  std::cout<<"Matrix:: "<<std::endl;
+  vnlMat.print(std::cout);
+
+  vnl_complex_eigensystem syst(vnlMat, true, true);
+
+  vnl_matrix< ComplexType > pm = syst.L;
+ std::cout<<"Left:: "<<std::endl;
+  pm.print(std::cout);
+  std::cout<<"Right:: "<<std::endl; 
+
+
+  pm = syst.R;
+  pm.print(std::cout);
+  std::cout<<"W:: "<<std::endl;
+  vnl_vector< ComplexType > lol = syst.W;
+
+  for(unsigned i=0; i<lol.size(); i++)
+  {
+    std::cout<<"  "<<lol[i];
+  }
+  std::cout<<std::endl;
+
   return EXIT_SUCCESS;
 }
diff --git a/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx b/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
index ed970d3191..79c312c5cb 100644
--- a/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
+++ b/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
@@ -89,9 +89,10 @@ int otbReciprocalHAlphaImageFilter(int argc, char * argv[])
 
   PerBandMeanFilterType::Pointer perBandMeanFilter = PerBandMeanFilterType::New();
   perBandMeanFilter->SetInput(sinclairToCoherencyFilter->GetOutput());
-
+ 
   FilterType::Pointer filter = FilterType::New();
   filter->SetInput(perBandMeanFilter->GetOutput());
+  filter->SetNumberOfThreads(1);
 
   ExtractType::Pointer extract = ExtractType::New();
   extract->SetInput(filter->GetOutput());
@@ -102,6 +103,8 @@ int otbReciprocalHAlphaImageFilter(int argc, char * argv[])
 
   writer->SetFileName(outputFilename);
   writer->SetInput(extract->GetOutput());
+  writer->SetNumberOfThreads(1);
+writer->SetNumberOfStreamDivisions(1);
   writer->Update();
 
   return EXIT_SUCCESS;
diff --git a/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx b/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
index bdda5c3240..97a6220613 100644
--- a/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
+++ b/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
@@ -42,7 +42,6 @@ void RegisterTests()
   REGISTER_TEST(otbMuellerToPolarisationDegreeAndPowerImageFilter);
   REGISTER_TEST(otbMuellerToCovarianceImageFilterNew);
   REGISTER_TEST(otbMuellerToCovarianceImageFilter);
-  REGISTER_TEST(otbHermitianEigenAnalysisTest);
   REGISTER_TEST(otbPolarimetricDataNew);
   REGISTER_TEST(otbPolarimetricDataTest);
 }
-- 
GitLab