44 #include "AbstractLinAlgPack_MatrixSparseCOORSerial.hpp"
45 #include "AbstractLinAlgPack_MatrixCOORTmplItfc.hpp"
46 #include "AbstractLinAlgPack_COOMatrixTmplOp.hpp"
47 #include "AbstractLinAlgPack_VectorDenseEncap.hpp"
48 #include "AbstractLinAlgPack_AssertOp.hpp"
49 #include "AbstractLinAlgPack_LinAlgOpPackHack.hpp"
50 #include "Teuchos_Assert.hpp"
51 #include "Teuchos_dyn_cast.hpp"
53 namespace AbstractLinAlgPack {
55 MatrixSparseCOORSerial::ReleaseValRowColArrays::~ReleaseValRowColArrays()
58 if(val_)
delete [] val_;
59 if(row_i_)
delete [] row_i_;
60 if(col_j_)
delete [] col_j_;
72 MatrixSparseCOORSerial::release_resource_null_ = Teuchos::null;
100 const char msg_err[] =
"MatrixSparseCOORSerial::set_buffer(...) : Error,!";
111 self_allocate_ =
false;
118 if( nz && check_input ) {
137 release_resource_ = Teuchos::null;
138 self_allocate_ =
true;
183 max_nz_ = Mc.max_nz_;
187 release_resource_ = Mc.release_resource_;
188 self_allocate_ = Mc.self_allocate_;
204 <<
"Sparse " << rows <<
" x " <<
cols <<
" matrix with "
205 <<
nz <<
" nonzero entries:\n";
208 *itr_val_end = itr_val + nz_;
210 *itr_ivect = &row_i_[0],
211 *itr_jvect = &col_j_[0];
212 for(; itr_val != itr_val_end; ++itr_val, ++itr_ivect, ++itr_jvect)
213 out << *itr_val <<
":" << *itr_ivect <<
":" << *itr_jvect <<
" ";
216 if( rows *
cols <= 400 ) {
217 out <<
"Converted to dense =\n";
226 ,
const Vector& x, value_type b
235 rows_,cols_,nz_,0,0,val_,row_i_,col_j_ )
249 namespace rcp = MemMngPack;
251 const char msg_err_head[] =
"MatrixSparseCOORSerial::reinitialize(...) : Error";
257 element_uniqueness_ = element_uniqueness;
258 if( self_allocate_ ) {
259 if(max_nz_ < max_nz) {
262 val_ =
new value_type[max_nz]
263 ,row_i_ =
new index_type[max_nz]
264 ,col_j_ =
new index_type[max_nz]
274 max_nz <= max_nz_, std::invalid_argument
275 ,msg_err_head <<
"Buffers set up by client in set_buffers() only allows storage for "
276 "max_nz_ = " << max_nz_ <<
" nonzero entries while client requests storage for "
277 "max_nz = " << max_nz <<
" nonzero entries!" );
280 reload_val_only_ =
false;
281 reload_val_only_nz_last_ = 0;
290 rows_ == 0 || cols_ == 0, std::invalid_argument
291 ,
"MatrixSparseCOORSerial::reset_to_load_values(...) : Error, "
292 "this matrix is not initialized so it can't be rest to load "
293 "new values for nonzero entries." );
295 reload_val_only_ =
true;
296 reload_val_only_nz_last_ = nz_;
302 size_type max_nz_load
310 max_nz_load_ != 0 , std::logic_error
311 ,
"MatrixSparseCOORSerial::get_load_nonzeros_buffers(...) : Error, "
312 "You must call commit_load_nonzeros_buffers() between calls to this method!" );
314 max_nz_load <= 0 || max_nz_load > max_nz_ - nz_, std::invalid_argument
315 ,
"MatrixSparseCOORSerial::get_load_nonzeros_buffers(...) : Error, "
316 "The number of nonzeros to load max_nz_load = " << max_nz_load <<
" can not "
317 "be greater than max_nz - nz = " << max_nz_ <<
" - " << nz_ <<
" = " << (max_nz_-nz_) <<
320 reload_val_only_ && (row_i != NULL || col_j != NULL), std::invalid_argument
321 ,
"MatrixSparseCOORSerial::get_load_nonzeros_buffers(...) : Error, "
322 "reset_to_load_values() was called and therefore the structure of the matrix "
325 !reload_val_only_ && (row_i == NULL || col_j == NULL), std::invalid_argument
326 ,
"MatrixSparseCOORSerial::get_load_nonzeros_buffers(...) : Error, "
327 "both *row_i and *col_j must be non-NULL since reinitialize() was called" );
329 max_nz_load_ = max_nz_load;
331 if(!reload_val_only_)
332 *row_i = row_i_ + nz_;
333 if(!reload_val_only_)
334 *col_j = col_j_ + nz_;
346 max_nz_load_ == 0 , std::logic_error
347 ,
"MatrixSparseCOORSerial::commit_load_nonzeros_buffers(...) : Error, "
348 "You must call get_load_nonzeros_buffers() before calling this method!" );
350 nz_commit > max_nz_load_ , std::logic_error
351 ,
"MatrixSparseCOORSerial::commit_load_nonzeros_buffers(...) : Error, "
352 "You can not commit more nonzero entries than you requested buffer space for in "
353 "get_load_nonzeros_buffers(...)!" );
357 ,
"MatrixSparseCOORSerial::commit_load_nonzeros_buffers(...) : Error, "
358 "This is not the buffer I give you in get_load_nonzeros_buffers(...)!" );
360 reload_val_only_ && (row_i != NULL || col_j != NULL), std::invalid_argument
361 ,
"MatrixSparseCOORSerial::commit_load_nonzeros_buffers(...) : Error, "
362 "reset_to_load_values() was called and therefore the structure of the matrix "
372 reload_val_only_ ==
true && reload_val_only_nz_last_ != nz_, std::logic_error
373 ,
"MatrixSparseCOORSerial::finish_construction() : Error, the number of nonzeros on"
374 " the initial load with row and column indexes was = " << reload_val_only_nz_last_ <<
375 " and does not agree with the number of nonzero values = " << nz_ <<
" loaded this time!" );
377 for( size_type k = 0; k < nz_; ++k ) {
382 i < 1 || rows_ < i, std::logic_error
383 ,
"MatrixSparseCOORSerial::finish_construction(true) : Error, "
384 "row_i[" << k <<
"] = " << i <<
" is not in the range [1,rows] = [1,"<<rows_<<
"]!" );
386 j < 1 || cols_ < j, std::logic_error
387 ,
"MatrixSparseCOORSerial::finish_construction(true) : Error, "
388 "col_j[" << k <<
"] = " << j <<
" is not in the range [1,cols] = [1,"<<cols_<<
"]!" );
398 #define VALIDATE_ROW_COL_IN_RANGE() \
399 TEUCHOS_TEST_FOR_EXCEPTION( \
400 i < 1 || rows_ < i, std::invalid_argument \
401 ,err_msg_head<<", i = inv_row_perm[(row_i["<<k<<"]=="<<*row_i<<")-1] = "<<i<<" > rows = "<<rows_ ); \
402 TEUCHOS_TEST_FOR_EXCEPTION( \
403 j < 1 || cols_ < j, std::invalid_argument \
404 ,err_msg_head<<", j = inv_col_perm[(col_j["<<k<<"]=="<<*col_j<<")-1] = "<<j<<" > rows = "<<cols_ );
406 #define VALIDATE_ROW_COL_IN_RANGE()
411 ,
const index_type inv_row_perm[]
412 ,
const index_type inv_col_perm[]
420 const char err_msg_head[] =
"MatrixSparseCOORSerial::count_nonzeros(...): Error";
424 ,err_msg_head <<
", the client requests a count for unique "
425 "elements but this sparse matrix object is not allowed to assume this!" );
428 row_rng = RangePack::full_range(row_rng_in,1,rows_),
429 col_rng = RangePack::full_range(col_rng_in,1,rows_),
430 row_rng_full(1,rows_),
431 col_rng_full(1,cols_);
438 if( dl == -row_rng.
ubound() + col_rng.lbound() && du == +col_rng.ubound() - row_rng.
lbound() ) {
440 if( row_rng == row_rng_full && col_rng == col_rng_full ) {
446 if( inv_row_perm == NULL && inv_col_perm == NULL ) {
448 for( k = 0; k < nz_; ++
row_i, ++
col_j, ++k ) {
452 VALIDATE_ROW_COL_IN_RANGE();
453 cnt_nz += row_rng.
in_range(i) && col_rng.in_range(j) ? 1 : 0;
456 else if ( inv_row_perm != NULL && inv_col_perm == NULL ) {
458 for( k = 0; k < nz_; ++
row_i, ++
col_j, ++k ) {
460 i = inv_row_perm[(*row_i)-1],
462 VALIDATE_ROW_COL_IN_RANGE();
463 cnt_nz += row_rng.
in_range(i) && col_rng.in_range(j) ? 1 : 0;
466 else if ( inv_row_perm == NULL && inv_col_perm != NULL ) {
468 for( k = 0; k < nz_; ++
row_i, ++
col_j, ++k ) {
471 j = inv_col_perm[(*col_j)-1];
472 VALIDATE_ROW_COL_IN_RANGE();
473 cnt_nz += row_rng.
in_range(i) && col_rng.in_range(j) ? 1 : 0;
478 for( k = 0; k < nz_; ++
row_i, ++
col_j, ++k ) {
480 i = inv_row_perm[(*row_i)-1],
481 j = inv_col_perm[(*col_j)-1];
482 VALIDATE_ROW_COL_IN_RANGE();
483 cnt_nz += row_rng.
in_range(i) && col_rng.in_range(j) ? 1 : 0;
497 ,
const index_type inv_row_perm[]
498 ,
const index_type inv_col_perm[]
504 ,
const index_type len_Aval
506 ,
const index_type len_Aij
509 ,
const index_type row_offset
510 ,
const index_type col_offset
514 const char err_msg_head[] =
"MatrixSparseCOORSerial::count_nonzeros(...): Error";
518 ,err_msg_head <<
", the client requests extraction of unique "
519 "elements but this sparse matrix object can not guarantee this!" );
522 row_rng = RangePack::full_range(row_rng_in,1,rows_),
523 col_rng = RangePack::full_range(col_rng_in,1,rows_),
524 row_rng_full(1,rows_),
525 col_rng_full(1,cols_);
534 if( dl == -row_rng.
ubound() + col_rng.lbound() && du == +col_rng.ubound() - row_rng.
lbound() ) {
536 if( row_rng == row_rng_full && col_rng == col_rng_full ) {
538 if( inv_row_perm == NULL && inv_col_perm == NULL ) {
545 *Arow++ = *row_i + row_offset;
546 *Acol++ = *col_j + col_offset;
556 if( inv_row_perm == NULL && inv_col_perm == NULL ) {
562 VALIDATE_ROW_COL_IN_RANGE();
563 if( row_rng.
in_range(i) && col_rng.in_range(j) ) {
568 *Arow++ = i + row_offset;
569 *Acol++ = j + col_offset;
574 else if( inv_row_perm != NULL && inv_col_perm == NULL ) {
578 i = inv_row_perm[(*row_i)-1],
580 VALIDATE_ROW_COL_IN_RANGE();
581 if( row_rng.
in_range(i) && col_rng.in_range(j) ) {
586 *Arow++ = i + row_offset;
587 *Acol++ = j + col_offset;
592 else if( inv_row_perm == NULL && inv_col_perm != NULL ) {
597 j = inv_col_perm[(*col_j)-1];
598 VALIDATE_ROW_COL_IN_RANGE();
599 if( row_rng.
in_range(i) && col_rng.in_range(j) ) {
604 *Arow++ = i + row_offset;
605 *Acol++ = j + col_offset;
614 i = inv_row_perm[(*row_i)-1],
615 j = inv_col_perm[(*col_j)-1];
616 VALIDATE_ROW_COL_IN_RANGE();
617 if( row_rng.
in_range(i) && col_rng.in_range(j) ) {
622 *Arow++ = i + row_offset;
623 *Acol++ = j + col_offset;
640 void MatrixSparseCOORSerial::make_storage_unique()
644 self_allocate_ =
true;
void reset_to_load_values()
Reinitialize internal counter to load new nonzero values.
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
void commit_load_nonzeros_buffers(size_type nz_commit, value_type **val, index_type **row_i, index_type **col_j)
void finish_construction(bool test_setup)
Coordinate matrix subclass.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
Entries must have unique row and column indexes.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_type rows(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
T_To & dyn_cast(T_From &from)
Subclass to delete dynamically allocated memory with delete[].
const release_resource_ptr_t & release_resource() const
std::ostream & output(std::ostream &out) const
const VectorSpace & space_rows() const
virtual std::ostream & output(std::ostream &out) const
Virtual output function.
void Vp_StMtV(VectorMutable *vs_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta) const
Templated class that supports the COOMatrixTemplateInterface template interface.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void set_buffers(size_type max_nz, value_type *val, index_type *row_i, index_type *col_j, const release_resource_ptr_t &release_resource, size_type rows=0, size_type cols=0, size_type nz=0, bool check_input=false)
Give memory to use to store nonzero elements.
Abstract interface for objects that represent a space for mutable coordinate vectors.
Extract a constant DenseLinAlgPack::DVectorSlice view of a Vector object.
void coor_extract_nonzeros(EElementUniqueness element_uniqueness, const index_type inv_row_perm[], const index_type inv_col_perm[], const Range1D &row_rng, const Range1D &col_rng, index_type dl, index_type du, value_type alpha, const index_type len_Aval, value_type Aval[], const index_type len_Aij, index_type Arow[], index_type Acol[], const index_type row_offset, const index_type col_offset) const
void get_load_nonzeros_buffers(size_type max_nz_load, value_type **val, index_type **row_i, index_type **col_j)
bool in_range(Index i) const
Base class for all matrices that support basic matrix operations.
void Vp_StCOOMtV(DVectorSlice *vs_lhs, value_type alpha, const T_COOM &coom_rhs1, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2)
vs_lhs += alpha * op(coom_rhs1) * vs_rhs2 (BLAS xGEMV) (time = O(coom_rhs.nz(), space = O(1)) ...
Entries allowed with duplicate row and column indexes with the understanding that the values are summ...
void initialize(size_type dim)
Initialize given the dimension of the vector space.
bool resource_is_bound() const
Overridden from ReleaseResource.
Abstract interface for mutable coordinate vectors {abstract}.
void Vp_MtV_assert_compatibility(VectorMutable *v_lhs, const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2)
v_lhs += op(m_rhs1) * v_rhs2
Extract a non-const DenseLinAlgPack::DVectorSlice view of a VectorMutable object. ...
void set_uninitialized()
Release all owned memory and make uninitialized.
MatrixSparseCOORSerial()
Let this allocate its own memory.
MatrixOp & operator=(const MatrixOp &M)
const VectorSpace & space_cols() const
void reinitialize(size_type rows, size_type cols, size_type max_nz, EAssumeElementUniqueness element_uniqueness)
size_type cols(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
index_type count_nonzeros(EElementUniqueness element_uniqueness, const index_type inv_row_perm[], const index_type inv_col_perm[], const Range1D &row_rng, const Range1D &col_rng, index_type dl, index_type du) const