33 typedef gsEigen::SparseVector<T> Fiber;
35 class InnerIterator : Fiber::InnerIterator
37 typedef typename Fiber::InnerIterator Base;
50 m_fibers[i] =
new Fiber(
cols);
54 : m_fibers(other.
rows())
56 for (
int i = 0; i <
rows(); ++i)
57 m_fibers[i] =
new Fiber( *other.m_fibers[i] );
61 : m_fibers(rowxpr.num)
63 for (
index_t i = 0; i < rowxpr.num; ++i)
64 m_fibers[i] =
new Fiber( *rowxpr.mat.m_fibers[rowxpr.start + i] );
85 inline index_t fibers()
const {
return m_fibers.size(); }
90 {
return m_fibers.size(); }
96 {
return ( m_fibers.size()>0 ? m_fibers.front()->size() : 0 ); }
104 Fiber& fiber(
index_t i) {
return *m_fibers[i]; }
105 const Fiber& fiber(
index_t i)
const {
return *m_fibers[i]; }
110 GISMO_ENSURE(IsRowMajor,
"Cannot access row in col-major fiber matrix");
114 const Fiber& row(
index_t i)
const
117 GISMO_ENSURE(IsRowMajor,
"Cannot access row in col-major fiber matrix");
124 GISMO_ENSURE(!IsRowMajor,
"Cannot access col in col-major fiber matrix");
128 const Fiber& col(
index_t i)
const
131 GISMO_ENSURE(!IsRowMajor,
"Cannot access col in row-major fiber matrix");
137 GISMO_ASSERT( i>=0 && i<
rows() && j>=0 && i<
cols(),
"Invalid element: "<<i<<
">=0 && "<<i<<
"<rows()"<<
"="<<
rows()<<
" && "<<j<<
">=0 && "<<i<<
"<cols()"<<
"="<<
cols() );
138 if (!IsRowMajor) std::swap(i,j);
139 return m_fibers[i]->coeff(j);
144 GISMO_ASSERT( i>=0 && i<
rows() && j>=0 && i<
cols(),
"Invalid element: "<<i<<
">=0 && "<<i<<
"<rows()"<<
"="<<
rows()<<
" && "<<j<<
">=0 && "<<i<<
"<cols()"<<
"="<<
cols() );
145 if (!IsRowMajor) std::swap(i,j);
146 return m_fibers[i]->coeffRef(j);
151 GISMO_ASSERT( i>=0 && i<
rows() && j>=0 && i<
cols(),
"Invalid element: "<<i<<
">=0 && "<<i<<
"<rows()"<<
"="<<
rows()<<
" && "<<j<<
">=0 && "<<i<<
"<cols()"<<
"="<<
cols() );
152 if (!IsRowMajor) std::swap(i,j);
153 m_fibers[i]->data().atWithInsertion(j);
158 GISMO_ASSERT( i>=0 && i<
rows() && j>=0 && i<
cols(),
"Invalid element: "<<i<<
">=0 && "<<i<<
"<rows()"<<
"="<<
rows()<<
" && "<<j<<
">=0 && "<<i<<
"<cols()"<<
"="<<
cols() );
159 if (!IsRowMajor) std::swap(i,j);
160 auto & vdata = m_fibers[i]->data();
161 const index_t jj = vdata.searchLowerIndex(j);
162 return ((jj==vdata.size()) || (vdata.index(jj)!=j));
167 for (
int i = 0; i < fibers(); ++i)
174 void swap(gsFiberMatrix& other)
176 m_fibers.swap( other.m_fibers );
185 for (
index_t i = 0; i < n; ++i)
186 m_fibers[i]->insert(i) = (T)(1.0);
191 for (
auto & fb : m_fibers)
192 std::fill(fb->valuePtr(), fb->valuePtr() + fb->nonZeros(), (T)0.);
198 if (!IsRowMajor) std::swap(
rows,
cols);
201 m_fibers.resize(
rows);
203 m_fibers[i] =
new Fiber(
cols);
206 void reservePerColumn(
index_t nz)
208 for (
index_t i = 0; i < fibers(); ++i)
209 m_fibers[i]->reserve(nz);
214 if (!IsRowMajor) std::swap(newRows,newCols);
216 const index_t oldRows = fibers();
219 for (
index_t i = newRows; i < oldRows; ++i)
222 m_fibers.resize(newRows);
225 for (
index_t i = oldRows; i < newRows; ++i)
226 m_fibers[i] =
new Fiber(newCols);
228 const index_t m = std::min(oldRows, newRows);
229 for (
index_t i = 0; i < m; ++i)
230 m_fibers[i]->conservativeResize(newCols);
235 GISMO_ASSERT(IsRowMajor && 0 <= k && k < fibers(),
"k out of bounds.");
240 m_fibers.resize(m_fibers.size()+1);
243 for (
index_t i = fibers() - 1; i > k + 1; --i)
244 m_fibers[i] = m_fibers[i-1];
247 m_fibers[k+1] =
new Fiber( row(k) );
252 RowBlockXpr topRows(
index_t num) {
return RowBlockXpr(*
this, 0, num); }
253 const RowBlockXpr topRows(
index_t num)
const {
return RowBlockXpr(*
this, 0, num); }
255 RowBlockXpr bottomRows(
index_t num) {
return RowBlockXpr(*
this, fibers() - num, num); }
256 const RowBlockXpr bottomRows(
index_t num)
const {
return RowBlockXpr(*
this, fibers() - num, num); }
258 RowBlockXpr middleRows(
index_t start,
index_t num) {
return RowBlockXpr(*
this, start, num); }
259 const RowBlockXpr middleRows(
index_t start,
index_t num)
const {
return RowBlockXpr(*
this, start, num); }
264 for (
index_t i = 0; i < fibers(); ++i)
265 nnz += m_fibers[i]->nonZeros();
269 template <
class Derived>
270 void toSparseMatrix(gsEigen::SparseMatrixBase<Derived>& m)
const
272 m.derived().resize(
rows(),
cols() );
273 m.derived().reserve( nonZeros() );
274 for (
index_t i = 0; i < fibers(); ++i)
276 for (
typename Fiber::InnerIterator it(*m_fibers[i]); it; ++it)
277 m.derived().insert(IsRowMajor?i:it.index(), IsRowMajor?it.index():i) = it.value();
279 m.derived().makeCompressed();
284 RowBlockXpr(
const gsFiberMatrix& _mat,
index_t _start,
index_t _num)
285 : mat(const_cast<gsFiberMatrix&>(_mat)), start(_start), num(_num)
290 GISMO_ASSERT( 0 <= num && 0 <= start ,
"Invalid block.");
292 GISMO_ASSERT( start + num <= mat.rows(),
"Invalid block.");
298 RowBlockXpr& operator= (
const RowBlockXpr& other)
300 GISMO_ASSERT(num == other.num,
"Wrong size in assignment.");
301 for (
index_t i = 0; i < num; ++i)
302 mat.row(start + i) = other.mat.row(other.start + i);
306 RowBlockXpr& operator= (
const gsFiberMatrix & other)
308 GISMO_ASSERT(num == other.rows(),
"Wrong size in assignment.");
309 for (
index_t i = 0; i < num; ++i)
310 mat.row(start + i) = other.row(i);
316 std::vector< Fiber* > m_fibers;
323 for (
index_t i = newRows; i < fibers(); ++i)
326 m_fibers.resize(newRows);