Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
indexed_vector.hpp
Go to the documentation of this file.
1#ifndef FSTINDEXEDVECTOR_H
2#define FSTINDEXEDVECTOR_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 <limits>
53#include <cmath>
54#include <cstring> // memcpy
55#include "error.hpp"
56#include "global.hpp"
57#include "indexed_matrix.hpp"
58
59/*============== Template parameter type naming conventions ==============
60--------- Numeric types: -------------------------------------------------
61DATATYPE - data sample values - usually real numbers (but may be integers
62 in text processing etc.)
63REALTYPE - must be real numbers - for representing intermediate results of
64 calculations like mean, covariance etc.
65IDXTYPE - index values for enumeration of data samples - (nonnegative) integers,
66 extent depends on numbers of samples in data
67DIMTYPE - index values for enumeration of features (dimensions), or classes (not
68 class sizes) - (nonnegative) integers, usually lower extent than IDXTYPE,
69 but be aware of expressions like _classes*_features*_features !
70 in linearized representations of feature matrices for all classes
71BINTYPE - feature selection marker type - represents ca. <10 different feature
72 states (selected, deselected, sel./desel. temporarily 1st nested loop, 2nd...)
73RETURNTYPE - criterion value: real value, but may be extended in future to support
74 multiple values
75--------- Class types: ---------------------------------------------------
76SUBSET - class of class type Subset
77CLASSIFIER - class implementing interface defined in abstract class Classifier
78EVALUATOR - class implementing interface defined in abstract class Sequential_Step
79DISTANCE - class implementing interface defined in abstract class Distance
80DATAACCESSOR - class implementing interface defined in abstract class Data_Accessor
81INTERVALCONTAINER - class of class type Data_Intervaller
82CONTAINER - STL container of class type Data_Interval
83========================================================================== */
84
85namespace FST {
86
87template<typename DATATYPE, typename DIMTYPE, class SUBSET>
88class Indexed_Matrix;
89
90template<typename DATATYPE, typename DIMTYPE, class SUBSET>
91class Indexed_Vector;
92
93template<typename DATATYPE, typename DIMTYPE, class SUBSET>
94std::ostream& operator<<(std::ostream& os, const Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>& tdb);
95
99template<typename DATATYPE, typename DIMTYPE, class SUBSET>
100class Indexed_Vector {
101public:
102 typedef std::shared_ptr<SUBSET> PSubset;
103 Indexed_Vector() : _n_max(0), _n(0), _d(0) {notify("Indexed_Vector (empty) constructor");}
104 Indexed_Vector(const DIMTYPE n) : _n_max(0), _n(0), _d(0) {notify("Indexed_Vector constructor"); reset(n);}
105 Indexed_Vector(const Indexed_Vector& iv);
107 ~Indexed_Vector() {notify("Indexed_Vector destructor");}
108 void reset(const DIMTYPE n_max);
109 void redim(const DIMTYPE n=0);
110
111 DATATYPE& operator[](const DIMTYPE i) {assert(i<_n); assert(_data); return _data[i];}
112 DATATYPE& at_raw(const DIMTYPE i) {assert(i<_n); assert(_data); return _data[i];}
113 DATATYPE& at(const DIMTYPE i) {assert(i<_d); assert(_index); return _data[_index[i]];}
114 DATATYPE* get_raw() {return _data.get();}
115 const DATATYPE& operator[](const DIMTYPE i) const {assert(i<_n); assert(_data); return _data[i];}
116 const DATATYPE& at_raw(const DIMTYPE i) const {assert(i<_n); assert(_data); return _data[i];}
117 const DATATYPE& at(const DIMTYPE i) const {assert(i<_d); assert(_index); return _data[_index[i]];}
118 const DATATYPE* get_raw() const {return _data.get();}
119
123 void narrow_to(const PSubset sub);
124 void denarrow();
125 DIMTYPE get_n() const {return _n;}
126 DIMTYPE get_d() const {return _d;}
127
128 // "raw" operations, ignoring index[]
129 void set_all_raw_to(const DATATYPE val);
130 void subtract_raw(const Indexed_Vector& vr);
131 void copy_raw(const Indexed_Vector& vr);
132
133 friend class Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET>;
134 friend std::ostream& operator<< <>(std::ostream& os, const Indexed_Vector& tdb);
135
136protected:
137 // NOTE: vector size is defined by:
138 // _n_max - hard constant representing maximum allocated space of size _n_max
139 // _n - "full feature set" dimensionality, _n<=_n_max
140 // _d - "virtual subset" dimensionality, _d<=_n
141 // (this logic replicates that in Indexed_Matrix, where it is more important)
142 DIMTYPE _n_max;
143 DIMTYPE _n;
144 std::unique_ptr<DATATYPE[]> _data;
145 // sub-vector access tools
146 DIMTYPE _d;
147 std::unique_ptr<DIMTYPE[]> _index;
148};
149
150template<typename DATATYPE, typename DIMTYPE, class SUBSET>
151Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>::Indexed_Vector(const Indexed_Vector& iv) : // copy-constructor
152 _n_max(iv._n_max),
153 _n(iv._n),
154 _d(iv._d)
155{
156 notify("Indexed_Vector copy-constructor.");
157 if(_n_max>0)
158 {
159 _data.reset(new DATATYPE[_n_max]); memcpy((void *)_data.get(),(void *)(iv._data).get(),sizeof(DATATYPE)*_n_max);
160 _index.reset(new DIMTYPE[_n_max]); memcpy((void *)_index.get(),(void *)(iv._index).get(),sizeof(DIMTYPE)*_n_max); // selected features (subspace) - index into _data
161 }
162}
163
164template<typename DATATYPE, typename DIMTYPE, class SUBSET>
165Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>& Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>::operator=(Indexed_Vector const &iv)
166{
167 notify("Indexed_Vector operator=.");
168 if (this != &iv)
169 {
170 _n=iv._n;
171 _d=iv._d;
172 if(_n_max!=iv._n_max)
173 {
174 _n_max=iv._n_max;
175 if(_n_max>0)
176 {
177 _data.reset(new DATATYPE[_n_max]);
178 _index.reset(new DIMTYPE[_n_max]);
179 } else {
180 assert(!iv._data);
181 assert(!iv._index);
182 _data.reset();
183 _index.reset();
184 }
185 }
186 if(_n_max>0)
187 {
188 memcpy((void *)_data.get(),(void *)(iv._data).get(),sizeof(DATATYPE)*_n_max);
189 memcpy((void *)_index.get(),(void *)(iv._index).get(),sizeof(DIMTYPE)*_n_max); // selected features (subspace) - index into _data
190 }
191 }
192 return *this;
193}
194
195template<typename DATATYPE, typename DIMTYPE, class SUBSET>
197{
198 notify("Indexed_Vector reset.");
199 assert(n_max>0);
200 if(n_max!=_n_max) {
201 _n_max=n_max;
202 _data.reset(new DATATYPE[_n_max]);
203 _index.reset(new DIMTYPE[n_max]); // selected features (subspace) - index into _data
204 }
205 // unconditionally, like Indexed_Matrix::reset — reset() always restores FULL dimensionality
206 // and the identity index map, also when the requested size equals the current allocation
207 // (it must not leave a stale redim()ed or narrow_to()'d _n/_d behind)
208 _n=_d=n_max;
209 for(DIMTYPE i=0;i<_n_max;i++) _index[i]=i;
210}
211
212template<typename DATATYPE, typename DIMTYPE, class SUBSET>
214{
215 notify("Indexed_Vector redim.");
216 assert(n<=_n_max);
217 assert(_data);
218 assert(_index);
219 if(n==0) _d=_n=_n_max; else _d=_n=n;
220 for(DIMTYPE i=0;i<_n;i++) _index[i]=i;
221}
222
223template<typename DATATYPE, typename DIMTYPE, class SUBSET>
224void Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>::narrow_to(const PSubset sub) // fill _index[] -> access to data is then mapped to sub-matrix
225{
226 assert(_n>=sub->get_d_raw()); // precondition: enough space to store the subset
227 assert(_index);
228 _d=0;
229 for(DIMTYPE f : sub->selected_features()) _index[_d++]=f;
230 assert(_d>0);
231}
232
233template<typename DATATYPE, typename DIMTYPE, class SUBSET>
234void Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>::denarrow() // reset _index[] -> access is reset to the full matrix
235{
236 assert(_index);
237 for(DIMTYPE i=0;i<_n;i++) _index[i]=i;
238 _d=_n;
239}
240
241template<typename DATATYPE, typename DIMTYPE, class SUBSET>
243{
244 assert(_data);
245 for(DIMTYPE i=0;i<_n;i++) _data[i]=val;
246}
247
248template<typename DATATYPE, typename DIMTYPE, class SUBSET>
250{
251 assert(_data);
252 assert(mr._data);
253 assert(mr.get_n()==_n);
254 for(DIMTYPE i=0;i<_n;i++) _data[i]-=mr._data[i];
255}
256
257template<typename DATATYPE, typename DIMTYPE, class SUBSET>
259{
260 assert(_data);
261 assert(mr._data);
262 assert(mr.get_n()==_n);
263 for(DIMTYPE i=0;i<_n;i++) _data[i]=mr._data[i];
264}
265
271template<typename DATATYPE, typename DIMTYPE, class SUBSET>
272std::ostream& operator<<(std::ostream& os, const Indexed_Vector<DATATYPE,DIMTYPE,SUBSET>& tdb)
273{
274 assert(tdb._n>0);
275 assert(tdb._d>0);
276 assert(tdb._data);
277 assert(tdb._index);
278 os << "----------------"<<std::endl;
279 os << "Indexed_Vector::" << std::endl;
280 os << "_index: "; for(DIMTYPE j=0;j<tdb._d;j++) {os << tdb._index[j] << " ";} os<<std::endl;
281 os << "_data (indexed): "; for(DIMTYPE j=0;j<tdb._d;j++) {os << tdb._data[tdb._index[j]] << " ";} os << std::endl;
282 os << "----------------"<<std::endl;
283 return os;
284}
285
286
287} // namespace
288#endif // FSTINDEXEDVECTOR_H ///:~
Matrix representation and operations, allows operation in selected subspace.
Definition indexed_matrix.hpp:102
Vector representation and operations, allows operation in selected subspace. Also serves as the helpe...
Definition indexed_vector.hpp:100
void copy_raw(const Indexed_Vector &vr)
this = vr, elementwise over the raw get_n() entries (requires vr.get_n()==get_n())
Definition indexed_vector.hpp:258
DIMTYPE _n
full ("raw") dimensionality currently in use, _n<=_n_max; see get_n()
Definition indexed_vector.hpp:143
const DATATYPE & at_raw(const DIMTYPE i) const
read-only raw (unindexed) element access – same as the const operator[]
Definition indexed_vector.hpp:116
DATATYPE & at(const DIMTYPE i)
indexed access through the narrow_to() subset map, i in [0,get_d())
Definition indexed_vector.hpp:113
void denarrow()
reset _index[] -> access is reset to the full vector (identity map, get_d()==get_n())
Definition indexed_vector.hpp:234
DATATYPE & at_raw(const DIMTYPE i)
raw (unindexed) element access, i in [0,get_n()) – same as operator[]
Definition indexed_vector.hpp:112
const DATATYPE * get_raw() const
read-only raw pointer to the underlying buffer (get_n() valid entries)
Definition indexed_vector.hpp:118
void subtract_raw(const Indexed_Vector &vr)
this -= vr, elementwise over the raw get_n() entries (requires vr.get_n()==get_n())
Definition indexed_vector.hpp:249
const DATATYPE & operator[](const DIMTYPE i) const
read-only raw (unindexed) element access, i in [0,get_n())
Definition indexed_vector.hpp:115
DATATYPE & operator[](const DIMTYPE i)
raw (unindexed) element access, i in [0,get_n())
Definition indexed_vector.hpp:111
DATATYPE * get_raw()
raw pointer to the underlying buffer (get_n() valid entries)
Definition indexed_vector.hpp:114
void redim(const DIMTYPE n=0)
keeps the existing allocation (reset() must have run already), resets to an unnarrowed identity index...
Definition indexed_vector.hpp:213
std::unique_ptr< DIMTYPE[]> _index
maps virtual sub-vector _d dimensions to original _n dimensions (identity after reset()/redim()/denar...
Definition indexed_vector.hpp:147
const DATATYPE & at(const DIMTYPE i) const
read-only indexed access through the narrow_to() subset map, i in [0,get_d())
Definition indexed_vector.hpp:117
DIMTYPE get_n() const
the full ("raw") dimensionality set by reset()/redim()
Definition indexed_vector.hpp:125
void reset(const DIMTYPE n_max)
(re)allocates for n_max features and resets to full, unnarrowed dimensionality (get_n()==get_d()==n_m...
Definition indexed_vector.hpp:196
DIMTYPE _d
current virtual (narrow_to()'d) sub-vector dimensionality, _d<=_n; see get_d()
Definition indexed_vector.hpp:146
std::shared_ptr< SUBSET > PSubset
shared pointer to a feature subset (the narrowing selector)
Definition indexed_vector.hpp:102
Indexed_Vector & operator=(Indexed_Vector const &iv)
deep-copy assignment (reallocates only if iv's capacity differs)
Definition indexed_vector.hpp:165
Indexed_Vector(const DIMTYPE n)
allocates for n features via reset(); starts unnarrowed (get_n()==get_d()==n)
Definition indexed_vector.hpp:104
DIMTYPE _n_max
allocated capacity: _data/_index can hold up to _n_max elements
Definition indexed_vector.hpp:142
std::unique_ptr< DATATYPE[]> _data
raw vector data buffer (_n_max entries allocated)
Definition indexed_vector.hpp:144
void set_all_raw_to(const DATATYPE val)
sets all get_n() raw entries to val (ignores the index map)
Definition indexed_vector.hpp:242
DIMTYPE get_d() const
the current virtual (narrow_to()'d) dimensionality, get_d()<=get_n()
Definition indexed_vector.hpp:126
void narrow_to(const PSubset sub)
fill _index[] -> access to data is then mapped to sub-vector; get_d() becomes the subset size.
Definition indexed_vector.hpp:224
FST4 specific error passing class.
Global definitions.
Matrix representation and operations, allows operation in selected subspace.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
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.