void DenseLinAlgPack::M_StMtInvM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs1 , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2 , BLAS_Cpp::Transp trans_rhs2) { Mp_MtM_assert_sizes( gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans , gms_rhs1.rows(), gms_rhs1.cols(), trans_rhs1 , tri_rhs2.gms().rows(), tri_rhs2.gms().cols(), trans_rhs2 ); i_trsm_alt(BLAS_Cpp::right,alpha,tri_rhs2,trans_rhs2,gms_rhs1,trans_rhs1,gms_lhs); }
void DenseLinAlgPack::M_StInvMtM(DMatrix* gm_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1 , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2 , BLAS_Cpp::Transp trans_rhs2) { MtM_assert_sizes( tri_rhs1.gms().rows(), tri_rhs1.gms().cols(), trans_rhs1 , gms_rhs2.rows(), gms_rhs2.cols(), trans_rhs2 ); gm_lhs->resize( rows(tri_rhs1.gms().rows(), tri_rhs1.gms().cols(), trans_rhs1) , cols(gms_rhs2.rows(), gms_rhs2.cols(), trans_rhs2) ); i_trsm_alt(BLAS_Cpp::left,alpha,tri_rhs1,trans_rhs1,gms_rhs2,trans_rhs2,&(*gm_lhs)()); }
void DenseLinAlgPack::V_InvMtV(DVectorSlice* vs_lhs, const DMatrixSliceTri& tri_rhs1, BLAS_Cpp::Transp trans_rhs1 , const DVectorSlice& vs_rhs2) { assert_gms_square(tri_rhs1.gms()); MtV_assert_sizes(tri_rhs1.gms().rows(), tri_rhs1.gms().cols(), trans_rhs1, vs_rhs2.dim()); Vp_V_assert_sizes( vs_lhs->dim(), tri_rhs1.gms().rows() ); (*vs_lhs) = vs_rhs2; BLAS_Cpp::trsv(tri_rhs1.uplo(),trans_rhs1,tri_rhs1.diag(),tri_rhs1.gms().rows() ,tri_rhs1.gms().col_ptr(1),tri_rhs1.gms().max_rows(), vs_lhs->raw_ptr(),vs_lhs->stride()); }
void DenseLinAlgPack::Vp_StMtV(DVectorSlice* vs_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1 , BLAS_Cpp::Transp trans_rhs1, const DVectorSlice& vs_rhs2, value_type beta) { Vp_MtV_assert_sizes(vs_lhs->dim(),tri_rhs1.gms().rows(),tri_rhs1.gms().cols() ,trans_rhs1,vs_rhs2.dim() ); // If op(gms_rhs2) == gms_lhs and beta = 0.0 then this is a direct call to the BLAS. if( vs_lhs->overlap(vs_rhs2) == SAME_MEM && beta == 0.0 ) { V_MtV(vs_lhs, tri_rhs1, trans_rhs1, vs_rhs2); if(alpha != 1.0) Vt_S(vs_lhs,alpha); } else { // This is something else so the alias problem is not handled. if(beta != 1.0) Vt_S(vs_lhs,beta); DVector tmp; V_MtV(&tmp, tri_rhs1, trans_rhs1, vs_rhs2); Vp_StV(vs_lhs,alpha,tmp()); } }
void DenseLinAlgPack::Mp_StM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs , BLAS_Cpp::Transp trans_rhs) { using BLAS_Cpp::trans; using BLAS_Cpp::no_trans; using BLAS_Cpp::lower; using BLAS_Cpp::upper; Mp_M_assert_sizes(gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans , tri_rhs.rows(), tri_rhs.cols(), trans_rhs ); // diagonal if( tri_rhs.diag() == BLAS_Cpp::nonunit ) Vp_StV( &gms_lhs->diag(), alpha, tri_rhs.gms().diag() ); else Vp_S( &gms_lhs->diag(), alpha ); // upper or lower triangle const size_type n = gms_lhs->rows(); // same as cols if( n == 1 ) return; // There is not lower or upper triangular region const DMatrixSliceTriEle tri = ( tri_rhs.uplo() == lower ? tri_ele(tri_rhs.gms()(2,n,1,n-1),lower) : tri_ele(tri_rhs.gms()(1,n-1,2,n),upper) ); const BLAS_Cpp::Uplo as_uplo = ( ( tri_rhs.uplo() == lower && trans_rhs == no_trans ) || ( tri_rhs.uplo() == upper && trans_rhs == trans ) ? lower : upper ); switch(as_uplo) { case lower: Mp_StM( const_cast<DenseLinAlgPack::DMatrixSliceTriEle*>( &tri_ele((*gms_lhs)(2,n,1,n-1),lower) ) , alpha, tri ); break; case upper: Mp_StM( const_cast<DenseLinAlgPack::DMatrixSliceTriEle*>( &tri_ele((*gms_lhs)(1,n-1,2,n),upper) ) , alpha, tri ); break; } }