// tri_lhs = tri_rhs
void DenseLinAlgPack::assign(DMatrixSliceTriEle* tri_lhs, const DMatrixSliceTriEle& tri_rhs)
{
  assert_gms_lhs(tri_lhs->gms(),tri_rhs.gms().rows(),tri_rhs.gms().cols(),BLAS_Cpp::no_trans);
    
  switch(tri_lhs->gms().overlap(tri_rhs.gms())) {
    case SAME_MEM:
      if(tri_lhs->uplo() == tri_rhs.uplo()) return; // Assignment to self to exit

    case SOME_OVERLAP:
      // Test for the special case where the upper tri region (above diagonal) of a
      // matrix is being copied into the BLAS_Cpp::lower tri region (below the diagonal) of
      // the same matrix or visa-versa.  No temp is need in this case
      if(tri_lhs->uplo() != tri_rhs.uplo()) {
        const DMatrixSlice	*up = (tri_lhs->uplo() == upper)
                        ? &tri_lhs->gms() : &tri_rhs.gms();
        const DMatrixSlice	*lo = (tri_rhs.uplo() == BLAS_Cpp::lower)
                        ? &tri_lhs->gms() : &tri_rhs.gms();
        if(lo->col_ptr(1) + lo->max_rows() - 1 == up->col_ptr(1)) { // false if SAME_MEM
          // One triangular region is being copied into another so no temp needed.
          i_assign_basic(tri_lhs, tri_rhs);
          return; 
        }
      }
      // Give up and copy the vs_rhs as a temp.
      {
        DMatrix temp(tri_rhs.gms());
        i_assign_basic(tri_lhs, tri_ele(temp(),tri_rhs.uplo()));
        return;
      }

    case NO_OVERLAP:	// no overlap so just perform the copy
      i_assign_basic(tri_lhs, tri_rhs);
      return;
  }
}
bool DenseLinAlgPack::comp(const DMatrixSliceTriEle& tri_gms1, value_type alpha)
{
  using BLAS_Cpp::bool_to_trans;
  BLAS_Cpp::Transp
    trans1 = bool_to_trans(tri_gms1.uplo() != BLAS_Cpp::lower);

  const size_type n = tri_gms1.rows();	// same as cols()
  for(size_type i = 1; i < n; ++i) {
    if( !comp( col(tri_gms1.gms(),trans1,i)(i,n), alpha ) )
      return false;
  }
  return true;
}
void DenseLinAlgPack::Mp_StM(DMatrixSliceTriEle* tri_lhs, value_type alpha, const DMatrixSliceTriEle& tri_ele_rhs)
{
  Mp_M_assert_sizes(tri_lhs->gms().rows(), tri_lhs->gms().cols(), BLAS_Cpp::no_trans
    , tri_ele_rhs.gms().rows(), tri_ele_rhs.gms().cols(), BLAS_Cpp::no_trans);

  BLAS_Cpp::Transp
    trans_lhs = (tri_lhs->uplo() == BLAS_Cpp::lower) ? BLAS_Cpp::no_trans : BLAS_Cpp::trans,
    trans_rhs = (tri_ele_rhs.uplo() == BLAS_Cpp::lower) ? BLAS_Cpp::no_trans : BLAS_Cpp::trans;

  DMatrixSlice::size_type n = tri_lhs->gms().cols();
  for(DMatrixSlice::size_type j = 1; j <= n; ++j)
    Vp_StV( &col(tri_lhs->gms(),trans_lhs,j)(j,n), alpha, col(tri_ele_rhs.gms(),trans_rhs,j)(j,n) );	
}