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 #include "base/Parameter.h"
00025
00026 #include <string.h>
00027
00028 namespace shogun
00029 {
00030 template <class ST> class CStringFeatures;
00031 template <class ST> class CSimpleFeatures;
00032 template <class ST> class CSimplePreProc;
00033 class CDotFeatures;
00034
00064 template <class ST> class CSimpleFeatures: public CDotFeatures
00065 {
00066 public:
00071 CSimpleFeatures(int32_t size=0)
00072 : CDotFeatures(size)
00073 {
00074 init();
00075 }
00076
00078 CSimpleFeatures(const CSimpleFeatures & orig)
00079 : CDotFeatures(orig)
00080 {
00081 copy_feature_matrix(orig.feature_matrix,
00082 orig.num_features, orig.num_vectors);
00083 initialize_cache();
00084 }
00085
00092 CSimpleFeatures(ST* src, int32_t num_feat, int32_t num_vec)
00093 : CDotFeatures()
00094 {
00095 init();
00096 copy_feature_matrix(src, num_feat, num_vec);
00097 }
00098
00103 CSimpleFeatures(CFile* loader)
00104 : CDotFeatures(loader)
00105 {
00106 init();
00107 load(loader);
00108 }
00109
00114 virtual CFeatures* duplicate() const
00115 {
00116 return new CSimpleFeatures<ST>(*this);
00117 }
00118
00119 virtual ~CSimpleFeatures()
00120 {
00121 free_features();
00122 }
00123
00127 void free_feature_matrix()
00128 {
00129 delete[] feature_matrix;
00130 feature_matrix = NULL;
00131 feature_matrix_num_features=num_features;
00132 feature_matrix_num_vectors=num_vectors;
00133 num_vectors=0;
00134 num_features=0;
00135 }
00136
00140 void free_features()
00141 {
00142 free_feature_matrix();
00143 SG_UNREF(feature_cache);
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*int64_t(num_features)];
00164 }
00165 else
00166 {
00167 ST* feat=NULL;
00168 dofree=false;
00169
00170 if (feature_cache)
00171 {
00172 feat=feature_cache->lock_entry(num);
00173
00174 if (feat)
00175 return feat;
00176 else
00177 {
00178 feat=feature_cache->set_entry(num);
00179 }
00180 }
00181
00182 if (!feat)
00183 dofree=true;
00184 feat=compute_feature_vector(num, len, feat);
00185
00186
00187 if (get_num_preproc())
00188 {
00189 int32_t tmp_len=len;
00190 ST* tmp_feat_before = feat;
00191 ST* tmp_feat_after = NULL;
00192
00193 for (int32_t i=0; i<get_num_preproc(); i++)
00194 {
00195 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00196 tmp_feat_after=p->apply_to_feature_vector(tmp_feat_before, tmp_len);
00197 SG_UNREF(p);
00198
00199 if (i!=0)
00200 delete[] tmp_feat_before;
00201 tmp_feat_before=tmp_feat_after;
00202 }
00203
00204 memcpy(feat, tmp_feat_after, sizeof(ST)*tmp_len);
00205 delete[] tmp_feat_after;
00206
00207 len=tmp_len ;
00208 }
00209 return feat ;
00210 }
00211 }
00212
00221 void set_feature_vector(ST* src, int32_t len, int32_t num)
00222 {
00223 if (num>=num_vectors)
00224 {
00225 SG_ERROR("Index out of bounds (number of vectors %d, you "
00226 "requested %d)\n", num_vectors, num);
00227 }
00228
00229 if (!feature_matrix)
00230 SG_ERROR("Requires a in-memory feature matrix\n");
00231
00232 if (len != num_features)
00233 SG_ERROR("Vector not of length %d (has %d)\n", num_features, len);
00234
00235 memcpy(&feature_matrix[num*int64_t(num_features)], src, int64_t(num_features)*sizeof(ST));
00236 }
00237
00244 void get_feature_vector(ST** dst, int32_t* len, int32_t num)
00245 {
00246 if (num>=num_vectors)
00247 {
00248 SG_ERROR("Index out of bounds (number of vectors %d, you "
00249 "requested %d)\n", num_vectors, num);
00250 }
00251
00252 int32_t vlen=0;
00253 bool free_vec;
00254
00255 ST* vec= get_feature_vector(num, vlen, free_vec);
00256
00257 *len=vlen;
00258 *dst=(ST*) malloc(vlen*sizeof(ST));
00259 memcpy(*dst, vec, vlen*sizeof(ST));
00260
00261 free_feature_vector(vec, num, free_vec);
00262 }
00263
00270 void free_feature_vector(ST* feat_vec, int32_t num, bool dofree)
00271 {
00272 if (feature_cache)
00273 feature_cache->unlock_entry(num);
00274
00275 if (dofree)
00276 delete[] feat_vec ;
00277 }
00278
00286 void get_feature_matrix(ST** dst, int32_t* num_feat, int32_t* num_vec)
00287 {
00288 ASSERT(feature_matrix);
00289
00290 int64_t num=int64_t(num_features)*num_vectors;
00291 *num_feat=num_features;
00292 *num_vec=num_vectors;
00293 *dst=(ST*) malloc(sizeof(ST)*num);
00294 if (!*dst)
00295 SG_ERROR("Allocating %ld bytes failes\n", sizeof(ST)*num);
00296 memcpy(*dst, feature_matrix, num * sizeof(ST));
00297 }
00298
00306 ST* get_feature_matrix(int32_t &num_feat, int32_t &num_vec)
00307 {
00308 num_feat=num_features;
00309 num_vec=num_vectors;
00310 return feature_matrix;
00311 }
00312
00317 CSimpleFeatures<ST>* get_transposed()
00318 {
00319 int32_t num_feat;
00320 int32_t num_vec;
00321 ST* fm=get_transposed(num_feat, num_vec);
00322
00323 return new CSimpleFeatures<ST>(fm, num_feat, num_vec);
00324 }
00325
00335 ST* get_transposed(int32_t &num_feat, int32_t &num_vec)
00336 {
00337 num_feat=num_vectors;
00338 num_vec=num_features;
00339
00340 ST* fm=new ST[int64_t(num_feat)*num_vec];
00341
00342 for (int32_t i=0; i<num_vectors; i++)
00343 {
00344 int32_t vlen;
00345 bool vfree;
00346 ST* vec=get_feature_vector(i, vlen, vfree);
00347
00348 for (int32_t j=0; j<vlen; j++)
00349 fm[j*int64_t(num_vectors)+i]=vec[j];
00350
00351 free_feature_vector(vec, i, vfree);
00352 }
00353
00354 return fm;
00355 }
00356
00367 virtual void set_feature_matrix(ST* fm, int32_t num_feat, int32_t num_vec)
00368 {
00369 free_feature_matrix();
00370 feature_matrix=fm;
00371 feature_matrix_num_features=num_feat;
00372 feature_matrix_num_vectors=num_vec;
00373
00374 num_features=num_feat;
00375 num_vectors=num_vec;
00376 initialize_cache();
00377 }
00378
00388 virtual void copy_feature_matrix(ST* src, int32_t num_feat, int32_t num_vec)
00389 {
00390 free_feature_matrix();
00391 feature_matrix=new ST[((int64_t) num_feat)*num_vec];
00392 feature_matrix_num_features=num_feat;
00393 feature_matrix_num_vectors=num_vec;
00394
00395 memcpy(feature_matrix, src, (sizeof(ST)*((int64_t) num_feat)*num_vec));
00396
00397 num_features=num_feat;
00398 num_vectors=num_vec;
00399 initialize_cache();
00400 }
00401
00406 void obtain_from_dot(CDotFeatures* df)
00407 {
00408 int32_t num_feat=df->get_dim_feature_space();
00409 int32_t num_vec=df->get_num_vectors();
00410
00411 ASSERT(num_feat>0 && num_vec>0);
00412
00413 free_feature_matrix();
00414 feature_matrix=new ST[((int64_t) num_feat)*num_vec];
00415 feature_matrix_num_features=num_feat;
00416 feature_matrix_num_vectors=num_vec;
00417
00418 for (int32_t i=0; i<num_vec; i++)
00419 {
00420 float64_t* dst;
00421 int32_t len;
00422 df->get_feature_vector(&dst, &len, i);
00423 ASSERT(num_feat==len);
00424
00425 for (int32_t j=0; j<num_feat; j++)
00426 feature_matrix[i*int64_t(num_feat)+j]=(ST) dst[j];
00427
00428 delete[] dst;
00429 }
00430 num_features=num_feat;
00431 num_vectors=num_vec;
00432 }
00433
00439 virtual bool apply_preproc(bool force_preprocessing=false)
00440 {
00441 SG_DEBUG( "force: %d\n", force_preprocessing);
00442
00443 if ( feature_matrix && get_num_preproc())
00444 {
00445
00446 for (int32_t i=0; i<get_num_preproc(); i++)
00447 {
00448 if ( (!is_preprocessed(i) || force_preprocessing) )
00449 {
00450 set_preprocessed(i);
00451 CSimplePreProc<ST>* p = (CSimplePreProc<ST>*) get_preproc(i);
00452 SG_INFO( "preprocessing using preproc %s\n", p->get_name());
00453 if (p->apply_to_feature_matrix(this) == NULL)
00454 {
00455 SG_UNREF(p);
00456 return false;
00457 }
00458 SG_UNREF(p);
00459 }
00460 }
00461 return true;
00462 }
00463 else
00464 {
00465 if (!feature_matrix)
00466 SG_ERROR( "no feature matrix\n");
00467
00468 if (!get_num_preproc())
00469 SG_ERROR( "no preprocessors available\n");
00470
00471 return false;
00472 }
00473 }
00474
00479 virtual int32_t get_size() { return sizeof(ST); }
00480
00481
00486 virtual inline int32_t get_num_vectors() { return num_vectors; }
00487
00492 inline int32_t get_num_features() { return num_features; }
00493
00498 inline void set_num_features(int32_t num)
00499 {
00500 num_features= num;
00501 initialize_cache();
00502 }
00503
00508 inline void set_num_vectors(int32_t num)
00509 {
00510 num_vectors= num;
00511 initialize_cache();
00512 }
00513
00514
00515 inline void initialize_cache()
00516 {
00517 if (num_features && num_vectors)
00518 {
00519 SG_UNREF(feature_cache);
00520 feature_cache= new CCache<ST>(get_cache_size(), num_features, num_vectors);
00521 SG_REF(feature_cache);
00522 }
00523 }
00524
00529 inline virtual EFeatureClass get_feature_class() { return C_SIMPLE; }
00530
00535 inline virtual EFeatureType get_feature_type();
00536
00543 virtual bool reshape(int32_t p_num_features, int32_t p_num_vectors)
00544 {
00545 if (p_num_features*p_num_vectors == this->num_features * this->num_vectors)
00546 {
00547 this->num_features=p_num_features;
00548 this->num_vectors=p_num_vectors;
00549 return true;
00550 }
00551 else
00552 return false;
00553 }
00554
00562 virtual int32_t get_dim_feature_space()
00563 {
00564 return num_features;
00565 }
00566
00574 virtual float64_t dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
00575 {
00576 ASSERT(df);
00577 ASSERT(df->get_feature_type() == get_feature_type());
00578 ASSERT(df->get_feature_class() == get_feature_class());
00579 CSimpleFeatures<ST>* sf=(CSimpleFeatures<ST>*) df;
00580
00581 int32_t len1, len2;
00582 bool free1, free2;
00583
00584 ST* vec1= get_feature_vector(vec_idx1, len1, free1);
00585 ST* vec2= sf->get_feature_vector(vec_idx2, len2, free2);
00586
00587 float64_t result=CMath::dot(vec1, vec2, len1);
00588
00589 free_feature_vector(vec1, vec_idx1, free1);
00590 sf->free_feature_vector(vec2, vec_idx2, free2);
00591
00592 return result;
00593 }
00594
00601 virtual float64_t dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len);
00602
00611 virtual void add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val=false)
00612 {
00613 ASSERT(vec2_len == num_features);
00614
00615 int32_t vlen;
00616 bool vfree;
00617 ST* vec1=get_feature_vector(vec_idx1, vlen, vfree);
00618
00619 ASSERT(vlen == num_features);
00620
00621 if (abs_val)
00622 {
00623 for (int32_t i=0; i<num_features; i++)
00624 vec2[i]+=alpha*CMath::abs(vec1[i]);
00625 }
00626 else
00627 {
00628 for (int32_t i=0; i<num_features; i++)
00629 vec2[i]+=alpha*vec1[i];
00630 }
00631
00632 free_feature_vector(vec1, vec_idx1, vfree);
00633 }
00634
00640 virtual inline int32_t get_nnz_features_for_vector(int32_t num)
00641 {
00642 return num_features;
00643 }
00644
00652 virtual inline bool Align_char_features(
00653 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00654 {
00655 return false;
00656 }
00657
00662 virtual inline void load(CFile* loader);
00663
00668 virtual inline void save(CFile* saver);
00669
00671 struct simple_feature_iterator
00672 {
00674 ST* vec;
00676 int32_t vidx;
00678 int32_t vlen;
00680 bool vfree;
00681
00683 int32_t index;
00684 };
00685
00695 virtual void* get_feature_iterator(int32_t vector_index)
00696 {
00697 if (vector_index>=num_vectors)
00698 {
00699 SG_ERROR("Index out of bounds (number of vectors %d, you "
00700 "requested %d)\n", num_vectors, vector_index);
00701 }
00702
00703 simple_feature_iterator* iterator=new simple_feature_iterator[1];
00704 iterator->vec= get_feature_vector(vector_index, iterator->vlen, iterator->vfree);
00705 iterator->vidx=vector_index;
00706 iterator->index=0;
00707 return iterator;
00708 }
00709
00720 virtual bool get_next_feature(int32_t& index, float64_t& value, void* iterator)
00721 {
00722 simple_feature_iterator* it=(simple_feature_iterator*) iterator;
00723 if (!it || it->index>=it->vlen)
00724 return false;
00725
00726 index=it->index++;
00727 value = (float64_t) it->vec[index];
00728
00729 return true;
00730 }
00731
00737 virtual void free_feature_iterator(void* iterator)
00738 {
00739 if (!iterator)
00740 return;
00741
00742 simple_feature_iterator* it=(simple_feature_iterator*) iterator;
00743 free_feature_vector(it->vec, it->vidx, it->vfree);
00744 delete[] it;
00745 }
00746
00748 inline virtual const char* get_name() const { return "SimpleFeatures"; }
00749
00750 protected:
00762 virtual ST* compute_feature_vector(int32_t num, int32_t& len, ST* target=NULL)
00763 {
00764 len=0;
00765 return NULL;
00766 }
00767
00768 private:
00769 void init()
00770 {
00771 num_vectors=0;
00772 num_features=0;
00773
00774 feature_matrix=NULL;
00775 feature_matrix_num_vectors=0;
00776 feature_matrix_num_features=0;
00777
00778 feature_cache=NULL;
00779
00780 set_generic<ST>();
00781 m_parameters->add(&num_vectors,
00782 "num_vectors", "Number of vectors.");
00783 m_parameters->add(&num_features,
00784 "num_features", "Number of features.");
00785 m_parameters->add_matrix(&feature_matrix,
00786 &feature_matrix_num_features, &feature_matrix_num_vectors,
00787 "feature_matrix", "Matrix of feature vectors / 1 vector per column.");
00788 }
00789
00790 protected:
00792 int32_t num_vectors;
00793
00795 int32_t num_features;
00796
00801 ST* feature_matrix;
00802 int32_t feature_matrix_num_vectors;
00803 int32_t feature_matrix_num_features;
00804
00806 CCache<ST>* feature_cache;
00807 };
00808
00809 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00810
00811 #define GET_FEATURE_TYPE(f_type, sg_type) \
00812 template<> inline EFeatureType CSimpleFeatures<sg_type>::get_feature_type() \
00813 { \
00814 return f_type; \
00815 }
00816
00817 GET_FEATURE_TYPE(F_BOOL, bool)
00818 GET_FEATURE_TYPE(F_CHAR, char)
00819 GET_FEATURE_TYPE(F_BYTE, uint8_t)
00820 GET_FEATURE_TYPE(F_BYTE, int8_t)
00821 GET_FEATURE_TYPE(F_SHORT, int16_t)
00822 GET_FEATURE_TYPE(F_WORD, uint16_t)
00823 GET_FEATURE_TYPE(F_INT, int32_t)
00824 GET_FEATURE_TYPE(F_UINT, uint32_t)
00825 GET_FEATURE_TYPE(F_LONG, int64_t)
00826 GET_FEATURE_TYPE(F_ULONG, uint64_t)
00827 GET_FEATURE_TYPE(F_SHORTREAL, float32_t)
00828 GET_FEATURE_TYPE(F_DREAL, float64_t)
00829 GET_FEATURE_TYPE(F_LONGREAL, floatmax_t)
00830 #undef GET_FEATURE_TYPE
00831
00840 template<> inline bool CSimpleFeatures<float64_t>::Align_char_features(
00841 CStringFeatures<char>* cf, CStringFeatures<char>* Ref, float64_t gapCost)
00842 {
00843 ASSERT(cf);
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 return true;
00870 }
00871
00872 template<> inline float64_t CSimpleFeatures<bool>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00873 {
00874 ASSERT(vec2_len == num_features);
00875
00876 int32_t vlen;
00877 bool vfree;
00878 bool* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00879
00880 ASSERT(vlen == num_features);
00881 float64_t result=0;
00882
00883 for (int32_t i=0 ; i<num_features; i++)
00884 result+=vec1[i] ? vec2[i] : 0;
00885
00886 free_feature_vector(vec1, vec_idx1, vfree);
00887
00888 return result;
00889 }
00890
00891
00892 template<> inline float64_t CSimpleFeatures<char>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00893 {
00894 ASSERT(vec2_len == num_features);
00895
00896 int32_t vlen;
00897 bool vfree;
00898 char* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00899
00900 ASSERT(vlen == num_features);
00901 float64_t result=0;
00902
00903 for (int32_t i=0 ; i<num_features; i++)
00904 result+=vec1[i]*vec2[i];
00905
00906 free_feature_vector(vec1, vec_idx1, vfree);
00907
00908 return result;
00909 }
00910
00911 template<> inline float64_t CSimpleFeatures<int8_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00912 {
00913 ASSERT(vec2_len == num_features);
00914
00915 int32_t vlen;
00916 bool vfree;
00917 int8_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00918
00919 ASSERT(vlen == num_features);
00920 float64_t result=0;
00921
00922 for (int32_t i=0 ; i<num_features; i++)
00923 result+=vec1[i]*vec2[i];
00924
00925 free_feature_vector(vec1, vec_idx1, vfree);
00926
00927 return result;
00928 }
00929
00930 template<> inline float64_t CSimpleFeatures<uint8_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00931 {
00932 ASSERT(vec2_len == num_features);
00933
00934 int32_t vlen;
00935 bool vfree;
00936 uint8_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00937
00938 ASSERT(vlen == num_features);
00939 float64_t result=0;
00940
00941 for (int32_t i=0 ; i<num_features; i++)
00942 result+=vec1[i]*vec2[i];
00943
00944 free_feature_vector(vec1, vec_idx1, vfree);
00945
00946 return result;
00947 }
00948
00949 template<> inline float64_t CSimpleFeatures<int16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00950 {
00951 ASSERT(vec2_len == num_features);
00952
00953 int32_t vlen;
00954 bool vfree;
00955 int16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00956
00957 ASSERT(vlen == num_features);
00958 float64_t result=0;
00959
00960 for (int32_t i=0 ; i<num_features; i++)
00961 result+=vec1[i]*vec2[i];
00962
00963 free_feature_vector(vec1, vec_idx1, vfree);
00964
00965 return result;
00966 }
00967
00968
00969 template<> inline float64_t CSimpleFeatures<uint16_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00970 {
00971 ASSERT(vec2_len == num_features);
00972
00973 int32_t vlen;
00974 bool vfree;
00975 uint16_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00976
00977 ASSERT(vlen == num_features);
00978 float64_t result=0;
00979
00980 for (int32_t i=0 ; i<num_features; i++)
00981 result+=vec1[i]*vec2[i];
00982
00983 free_feature_vector(vec1, vec_idx1, vfree);
00984
00985 return result;
00986 }
00987
00988 template<> inline float64_t CSimpleFeatures<int32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00989 {
00990 ASSERT(vec2_len == num_features);
00991
00992 int32_t vlen;
00993 bool vfree;
00994 int32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
00995
00996 ASSERT(vlen == num_features);
00997 float64_t result=0;
00998
00999 for (int32_t i=0 ; i<num_features; i++)
01000 result+=vec1[i]*vec2[i];
01001
01002 free_feature_vector(vec1, vec_idx1, vfree);
01003
01004 return result;
01005 }
01006
01007 template<> inline float64_t CSimpleFeatures<uint32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01008 {
01009 ASSERT(vec2_len == num_features);
01010
01011 int32_t vlen;
01012 bool vfree;
01013 uint32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01014
01015 ASSERT(vlen == num_features);
01016 float64_t result=0;
01017
01018 for (int32_t i=0 ; i<num_features; i++)
01019 result+=vec1[i]*vec2[i];
01020
01021 free_feature_vector(vec1, vec_idx1, vfree);
01022
01023 return result;
01024 }
01025
01026 template<> inline float64_t CSimpleFeatures<int64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01027 {
01028 ASSERT(vec2_len == num_features);
01029
01030 int32_t vlen;
01031 bool vfree;
01032 int64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01033
01034 ASSERT(vlen == num_features);
01035 float64_t result=0;
01036
01037 for (int32_t i=0 ; i<num_features; i++)
01038 result+=vec1[i]*vec2[i];
01039
01040 free_feature_vector(vec1, vec_idx1, vfree);
01041
01042 return result;
01043 }
01044
01045 template<> inline float64_t CSimpleFeatures<uint64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01046 {
01047 ASSERT(vec2_len == num_features);
01048
01049 int32_t vlen;
01050 bool vfree;
01051 uint64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01052
01053 ASSERT(vlen == num_features);
01054 float64_t result=0;
01055
01056 for (int32_t i=0 ; i<num_features; i++)
01057 result+=vec1[i]*vec2[i];
01058
01059 free_feature_vector(vec1, vec_idx1, vfree);
01060
01061 return result;
01062 }
01063
01064 template<> inline float64_t CSimpleFeatures<float32_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01065 {
01066 ASSERT(vec2_len == num_features);
01067
01068 int32_t vlen;
01069 bool vfree;
01070 float32_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01071
01072 ASSERT(vlen == num_features);
01073 float64_t result=0;
01074
01075 for (int32_t i=0 ; i<num_features; i++)
01076 result+=vec1[i]*vec2[i];
01077
01078 free_feature_vector(vec1, vec_idx1, vfree);
01079
01080 return result;
01081 }
01082
01083 template<> inline float64_t CSimpleFeatures<float64_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01084 {
01085 ASSERT(vec2_len == num_features);
01086
01087 int32_t vlen;
01088 bool vfree;
01089 float64_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01090
01091 ASSERT(vlen == num_features);
01092 float64_t result=CMath::dot(vec1, vec2, num_features);
01093
01094 free_feature_vector(vec1, vec_idx1, vfree);
01095
01096 return result;
01097 }
01098
01099 template<> inline float64_t CSimpleFeatures<floatmax_t>:: dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
01100 {
01101 ASSERT(vec2_len == num_features);
01102
01103 int32_t vlen;
01104 bool vfree;
01105 floatmax_t* vec1= get_feature_vector(vec_idx1, vlen, vfree);
01106
01107 ASSERT(vlen == num_features);
01108 float64_t result=0;
01109
01110 for (int32_t i=0 ; i<num_features; i++)
01111 result+=vec1[i]*vec2[i];
01112
01113 free_feature_vector(vec1, vec_idx1, vfree);
01114
01115 return result;
01116 }
01117
01118 #define LOAD(f_load, sg_type) \
01119 template<> inline void CSimpleFeatures<sg_type>::load(CFile* loader) \
01120 { \
01121 SG_SET_LOCALE_C; \
01122 ASSERT(loader); \
01123 sg_type* matrix; \
01124 int32_t num_feat; \
01125 int32_t num_vec; \
01126 loader->f_load(matrix, num_feat, num_vec); \
01127 set_feature_matrix(matrix, num_feat, num_vec); \
01128 SG_RESET_LOCALE; \
01129 }
01130
01131 LOAD(get_bool_matrix, bool)
01132 LOAD(get_char_matrix, char)
01133 LOAD(get_int8_matrix, int8_t)
01134 LOAD(get_byte_matrix, uint8_t)
01135 LOAD(get_short_matrix, int16_t)
01136 LOAD(get_word_matrix, uint16_t)
01137 LOAD(get_int_matrix, int32_t)
01138 LOAD(get_uint_matrix, uint32_t)
01139 LOAD(get_long_matrix, int64_t)
01140 LOAD(get_ulong_matrix, uint64_t)
01141 LOAD(get_shortreal_matrix, float32_t)
01142 LOAD(get_real_matrix, float64_t)
01143 LOAD(get_longreal_matrix, floatmax_t)
01144 #undef LOAD
01145
01146 #define SAVE(f_write, sg_type) \
01147 template<> inline void CSimpleFeatures<sg_type>::save(CFile* writer) \
01148 { \
01149 SG_SET_LOCALE_C; \
01150 ASSERT(writer); \
01151 writer->f_write(feature_matrix, num_features, num_vectors); \
01152 SG_RESET_LOCALE; \
01153 }
01154
01155 SAVE(set_bool_matrix, bool)
01156 SAVE(set_char_matrix, char)
01157 SAVE(set_int8_matrix, int8_t)
01158 SAVE(set_byte_matrix, uint8_t)
01159 SAVE(set_short_matrix, int16_t)
01160 SAVE(set_word_matrix, uint16_t)
01161 SAVE(set_int_matrix, int32_t)
01162 SAVE(set_uint_matrix, uint32_t)
01163 SAVE(set_long_matrix, int64_t)
01164 SAVE(set_ulong_matrix, uint64_t)
01165 SAVE(set_shortreal_matrix, float32_t)
01166 SAVE(set_real_matrix, float64_t)
01167 SAVE(set_longreal_matrix, floatmax_t)
01168 #undef SAVE
01169
01170 #endif // DOXYGEN_SHOULD_SKIP_THIS
01171 }
01172 #endif // _SIMPLEFEATURES__H__