00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _SIMPLEFEATURES__H__
00013 #define _SIMPLEFEATURES__H__
00014
00015 #include "lib/common.h"
00016 #include "lib/Mathematics.h"
00017 #include "lib/io.h"
00018 #include "lib/Cache.h"
00019 #include "lib/File.h"
00020 #include "preproc/SimplePreProc.h"
00021 #include "features/DotFeatures.h"
00022 #include "features/StringFeatures.h"
00023
00024 #include <string.h>
00025
00026 namespace shogun
00027 {
00028 template <class ST> class CStringFeatures;
00029 template <class ST> class CSimpleFeatures;
00030 template <class ST> class CSimplePreProc;
00031
00061 template <class ST> class CSimpleFeatures: public CDotFeatures
00062 {
00063 public:
00068 CSimpleFeatures(int32_t size=0)
00069 : CDotFeatures(size), num_vectors(0), num_features(0),
00070 feature_matrix(NULL), feature_cache(NULL) {}
00071
00073 CSimpleFeatures(const CSimpleFeatures & orig)
00074 : CDotFeatures(orig), num_vectors(orig.num_vectors),
00075 num_features(orig.num_features),
00076 feature_matrix(orig.feature_matrix),
00077 feature_cache(orig.feature_cache)
00078 {
00079 if (orig.feature_matrix)
00080 {
00081 free_feature_matrix();
00082 feature_matrix=new ST(num_vectors*num_features);
00083 memcpy(feature_matrix, orig.feature_matrix, sizeof(float64_t)*num_vectors*num_features);
00084 }
00085 }
00086
00093 CSimpleFeatures(ST* src, int32_t num_feat, int32_t num_vec)
00094 : CDotFeatures(0), num_vectors(0), num_features(0),
00095 feature_matrix(NULL), feature_cache(NULL)
00096 {
00097 copy_feature_matrix(src, num_feat, num_vec);
00098 }
00099
00106 CSimpleFeatures(char* fname)
00107 : CDotFeatures(fname), num_vectors(0), num_features(0),
00108 feature_matrix(NULL), feature_cache(NULL) {}
00109
00114 virtual CFeatures* duplicate() const
00115 {
00116 return new CSimpleFeatures<ST>(*this);
00117 }
00118
00119 virtual ~CSimpleFeatures()
00120 {
00121 SG_DEBUG("deleting simplefeatures (0x%p)\n", this);
00122 free_features();
00123 }
00124
00128 void free_feature_matrix()
00129 {
00130 delete[] feature_matrix;
00131 feature_matrix = NULL;
00132 num_vectors=0;
00133 num_features=0;
00134 }
00135
00139 void free_features()
00140 {
00141 free_feature_matrix();
00142 delete feature_cache;
00143 feature_cache = NULL;
00144 }
00145
00156 ST* get_feature_vector(int32_t num, int32_t& len, bool& dofree)
00157 {
00158 len=num_features;
00159
00160 if (feature_matrix)
00161 {
00162 dofree=false;
00163 return &feature_matrix[num*num_features];
00164 }
00165 else
00166 {
00167 SG_DEBUG( "compute feature!!!\n") ;
00168
00169 ST* feat=NULL;
00170 dofree=false;
00171
00172 if (feature_cache)
00173 {
00174 feat=feature_cache->lock_entry(num);
00175
00176 if (feat)
00177 return feat;
00178 else
00179 {
00180 feat=feature_cache->set_entry(num);
00181 }
00182 }
00183
00184 if (!feat)
00185 dofree=true;
00186 feat=compute_feature_vector(num, len, feat);
00187
00188
00189 if (get_num_preproc())
00190 {
00191 int32_t tmp_len=len;
00192 ST* tmp_feat_before = feat;
00193 ST* tmp_feat_after = NULL;
00194
00195 for (int32_t i=0; i<get_num_preproc(); i++)
00196 {
00197 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00198 tmp_feat_after=p->apply_to_feature_vector(tmp_feat_before, tmp_len);
00199 SG_UNREF(p);
00200
00201 if (i!=0)
00202 delete[] tmp_feat_before;
00203 tmp_feat_before=tmp_feat_after;
00204 }
00205
00206 memcpy(feat, tmp_feat_after, sizeof(ST)*tmp_len);
00207 delete[] tmp_feat_after;
00208
00209 len=tmp_len ;
00210 SG_DEBUG( "len: %d len2: %d\n", len, num_features);
00211 }
00212 return feat ;
00213 }
00214 }
00215
00224 void set_feature_vector(ST* src, int32_t len, int32_t num)
00225 {
00226 if (num>=num_vectors)
00227 {
00228 SG_ERROR("Index out of bounds (number of vectors %d, you "
00229 "requested %d)\n", num_vectors, num);
00230 }
00231
00232 if (!feature_matrix)
00233 SG_ERROR("Requires a in-memory feature matrix\n");
00234
00235 if (len != num_features)
00236 SG_ERROR("Vector not of length %d (has %d)\n", num_features, len);
00237
00238 memcpy(&feature_matrix[num*num_features], src, num_features*sizeof(ST));
00239 }
00240
00247 void get_feature_vector(ST** dst, int32_t* len, int32_t num)
00248 {
00249 if (num>=num_vectors)
00250 {
00251 SG_ERROR("Index out of bounds (number of vectors %d, you "
00252 "requested %d)\n", num_vectors, num);
00253 }
00254
00255 int32_t vlen=0;
00256 bool free_vec;
00257
00258 ST* vec= get_feature_vector(num, vlen, free_vec);
00259
00260 *len=vlen;
00261 *dst=(ST*) malloc(vlen*sizeof(ST));
00262 memcpy(*dst, vec, vlen*sizeof(ST));
00263
00264 free_feature_vector(vec, num, free_vec);
00265 }
00266
00273 void free_feature_vector(ST* feat_vec, int32_t num, bool dofree)
00274 {
00275 if (feature_cache)
00276 feature_cache->unlock_entry(num);
00277
00278 if (dofree)
00279 delete[] feat_vec ;
00280 }
00281
00289 void get_feature_matrix(ST** dst, int32_t* num_feat, int32_t* num_vec)
00290 {
00291 ASSERT(feature_matrix);
00292
00293 int64_t num=num_features*num_vectors;
00294 *num_feat=num_features;
00295 *num_vec=num_vectors;
00296 *dst=(ST*) malloc(sizeof(ST)*num);
00297 memcpy(*dst, feature_matrix, num * sizeof(ST));
00298 }
00299
00307 ST* get_feature_matrix(int32_t &num_feat, int32_t &num_vec)
00308 {
00309 num_feat=num_features;
00310 num_vec=num_vectors;
00311 return feature_matrix;
00312 }
00313
00324 virtual void set_feature_matrix(ST* fm, int32_t num_feat, int32_t num_vec)
00325 {
00326 free_feature_matrix();
00327 feature_matrix=fm;
00328 num_features=num_feat;
00329 num_vectors=num_vec;
00330 }
00331
00341 virtual void copy_feature_matrix(ST* src, int32_t num_feat, int32_t num_vec)
00342 {
00343 free_feature_matrix();
00344 feature_matrix=new ST[((int64_t) num_feat)*num_vec];
00345 memcpy(feature_matrix, src, (sizeof(ST)*((int64_t) num_feat)*num_vec));
00346
00347 num_features=num_feat;
00348 num_vectors=num_vec;
00349 }
00350
00356 virtual bool apply_preproc(bool force_preprocessing=false)
00357 {
00358 SG_DEBUG( "force: %d\n", force_preprocessing);
00359
00360 if ( feature_matrix && get_num_preproc())
00361 {
00362
00363 for (int32_t i=0; i<get_num_preproc(); i++)
00364 {
00365 if ( (!is_preprocessed(i) || force_preprocessing) )
00366 {
00367 set_preprocessed(i);
00368 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00369 SG_INFO( "preprocessing using preproc %s\n", p->get_name());
00370 if (p->apply_to_feature_matrix(this) == NULL)
00371 {
00372 SG_UNREF(p);
00373 return false;
00374 }
00375 SG_UNREF(p);
00376 }
00377 }
00378 return true;
00379 }
00380 else
00381 {
00382 if (!feature_matrix)
00383 SG_ERROR( "no feature matrix\n");
00384
00385 if (!get_num_preproc())
00386 SG_ERROR( "no preprocessors available\n");
00387
00388 return false;
00389 }
00390 }
00391
00396 virtual int32_t get_size() { return sizeof(ST); }
00397
00398
00403 virtual inline int32_t get_num_vectors() { return num_vectors; }
00404
00409 inline int32_t get_num_features() { return num_features; }
00410
00415 inline void set_num_features(int32_t num)
00416 {
00417 num_features= num;
00418
00419 if (num_features && num_vectors)
00420 {
00421 delete feature_cache;
00422 feature_cache= new CCache<ST>(get_cache_size(), num_features, num_vectors);
00423 }
00424 }
00425
00430 inline void set_num_vectors(int32_t num)
00431 {
00432 num_vectors= num;
00433 if (num_features && num_vectors)
00434 {
00435 delete feature_cache;
00436 feature_cache= new CCache<ST>(get_cache_size(), num_features, num_vectors);
00437 }
00438 }
00439
00444 inline virtual EFeatureClass get_feature_class() { return C_SIMPLE; }
00445
00450 inline virtual EFeatureType get_feature_type();
00451
00458 virtual bool reshape(int32_t p_num_features, int32_t p_num_vectors)
00459 {
00460 if (p_num_features*p_num_vectors == this->num_features * this->num_vectors)
00461 {
00462 this->num_features=p_num_features;
00463 this->num_vectors=p_num_vectors;
00464 return true;
00465 }
00466 else
00467 return false;
00468 }
00469
00477 virtual int32_t get_dim_feature_space()
00478 {
00479 return num_features;
00480 }
00481
00488 virtual float64_t dot(int32_t vec_idx1, int32_t vec_idx2)
00489 {
00490 int32_t len1, len2;
00491 bool free1, free2;
00492
00493 ST* vec1= get_feature_vector(vec_idx1, len1, free1);
00494 ST* vec2= get_feature_vector(vec_idx2, len2, free2);
00495
00496 float64_t result=CMath::dot(vec1, vec2, len1);
00497
00498 free_feature_vector(vec1, vec_idx1, free1);
00499 free_feature_vector(vec2, vec_idx2, free2);
00500
00501 return result;
00502 }
00503
00510 virtual float64_t dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len);
00511
00520 virtual void add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val=false)
00521 {
00522 ASSERT(vec2_len == num_features);
00523
00524 int32_t vlen;
00525 bool vfree;
00526 ST* vec1=get_feature_vector(vec_idx1, vlen, vfree);
00527
00528 ASSERT(vlen == num_features);
00529
00530 if (abs_val)
00531 {
00532 for (int32_t i=0; i<num_features; i++)
00533 vec2[i]+=alpha*CMath::abs(vec1[i]);
00534 }
00535 else
00536 {
00537 for (int32_t i=0; i<num_features; i++)
00538 vec2[i]+=alpha*vec1[i];
00539 }
00540
00541 free_feature_vector(vec1, vec_idx1, vfree);
00542 }
00543
00549 virtual inline int32_t get_nnz_features_for_vector(int32_t num)
00550 {
00551 return num_features;
00552 }
00553
00561 virtual inline bool Align_char_features(
00562 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00563 {
00564 return false;
00565 }
00566
00572 virtual bool load(char* fname)
00573 {
00574 bool status=false;
00575 num_vectors=1;
00576 num_features=0;
00577 CFile f(fname, 'r', get_feature_type());
00578 int64_t numf=0;
00579 free_feature_matrix();
00580 feature_matrix=f.load_data<ST>(NULL, numf);
00581 num_features=numf;
00582
00583 if (!f.is_ok())
00584 SG_ERROR( "loading file \"%s\" failed", fname);
00585 else
00586 status=true;
00587
00588 return status;
00589 }
00590
00596 virtual bool save(char* fname)
00597 {
00598 int32_t len;
00599 bool free;
00600 ST* fv;
00601
00602 CFile f(fname, 'w', get_feature_type());
00603
00604 for (int32_t i=0; i< (int32_t) num_vectors && f.is_ok(); i++)
00605 {
00606 if (!(i % (num_vectors/10+1)))
00607 SG_PRINT( "%02d%%.", (int) (100.0*i/num_vectors));
00608 else if (!(i % (num_vectors/200+1)))
00609 SG_PRINT( ".");
00610
00611 fv=get_feature_vector(i, len, free);
00612 f.save_data<ST>(fv, len);
00613 free_feature_vector(fv, i, free) ;
00614 }
00615
00616 if (f.is_ok())
00617 SG_INFO( "%d vectors with %d features each successfully written (filesize: %ld)\n", num_vectors, num_features, num_vectors*num_features*sizeof(float64_t));
00618
00619 return true;
00620 }
00621
00623 inline virtual const char* get_name() const { return "SimpleFeatures"; }
00624
00625
00626 #ifdef HAVE_BOOST_SERIALIZATION
00627 private:
00628
00632 friend class ::boost::serialization::access;
00633 template<class Archive>
00634 void save(Archive & ar, const unsigned int archive_version) const
00635 {
00636
00637 SG_DEBUG("archiving SimpleFeatures\n");
00638
00639 ar & ::boost::serialization::base_object<CDotFeatures>(*this);
00640
00641
00642
00643
00644 ar & num_vectors;
00645 ar & num_features;
00646
00647 for (int i=0; i < num_vectors*num_features; ++i)
00648 {
00649 ar & feature_matrix[i];
00650 }
00651
00652 SG_DEBUG("done SimpleFeatures\n");
00653
00654
00655 }
00656
00657 template<class Archive>
00658 void load(Archive & ar, const unsigned int archive_version)
00659 {
00660
00661 SG_DEBUG("archiving SimpleFeatures\n");
00662
00663 ar & ::boost::serialization::base_object<CDotFeatures>(*this);
00664
00665
00666
00667
00668 ar & num_vectors;
00669 ar & num_features;
00670
00671 feature_matrix = new ST[num_vectors*num_features];
00672 for (int i=0; i< num_vectors*num_features; ++i){
00673 ar & feature_matrix[i];
00674 }
00675
00676
00677 SG_DEBUG("done SimpleFeatures\n");
00678
00679 }
00680
00681 GLOBAL_BOOST_SERIALIZATION_SPLIT_MEMBER();
00682
00683 #endif //HAVE_BOOST_SERIALIZATION
00684
00685
00686 protected:
00698 virtual ST* compute_feature_vector(int32_t num, int32_t& len, ST* target=NULL)
00699 {
00700 len=0;
00701 return NULL;
00702 }
00703
00705 int32_t num_vectors;
00706
00708 int32_t num_features;
00709
00711 ST* feature_matrix;
00712
00714 CCache<ST>* feature_cache;
00715 };
00716
00717 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00718
00722 template<> inline EFeatureType CSimpleFeatures<bool>::get_feature_type()
00723 {
00724 return F_BOOL;
00725 }
00726
00731 template<> inline EFeatureType CSimpleFeatures<char>::get_feature_type()
00732 {
00733 return F_CHAR;
00734 }
00735
00740 template<> inline EFeatureType CSimpleFeatures<uint8_t>::get_feature_type()
00741 {
00742 return F_BYTE;
00743 }
00744
00749 template<> inline EFeatureType CSimpleFeatures<int16_t>::get_feature_type()
00750 {
00751 return F_SHORT;
00752 }
00753
00758 template<> inline EFeatureType CSimpleFeatures<uint16_t>::get_feature_type()
00759 {
00760 return F_WORD;
00761 }
00762
00763
00768 template<> inline EFeatureType CSimpleFeatures<int32_t>::get_feature_type()
00769 {
00770 return F_INT;
00771 }
00772
00777 template<> inline EFeatureType CSimpleFeatures<uint32_t>::get_feature_type()
00778 {
00779 return F_UINT;
00780 }
00781
00786 template<> inline EFeatureType CSimpleFeatures<int64_t>::get_feature_type()
00787 {
00788 return F_LONG;
00789 }
00790
00795 template<> inline EFeatureType CSimpleFeatures<uint64_t>::get_feature_type()
00796 {
00797 return F_ULONG;
00798 }
00799
00804 template<> inline EFeatureType CSimpleFeatures<float32_t>::get_feature_type()
00805 {
00806 return F_SHORTREAL;
00807 }
00808
00813 template<> inline EFeatureType CSimpleFeatures<float64_t>::get_feature_type()
00814 {
00815 return F_DREAL;
00816 }
00817
00822 template<> inline EFeatureType CSimpleFeatures<floatmax_t>::get_feature_type()
00823 {
00824 return F_LONGREAL;
00825 }
00826
00828 template<> inline const char* CSimpleFeatures<bool>::get_name() const
00829 {
00830 return "BoolFeatures";
00831 }
00832
00834 template<> inline const char* CSimpleFeatures<char>::get_name() const
00835 {
00836 return "CharFeatures";
00837 }
00838
00840 template<> inline const char* CSimpleFeatures<uint8_t>::get_name() const
00841 {
00842 return "ByteFeatures";
00843 }
00844
00846 template<> inline const char* CSimpleFeatures<int16_t>::get_name() const
00847 {
00848 return "ShortFeatures";
00849 }
00850
00852 template<> inline const char* CSimpleFeatures<uint16_t>::get_name() const
00853 {
00854 return "WordFeatures";
00855 }
00856
00858 template<> inline const char* CSimpleFeatures<int32_t>::get_name() const
00859 {
00860 return "IntFeatures";
00861 }
00862
00864 template<> inline const char* CSimpleFeatures<uint32_t>::get_name() const
00865 {
00866 return "UIntFeatures";
00867 }
00868
00870 template<> inline const char* CSimpleFeatures<int64_t>::get_name() const
00871 {
00872 return "LongIntFeatures";
00873 }
00874
00876 template<> inline const char* CSimpleFeatures<uint64_t>::get_name() const
00877 {
00878 return "ULongIntFeatures";
00879 }
00880
00882 template<> inline const char* CSimpleFeatures<float32_t>::get_name() const
00883 {
00884 return "ShortRealFeatures";
00885 }
00886
00888 template<> inline const char* CSimpleFeatures<float64_t>::get_name() const
00889 {
00890 return "RealFeatures";
00891 }
00892
00894 template<> inline const char* CSimpleFeatures<floatmax_t>::get_name() const
00895 {
00896 return "LongRealFeatures";
00897 }
00898
00907 template<> inline bool CSimpleFeatures<float64_t>::Align_char_features(
00908 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00909 {
00910 ASSERT(cf);
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 return true;
00937 }
00938
00939 template<> inline float64_t CSimpleFeatures<bool>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00940 {
00941 ASSERT(vec2_len == num_features);
00942
00943 int32_t vlen;
00944 bool vfree;
00945 bool* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00946
00947 ASSERT(vlen == num_features);
00948 float64_t result=0;
00949
00950 for (int32_t i=0 ; i<num_features; i++)
00951 result+=vec1[i] ? vec2[i] : 0;
00952
00953 free_feature_vector(vec1, vec_idx1, vfree);
00954
00955 return result;
00956 }
00957
00958
00959 template<> inline float64_t CSimpleFeatures<char>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00960 {
00961 ASSERT(vec2_len == num_features);
00962
00963 int32_t vlen;
00964 bool vfree;
00965 char* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00966
00967 ASSERT(vlen == num_features);
00968 float64_t result=0;
00969
00970 for (int32_t i=0 ; i<num_features; i++)
00971 result+=vec1[i]*vec2[i];
00972
00973 free_feature_vector(vec1, vec_idx1, vfree);
00974
00975 return result;
00976 }
00977
00978 template<> inline float64_t CSimpleFeatures<uint8_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00979 {
00980 ASSERT(vec2_len == num_features);
00981
00982 int32_t vlen;
00983 bool vfree;
00984 uint8_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00985
00986 ASSERT(vlen == num_features);
00987 float64_t result=0;
00988
00989 for (int32_t i=0 ; i<num_features; i++)
00990 result+=vec1[i]*vec2[i];
00991
00992 free_feature_vector(vec1, vec_idx1, vfree);
00993
00994 return result;
00995 }
00996
00997 template<> inline float64_t CSimpleFeatures<int16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00998 {
00999 ASSERT(vec2_len == num_features);
01000
01001 int32_t vlen;
01002 bool vfree;
01003 int16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01004
01005 ASSERT(vlen == num_features);
01006 float64_t result=0;
01007
01008 for (int32_t i=0 ; i<num_features; i++)
01009 result+=vec1[i]*vec2[i];
01010
01011 free_feature_vector(vec1, vec_idx1, vfree);
01012
01013 return result;
01014 }
01015
01016
01017 template<> inline float64_t CSimpleFeatures<uint16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01018 {
01019 ASSERT(vec2_len == num_features);
01020
01021 int32_t vlen;
01022 bool vfree;
01023 uint16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01024
01025 ASSERT(vlen == num_features);
01026 float64_t result=0;
01027
01028 for (int32_t i=0 ; i<num_features; i++)
01029 result+=vec1[i]*vec2[i];
01030
01031 free_feature_vector(vec1, vec_idx1, vfree);
01032
01033 return result;
01034 }
01035
01036 template<> inline float64_t CSimpleFeatures<int32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01037 {
01038 ASSERT(vec2_len == num_features);
01039
01040 int32_t vlen;
01041 bool vfree;
01042 int32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01043
01044 ASSERT(vlen == num_features);
01045 float64_t result=0;
01046
01047 for (int32_t i=0 ; i<num_features; i++)
01048 result+=vec1[i]*vec2[i];
01049
01050 free_feature_vector(vec1, vec_idx1, vfree);
01051
01052 return result;
01053 }
01054
01055 template<> inline float64_t CSimpleFeatures<uint32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01056 {
01057 ASSERT(vec2_len == num_features);
01058
01059 int32_t vlen;
01060 bool vfree;
01061 uint32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01062
01063 ASSERT(vlen == num_features);
01064 float64_t result=0;
01065
01066 for (int32_t i=0 ; i<num_features; i++)
01067 result+=vec1[i]*vec2[i];
01068
01069 free_feature_vector(vec1, vec_idx1, vfree);
01070
01071 return result;
01072 }
01073
01074 template<> inline float64_t CSimpleFeatures<int64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01075 {
01076 ASSERT(vec2_len == num_features);
01077
01078 int32_t vlen;
01079 bool vfree;
01080 int64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01081
01082 ASSERT(vlen == num_features);
01083 float64_t result=0;
01084
01085 for (int32_t i=0 ; i<num_features; i++)
01086 result+=vec1[i]*vec2[i];
01087
01088 free_feature_vector(vec1, vec_idx1, vfree);
01089
01090 return result;
01091 }
01092
01093 template<> inline float64_t CSimpleFeatures<uint64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01094 {
01095 ASSERT(vec2_len == num_features);
01096
01097 int32_t vlen;
01098 bool vfree;
01099 uint64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01100
01101 ASSERT(vlen == num_features);
01102 float64_t result=0;
01103
01104 for (int32_t i=0 ; i<num_features; i++)
01105 result+=vec1[i]*vec2[i];
01106
01107 free_feature_vector(vec1, vec_idx1, vfree);
01108
01109 return result;
01110 }
01111
01112 template<> inline float64_t CSimpleFeatures<float32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01113 {
01114 ASSERT(vec2_len == num_features);
01115
01116 int32_t vlen;
01117 bool vfree;
01118 float32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01119
01120 ASSERT(vlen == num_features);
01121 float64_t result=0;
01122
01123 for (int32_t i=0 ; i<num_features; i++)
01124 result+=vec1[i]*vec2[i];
01125
01126 free_feature_vector(vec1, vec_idx1, vfree);
01127
01128 return result;
01129 }
01130
01131 template<> inline float64_t CSimpleFeatures<float64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01132 {
01133 ASSERT(vec2_len == num_features);
01134
01135 int32_t vlen;
01136 bool vfree;
01137 float64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01138
01139 ASSERT(vlen == num_features);
01140 float64_t result=CMath::dot(vec1, vec2, num_features);
01141
01142 free_feature_vector(vec1, vec_idx1, vfree);
01143
01144 return result;
01145 }
01146
01147 template<> inline float64_t CSimpleFeatures<floatmax_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01148 {
01149 ASSERT(vec2_len == num_features);
01150
01151 int32_t vlen;
01152 bool vfree;
01153 floatmax_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01154
01155 ASSERT(vlen == num_features);
01156 float64_t result=0;
01157
01158 for (int32_t i=0 ; i<num_features; i++)
01159 result+=vec1[i]*vec2[i];
01160
01161 free_feature_vector(vec1, vec_idx1, vfree);
01162
01163 return result;
01164 }
01165 #endif // DOXYGEN_SHOULD_SKIP_THIS
01166 }
01167 #endif // _SIMPLEFEATURES__H__