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