00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef DENSE_V_P_S_T_P_T_M_T_V_H
00030 #define DENSE_V_P_S_T_P_T_M_T_V_H
00031
00032 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_SpVectorClass.hpp"
00033 #include "AbstractLinAlgPack_SpVectorOp.hpp"
00034 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_EtaVector.hpp"
00035 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_GenPermMatrixSlice.hpp"
00036 #include "AbstractLinAlgPack_GenPermMatrixSliceOp.hpp"
00037 #include "AbstractLinAlgPack_LinAlgOpPackHack.hpp"
00038 #include "DenseLinAlgPack_DMatrixClass.hpp"
00039 #include "DenseLinAlgPack_DMatrixOut.hpp"
00040 #include "DenseLinAlgPack_AssertOp.hpp"
00041 #include "MiWorkspacePack.h"
00042
00043 namespace AbstractLinAlgPack {
00044
00051 template<class M_t, class V_t>
00052 void dense_Vp_StPtMtV(
00053 DVectorSlice *y
00054 ,value_type a
00055 ,const GenPermMatrixSlice &P
00056 ,BLAS_Cpp::Transp P_trans
00057 ,const M_t &M
00058 ,BLAS_Cpp::Transp M_trans
00059 ,const V_t &x
00060 ,value_type b
00061 )
00062 {
00063 using BLAS_Cpp::no_trans;
00064 using BLAS_Cpp::trans;
00065 using BLAS_Cpp::trans_not;
00066 using BLAS_Cpp::rows;
00067 using BLAS_Cpp::cols;
00068 using DenseLinAlgPack::dot;
00069 using DenseLinAlgPack::DVector;
00070 using DenseLinAlgPack::Vt_S;
00071 using AbstractLinAlgPack::dot;
00072 using AbstractLinAlgPack::Vp_StMtV;
00073 using AbstractLinAlgPack::GenPermMatrixSlice;
00074 typedef AbstractLinAlgPack::EtaVector eta;
00075 using Teuchos::Workspace;
00076 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00077
00078
00079
00080
00081
00082 const DenseLinAlgPack::size_type
00083 ny = y->size(),
00084 nx = x.size(),
00085 opM_rows = rows( M.rows(), M.cols(), M_trans ),
00086 opM_cols = cols( M.rows(), M.cols(), M_trans );
00087 if( ny != rows( P.rows(), P.cols(), P_trans )
00088 || nx != opM_cols
00089 || cols( P.rows(), P.cols(), P_trans ) != opM_rows )
00090 throw std::length_error( "MatrixOp::Vp_StPtMtV(...) : Error, "
00091 "sizes of arguments does not match up" );
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 if( !P.nz() ) {
00103
00104 if(b==0.0) *y = 0.0;
00105 else if(b!=1.0) Vt_S(y,b);
00106 }
00107 else if( opM_rows > P.nz() || P.is_identity() ) {
00108
00109 Workspace<value_type> t_ws(wss,opM_rows);
00110 DVectorSlice t(&t_ws[0],t_ws.size());
00111 LinAlgOpPack::V_MtV( &t, M, M_trans, x );
00112
00113 Vp_StMtV( y, a, P, P_trans, t(), b );
00114 }
00115 else {
00116
00117 if(b==0.0) *y = 0.0;
00118 else if(b!=1.0) Vt_S(y,b);
00119
00120 Workspace<value_type> t_ws(wss,opM_cols);
00121 DVectorSlice t(&t_ws[0],t_ws.size());
00122 if( P.is_identity() ) {
00123 for( size_type k = 1; k <= P.nz(); ++k ) {
00124 const size_type
00125 i = k,
00126 j = k;
00127
00128 LinAlgOpPack::V_MtV( &t, M, trans_not(M_trans), eta(j,opM_rows)() );
00129
00130 (*y)(i) += a * dot( t(), x );
00131 }
00132 }
00133 else {
00134 for( GenPermMatrixSlice::const_iterator itr = P.begin(); itr != P.end(); ++itr ) {
00135 const DenseLinAlgPack::size_type
00136 i = P_trans == no_trans ? itr->row_i() : itr->col_j(),
00137 j = P_trans == no_trans ? itr->col_j() : itr->row_i();
00138
00139 LinAlgOpPack::V_MtV( &t, M, trans_not(M_trans), eta(j,opM_rows)() );
00140
00141 (*y)(i) += a * dot( t(), x );
00142 }
00143 }
00144 }
00145 }
00146
00147 }
00148
00149 #endif // DENSE_V_P_S_T_P_T_M_T_V_H