/** * @file FullVector.cpp * @brief non sparse vector * @author Erik Rodner * @date 05/11/2008 */ #include #include #include #include #include #include #include "vislearning/math/mathbase/FullVector.h" #include #include "core/basics/StringTools.h" // whether to throw a exception when we divide by zero #undef FULLVECTOR_THROW_NORMALIZATION_EXCEPTION using namespace OBJREC; using namespace NICE; using namespace std; FullVector::FullVector ( const map & mymap ) { length = 0; for ( map::const_iterator i = mymap.begin(); i != mymap.end(); i++ ) { int k = i->first; if ( k+1 > length ) length = k+1; } data = new double[length]; memset ( (void *)data, 0, sizeof(double)*length ); for ( map::const_iterator i = mymap.begin(); i != mymap.end(); i++ ) { int k = i->first; double v = i->second; data[k] = v; } } FullVector::FullVector ( const map & mymap ) { length = 0; for ( map::const_iterator i = mymap.begin(); i != mymap.end(); i++ ) { int k = (int)i->first; if ( k+1 > length ) length = k+1; } data = new double[length]; memset ( (void *)data, 0, sizeof(double)*length ); for ( map::const_iterator i = mymap.begin(); i != mymap.end(); i++ ) { int k = i->first; double v = i->second; data[k] = v; } } FullVector::FullVector ( const FullVector & v ) { length = v.length; if ( length == 0 ) data = NULL; else { data = new double[length]; memset ( (void *)data, 0, sizeof(double)*length ); for ( int i = 0 ; i < length ; i++ ) data[i] = v.data[i]; } } FullVector::FullVector () { length = 0; data = NULL; } FullVector::FullVector (int _length) { length = _length; if ( length > 0 ) { data = new double[length]; memset ( (void *)data, 0, sizeof(double)*length ); } else { data = NULL; } } FullVector::~FullVector () { if ( data != NULL ) delete [] data; } void FullVector::set ( double val ) { for ( int i = 0 ; i < length ; i++ ) data[i] = val; } void FullVector::reinit ( int _length ) { if ( data != NULL ) { delete [] data; } length = _length; data = new double [ length ]; memset ( (void *)data, 0, sizeof(double)*length ); } void FullVector::add ( const FullVector & v ) { add ( v, 1.0 ); } double & FullVector::operator[] (int i) { assert ( i < length ); return data[i]; } const double & FullVector::operator[] (int i) const { assert ( i < length ); return data[i]; } void FullVector::add ( const FullVector & v, double lambda ) { assert ( v.length >= length ); for ( int i = 0 ; i < v.length ; i++ ) data[i] += v.data[i] * lambda; } void FullVector::add ( double beta ) { for ( int i = 0 ; i < length; i++ ) data[i] += beta; } void FullVector::divide ( const FullVector & v ) { assert ( v.length >= length ); for ( int i = 0 ; i < length ; i++ ) { if ( fabs(data[i]) < 10e-11 ) continue; double value = v.data[i]; if ( fabs(value) < 10e-11 ) { fprintf (stderr, "FullVector::divide: Division by Zero !\n"); exit(-1); } else { data[i] /= value; } } } void FullVector::multiply ( const FullVector & v ) { assert ( v.length >= length ); for ( int i = 0 ; i < length ; i++ ) { data[i] *= v.data[i]; } } void FullVector::multiply ( double val ) { for ( int i = 0 ; i < length ; i++ ) data[i] *= val; } void FullVector::restore (istream & is, int format) { std::string tag; is >> tag; if ( tag != "SVECTOR" ) { fprintf (stderr, "FullVector: format error !\n"); } const int bufsize = 1024*1024; char *buf = new char[bufsize]; std::string buf_s; vector elements; vector pair; elements.clear(); is.get ( buf, bufsize ); buf_s = buf; if ( buf_s.size() <= 0 ) return; StringTools::split ( buf_s, ' ', elements ); if ( elements.size() <= 1 ) return; reinit(elements.size()-1); size_t l = 0; // skip first element because of white space for ( vector::const_iterator i = elements.begin()+1; i != elements.end(); i++, l++ ) { pair.clear(); StringTools::split ( *i, ':', pair ); if ( pair.size() == 2 ) { double val = atof ( pair[1].c_str() ); (*this)[l] = val; } } delete [] buf; } void FullVector::store (ostream & os, int format) const { os << "SVECTOR "; for ( int i = 0 ; i < length ; i++ ) { os << i << ":" << data[i] << " "; } os << "END" << endl; } void FullVector::clear () { if ( length != 0 ) memset ( data, 0x0, sizeof(double)*length ); } double FullVector::sum () const { double sumv = 0.0; for ( int i = 0 ; i < length ; i++ ) sumv += data[i]; return sumv; } void FullVector::normalize () { double sum = 0; for ( int i = 0 ; i < length ; i++ ) sum += data[i]; #ifdef FULLVECTOR_THROW_NORMALIZATION_EXCEPTION assert ( fabs(sum) > 1e-10 ); #endif if ( fabs(sum) < 1e-10 ) { //fprintf (stderr, "WARNING: normalization failed !\n"); for ( int i = 0 ; i < length ; i++ ) data[i] = 0.0; } else { for ( int i = 0 ; i < length ; i++ ) data[i] /= sum; } } void FullVector::addMap ( const map & v, double lambda ) { for ( map::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ ) { int i = v_it->first; assert ( i < length ); data[i] += v_it->second * lambda; } } void FullVector::addMap ( const map & v, double lambda ) { for ( map::const_iterator v_it = v.begin(); v_it != v.end(); v_it++ ) { int i = v_it->first; assert ( i < length ); data[i] += v_it->second * lambda; } } int FullVector::maxElement () const { int maxindex = 0; double max = - numeric_limits::max(); for ( int i = 0 ; i < length ; i++ ) { if ( data[i] > max ) { maxindex = i; max = data[i]; } } return maxindex; } int FullVector::maxElementExclusive ( int key ) const { int maxindex = (key == 0) ? 1 : 0; double max = - numeric_limits::max(); for ( int i = 0 ; i < length ; i++ ) { double val = data[i]; if ( (i != key) && (val > max) ) { maxindex = i; max = val; } } return maxindex; } double FullVector::entropy () const { double entropy = 0.0; double sum = 0.0; for ( int i = 0 ; i < length ; i++ ) { double val = data[i]; if ( val <= 0.0 ) continue; entropy -= val*log(val); sum += val; } entropy /= sum; entropy += log(sum); return entropy; } void FullVector::getSortedIndices ( vector & indizes ) const { vector< pair > tmp; for ( int i = 0 ; i < length ; i++ ) if ( fabs(data[i]) > 10e-11 ) tmp.push_back ( pair ( data[i], i ) ); sort ( tmp.begin(), tmp.end() ); for ( vector >::const_iterator j = tmp.begin(); j != tmp.end(); j++ ) indizes.push_back ( j->second ); } double FullVector::max () const { double max = - numeric_limits::max(); for ( int i = 0 ; i < length ; i++ ) { if ( data[i] > max ) max = data[i]; } return max; } double FullVector::min () const { double min = numeric_limits::max(); for ( int i = 0 ; i < length ; i++ ) { if ( data[i] < min ) min = data[i]; } return min; } double FullVector::get ( size_t i ) const { assert ( (int)i < length ); return data[i]; } void FullVector::operator= ( const FullVector & v ) { if ( data != NULL ) delete [] data; length = v.length; if ( length == 0 ) data = NULL; else { data = new double[length]; memset ( (void *)data, 0, sizeof(double)*length ); for ( int i = 0 ; i < length ; i++ ) data[i] = v.data[i]; } }