namespace lasd { /* ************************************************************************** */ template MatrixCSR::MatrixCSR(){ R.Resize(1); R[0] = &head; } template MatrixCSR::MatrixCSR(const ulong r, const ulong c){ rows = r; columns = c; R.Resize(rows+1); for(ulong i=0 ; i MatrixCSR::MatrixCSR(const MatrixCSR& toCopy) : MatrixCSR(toCopy.rows, toCopy.columns) { /* For each element in the "R" vector, insert it in the matrix (represented as a list) in this way: The row index is represented by "i" (the variable that iterates over the R array), meanwhile the column index is represented by the second element in the pair of the node. The current element is stored in the first element in the pair of the node. The update of the newely created R array is left to operator()(). */ for(ulong i=0 ; i < (toCopy.R.Size()-1) ; ++i){ for(Node** ptr = toCopy.R[i] ; ptr!=toCopy.R[i+1] ; ptr = &( (*(*ptr)).next ) ){ (*this)(i , ((*ptr)->value).second) = ((*ptr)->value).first; } } } template MatrixCSR::MatrixCSR(MatrixCSR&& toMove) noexcept{ std::swap(rows, toMove.rows); std::swap(columns, toMove.columns); std::swap(size, toMove.size); std::swap(head, toMove.head); std::swap(R, toMove.R); toMove.R.Resize(1); // the moved matrix must be empty toMove.R[0] = &toMove.head; Node** oldHead = R[0]; for(ulong i=0 ; i MatrixCSR::~MatrixCSR(){ Clear(); } template MatrixCSR& MatrixCSR::operator=(const MatrixCSR& toCopy){ MatrixCSR tmp(toCopy); std::swap(tmp, *this); return *this; } template MatrixCSR& MatrixCSR::operator=(MatrixCSR&& toMove) noexcept{ std::swap(rows, toMove.rows); std::swap(columns, toMove.columns); std::swap(size, toMove.size); std::swap(head, toMove.head); std::swap(R, toMove.R); // Fix of the R vector after the swap, both in (*this) and in toMove Node** oldHead; oldHead = R[0]; for(ulong i=0 ; i bool MatrixCSR::operator==(const MatrixCSR& toCompare) const noexcept{ /* * Check the # of rows, of columns and of elements. * For each row, check if the nodes in that row have the same value (data and column). * If one row ends before the other one, return false. */ if(columns == toCompare.columns && rows == toCompare.rows && size==toCompare.size){ for(ulong i=0 ; i<(R.Size()-1) ; ++i){ for(Node** ptr1 = R[i] , **ptr2 = (toCompare.R)[i] ; ptr1!=R[i+1] && ptr2!=toCompare.R[i+1] ; ptr1 = &( (*(*ptr1)).next ) , ptr2 = &( (*(*ptr2)).next ) ){ if( ( ((*ptr1)->value).first != ((*ptr2)->value).first ) || ( ((*ptr1)->value).second != ((*ptr2)->value).second )) return false; if( (&((*(*ptr1)).next)==R[i+1] && &((*(*ptr2)).next) != toCompare.R[i+1]) || (&((*(*ptr1)).next)!=R[i+1] && &((*(*ptr2)).next) == toCompare.R[i+1])){ return false; } } } return true; }else{ return false; } } template bool MatrixCSR::operator!=(const MatrixCSR& toCompare) const noexcept{ return !(*this == toCompare); } template void MatrixCSR::RowResize(const ulong& new_row_size){ if(new_row_size > rows){ R.Resize(new_row_size+1); for(ulong i=rows+1 ; inext; delete toDelete; toDelete = tmp; --size; } *(R[new_row_size]) = nullptr; R.Resize(new_row_size+1); rows = new_row_size; } } template void MatrixCSR::ColumnResize(const ulong& new_column_size){ if(new_column_size < columns){ Node** prev; // in case an element must be deleted, this is its previous element. Node* toDelete; Node** toModify; for(ulong i=0 ; ivalue).second < new_column_size){ prev = &( (*(*ptr)).next ); // This, alongside line 157 is redundant, but maybe it gives more clarity ptr = &( (*(*ptr)).next); }else{ toDelete = *ptr; toModify = &( (*(*ptr)).next ); *ptr = (*(*ptr)).next; delete toDelete; --size; for(ulong j=i+1 ; j bool MatrixCSR::ExistsCell(const ulong& r, const ulong& c) const noexcept{ if(r>=rows || c>=columns) return false; Node** ptr = R[r]; while(ptr != R[r+1]){ if( (**ptr).value.second == c ) return true; ptr = &((**ptr).next); } return false; } template const Data& MatrixCSR::operator()(const ulong r, const ulong c) const{ if(r>=rows || c>=columns) throw std::out_of_range("Tried to access an invalid position!"); else{ Node** ptr = R[r]; while(ptr != R[r+1]){ if( (**ptr).value.second == c ){ return (**ptr).value.first; } ptr = &((**ptr).next); } throw std::length_error("The element does not exist!"); } } template Data& MatrixCSR::operator()(const ulong r, const ulong c){ if(r>=rows || c>=columns) throw std::out_of_range("Tried to access an invalid position!"); else{ Node** ptr = R[r]; Node** last = R[r+1]; // pointer to the pointer inside the last element of the r-th cell while(ptr != R[r+1] && ((**ptr).value.second <= c)){ if((**ptr).value.second == c){ return (**ptr).value.first; } else if( (**ptr).value.second < c ){ ptr = &((**ptr).next); } } Node* newNode = new Node(); Node* nextNode = *ptr; *ptr = newNode; newNode->next = nextNode; (newNode->value).second = c; ++size; if(last == ptr){ // the newely inserted element is the last one in its row for(ulong i=r+1 ; inext); // assign the address of the pointer of the next node } else break; } } return (newNode->value).first; } } template void MatrixCSR::Clear(){ List>::Clear(); columns = 0; rows = 0; size = 0; R.Resize(1); R[0] = &head; } template void MatrixCSR::MapPreOrder(const typename MappableContainer::MapFunctor fun, void* par){ List>::MapPreOrder( [&fun](std::pair& datx, void* parx){fun(datx.first, parx); } , par); } template void MatrixCSR::MapPostOrder(const typename MappableContainer::MapFunctor fun, void* par){ List>::MapPostOrder( [&fun](std::pair& datx, void* parx){fun(datx.first, parx); } , par); } template void MatrixCSR::FoldPreOrder(const typename FoldableContainer::FoldFunctor fun, const void* par, void* acc) const{ List>::FoldPreOrder( [&fun](const std::pair& datx, const void* parx, void* accx) {fun(datx.first, parx, accx); } , par , acc); } template void MatrixCSR::FoldPostOrder(const typename FoldableContainer::FoldFunctor fun, const void* par, void* acc) const{ List>::FoldPostOrder( [&fun](const std::pair& datx, const void* parx, void* accx) {fun(datx.first, parx, accx); } , par , acc); } template void MatrixCSR::debug(){ std::cout<value).first<<"|"<< (tmp->value).second; std::cout<next); std::cout<next; } std::cout << "\nR VECTOR:" << '\n'; for(ulong i=0; i