1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup SpCol
20 //! @{
21 
22 
23 
24 template<typename eT>
25 inline
SpCol()26 SpCol<eT>::SpCol()
27   : SpMat<eT>(arma_vec_indicator(), 1)
28   {
29   arma_extra_debug_sigprint();
30   }
31 
32 
33 
34 template<typename eT>
35 inline
SpCol(const uword in_n_elem)36 SpCol<eT>::SpCol(const uword in_n_elem)
37   : SpMat<eT>(arma_vec_indicator(), in_n_elem, 1, 1)
38   {
39   arma_extra_debug_sigprint();
40   }
41 
42 
43 
44 template<typename eT>
45 inline
SpCol(const uword in_n_rows,const uword in_n_cols)46 SpCol<eT>::SpCol(const uword in_n_rows, const uword in_n_cols)
47   : SpMat<eT>(arma_vec_indicator(), in_n_rows, in_n_cols, 1)
48   {
49   arma_extra_debug_sigprint();
50   }
51 
52 
53 
54 template<typename eT>
55 inline
SpCol(const SizeMat & s)56 SpCol<eT>::SpCol(const SizeMat& s)
57   : SpMat<eT>(arma_vec_indicator(), 0, 0, 1)
58   {
59   arma_extra_debug_sigprint();
60 
61   SpMat<eT>::init(s.n_rows, s.n_cols);
62   }
63 
64 
65 
66 template<typename eT>
67 inline
SpCol(const char * text)68 SpCol<eT>::SpCol(const char* text)
69   : SpMat<eT>(arma_vec_indicator(), 1)
70   {
71   arma_extra_debug_sigprint();
72 
73   SpMat<eT>::init(std::string(text));
74   }
75 
76 
77 
78 template<typename eT>
79 inline
80 SpCol<eT>&
operator =(const char * text)81 SpCol<eT>::operator=(const char* text)
82   {
83   arma_extra_debug_sigprint();
84 
85   SpMat<eT>::init(std::string(text));
86 
87   return *this;
88   }
89 
90 
91 
92 template<typename eT>
93 inline
SpCol(const std::string & text)94 SpCol<eT>::SpCol(const std::string& text)
95   : SpMat<eT>(arma_vec_indicator(), 1)
96   {
97   arma_extra_debug_sigprint();
98 
99   SpMat<eT>::init(text);
100   }
101 
102 
103 
104 template<typename eT>
105 inline
106 SpCol<eT>&
operator =(const std::string & text)107 SpCol<eT>::operator=(const std::string& text)
108   {
109   arma_extra_debug_sigprint();
110 
111   SpMat<eT>::init(text);
112 
113   return *this;
114   }
115 
116 
117 
118 template<typename eT>
119 inline
120 SpCol<eT>&
operator =(const eT val)121 SpCol<eT>::operator=(const eT val)
122   {
123   arma_extra_debug_sigprint();
124 
125   SpMat<eT>::operator=(val);
126 
127   return *this;
128   }
129 
130 
131 
132 template<typename eT>
133 template<typename T1>
134 inline
SpCol(const Base<eT,T1> & X)135 SpCol<eT>::SpCol(const Base<eT,T1>& X)
136   : SpMat<eT>(arma_vec_indicator(), 1)
137   {
138   arma_extra_debug_sigprint();
139 
140   SpMat<eT>::operator=(X.get_ref());
141   }
142 
143 
144 
145 template<typename eT>
146 template<typename T1>
147 inline
148 SpCol<eT>&
operator =(const Base<eT,T1> & X)149 SpCol<eT>::operator=(const Base<eT,T1>& X)
150   {
151   arma_extra_debug_sigprint();
152 
153   SpMat<eT>::operator=(X.get_ref());
154 
155   return *this;
156   }
157 
158 
159 
160 template<typename eT>
161 template<typename T1>
162 inline
SpCol(const SpBase<eT,T1> & X)163 SpCol<eT>::SpCol(const SpBase<eT,T1>& X)
164   : SpMat<eT>(arma_vec_indicator(), 1)
165   {
166   arma_extra_debug_sigprint();
167 
168   SpMat<eT>::operator=(X.get_ref());
169   }
170 
171 
172 
173 template<typename eT>
174 template<typename T1>
175 inline
176 SpCol<eT>&
operator =(const SpBase<eT,T1> & X)177 SpCol<eT>::operator=(const SpBase<eT,T1>& X)
178   {
179   arma_extra_debug_sigprint();
180 
181   SpMat<eT>::operator=(X.get_ref());
182 
183   return *this;
184   }
185 
186 
187 
188 template<typename eT>
189 template<typename T1, typename T2>
190 inline
SpCol(const SpBase<typename SpCol<eT>::pod_type,T1> & A,const SpBase<typename SpCol<eT>::pod_type,T2> & B)191 SpCol<eT>::SpCol
192   (
193   const SpBase<typename SpCol<eT>::pod_type, T1>& A,
194   const SpBase<typename SpCol<eT>::pod_type, T2>& B
195   )
196   : SpMat<eT>(arma_vec_indicator(), 1)
197   {
198   arma_extra_debug_sigprint();
199 
200   SpMat<eT>::init(A,B);
201   }
202 
203 
204 
205 template<typename eT>
206 inline
207 arma_warn_unused
208 const SpOp<SpCol<eT>,spop_htrans>
t() const209 SpCol<eT>::t() const
210   {
211   return SpOp<SpCol<eT>,spop_htrans>(*this);
212   }
213 
214 
215 
216 template<typename eT>
217 inline
218 arma_warn_unused
219 const SpOp<SpCol<eT>,spop_htrans>
ht() const220 SpCol<eT>::ht() const
221   {
222   return SpOp<SpCol<eT>,spop_htrans>(*this);
223   }
224 
225 
226 
227 template<typename eT>
228 inline
229 arma_warn_unused
230 const SpOp<SpCol<eT>,spop_strans>
st() const231 SpCol<eT>::st() const
232   {
233   return SpOp<SpCol<eT>,spop_strans>(*this);
234   }
235 
236 
237 
238 //! remove specified row
239 template<typename eT>
240 inline
241 void
shed_row(const uword row_num)242 SpCol<eT>::shed_row(const uword row_num)
243   {
244   arma_extra_debug_sigprint();
245 
246   arma_debug_check_bounds( row_num >= SpMat<eT>::n_rows, "SpCol::shed_row(): out of bounds" );
247 
248   shed_rows(row_num, row_num);
249   }
250 
251 
252 
253 //! remove specified rows
254 template<typename eT>
255 inline
256 void
shed_rows(const uword in_row1,const uword in_row2)257 SpCol<eT>::shed_rows(const uword in_row1, const uword in_row2)
258   {
259   arma_extra_debug_sigprint();
260 
261   arma_debug_check_bounds
262     (
263     (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows),
264     "SpCol::shed_rows(): indices out of bounds or incorrectly used"
265     );
266 
267   SpMat<eT>::sync_csc();
268 
269   const uword diff = (in_row2 - in_row1 + 1);
270 
271   // This is easy because everything is in one column.
272   uword start = 0, end = 0;
273   bool start_found = false, end_found = false;
274   for(uword i = 0; i < SpMat<eT>::n_nonzero; ++i)
275     {
276     // Start position found?
277     if(SpMat<eT>::row_indices[i] >= in_row1 && !start_found)
278       {
279       start = i;
280       start_found = true;
281       }
282 
283     // End position found?
284     if(SpMat<eT>::row_indices[i] > in_row2)
285       {
286       end = i;
287       end_found = true;
288       break;
289       }
290     }
291 
292   if(!end_found)
293     {
294     end = SpMat<eT>::n_nonzero;
295     }
296 
297   // Now we can make the copy.
298   if(start != end)
299     {
300     const uword elem_diff = end - start;
301 
302     eT*    new_values      = memory::acquire<eT>   (SpMat<eT>::n_nonzero - elem_diff);
303     uword* new_row_indices = memory::acquire<uword>(SpMat<eT>::n_nonzero - elem_diff);
304 
305     // Copy before the section we are dropping (if it exists).
306     if(start > 0)
307       {
308       arrayops::copy(new_values, SpMat<eT>::values, start);
309       arrayops::copy(new_row_indices, SpMat<eT>::row_indices, start);
310       }
311 
312     // Copy after the section we are dropping (if it exists).
313     if(end != SpMat<eT>::n_nonzero)
314       {
315       arrayops::copy(new_values + start, SpMat<eT>::values + end, (SpMat<eT>::n_nonzero - end));
316       arrayops::copy(new_row_indices + start, SpMat<eT>::row_indices + end, (SpMat<eT>::n_nonzero - end));
317       arrayops::inplace_minus(new_row_indices + start, diff, (SpMat<eT>::n_nonzero - end));
318       }
319 
320     memory::release(SpMat<eT>::values);
321     memory::release(SpMat<eT>::row_indices);
322 
323     access::rw(SpMat<eT>::values) = new_values;
324     access::rw(SpMat<eT>::row_indices) = new_row_indices;
325 
326     access::rw(SpMat<eT>::n_nonzero) -= elem_diff;
327     access::rw(SpMat<eT>::col_ptrs[1]) -= elem_diff;
328     }
329 
330   access::rw(SpMat<eT>::n_rows) -= diff;
331   access::rw(SpMat<eT>::n_elem) -= diff;
332 
333   SpMat<eT>::invalidate_cache();
334   }
335 
336 
337 
338 // //! insert N rows at the specified row position,
339 // //! optionally setting the elements of the inserted rows to zero
340 // template<typename eT>
341 // inline
342 // void
343 // SpCol<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
344 //   {
345 //   arma_extra_debug_sigprint();
346 //
347 //   arma_debug_check(set_to_zero == false, "SpCol::insert_rows(): cannot set nonzero values");
348 //
349 //   arma_debug_check_bounds((row_num > SpMat<eT>::n_rows), "SpCol::insert_rows(): out of bounds");
350 //
351 //   for(uword row = 0; row < SpMat<eT>::n_rows; ++row)
352 //     {
353 //     if(SpMat<eT>::row_indices[row] >= row_num)
354 //       {
355 //       access::rw(SpMat<eT>::row_indices[row]) += N;
356 //       }
357 //     }
358 //
359 //   access::rw(SpMat<eT>::n_rows) += N;
360 //   access::rw(SpMat<eT>::n_elem) += N;
361 //   }
362 
363 
364 
365 template<typename eT>
366 inline
367 typename SpCol<eT>::row_iterator
begin_row(const uword row_num)368 SpCol<eT>::begin_row(const uword row_num)
369   {
370   arma_extra_debug_sigprint();
371 
372   arma_debug_check_bounds( (row_num >= SpMat<eT>::n_rows), "SpCol::begin_row(): index out of bounds" );
373 
374   SpMat<eT>::sync_csc();
375 
376   return row_iterator(*this, row_num, 0);
377   }
378 
379 
380 
381 template<typename eT>
382 inline
383 typename SpCol<eT>::const_row_iterator
begin_row(const uword row_num) const384 SpCol<eT>::begin_row(const uword row_num) const
385   {
386   arma_extra_debug_sigprint();
387 
388   arma_debug_check_bounds( (row_num >= SpMat<eT>::n_rows), "SpCol::begin_row(): index out of bounds" );
389 
390   SpMat<eT>::sync_csc();
391 
392   return const_row_iterator(*this, row_num, 0);
393   }
394 
395 
396 
397 template<typename eT>
398 inline
399 typename SpCol<eT>::row_iterator
end_row(const uword row_num)400 SpCol<eT>::end_row(const uword row_num)
401   {
402   arma_extra_debug_sigprint();
403 
404   arma_debug_check_bounds( (row_num >= SpMat<eT>::n_rows), "SpCol::end_row(): index out of bounds" );
405 
406   SpMat<eT>::sync_csc();
407 
408   return row_iterator(*this, row_num + 1, 0);
409   }
410 
411 
412 
413 template<typename eT>
414 inline
415 typename SpCol<eT>::const_row_iterator
end_row(const uword row_num) const416 SpCol<eT>::end_row(const uword row_num) const
417   {
418   arma_extra_debug_sigprint();
419 
420   arma_debug_check_bounds( (row_num >= SpMat<eT>::n_rows), "SpCol::end_row(): index out of bounds" );
421 
422   SpMat<eT>::sync_csc();
423 
424   return const_row_iterator(*this, row_num + 1, 0);
425   }
426 
427 
428 
429 #ifdef ARMA_EXTRA_SPCOL_MEAT
430   #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_MEAT)
431 #endif
432 
433 
434 
435 //! @}
436