Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
subset.hpp
Go to the documentation of this file.
1#ifndef FSTSUBSET_H
2#define FSTSUBSET_H
3 /*
27=========================================================================
28Copyright and license:
29 * FST4 software (with the exception of any bundled or externally linked
30 third-party components) is Copyright (C) 2000-present Institute of
31 Information Theory and Automation of the Czech Academy of Sciences (UTIA).
32 * FST4 is free software: you can redistribute it and/or modify it under
33 the terms of the GNU Affero General Public License as published by the
34 Free Software Foundation, version 3. The full text of the license is in
35 the file LICENSE in the distribution root and at
36 https://www.gnu.org/licenses/agpl-3.0.html.
37 * FST4 is distributed in the hope that it will be useful, but WITHOUT ANY
38 WARRANTY; without even the implied warranty of MERCHANTABILITY or
39 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
40 License for more details.
41 * Closed-source use without the AGPL's copyleft obligations requires a
42 commercial license from UTIA; in case of interest write to
43 utia@utia.cas.cz. LICENSING.md in the distribution root explains both
44 options, the contributor license agreement that every contribution
45 requires, and the contacts (technical questions and pull requests:
46 somol@utia.cas.cz, with "FST" in the subject line).
47========================================================================== */
48
49#include <memory>
50#include <cassert>
51#include <iostream>
52#include <cstdlib>
53#include "fst_rand.hpp" // FST-owned PRNG: identical random sequences on every platform
54#include "error.hpp"
55#include "global.hpp"
56
57/*============== Template parameter type naming conventions ==============
58--------- Numeric types: -------------------------------------------------
59DATATYPE - data sample values - usually real numbers (but may be integers
60 in text processing etc.)
61REALTYPE - must be real numbers - for representing intermediate results of
62 calculations like mean, covariance etc.
63IDXTYPE - index values for enumeration of data samples - (nonnegative) integers,
64 extent depends on numbers of samples in data
65DIMTYPE - index values for enumeration of features (dimensions), or classes (not
66 class sizes) - (nonnegative) integers, usually lower extent than IDXTYPE,
67 but be aware of expressions like _classes*_features*_features !
68 in linearized representations of feature matrices for all classes
69BINTYPE - feature selection marker type - represents ca. <10 different feature
70 states (selected, deselected, sel./desel. temporarily 1st nested loop, 2nd...)
71RETURNTYPE - criterion value: real value, but may be extended in future to support
72 multiple values
73--------- Class types: ---------------------------------------------------
74SUBSET - class of class type Subset
75CLASSIFIER - class implementing interface defined in abstract class Classifier
76EVALUATOR - class implementing interface defined in abstract class Sequential_Step
77DISTANCE - class implementing interface defined in abstract class Distance
78DATAACCESSOR - class implementing interface defined in abstract class Data_Accessor
79INTERVALCONTAINER - class of class type Data_Intervaller
80CONTAINER - STL container of class type Data_Interval
81========================================================================== */
82
83namespace FST {
84
85template<class BINTYPE, typename DIMTYPE>
86class Subset;
87
88template<class BINTYPE, typename DIMTYPE>
89std::ostream& operator<<(std::ostream& os, const Subset<BINTYPE,DIMTYPE>& tdb);
90
103template<class BINTYPE, typename DIMTYPE>
104class Subset {
106 friend std::ostream& operator<< <>(std::ostream& os, const Subset<BINTYPE,DIMTYPE>& tdb);
107public:
108 Subset(const DIMTYPE n);
114 ~Subset();
126 void stateless_copy(Subset<BINTYPE,DIMTYPE>& sub); // copies subset from sub - all features converted to id_sel or id_desel only
127 bool equivalent(const Subset<BINTYPE,DIMTYPE>& sub);
128
129 // adaptable methods - output depends on _frozen_mode - to be called in SearchMethods()
130 void select(const DIMTYPE i);
131 void select(const DIMTYPE _from, const DIMTYPE _to) {assert(_to>_from); assert(_to<get_n()); for(DIMTYPE i=_from;i<=_to;i++) select(i);}
132 void select_all() {for(DIMTYPE i=0;i<_n;i++) if(_bin[i]!=id_frozen) _bin[i]=id_sel;}
133 void deselect(const DIMTYPE i);
134 void deselect(const DIMTYPE _from, const DIMTYPE _to) {assert(_to>_from); assert(_to<get_n()); for(DIMTYPE i=_from;i<=_to;i++) deselect(i);}
135 void deselect_all() {for(DIMTYPE i=0;i<_n;i++) if(_bin[i]!=id_frozen) _bin[i]=id_desel;}
136 DIMTYPE get_n() const {DIMTYPE z=0; for(DIMTYPE i=0;i<_n;i++) if(_bin[i]==id_frozen) ++z; return _n-z;}
137 DIMTYPE get_d() const {DIMTYPE d=0; for(DIMTYPE i=0;i<_n;i++) if(_bin[i]>0 && _bin[i]!=id_frozen && _bin[i]!=-id_frozen) ++d; return d;}
138
139 // "raw" versions - to be called in Criterion()
140 void select_raw(const DIMTYPE i) {assert(i<_n); _bin[i]=id_sel;}
142 void select_all_raw() {for(DIMTYPE i=0;i<_n;i++) _bin[i]=id_sel;}
143 void deselect_raw(const DIMTYPE i) {assert(i<_n); _bin[i]=id_desel;}
145 void deselect_all_raw() {for(DIMTYPE i=0;i<_n;i++) _bin[i]=id_desel;}
146 DIMTYPE get_n_raw() const {return _n;}
147 DIMTYPE get_d_raw() const {DIMTYPE d=0; for(DIMTYPE i=0;i<_n;i++) if(_bin[i]>0) ++d; return d;}
148 bool selected_raw(const DIMTYPE i) const {if(i>=0&&i<_n) return (_bin[i]>0); else return false;}
149
154 void make_random_subset(const DIMTYPE d);
157 void make_random_subset(const DIMTYPE lo_d, const DIMTYPE hi_d);
162 void make_random_subset(const float d_prob);
163
168 void set_forward_mode(const bool forward=true);
169 bool get_forward_mode() const {return _forward_mode;}
170
178 void set_frozen_mode(const bool freeze=false);
179 bool get_frozen_mode() const {return _frozen_mode;}
180
181 // NOTE: regardles _frozen_mode always returns all selected features (id_sel, id_frozen, id_traverse)
186 bool getFirstFeature(DIMTYPE &feat, bool selected=true, const int looplevel=0); // NOTE: selected and looplevel so far ignored
189 bool getNextFeature(DIMTYPE &feat);
190
191 bool getFirstCandidateSubset(const DIMTYPE g, bool reverse=false);
193 DIMTYPE getNoOfCandidateSubsets(const DIMTYPE g, bool reverse=false);
197 bool getFirstTemporaryFeature(DIMTYPE &feat); // traversing through temporary features in current CandidateSubset
200 bool getNextTemporaryFeature(DIMTYPE &feat); // traversing through temporary features in current CandidateSubset
201 DIMTYPE getNoOfTemporaryFeatures();
202
212 public:
218
219 class iterator {
220 public:
222 iterator(const Subset *s, const DIMTYPE i, const Kind k) : _s(s), _i(i), _k(k) {advance();}
223 DIMTYPE operator*() const {return _i;}
224 iterator& operator++() {++_i; advance(); return *this;}
225 bool operator!=(const iterator& o) const {return _i!=o._i;}
226 private:
227 bool match() const {return (_k==SELECTED) ? (_s->_bin[_i]>0) : (_s->_bin[_i]==_s->tmp_id_traverse);}
228 void advance() {while(_i<_s->_n && !match()) ++_i;}
229 const Subset *_s;
230 DIMTYPE _i;
232 };
234 Feature_Range(const Subset *s, const Kind k) : _s(s), _k(k) {}
235 iterator begin() const {return iterator(_s,0,_k);}
236 iterator end() const {return iterator(_s,_s->_n,_k);}
237 private:
238 const Subset *_s;
240 };
245
246private:
247 const DIMTYPE _n;
248 const std::unique_ptr<BINTYPE[]> _bin;
249
250 BINTYPE id_sel;
251 BINTYPE id_desel;
252 BINTYPE id_traverse;
253 BINTYPE id_frozen;
254 BINTYPE tmp_id_sel;
255 BINTYPE tmp_id_desel;
258 DIMTYPE get_combinations(const DIMTYPE n, const DIMTYPE k); // NOTE: throws if C(n,k) overflows DIMTYPE (or 64-bit intermediates)
259
262
265
267};
268
269template<class BINTYPE, typename DIMTYPE>
270Subset<BINTYPE,DIMTYPE>::Subset(const DIMTYPE n) : _n(n), _bin(new BINTYPE[n])
271{
273 for(DIMTYPE i=0;i<_n;i++) _bin[i]=id_desel;
274 _forward_mode=true;
275 _frozen_mode=false;
279 notify("Subset constructor.");
280}
281
282
283template<class BINTYPE, typename DIMTYPE>
284Subset<BINTYPE,DIMTYPE>::~Subset()
285{
286 notify("Subset destructor.");
287}
288
289
290template<class BINTYPE, typename DIMTYPE>
292{
294 for(DIMTYPE i=0;i<_n;i++) _bin[i]=sub._bin[i];
300 notify("Subset copy-constructor.");
301}
302
303
304template<class BINTYPE, typename DIMTYPE>
306{
307 // NOTE: the literal +1/-1 written below are mode-independent - membership is encoded by the
308 // marker's sign in both modes (see the class notes); only the step operations' meaning
309 // of "select" flips with set_forward_mode()
310 assert(_bin);
311 assert(_n>=sub.get_n_raw());
312 for(DIMTYPE i=0;i<_n;i++) if(_bin[i]!=id_frozen && _bin[i]!=-id_frozen) _bin[i]=-1; // NOTE: hard constant
313 DIMTYPE f;
314 for(bool b=sub.getFirstFeature(f);b!=false;b=sub.getNextFeature(f)) {
315 assert(f<_n);
316 if(_bin[f]!=id_frozen && _bin[f]!=-id_frozen) _bin[f]=1; // NOTE: hard constant
317 }
318}
319
320template<class BINTYPE, typename DIMTYPE>
322{
323 assert(_bin);
324 assert(_n>0);
325 bool eq=true;
326 DIMTYPE fidx=0;
327 while(eq && fidx<_n) if((_bin[fidx]<=0 && sub._bin[fidx]>0)||(_bin[fidx]>0 && sub._bin[fidx]<=0)) eq=false; else ++fidx;
328 return eq;
329}
330
331template<class BINTYPE, typename DIMTYPE>
333{
334 assert(_bin);
335 assert(i<get_n());
336 DIMTYPE u=0, c=i;
337 while(u<_n && _bin[u]==id_frozen) ++u;
338 while(u<_n && c>0) {
339 ++u; --c;
340 while(u<_n && _bin[u]==id_frozen) ++u;
341 }
342 assert(u<_n);
343 _bin[u]=id_sel;
344}
345
346
347template<class BINTYPE, typename DIMTYPE>
349{
350 assert(_bin);
351 assert(i<get_n());
352 DIMTYPE u=0, c=i;
353 while(u<_n && _bin[u]==id_frozen) ++u;
354 while(u<_n && c>0) {
355 ++u; --c;
356 while(u<_n && _bin[u]==id_frozen) ++u;
357 }
358 assert(u<_n);
359 _bin[u]=id_desel;
360}
361
362template<class BINTYPE, typename DIMTYPE>
364{
365 assert(_bin);
366 //for(DIMTYPE i=0;i<_n;i++) if(_bin[i]!=id_frozen && _bin[i]!=-id_frozen) _bin[i]=-1; // NOTE: hard constant
367 bool go = true;
368 DIMTYPE f;
369 for(bool b=sub.getFirstFeature(f);go && b!=false;b=sub.getNextFeature(f)) {
370 if(f<_n) _bin[f]=id_sel; else go=false;
371 }
372}
373
374template<class BINTYPE, typename DIMTYPE>
376{
377 assert(_bin);
378 //for(DIMTYPE i=0;i<_n;i++) if(_bin[i]!=id_frozen && _bin[i]!=-id_frozen) _bin[i]=-1; // NOTE: hard constant
379 bool go = true;
380 DIMTYPE f;
381 for(bool b=sub.getFirstFeature(f);go && b!=false;b=sub.getNextFeature(f)) {
382 if(f<_n) _bin[f]=id_desel; else go=false;
383 }
384}
385
386template<class BINTYPE, typename DIMTYPE>
388{
389 assert(_bin);
390 assert(d>=1 && d<=get_n());
391 // assert bin must contain >=d non-frozen slots
392 DIMTYPE i,piv;
393 for(i=0;i<_n;i++) if(_bin[i]!=id_frozen) _bin[i]=id_desel;
394 for(i=0;i<d;i++)
395 {
396 piv=(DIMTYPE)fst_rand_below((unsigned long)_n); assert(piv<_n);
397 while(_bin[piv]!=id_desel) {piv++; if(piv>_n-1) piv=0;}
398 _bin[piv]=id_sel;
399 }
400}
401
402template<class BINTYPE, typename DIMTYPE>
403void Subset<BINTYPE,DIMTYPE>::make_random_subset(const DIMTYPE lo_d, const DIMTYPE hi_d)
404{
405 assert(lo_d>=1 && lo_d<=get_n());
406 assert(hi_d>=1 && hi_d<=get_n());
407 assert(lo_d<=hi_d);
408 DIMTYPE d;
409 d=lo_d+(DIMTYPE)fst_rand_below((unsigned long)(hi_d-lo_d+1)); assert(lo_d<=d && d<=hi_d);
411}
412
413template<class BINTYPE, typename DIMTYPE>
414void Subset<BINTYPE,DIMTYPE>::make_random_subset(const float d_prob) // d_prob must be from (0,1]; generates random subset of random size where the mean size over a series of calls is d_prob*no_of_all_features
415{
416 assert(_bin);
417 assert(d_prob>0.0 && d_prob<=1.0);
418 do {
419 DIMTYPE i;
420 for(i=0;i<_n;i++) if(_bin[i]!=id_frozen) {
421 if((float)fst_rand()/(float)FST_RAND_MAX<d_prob) _bin[i]=id_sel;
422 else _bin[i]=id_desel;
423 }
424 } while(get_d()==0);
425}
426
427template<class BINTYPE, typename DIMTYPE>
429{
430 assert(_gen_features==0); // no traversal is going on
431 assert(_enum_selected==0); // no feature iteration is going on
432 assert(_frozen_mode==false); // in frozen mode change direction of traversal using getFirstCandidateSubset() 'reverse' parameter
433 if(forward) {
434 id_desel=-1; id_sel=1; id_traverse=3; /*if(_frozen_mode==0)*/ id_frozen=9;
435 _forward_mode=true;
436 } else {
437 id_desel=1; id_sel=-1; id_traverse=-3; /*if(_frozen_mode==0)*/ id_frozen=-9;
438 _forward_mode=false;
439 }
440}
441
442
443template<class BINTYPE, typename DIMTYPE>
445{
446 assert(_bin);
447 assert(_gen_features==0); // no traversal is going on
448 assert(_enum_selected==0); // no feature iteration is going on
449 assert(freeze!=_frozen_mode); // repeated initiation of the same mode would produce unexpected results
450 if(freeze) {
451 for(DIMTYPE i=0;i<_n;i++) if(_bin[i]==id_sel || _bin[i]==id_traverse) _bin[i]=id_frozen;
452 _frozen_mode=true;
453 } else {
454 for(DIMTYPE i=0;i<_n;i++) if(_bin[i]==id_frozen || _bin[i]==id_traverse) _bin[i]=id_sel;
455 _frozen_mode=false;
456 }
457}
458
459template<class BINTYPE, typename DIMTYPE>
460bool Subset<BINTYPE,DIMTYPE>::getFirstFeature(DIMTYPE &feat, bool selected, const int looplevel)
461{
462 assert(_bin);
463 assert(_n>0);
466 feat=_enum_selected;
468 // reset on unsuccessful end-of-iteration just as getNextFeature() does: set_forward_mode() and
469 // set_frozen_mode() assert that no iteration is in progress, and a cursor left non-zero by a
470 // traversal that found nothing would make those asserts fire spuriously
471 if(feat<_n) return true; else {_enum_selected=0; return false;}
472}
473
474
475template<class BINTYPE, typename DIMTYPE>
477{
478 assert(_bin);
479 assert(_n>0);
480 assert(_enum_selected>0); // i.e., getFirstFeature has been called before
482 feat=_enum_selected;
484 if(feat<_n) return true; else {_enum_selected=0; return false;}
485}
486
487
488template<class BINTYPE, typename DIMTYPE>
489bool Subset<BINTYPE,DIMTYPE>::getFirstCandidateSubset(const DIMTYPE g, bool reverse) // traversing through candidate subsets (adding/removing) g-touples of features
490{
491 assert(_bin);
492 assert(g>=1 && g<=_n);
495 DIMTYPE rr=g;
496 for(DIMTYPE i=0;((rr>0)&&(i<_n));i++) if(_bin[i]==tmp_id_desel) {_bin[i]=tmp_id_traverse; --rr;} /* initialize _bin for exhaustive step */
497 if(rr==0) {_gen_features=g; return true;}
498 else {for(DIMTYPE i=0;((rr>0)&&(i<_n));i++) if(_bin[i]==tmp_id_traverse) _bin[i]=tmp_id_desel; _gen_features=0; return false;}
499}
500
501template<class BINTYPE, typename DIMTYPE>
503{
504 assert(_bin);
505 assert(_gen_features>0 && _gen_features<=_n); // g==_n is a legitimate traversal (the single full set), reached by an all-cardinalities exhaustive search
506 DIMTYPE beg, piv, pom;
507 /* finding new candidate configuration.
508 The g traversed positions are enumerated in lexicographic order over the eligible
509 (tmp_id_desel) positions: find the rightmost traversed marker that still has an eligible
510 position to its right, move it one eligible position right, then pack all traversed markers
511 left of it back against the start of the array. Exhaustion is detected by there being no
512 eligible position to the right at all, in which case every traversed marker is restored to
513 tmp_id_desel and the traversal ends. */
514 for(beg=0;beg<_n && _bin[beg]!=tmp_id_traverse;beg++);
515 for(piv=beg;piv<_n && _bin[piv]!=tmp_id_desel;piv++);
516 if(piv==_n) { // no more configurations
517 for(beg=0;beg<_n;beg++) if(_bin[beg]==tmp_id_traverse) _bin[beg]=tmp_id_desel;
519 return false;
520 }
521 else
522 {
523 pom=piv; /* remember the position of first (desel) on the right */
524 do piv--; while(_bin[piv]!=tmp_id_traverse); /* find the real pivot */
525 _bin[piv]=tmp_id_desel; _bin[pom]=tmp_id_traverse; /* shift pivot to the right */
526 pom=0;
527 /* run "pom" from left, "piv" from right. the desel,travers pairs found are changed to travers,desel */
528 if(piv>0) --piv;
529 while((piv>0)&&(_bin[piv]!=tmp_id_traverse)) --piv;
530 while((pom<piv)&&(_bin[pom]!=tmp_id_desel)) pom++;
531 while(piv>pom)
532 {
534 if(piv>0) --piv;
535 while((piv>0)&&(_bin[piv]!=tmp_id_traverse)) --piv;
536 while((pom<piv)&&(_bin[pom]!=tmp_id_desel))pom++;
537 }
538 }
539 return true;
540}
541
542template<class BINTYPE, typename DIMTYPE>
543DIMTYPE Subset<BINTYPE,DIMTYPE>::getNoOfCandidateSubsets(const DIMTYPE g, bool reverse) // returns loop size (the number of to-be-traversed subsets)
544{
545 // NOTE: get_combinations() throws if the count overflows DIMTYPE;
546 // no issue for g==1, possible for large n with g farther from 1 or n
547 assert(_bin);
548 assert(g>=1 && g<_n);
549 BINTYPE id_empty; if(reverse) id_empty=-id_desel; else id_empty=id_desel;
550 DIMTYPE ecnt=0; for(DIMTYPE i=0;i<_n;i++) if(_bin[i]==id_empty) ++ecnt;
551 if(g>ecnt) return 0;
552 if(g==1) return ecnt; // just acceleration
553 else return get_combinations(ecnt,g);
554}
555
556template<class BINTYPE, typename DIMTYPE>
557bool Subset<BINTYPE,DIMTYPE>::getFirstTemporaryFeature(DIMTYPE &feat) // traversing through temporary features in current CandidateSubset
558{
559 assert(_bin);
560 assert(_n>0);
563 feat=_enum_temporary;
565 if(feat<_n) return true; else {_enum_temporary=0; return false;}
566}
567
568template<class BINTYPE, typename DIMTYPE>
569bool Subset<BINTYPE,DIMTYPE>::getNextTemporaryFeature(DIMTYPE &feat) // traversing through temporary features in current CandidateSubset
570{
571 assert(_bin);
572 assert(_n>0);
573 assert(_enum_temporary>0); // i.e., getFirstTemporaryFeature has been called before
575 feat=_enum_temporary;
577 if(feat<_n) return true; else {_enum_temporary=0; return false;}
578}
579template<class BINTYPE, typename DIMTYPE>
580DIMTYPE Subset<BINTYPE,DIMTYPE>::getNoOfTemporaryFeatures() // returns the number of temporarily selected features (indicated by tmp_id_traverse) in current CandidateSubset
581{
582 assert(_bin);
583 assert(_n>0);
584 DIMTYPE _sum=0;
585 for(DIMTYPE i=0; i<_n; i++) if(_bin[i]==tmp_id_traverse) _sum++;
586 return _sum;
587}
588
589template<class BINTYPE, typename DIMTYPE>
590DIMTYPE Subset<BINTYPE,DIMTYPE>::get_combinations(const DIMTYPE n, const DIMTYPE k)
591{
592 assert(n>0);
593 assert(n>=k);
594 if(k==0 || n==k) return 1;
595 // C(n,k)==C(n,n-k) - iterate over the smaller of the two to minimize intermediates
596 const unsigned long long kk=((unsigned long long)k<=(unsigned long long)(n-k))?(unsigned long long)k:(unsigned long long)(n-k);
597 // incremental product C(n,kk)=prod_{i=1..kk}(n-kk+i)/i; after step i the value equals
598 // C(n-kk+i,i), an integer, so each division is exact and overflow can occur only in
599 // the multiplication (checked below) or in the final narrowing to DIMTYPE
600 unsigned long long result=1, tempcheck;
601 for(unsigned long long i=1;i<=kk;i++) {
602 const unsigned long long factor=(unsigned long long)n-kk+i;
603 tempcheck=result*factor;
604 if(tempcheck/factor!=result) throw FST::fst_error("Subset::get_combinations() numeric representation overflow.");
605 result=tempcheck/i;
606 }
607 DIMTYPE dimresult=(DIMTYPE)result;
608 if((unsigned long long)dimresult!=result) throw FST::fst_error("Subset::get_combinations() numeric representation overflow.");
609 return dimresult;
610}
611
616template<class BINTYPE, typename DIMTYPE>
617std::ostream& operator<<(std::ostream& os, const Subset<BINTYPE,DIMTYPE>& tdb)
618{
619 assert(tdb._bin);
620 assert(tdb._n>0);
621 assert(tdb._bin);
622 const DIMTYPE d_raw=tdb.get_d_raw();
623 os << "Subset<n=" << tdb._n << ", d=" << d_raw <<">: ";
624#ifdef DEBUG
625 for(DIMTYPE i=0;i<tdb._n;i++) {os << (int)tdb._bin[i] << " ";}
626 os << " ~ ";
627#endif
628 if(d_raw==0) os << "empty";
629 else for(DIMTYPE i=0;i<tdb._n;i++) {if(tdb._bin[i]>0) os << i << " ";}
630 return os;
631}
632
633} // namespace
634#endif // FSTSUBSET_H ///:~
Forward iterator over raw feature indices matching a Kind, skipping non-matching ones.
Definition subset.hpp:219
bool match() const
whether the current index matches this iterator's Kind
Definition subset.hpp:227
bool operator!=(const iterator &o) const
range-for only ever compares against end(); true until the index reaches end()'s
Definition subset.hpp:225
DIMTYPE _i
the current raw feature index
Definition subset.hpp:230
void advance()
skips forward from the current index to the next match (or to end())
Definition subset.hpp:228
const Subset * _s
the subset iterated
Definition subset.hpp:229
Kind _k
which Kind is matched
Definition subset.hpp:231
iterator(const Subset *s, const DIMTYPE i, const Kind k)
Positions at feature index i or the first matching feature at or after it (advance() skips non-matche...
Definition subset.hpp:222
DIMTYPE operator*() const
the current (raw) feature index
Definition subset.hpp:223
iterator & operator++()
advances to the next matching feature index
Definition subset.hpp:224
Read-only forward range over feature indices.
Definition subset.hpp:211
Kind _k
which kind of feature this range selects
Definition subset.hpp:239
iterator begin() const
an iterator positioned at the first matching feature, or already at end() if there are none
Definition subset.hpp:235
Kind
Which raw features a Feature_Range/iterator matches.
Definition subset.hpp:214
@ SELECTED
features with a positive raw marker (selected, frozen, or under traversal; matches get_d_raw(),...
Definition subset.hpp:215
@ TEMPORARY
features currently marked tmp_id_traverse by an in-progress getFirstCandidateSubset()/getNextCandidat...
Definition subset.hpp:216
const Subset * _s
the subset iterated
Definition subset.hpp:238
Feature_Range(const Subset *s, const Kind k)
Constructs a range over s's features of the given k (SELECTED or TEMPORARY).
Definition subset.hpp:234
iterator end() const
the sentinel end iterator
Definition subset.hpp:236
Stores the info on currently selected features, enables generating permutations, etc.
Definition subset.hpp:104
DIMTYPE _gen_features
the g-tuple size of the getFirstCandidateSubset() traversal in progress, or 0 if none
Definition subset.hpp:263
void select_all_raw()
mark all features (including frozen ones) as selected
Definition subset.hpp:142
bool getFirstTemporaryFeature(DIMTYPE &feat)
Definition subset.hpp:557
BINTYPE id_traverse
the marker value for a feature in the g-tuple currently being traversed by getFirstCandidateSubset()/...
Definition subset.hpp:252
void deselect_all()
mark all (non-frozen) features as deselected
Definition subset.hpp:135
bool getFirstFeature(DIMTYPE &feat, bool selected=true, const int looplevel=0)
Definition subset.hpp:460
DIMTYPE get_n() const
the number of features select()/deselect() address: get_n_raw() minus currently frozen features
Definition subset.hpp:136
void select_all()
mark all (non-frozen) features as selected
Definition subset.hpp:132
BINTYPE tmp_id_sel
id_sel/id_desel/id_traverse as resolved for the CURRENT getFirstCandidateSubset() call's reverse dire...
Definition subset.hpp:254
DIMTYPE getNoOfTemporaryFeatures()
the number of features currently marked tmp_id_traverse (the g-tuple size of the CandidateSubset trav...
Definition subset.hpp:580
void set_frozen_mode(const bool freeze=false)
Freezes (or unfreezes) the currently selected features, excluding them from further select()/deselect...
Definition subset.hpp:444
void set_forward_mode(const bool forward=true)
Flips the sign convention of id_sel/id_desel/id_traverse/id_frozen (forward: selected>0; backward: se...
Definition subset.hpp:428
const DIMTYPE _n
max. No. of features (full set size)
Definition subset.hpp:247
bool getFirstCandidateSubset(const DIMTYPE g, bool reverse=false)
begins traversal of all g-tuples of currently DESELECTED features (candidates to ADD) if reverse is f...
Definition subset.hpp:489
bool get_forward_mode() const
true if in forward mode (the constructor default); see set_forward_mode()
Definition subset.hpp:169
DIMTYPE get_d_raw() const
number of features whose raw marker is positive: selected/traversed/frozen in forward mode,...
Definition subset.hpp:147
DIMTYPE _enum_temporary
cursor state for the deprecated getFirstTemporaryFeature()/getNextTemporaryFeature() pair
Definition subset.hpp:264
DIMTYPE get_combinations(const DIMTYPE n, const DIMTYPE k)
Number of size-k combinations of n features (n choose k); throws if the result overflows DIMTYPE (or ...
Definition subset.hpp:590
bool _frozen_mode
set by set_frozen_mode(); read by get_frozen_mode()
Definition subset.hpp:261
void select(const DIMTYPE i)
mark i-th feature as selected
Definition subset.hpp:332
BINTYPE id_frozen
the marker value for a frozen feature (see set_frozen_mode())
Definition subset.hpp:253
bool getNextTemporaryFeature(DIMTYPE &feat)
Definition subset.hpp:569
Feature_Range temporary_features() const
reentrant range over temporary features in the current CandidateSubset (as with getFirstTemporaryFeat...
Definition subset.hpp:244
Subset(const DIMTYPE n)
Definition subset.hpp:270
void deselect(const DIMTYPE i)
mark i-th feature as deselected
Definition subset.hpp:348
bool equivalent(const Subset< BINTYPE, DIMTYPE > &sub)
tests whether sub represents the same subset (ignoring internal state)
Definition subset.hpp:321
BINTYPE id_desel
the marker value for a deselected feature; sign flips with set_forward_mode()
Definition subset.hpp:251
bool get_frozen_mode() const
true if currently frozen; see set_frozen_mode()
Definition subset.hpp:179
BINTYPE tmp_id_desel
see tmp_id_sel; local to get*CandidateSubset()
Definition subset.hpp:255
void deselect_raw(const DIMTYPE i)
mark i-th feature as deselected
Definition subset.hpp:143
DIMTYPE get_d() const
number of currently selected, non-frozen features (get_d_raw() minus frozen ones)
Definition subset.hpp:137
bool getNextFeature(DIMTYPE &feat)
Definition subset.hpp:476
DIMTYPE getNoOfCandidateSubsets(const DIMTYPE g, bool reverse=false)
Definition subset.hpp:543
BINTYPE tmp_id_traverse
Definition subset.hpp:256
void deselect_all_raw()
mark all features (including frozen ones) as deselected
Definition subset.hpp:145
void stateless_copy(Subset< BINTYPE, DIMTYPE > &sub)
Overwrites this subset's selection state from sub's currently selected features (via getFirstFeature(...
Definition subset.hpp:305
DIMTYPE _enum_selected
cursor state for the deprecated getFirstFeature()/getNextFeature() pair
Definition subset.hpp:266
BINTYPE id_sel
the marker value for a selected feature; sign flips with set_forward_mode()
Definition subset.hpp:250
const std::unique_ptr< BINTYPE[]> _bin
default format to store subset info
Definition subset.hpp:248
bool _forward_mode
set by set_forward_mode(); read by get_forward_mode()
Definition subset.hpp:260
void deselect(const DIMTYPE _from, const DIMTYPE _to)
mark features _from,..,_to as deselected
Definition subset.hpp:134
void select_raw(const DIMTYPE i)
mark i-th feature as selected
Definition subset.hpp:140
Feature_Range selected_features() const
reentrant range over all currently selected features (id_sel, id_frozen, id_traverse - as with getFir...
Definition subset.hpp:242
void select(const DIMTYPE _from, const DIMTYPE _to)
mark features _from,..,_to as selected
Definition subset.hpp:131
void make_random_subset(const DIMTYPE d)
Generate random subset of exactly d features. Draws from the library PRNG (FST::fst_rand(),...
Definition subset.hpp:387
bool selected_raw(const DIMTYPE i) const
true if raw feature index i is currently selected (or frozen); false (not an error) for an out-of-ran...
Definition subset.hpp:148
bool getNextCandidateSubset()
advances to the next g-tuple begun by getFirstCandidateSubset(); returns false once exhausted
Definition subset.hpp:502
DIMTYPE get_n_raw() const
the full allocation size (max_n passed to the constructor), regardless of frozen features
Definition subset.hpp:146
FST4 specific error passing class.
Definition error.hpp:61
FST4 specific error passing class.
FST4-owned pseudo-random number generator (UCRT-compatible LCG), replacing platform-specific std::ran...
Global definitions.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
int fst_rand()
Returns the next pseudo-random draw in 0..FST_RAND_MAX; use instead of std::rand().
Definition fst_rand.hpp:93
unsigned long fst_rand_below(const unsigned long n)
Returns a pseudo-random index in 0..n-1 (n >= 1); use instead of fst_rand()n.
Definition fst_rand.hpp:112
const int FST_RAND_MAX
Maximum value fst_rand() can return; use instead of the libc macro RAND_MAX.
Definition fst_rand.hpp:101
void notify(const std::string msg)
Prints msg followed by a newline via syncout::print(); a no-op unless the preprocessor macro DEBUG is...
Definition global.hpp:112
std::ostream & operator<<(std::ostream &os, const Data_Intervaller< CONTAINER, IDXTYPE > &ia)
Streams every contained interval as "si:<startidx>, c:<count>" lines to os.
Definition data_intervaller.hpp:152
Copyright © 2000–present ÚTIA, Institute of Information Theory and Automation of the Czech Academy of Sciences · Contacts · This site sets no cookies and uses no analytics.