48 #include "AbstractLinAlgPack_GenPermMatrixSlice.hpp"
49 #include "Teuchos_Assert.hpp"
64 AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::swap(v1,v2);
76 T my_min(
const T& v1,
const T& v2 ) {
return v1 < v2 ? v1 : v2; }
79 const char* ordered_by_str(
80 AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::EOrderedBy ordered_by )
82 switch( ordered_by ) {
83 case AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::BY_ROW:
85 case AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::BY_COL:
87 case AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::BY_ROW_AND_COL:
88 return "BY_ROW_AND_COL";
89 case AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::UNORDERED:
100 :
public std::binary_function<
101 AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::row_col_value_type<T>
102 ,AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::row_col_value_type<T>
111 return v1.row_i_ < v2.row_i_;
117 :
public std::binary_function<
118 AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::row_col_value_type<T>
119 ,AbstractLinAlgPack::GenPermMatrixSliceIteratorPack::row_col_value_type<T>
128 return v1.col_j_ < v2.col_j_;
140 namespace AbstractLinAlgPack {
143 : rows_(0), cols_(0), nz_(0)
150 nz_ = type == IDENTITY_MATRIX ? my_min(rows,cols) : 0;
151 ordered_by_ = GenPermMatrixSliceIteratorPack::BY_ROW_AND_COL;
164 ,EOrderedBy ordered_by
165 ,
const size_type row_i[]
166 ,
const size_type col_j[]
170 namespace GPMSIP = GenPermMatrixSliceIteratorPack;
173 std::ostringstream omsg;
174 omsg <<
"\nGenPermMatrixSlice::initialize(...) : Error: ";
176 validate_input_data(rows,cols,nz,row_off,col_off,ordered_by,row_i,col_j,omsg);
178 const size_type *ordered_sequence = NULL;
179 if( ordered_by == GPMSIP::BY_ROW || ordered_by == GPMSIP::BY_ROW_AND_COL ) {
180 for( size_type k = 1; k <
nz; ++k ) {
182 row_i[k-1] >= row_i[k], std::invalid_argument
183 ,
"GenPermMatrixSlice::initialize(...) : Error: "
184 "row_i[" << k-1 <<
"] = " << row_i[k-1]
185 <<
" >= row_i[" << k <<
"] = " << row_i[k]
186 <<
"\nThis is not sorted by row!" );
189 if( ordered_by == GPMSIP::BY_COL || ordered_by == GPMSIP::BY_ROW_AND_COL ) {
190 for( size_type k = 1; k <
nz; ++k ) {
192 col_j[k-1] >= col_j[k], std::invalid_argument
193 ,
"GenPermMatrixSlice::initialize(...) : Error: "
194 "col_j[" << k-1 <<
"] = " << col_j[k-1]
195 <<
" >= col_j[" << k <<
"] = " << col_j[k]
196 <<
"\nThis is not sorted by column!" );
207 row_i_ = nz ? row_i : NULL;
208 col_j_ = nz ? col_j : NULL;
217 ,EOrderedBy ordered_by
223 namespace GPMSIP = GenPermMatrixSliceIteratorPack;
225 ordered_by == GPMSIP::BY_ROW_AND_COL, std::invalid_argument
226 ,
"GenPermMatrixSlice::initialize_and_sort(...) : Error, "
227 "ordered_by == GPMSIP::BY_ROW_AND_COL, we can not sort by row and column!" );
229 std::ostringstream omsg;
230 omsg <<
"\nGenPermMatrixSlice::initialize_and_sort(...) : Error:\n";
232 validate_input_data(rows,cols,nz,row_off,col_off,ordered_by,row_i,col_j,omsg);
236 typedef GPMSIP::row_col_iterator<size_type> row_col_itr_t;
238 row_col_itr = row_col_itr_t( row_off, col_off, row_i, col_j, nz );
239 if( ordered_by == GPMSIP::BY_ROW ) {
240 std::stable_sort( row_col_itr, row_col_itr + nz
241 , imp_row_less<size_type>() );
243 else if( ordered_by == GPMSIP::BY_COL ) {
244 std::stable_sort( row_col_itr, row_col_itr + nz
245 , imp_col_less<size_type>() );
248 initialize(rows,cols,nz,row_off,col_off,ordered_by,row_i,col_j,test_setup);
253 this->
initialize( gpms.rows_, gpms.cols_, gpms.nz_, gpms.row_off_
254 , gpms.col_off_, gpms.ordered_by_, gpms.row_i_, gpms.col_j_
260 namespace QPMSIP = GenPermMatrixSliceIteratorPack;
261 if( col_j < 1 || cols_ < col_j )
263 "GenPermMatrixSlice::lookup_row_i(col_j) : Error, "
264 "col_j is out of bounds" );
268 return col_j <= nz_ ? col_j : 0;
272 itr = std::lower_bound( col_j_, col_j_ + nz_, col_j );
274 itr = std::find( col_j_, col_j_ + nz_, col_j );
275 return (itr != col_j_ + nz_ && *itr == col_j) ? row_i_[itr - col_j_] : 0;
280 namespace QPMSIP = GenPermMatrixSliceIteratorPack;
281 if( row_i < 1 || rows_ < row_i )
283 "GenPermMatrixSlice::lookup_col_j(row_i) : Error, "
284 "row_i is out of bounds" );
288 return row_i <= nz_ ? row_i : 0;
292 itr = std::lower_bound( row_i_, row_i_ + nz_, row_i );
294 itr = std::find( row_i_, row_i_ + nz_, row_i );
295 return (itr != row_i_ + nz_ && *itr == row_i) ? col_j_[itr - row_i_] : 0;
300 validate_not_identity();
306 validate_not_identity();
311 const Range1D& rng, EOrderedBy ordered_by )
const
313 namespace GPMSIP = GenPermMatrixSliceIteratorPack;
315 validate_not_identity();
319 ordered_by == GPMSIP::BY_ROW_AND_COL, std::invalid_argument
320 ,
"GenPermMatrixSlice::initialize_and_sort(...) : Error, "
321 "ordered_by == GPMSIP::BY_ROW_AND_COL, we can not sort by row and column!" );
324 "GenPermMatrixSlice::create_submatrix(...) : Error, "
325 "The range argument can not be rng.full_range() == true" );
327 ordered_by == GPMSIP::BY_ROW && rng.
ubound() >
rows(), std::logic_error
328 ,
"GenPermMatrixSlice::create_submatrix(...) : Error, "
329 "rng.ubound() can not be larger than this->rows()" );
331 ordered_by == GPMSIP::BY_COL && rng.
ubound() >
cols(), std::logic_error
332 ,
"GenPermMatrixSlice::create_submatrix(...) : Error, "
333 "rng.ubound() can not be larger than this->cols()" );
335 ordered_by == GPMSIP::UNORDERED, std::logic_error
336 ,
"GenPermMatrixSlice::create_submatrix(...) : Error, "
337 "You can have ordered_by == GPMSIP::UNORDERED" );
349 switch( ordered_by ) {
353 TEUCHOS_TEST_FOR_EXCEPTION(
357 ,
"GenPermMatrixSlice::create_submatrix(...) : Error, "
358 <<
"nz = " <<
nz() <<
" > 1 and "
359 <<
"ordered_by = " << ordered_by_str(ordered_by)
360 <<
" != this->ordered_by() = "
367 if( ordered_by == GPMSIP::BY_ROW ) {
369 search_k_off = row_off_;
377 search_k_off = col_off_;
385 *l = std::lower_bound( search_k, search_k +
nz()
386 , rng.
lbound() - search_k_off );
392 *u = std::upper_bound( search_k, search_k +
nz()
393 , rng.
ubound() - search_k_off );
401 case GPMSIP::UNORDERED:
405 if( k_u - k_l > 0 && k_u !=
nz() + 1 ) {
430 void GenPermMatrixSlice::validate_input_data(
434 ,difference_type row_off
435 ,difference_type col_off
436 ,EOrderedBy ordered_by
437 ,
const size_type row_i[]
438 ,
const size_type col_j[]
439 ,std::ostringstream &omsg
442 namespace GPMSIP = GenPermMatrixSliceIteratorPack;
445 nz > rows * cols, std::invalid_argument
446 ,omsg.str() <<
"nz = " << nz <<
" can not be greater than rows * cols = "
447 << rows <<
" * " << cols <<
" = " << rows *
cols );
450 for( size_type k = 0; k <
nz; ++k ) {
452 row_i[k] + row_off < 1 || rows < row_i[k] + row_off, std::invalid_argument
453 ,omsg.str() <<
"row_i[" << k <<
"] + row_off = " << row_i[k] <<
" + " << row_off
454 <<
" = " << (row_i[k] + row_off)
455 <<
" is out of range [1,rows] = [1," << rows <<
"]" );
457 col_j[k] + col_off < 1 || cols < col_j[k] + col_off, std::invalid_argument
458 ,omsg.str() <<
"col_j[" << k <<
"] + col_off = " << col_j[k] <<
" + " << col_off
459 <<
" = " << (col_j[k] + col_off)
460 <<
" is out of range [1,cols] = [1," << cols <<
"]" );
470 void GenPermMatrixSlice::validate_not_identity()
const
474 ,
"GenPermMatrixSlice::validate_not_identity() : "
475 "Error, this->is_identity() is true" );
GenPermMatrixSlice()
Construct to an uninitialzied, unsized matrix.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void initialize(index_type rows, index_type cols, EIdentityOrZero type)
Initialize an identity or zero permutation.
size_type rows(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
const_iterator end() const
Return the end of this->const_iterator_begin().
Internal storage for the iterator of the row and column indices.
void bind(const GenPermMatrixSlice &gpms)
Bind the view of another GenPermMatrixSlice object.
This is a full random access iterator for accessing row and colunmn indices.
const GenPermMatrixSlice create_submatrix(const Range1D &rng, EOrderedBy ordered_by) const
Create a submatrix by row, by column.
const_iterator begin() const
Return a random access iterator for accessing which row and column that each nonzero 1...
ptrdiff_t difference_type
External storage of a row and column indice. This is required for creating a temporary in an assignme...
size_type cols(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
EOrderedBy ordered_by() const
index_type lookup_row_i(index_type col_j) const
Lookup the ith row index for the nonzero entry in the jth column if it exists.
void initialize_and_sort(index_type rows, index_type cols, index_type nz, difference_type row_off, difference_type col_off, EOrderedBy ordered_by, index_type row_i[], index_type col_j[], bool test_setup=false)
Initialize and sort.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
index_type lookup_col_j(index_type row_i) const
Lookup the jth column index for the nonzero entry in the ith row if it exists.
Concrete matrix type to represent general permutation (mapping) matrices.
GenPermMatrixSliceIteratorPack::row_col_iterator< const index_type > const_iterator