#ifndef __KOKKOSBATCHED_UTV_DECL_HPP__
#define __KOKKOSBATCHED_UTV_DECL_HPP__


/// \author Kyungjoo Kim (kyukim@sandia.gov)

#include "KokkosBatched_Util.hpp"

namespace KokkosBatched {

  ///
  /// For given A, it performs UTV factorization i.e., UTV = A P^T
  /// - input:
  ///   - A is m x m real matrix
  ///   - p is m integer vector
  ///   - U is m x m real matrix
  ///   - V is m x m real matrix
  ///   - w is 3*m real vector workspace (contiguous)
  /// - output:
  ///   - A is overwritten as lower triangular matrix_rank x matrix_rank real matrix
  ///   - P^T includes pivot indicies (note that this is different from permutation indicies)
  ///   - U is left orthogonal matrix m x matrix_rank
  ///   - V is right orthogonal matrix matrix_rank x m
  ///
  /// When A is a full rank i.e., matrix_rank == m, this only compute a QR with column pivoting
  /// - output:
  ///   - A is overwritten as upper triangular matrix
  ///   - P^T includes pivot indicies (note that this is different from permutation indicies)  
  ///   - U is an orthogonal matrix m x m
  ///   - V is not touched
  ///
  /// For the solution of a rank-deficient problem, it is recommended to use SolveUTV.
  ///
  
  ///
  /// TeamVector UTV
  ///

  template<typename MemberType,
           typename ArgAlgo>
  struct TeamVectorUTV {
    template<typename AViewType,
	     typename pViewType,
	     typename UViewType,
	     typename VViewType,
             typename wViewType>
    KOKKOS_INLINE_FUNCTION
    static int
    invoke(const MemberType &member, 
           const AViewType &A,
	   const pViewType &p,
	   const UViewType &U,
	   const VViewType &V, 
           const wViewType &w,
	   int &matrix_rank);
  };

}

#include "KokkosBatched_UTV_TeamVector_Impl.hpp"

#endif
