00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SIMPLEFEATURES__H__
00014 #define _SIMPLEFEATURES__H__
00015
00016 #include "lib/common.h"
00017 #include "lib/Mathematics.h"
00018 #include "lib/io.h"
00019 #include "lib/Cache.h"
00020 #include "lib/File.h"
00021 #include "preproc/SimplePreProc.h"
00022 #include "features/DotFeatures.h"
00023 #include "features/StringFeatures.h"
00024
00025 #include <string.h>
00026
00027 namespace shogun
00028 {
00029 template <class ST> class CStringFeatures;
00030 template <class ST> class CSimpleFeatures;
00031 template <class ST> class CSimplePreProc;
00032 class CDotFeatures;
00033
00063 template <class ST> class CSimpleFeatures: public CDotFeatures
00064 {
00065 public:
00070 CSimpleFeatures(int32_t size=0)
00071 : CDotFeatures(size), num_vectors(0), num_features(0),
00072 feature_matrix(NULL), feature_cache(NULL) {}
00073
00075 CSimpleFeatures(const CSimpleFeatures & orig)
00076 : CDotFeatures(orig), num_vectors(orig.num_vectors),
00077 num_features(orig.num_features),
00078 feature_matrix(orig.feature_matrix),
00079 feature_cache(orig.feature_cache)
00080 {
00081 if (orig.feature_matrix)
00082 {
00083 free_feature_matrix();
00084 feature_matrix=new ST(num_vectors*num_features);
00085 memcpy(feature_matrix, orig.feature_matrix, sizeof(float64_t)*int64_t(num_vectors)*num_features);
00086 }
00087 }
00088
00095 CSimpleFeatures(ST* src, int32_t num_feat, int32_t num_vec)
00096 : CDotFeatures(0), num_vectors(0), num_features(0),
00097 feature_matrix(NULL), feature_cache(NULL)
00098 {
00099 copy_feature_matrix(src, num_feat, num_vec);
00100 }
00101
00106 CSimpleFeatures(CFile* loader)
00107 : CDotFeatures(loader), num_vectors(0), num_features(0),
00108 feature_matrix(NULL), feature_cache(NULL)
00109 {
00110 load(loader);
00111 }
00112
00117 virtual CFeatures* duplicate() const
00118 {
00119 return new CSimpleFeatures<ST>(*this);
00120 }
00121
00122 virtual ~CSimpleFeatures()
00123 {
00124 SG_DEBUG("deleting simplefeatures (0x%p)\n", this);
00125 free_features();
00126 }
00127
00131 void free_feature_matrix()
00132 {
00133 delete[] feature_matrix;
00134 feature_matrix = NULL;
00135 num_vectors=0;
00136 num_features=0;
00137 }
00138
00142 void free_features()
00143 {
00144 free_feature_matrix();
00145 delete feature_cache;
00146 feature_cache = NULL;
00147 }
00148
00159 ST* get_feature_vector(int32_t num, int32_t& len, bool& dofree)
00160 {
00161 len=num_features;
00162
00163 if (feature_matrix)
00164 {
00165 dofree=false;
00166 return &feature_matrix[num*int64_t(num_features)];
00167 }
00168 else
00169 {
00170 SG_DEBUG( "compute feature!!!\n") ;
00171
00172 ST* feat=NULL;
00173 dofree=false;
00174
00175 if (feature_cache)
00176 {
00177 feat=feature_cache->lock_entry(num);
00178
00179 if (feat)
00180 return feat;
00181 else
00182 {
00183 feat=feature_cache->set_entry(num);
00184 }
00185 }
00186
00187 if (!feat)
00188 dofree=true;
00189 feat=compute_feature_vector(num, len, feat);
00190
00191
00192 if (get_num_preproc())
00193 {
00194 int32_t tmp_len=len;
00195 ST* tmp_feat_before = feat;
00196 ST* tmp_feat_after = NULL;
00197
00198 for (int32_t i=0; i<get_num_preproc(); i++)
00199 {
00200 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00201 tmp_feat_after=p->apply_to_feature_vector(tmp_feat_before, tmp_len);
00202 SG_UNREF(p);
00203
00204 if (i!=0)
00205 delete[] tmp_feat_before;
00206 tmp_feat_before=tmp_feat_after;
00207 }
00208
00209 memcpy(feat, tmp_feat_after, sizeof(ST)*tmp_len);
00210 delete[] tmp_feat_after;
00211
00212 len=tmp_len ;
00213 SG_DEBUG( "len: %d len2: %d\n", len, num_features);
00214 }
00215 return feat ;
00216 }
00217 }
00218
00227 void set_feature_vector(ST* src, int32_t len, int32_t num)
00228 {
00229 if (num>=num_vectors)
00230 {
00231 SG_ERROR("Index out of bounds (number of vectors %d, you "
00232 "requested %d)\n", num_vectors, num);
00233 }
00234
00235 if (!feature_matrix)
00236 SG_ERROR("Requires a in-memory feature matrix\n");
00237
00238 if (len != num_features)
00239 SG_ERROR("Vector not of length %d (has %d)\n", num_features, len);
00240
00241 memcpy(&feature_matrix[num*int64_t(num_features)], src, int64_t(num_features)*sizeof(ST));
00242 }
00243
00250 void get_feature_vector(ST** dst, int32_t* len, int32_t num)
00251 {
00252 if (num>=num_vectors)
00253 {
00254 SG_ERROR("Index out of bounds (number of vectors %d, you "
00255 "requested %d)\n", num_vectors, num);
00256 }
00257
00258 int32_t vlen=0;
00259 bool free_vec;
00260
00261 ST* vec= get_feature_vector(num, vlen, free_vec);
00262
00263 *len=vlen;
00264 *dst=(ST*) malloc(vlen*sizeof(ST));
00265 memcpy(*dst, vec, vlen*sizeof(ST));
00266
00267 free_feature_vector(vec, num, free_vec);
00268 }
00269
00276 void free_feature_vector(ST* feat_vec, int32_t num, bool dofree)
00277 {
00278 if (feature_cache)
00279 feature_cache->unlock_entry(num);
00280
00281 if (dofree)
00282 delete[] feat_vec ;
00283 }
00284
00292 void get_feature_matrix(ST** dst, int32_t* num_feat, int32_t* num_vec)
00293 {
00294 ASSERT(feature_matrix);
00295
00296 int64_t num=int64_t(num_features)*num_vectors;
00297 *num_feat=num_features;
00298 *num_vec=num_vectors;
00299 *dst=(ST*) malloc(sizeof(ST)*num);
00300 if (!*dst)
00301 SG_ERROR("Allocating %ld bytes failes\n", sizeof(ST)*num);
00302 memcpy(*dst, feature_matrix, num * sizeof(ST));
00303 }
00304
00312 ST* get_feature_matrix(int32_t &num_feat, int32_t &num_vec)
00313 {
00314 num_feat=num_features;
00315 num_vec=num_vectors;
00316 return feature_matrix;
00317 }
00318
00323 CSimpleFeatures<ST>* get_transposed()
00324 {
00325 int32_t num_feat;
00326 int32_t num_vec;
00327 ST* fm=get_transposed(num_feat, num_vec);
00328
00329 return new CSimpleFeatures<ST>(fm, num_feat, num_vec);
00330 }
00331
00341 ST* get_transposed(int32_t &num_feat, int32_t &num_vec)
00342 {
00343 num_feat=num_vectors;
00344 num_vec=num_features;
00345
00346 ST* fm=new ST[int64_t(num_feat)*num_vec];
00347
00348 for (int32_t i=0; i<num_vectors; i++)
00349 {
00350 int32_t vlen;
00351 bool vfree;
00352 ST* vec=get_feature_vector(i, vlen, vfree);
00353
00354 for (int32_t j=0; j<vlen; j++)
00355 fm[j*int64_t(num_vectors)+i]=vec[j];
00356
00357 free_feature_vector(vec, i, vfree);
00358 }
00359
00360 return fm;
00361 }
00362
00373 virtual void set_feature_matrix(ST* fm, int32_t num_feat, int32_t num_vec)
00374 {
00375 free_feature_matrix();
00376 feature_matrix=fm;
00377 num_features=num_feat;
00378 num_vectors=num_vec;
00379 }
00380
00390 virtual void copy_feature_matrix(ST* src, int32_t num_feat, int32_t num_vec)
00391 {
00392 free_feature_matrix();
00393 feature_matrix=new ST[((int64_t) num_feat)*num_vec];
00394 memcpy(feature_matrix, src, (sizeof(ST)*((int64_t) num_feat)*num_vec));
00395
00396 num_features=num_feat;
00397 num_vectors=num_vec;
00398 }
00399
00404 void obtain_from_dot(CDotFeatures* df)
00405 {
00406 int32_t num_feat=df->get_dim_feature_space();
00407 int32_t num_vec=df->get_num_vectors();
00408
00409 ASSERT(num_feat>0 && num_vec>0);
00410
00411 free_feature_matrix();
00412 feature_matrix=new ST[((int64_t) num_feat)*num_vec];
00413
00414 for (int32_t i=0; i<num_vec; i++)
00415 {
00416 float64_t* dst;
00417 int32_t len;
00418 df->get_feature_vector(&dst, &len, i);
00419 ASSERT(num_feat==len);
00420
00421 for (int32_t j=0; j<num_feat; j++)
00422 feature_matrix[i*int64_t(num_feat)+j]=(ST) dst[j];
00423
00424 delete[] dst;
00425 }
00426 num_features=num_feat;
00427 num_vectors=num_vec;
00428 }
00429
00435 virtual bool apply_preproc(bool force_preprocessing=false)
00436 {
00437 SG_DEBUG( "force: %d\n", force_preprocessing);
00438
00439 if ( feature_matrix && get_num_preproc())
00440 {
00441
00442 for (int32_t i=0; i<get_num_preproc(); i++)
00443 {
00444 if ( (!is_preprocessed(i) || force_preprocessing) )
00445 {
00446 set_preprocessed(i);
00447 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00448 SG_INFO( "preprocessing using preproc %s\n", p->get_name());
00449 if (p->apply_to_feature_matrix(this) == NULL)
00450 {
00451 SG_UNREF(p);
00452 return false;
00453 }
00454 SG_UNREF(p);
00455 }
00456 }
00457 return true;
00458 }
00459 else
00460 {
00461 if (!feature_matrix)
00462 SG_ERROR( "no feature matrix\n");
00463
00464 if (!get_num_preproc())
00465 SG_ERROR( "no preprocessors available\n");
00466
00467 return false;
00468 }
00469 }
00470
00475 virtual int32_t get_size() { return sizeof(ST); }
00476
00477
00482 virtual inline int32_t get_num_vectors() { return num_vectors; }
00483
00488 inline int32_t get_num_features() { return num_features; }
00489
00494 inline void set_num_features(int32_t num)
00495 {
00496 num_features= num;
00497
00498 if (num_features && num_vectors)
00499 {
00500 delete feature_cache;
00501 feature_cache= new CCache<ST>(get_cache_size(), num_features, num_vectors);
00502 }
00503 }
00504
00509 inline void set_num_vectors(int32_t num)
00510 {
00511 num_vectors= num;
00512 if (num_features && num_vectors)
00513 {
00514 delete feature_cache;
00515 feature_cache= new CCache<ST>(get_cache_size(), num_features, num_vectors);
00516 }
00517 }
00518
00523 inline virtual EFeatureClass get_feature_class() { return C_SIMPLE; }
00524
00529 inline virtual EFeatureType get_feature_type();
00530
00537 virtual bool reshape(int32_t p_num_features, int32_t p_num_vectors)
00538 {
00539 if (p_num_features*p_num_vectors == this->num_features * this->num_vectors)
00540 {
00541 this->num_features=p_num_features;
00542 this->num_vectors=p_num_vectors;
00543 return true;
00544 }
00545 else
00546 return false;
00547 }
00548
00556 virtual int32_t get_dim_feature_space()
00557 {
00558 return num_features;
00559 }
00560
00567 virtual float64_t dot(int32_t vec_idx1, int32_t vec_idx2)
00568 {
00569 int32_t len1, len2;
00570 bool free1, free2;
00571
00572 ST* vec1= get_feature_vector(vec_idx1, len1, free1);
00573 ST* vec2= get_feature_vector(vec_idx2, len2, free2);
00574
00575 float64_t result=CMath::dot(vec1, vec2, len1);
00576
00577 free_feature_vector(vec1, vec_idx1, free1);
00578 free_feature_vector(vec2, vec_idx2, free2);
00579
00580 return result;
00581 }
00582
00589 virtual float64_t dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len);
00590
00599 virtual void add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val=false)
00600 {
00601 ASSERT(vec2_len == num_features);
00602
00603 int32_t vlen;
00604 bool vfree;
00605 ST* vec1=get_feature_vector(vec_idx1, vlen, vfree);
00606
00607 ASSERT(vlen == num_features);
00608
00609 if (abs_val)
00610 {
00611 for (int32_t i=0; i<num_features; i++)
00612 vec2[i]+=alpha*CMath::abs(vec1[i]);
00613 }
00614 else
00615 {
00616 for (int32_t i=0; i<num_features; i++)
00617 vec2[i]+=alpha*vec1[i];
00618 }
00619
00620 free_feature_vector(vec1, vec_idx1, vfree);
00621 }
00622
00628 virtual inline int32_t get_nnz_features_for_vector(int32_t num)
00629 {
00630 return num_features;
00631 }
00632
00640 virtual inline bool Align_char_features(
00641 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00642 {
00643 return false;
00644 }
00645
00650 virtual inline void load(CFile* loader);
00651
00656 virtual inline void save(CFile* saver);
00657
00659 struct simple_feature_iterator
00660 {
00662 ST* vec;
00664 int32_t vidx;
00666 int32_t vlen;
00668 bool vfree;
00669
00671 int32_t index;
00672 };
00673
00683 virtual void* get_feature_iterator(int32_t vector_index)
00684 {
00685 if (vector_index>=num_vectors)
00686 {
00687 SG_ERROR("Index out of bounds (number of vectors %d, you "
00688 "requested %d)\n", num_vectors, vector_index);
00689 }
00690
00691 simple_feature_iterator* iterator=new simple_feature_iterator[1];
00692 iterator->vec= get_feature_vector(vector_index, iterator->vlen, iterator->vfree);
00693 iterator->vidx=vector_index;
00694 iterator->index=0;
00695 return iterator;
00696 }
00697
00708 virtual bool get_next_feature(int32_t& index, float64_t& value, void* iterator)
00709 {
00710 simple_feature_iterator* it=(simple_feature_iterator*) iterator;
00711 if (!it || it->index>=it->vlen)
00712 return false;
00713
00714 index=it->index++;
00715 value = (float64_t) it->vec[index];
00716
00717 return true;
00718 }
00719
00725 virtual void free_feature_iterator(void* iterator)
00726 {
00727 if (!iterator)
00728 return;
00729
00730 simple_feature_iterator* it=(simple_feature_iterator*) iterator;
00731 free_feature_vector(it->vec, it->vidx, it->vfree);
00732 delete[] it;
00733 }
00734
00736 inline virtual const char* get_name() const { return "SimpleFeatures"; }
00737
00738
00739 #ifdef HAVE_BOOST_SERIALIZATION
00740 private:
00741
00745 friend class ::boost::serialization::access;
00746 template<class Archive>
00747 void save(Archive & ar, const unsigned int archive_version) const
00748 {
00749
00750 SG_DEBUG("archiving SimpleFeatures\n");
00751
00752 ar & ::boost::serialization::base_object<CDotFeatures>(*this);
00753
00754
00755
00756
00757 ar & num_vectors;
00758 ar & num_features;
00759
00760 for (int i=0; i < num_vectors*num_features; ++i)
00761 {
00762 ar & feature_matrix[i];
00763 }
00764
00765 SG_DEBUG("done SimpleFeatures\n");
00766
00767
00768 }
00769
00770 template<class Archive>
00771 void load(Archive & ar, const unsigned int archive_version)
00772 {
00773
00774 SG_DEBUG("archiving SimpleFeatures\n");
00775
00776 ar & ::boost::serialization::base_object<CDotFeatures>(*this);
00777
00778
00779
00780
00781 ar & num_vectors;
00782 ar & num_features;
00783
00784 feature_matrix = new ST[int64_t(num_vectors)*num_features];
00785 for (int i=0; i< num_vectors*num_features; ++i){
00786 ar & feature_matrix[i];
00787 }
00788
00789
00790 SG_DEBUG("done SimpleFeatures\n");
00791
00792 }
00793
00794 GLOBAL_BOOST_SERIALIZATION_SPLIT_MEMBER();
00795
00796 #endif //HAVE_BOOST_SERIALIZATION
00797
00798
00799 protected:
00811 virtual ST* compute_feature_vector(int32_t num, int32_t& len, ST* target=NULL)
00812 {
00813 len=0;
00814 return NULL;
00815 }
00816
00818 int32_t num_vectors;
00819
00821 int32_t num_features;
00822
00824 ST* feature_matrix;
00825
00827 CCache<ST>* feature_cache;
00828 };
00829
00830 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00831
00832 #define GET_FEATURE_TYPE(f_type, sg_type) \
00833 template<> inline EFeatureType CSimpleFeatures<sg_type>::get_feature_type() \
00834 { \
00835 return f_type; \
00836 }
00837
00838 GET_FEATURE_TYPE(F_BOOL, bool)
00839 GET_FEATURE_TYPE(F_CHAR, char)
00840 GET_FEATURE_TYPE(F_BYTE, uint8_t)
00841 GET_FEATURE_TYPE(F_SHORT, int16_t)
00842 GET_FEATURE_TYPE(F_WORD, uint16_t)
00843 GET_FEATURE_TYPE(F_INT, int32_t)
00844 GET_FEATURE_TYPE(F_UINT, uint32_t)
00845 GET_FEATURE_TYPE(F_LONG, int64_t)
00846 GET_FEATURE_TYPE(F_ULONG, uint64_t)
00847 GET_FEATURE_TYPE(F_SHORTREAL, float32_t)
00848 GET_FEATURE_TYPE(F_DREAL, float64_t)
00849 GET_FEATURE_TYPE(F_LONGREAL, floatmax_t)
00850 #undef GET_FEATURE_TYPE
00851
00852 #define GET_FEATURE_NAME(f_name, sg_type) \
00853 template<> inline const char* CSimpleFeatures<sg_type>::get_name() const \
00854 { \
00855 return f_name; \
00856 }
00857
00858 GET_FEATURE_NAME("BoolFeatures", bool)
00859 GET_FEATURE_NAME("CharFeatures", char)
00860 GET_FEATURE_NAME("ByteFeatures", uint8_t)
00861 GET_FEATURE_NAME("ShortFeatures", int16_t)
00862 GET_FEATURE_NAME("WordFeatures", uint16_t)
00863 GET_FEATURE_NAME("IntFeatures", int32_t)
00864 GET_FEATURE_NAME("UIntFeatures", uint32_t)
00865 GET_FEATURE_NAME("LongIntFeatures", int64_t)
00866 GET_FEATURE_NAME("ULongIntFeatures", uint64_t)
00867 GET_FEATURE_NAME("ShortRealFeatures", float32_t)
00868 GET_FEATURE_NAME("RealFeatures", float64_t)
00869 GET_FEATURE_NAME("LongRealFeatures", floatmax_t)
00870 #undef GET_FEATURE_NAME
00871
00880 template<> inline bool CSimpleFeatures<float64_t>::Align_char_features(
00881 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00882 {
00883 ASSERT(cf);
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 return true;
00910 }
00911
00912 template<> inline float64_t CSimpleFeatures<bool>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00913 {
00914 ASSERT(vec2_len == num_features);
00915
00916 int32_t vlen;
00917 bool vfree;
00918 bool* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00919
00920 ASSERT(vlen == num_features);
00921 float64_t result=0;
00922
00923 for (int32_t i=0 ; i<num_features; i++)
00924 result+=vec1[i] ? vec2[i] : 0;
00925
00926 free_feature_vector(vec1, vec_idx1, vfree);
00927
00928 return result;
00929 }
00930
00931
00932 template<> inline float64_t CSimpleFeatures<char>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00933 {
00934 ASSERT(vec2_len == num_features);
00935
00936 int32_t vlen;
00937 bool vfree;
00938 char* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00939
00940 ASSERT(vlen == num_features);
00941 float64_t result=0;
00942
00943 for (int32_t i=0 ; i<num_features; i++)
00944 result+=vec1[i]*vec2[i];
00945
00946 free_feature_vector(vec1, vec_idx1, vfree);
00947
00948 return result;
00949 }
00950
00951 template<> inline float64_t CSimpleFeatures<uint8_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00952 {
00953 ASSERT(vec2_len == num_features);
00954
00955 int32_t vlen;
00956 bool vfree;
00957 uint8_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00958
00959 ASSERT(vlen == num_features);
00960 float64_t result=0;
00961
00962 for (int32_t i=0 ; i<num_features; i++)
00963 result+=vec1[i]*vec2[i];
00964
00965 free_feature_vector(vec1, vec_idx1, vfree);
00966
00967 return result;
00968 }
00969
00970 template<> inline float64_t CSimpleFeatures<int16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00971 {
00972 ASSERT(vec2_len == num_features);
00973
00974 int32_t vlen;
00975 bool vfree;
00976 int16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00977
00978 ASSERT(vlen == num_features);
00979 float64_t result=0;
00980
00981 for (int32_t i=0 ; i<num_features; i++)
00982 result+=vec1[i]*vec2[i];
00983
00984 free_feature_vector(vec1, vec_idx1, vfree);
00985
00986 return result;
00987 }
00988
00989
00990 template<> inline float64_t CSimpleFeatures<uint16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00991 {
00992 ASSERT(vec2_len == num_features);
00993
00994 int32_t vlen;
00995 bool vfree;
00996 uint16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00997
00998 ASSERT(vlen == num_features);
00999 float64_t result=0;
01000
01001 for (int32_t i=0 ; i<num_features; i++)
01002 result+=vec1[i]*vec2[i];
01003
01004 free_feature_vector(vec1, vec_idx1, vfree);
01005
01006 return result;
01007 }
01008
01009 template<> inline float64_t CSimpleFeatures<int32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01010 {
01011 ASSERT(vec2_len == num_features);
01012
01013 int32_t vlen;
01014 bool vfree;
01015 int32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01016
01017 ASSERT(vlen == num_features);
01018 float64_t result=0;
01019
01020 for (int32_t i=0 ; i<num_features; i++)
01021 result+=vec1[i]*vec2[i];
01022
01023 free_feature_vector(vec1, vec_idx1, vfree);
01024
01025 return result;
01026 }
01027
01028 template<> inline float64_t CSimpleFeatures<uint32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01029 {
01030 ASSERT(vec2_len == num_features);
01031
01032 int32_t vlen;
01033 bool vfree;
01034 uint32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01035
01036 ASSERT(vlen == num_features);
01037 float64_t result=0;
01038
01039 for (int32_t i=0 ; i<num_features; i++)
01040 result+=vec1[i]*vec2[i];
01041
01042 free_feature_vector(vec1, vec_idx1, vfree);
01043
01044 return result;
01045 }
01046
01047 template<> inline float64_t CSimpleFeatures<int64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01048 {
01049 ASSERT(vec2_len == num_features);
01050
01051 int32_t vlen;
01052 bool vfree;
01053 int64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01054
01055 ASSERT(vlen == num_features);
01056 float64_t result=0;
01057
01058 for (int32_t i=0 ; i<num_features; i++)
01059 result+=vec1[i]*vec2[i];
01060
01061 free_feature_vector(vec1, vec_idx1, vfree);
01062
01063 return result;
01064 }
01065
01066 template<> inline float64_t CSimpleFeatures<uint64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01067 {
01068 ASSERT(vec2_len == num_features);
01069
01070 int32_t vlen;
01071 bool vfree;
01072 uint64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01073
01074 ASSERT(vlen == num_features);
01075 float64_t result=0;
01076
01077 for (int32_t i=0 ; i<num_features; i++)
01078 result+=vec1[i]*vec2[i];
01079
01080 free_feature_vector(vec1, vec_idx1, vfree);
01081
01082 return result;
01083 }
01084
01085 template<> inline float64_t CSimpleFeatures<float32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01086 {
01087 ASSERT(vec2_len == num_features);
01088
01089 int32_t vlen;
01090 bool vfree;
01091 float32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01092
01093 ASSERT(vlen == num_features);
01094 float64_t result=0;
01095
01096 for (int32_t i=0 ; i<num_features; i++)
01097 result+=vec1[i]*vec2[i];
01098
01099 free_feature_vector(vec1, vec_idx1, vfree);
01100
01101 return result;
01102 }
01103
01104 template<> inline float64_t CSimpleFeatures<float64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01105 {
01106 ASSERT(vec2_len == num_features);
01107
01108 int32_t vlen;
01109 bool vfree;
01110 float64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01111
01112 ASSERT(vlen == num_features);
01113 float64_t result=CMath::dot(vec1, vec2, num_features);
01114
01115 free_feature_vector(vec1, vec_idx1, vfree);
01116
01117 return result;
01118 }
01119
01120 template<> inline float64_t CSimpleFeatures<floatmax_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01121 {
01122 ASSERT(vec2_len == num_features);
01123
01124 int32_t vlen;
01125 bool vfree;
01126 floatmax_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01127
01128 ASSERT(vlen == num_features);
01129 float64_t result=0;
01130
01131 for (int32_t i=0 ; i<num_features; i++)
01132 result+=vec1[i]*vec2[i];
01133
01134 free_feature_vector(vec1, vec_idx1, vfree);
01135
01136 return result;
01137 }
01138
01139 #define LOAD(f_load, sg_type) \
01140 template<> inline void CSimpleFeatures<sg_type>::load(CFile* loader) \
01141 { \
01142 ASSERT(loader); \
01143 sg_type* matrix; \
01144 int32_t num_feat; \
01145 int32_t num_vec; \
01146 loader->f_load(matrix, num_feat, num_vec); \
01147 set_feature_matrix(matrix, num_feat, num_vec); \
01148 }
01149
01150 LOAD(get_bool_matrix, bool)
01151 LOAD(get_char_matrix, char)
01152 LOAD(get_byte_matrix, uint8_t)
01153 LOAD(get_short_matrix, int16_t)
01154 LOAD(get_word_matrix, uint16_t)
01155 LOAD(get_int_matrix, int32_t)
01156 LOAD(get_uint_matrix, uint32_t)
01157 LOAD(get_long_matrix, int64_t)
01158 LOAD(get_ulong_matrix, uint64_t)
01159 LOAD(get_shortreal_matrix, float32_t)
01160 LOAD(get_real_matrix, float64_t)
01161 LOAD(get_longreal_matrix, floatmax_t)
01162 #undef LOAD
01163
01164 #define SAVE(f_write, sg_type) \
01165 template<> inline void CSimpleFeatures<sg_type>::save(CFile* writer) \
01166 { \
01167 ASSERT(writer); \
01168 writer->f_write(feature_matrix, num_features, num_vectors); \
01169 }
01170
01171 SAVE(set_bool_matrix, bool)
01172 SAVE(set_char_matrix, char)
01173 SAVE(set_byte_matrix, uint8_t)
01174 SAVE(set_short_matrix, int16_t)
01175 SAVE(set_word_matrix, uint16_t)
01176 SAVE(set_int_matrix, int32_t)
01177 SAVE(set_uint_matrix, uint32_t)
01178 SAVE(set_long_matrix, int64_t)
01179 SAVE(set_ulong_matrix, uint64_t)
01180 SAVE(set_shortreal_matrix, float32_t)
01181 SAVE(set_real_matrix, float64_t)
01182 SAVE(set_longreal_matrix, floatmax_t)
01183 #undef SAVE
01184
01185 #endif // DOXYGEN_SHOULD_SKIP_THIS
01186 }
01187 #endif // _SIMPLEFEATURES__H__