File indexing completed on 2026-04-09 07:49:55
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <string>
0012 #include <vector>
0013 #include <iostream>
0014
0015 template <typename T>
0016 struct svec
0017 {
0018 static std::string Desc(const char* label, const std::vector<T>& a, int width=7);
0019 static void Dump(const char* label, const std::vector<T>& a );
0020 static void Dump2(const char* label, const std::vector<T>& a );
0021 static T MaxDiff(const std::vector<T>& a, const std::vector<T>& b, bool dump);
0022 static int FindIndexOfValue( const std::vector<T>& a, T value, T tolerance );
0023 static int FindIndexOfValue( const std::vector<T>& a, T value );
0024 static void MinMaxAvg(const std::vector<T>& a, T& mn, T& mx, T& av) ;
0025 static void MinMax(const std::vector<T>& a, T& mn, T& mx ) ;
0026 static void Extract(std::vector<T>& a, const char* str, const char* ignore="(),[]") ;
0027
0028 static int Compare( const char* name, const std::vector<T>& a, const std::vector<T>& b, std::ostream* out );
0029 static int CompareBytes(const void* a, const void* b, unsigned num_bytes, std::ostream* out);
0030 };
0031
0032
0033 #include <cassert>
0034 #include <cstring>
0035 #include <cmath>
0036 #include <sstream>
0037 #include <iomanip>
0038 #include <iterator>
0039 #include <algorithm>
0040 #include <numeric>
0041 #include <sstream>
0042
0043 #include "sstr.h"
0044
0045 template <typename T>
0046 inline void svec<T>::Dump( const char* label, const std::vector<T>& a )
0047 {
0048 std::cout << std::setw(10) << label ;
0049 for(unsigned i=0 ; i < a.size() ; i++) std::cout << std::setw(10) << a[i] << " " ;
0050 std::cout << std::endl ;
0051 }
0052
0053 template <typename T>
0054 inline std::string svec<T>::Desc( const char* label, const std::vector<T>& a, int width )
0055 {
0056 std::stringstream ss ;
0057 ss << std::setw(10) << label ;
0058 for(unsigned i=0 ; i < a.size() ; i++) ss << std::setw(width) << a[i] << " " ;
0059 return ss.str();
0060 }
0061
0062 template <typename T>
0063 inline void svec<T>::Dump2( const char* label, const std::vector<T>& a )
0064 {
0065 std::cout << std::setw(10) << label ;
0066 std::copy( a.begin(), a.end(), std::ostream_iterator<float>(std::cout, " ")) ;
0067 std::cout << std::endl ;
0068 }
0069
0070 template <typename T>
0071 inline T svec<T>::MaxDiff(const std::vector<T>& a, const std::vector<T>& b, bool dump)
0072 {
0073 assert( a.size() == b.size() );
0074 T mx = 0.f ;
0075 for(unsigned i=0 ; i < a.size() ; i++)
0076 {
0077 T df = a[i] - b[i] ;
0078 if( df < 0 ) df = -df ;
0079
0080 if(df > mx) mx = df ;
0081
0082 if(dump)
0083 std::cout
0084 << " a " << a[i]
0085 << " b " << b[i]
0086 << " df " << df
0087 << " mx " << mx
0088 << std::endl
0089 ;
0090
0091 }
0092 return mx ;
0093 }
0094
0095
0096 template <typename T>
0097 inline int svec<T>::FindIndexOfValue(const std::vector<T>& a, T value, T tolerance)
0098 {
0099 int idx = -1 ;
0100 for(unsigned i=0 ; i < a.size() ; i++)
0101 {
0102
0103 T df = a[i] - value ;
0104 if(df < 0) df = -df ;
0105
0106 if(df < tolerance)
0107 {
0108 idx = i ;
0109 break ;
0110 }
0111 }
0112 return idx ;
0113 }
0114
0115
0116 template <typename T>
0117 inline int svec<T>::FindIndexOfValue(const std::vector<T>& a, T value )
0118 {
0119 size_t idx = std::distance( a.begin(), std::find( a.begin(), a.end(), value )) ;
0120 return idx < a.size() ? idx : -1 ;
0121 }
0122
0123
0124
0125 template <typename T>
0126 inline void svec<T>::MinMaxAvg(const std::vector<T>& t, T& mn, T& mx, T& av)
0127 {
0128 typedef typename std::vector<T>::const_iterator IT ;
0129 IT mn_ = std::min_element( t.begin(), t.end() );
0130 IT mx_ = std::max_element( t.begin(), t.end() );
0131 double sum = std::accumulate(t.begin(), t.end(), T(0.) );
0132
0133 mn = *mn_ ;
0134 mx = *mx_ ;
0135 av = t.size() > 0 ? sum/T(t.size()) : T(-1.) ;
0136 }
0137
0138 template <typename T>
0139 inline void svec<T>::MinMax(const std::vector<T>& t, T& mn, T& mx )
0140 {
0141 typedef typename std::vector<T>::const_iterator IT ;
0142 IT mn_ = std::min_element( t.begin(), t.end() );
0143 IT mx_ = std::max_element( t.begin(), t.end() );
0144 mn = *mn_ ;
0145 mx = *mx_ ;
0146 }
0147
0148 template <typename T>
0149 inline void svec<T>::Extract(std::vector<T>& a, const char* str0, const char* ignore )
0150 {
0151 char swap = ' ';
0152 const char* str1 = sstr::ReplaceChars(str0, ignore, swap);
0153 std::stringstream ss(str1);
0154 std::string s ;
0155 T value ;
0156
0157 while(std::getline(ss, s, ' '))
0158 {
0159 if(strlen(s.c_str()) == 0 ) continue;
0160
0161
0162 std::stringstream tt(s);
0163 tt >> value ;
0164 a.push_back(value);
0165 }
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 template<typename T>
0179 inline int svec<T>::Compare( const char* name, const std::vector<T>& a, const std::vector<T>& b, std::ostream* out )
0180 {
0181 int mismatch = 0 ;
0182
0183 bool size_match = a.size() == b.size() ;
0184 if(!size_match && out) *out << "svec::Compare " << name << " size_match FAIL " << a.size() << " vs " << b.size() << "\n" ;
0185 if(!size_match) mismatch += 1 ;
0186 if(!size_match) return mismatch ;
0187
0188 int data_match = memcmp( a.data(), b.data(), a.size()*sizeof(T) ) ;
0189 if(data_match != 0 && out) *out << "svec::Compare " << name << " sizeof(T) " << sizeof(T) << " data_match FAIL " << "\n" ;
0190 if(data_match != 0) mismatch += 1 ;
0191
0192 int byte_match = CompareBytes( a.data(), b.data(), a.size()*sizeof(T), out ) ;
0193 if(byte_match != 0 && out) *out << "svec::Compare " << name << " sizeof(T) " << sizeof(T) << " byte_match FAIL : num different bytes : " << byte_match << "\n" ;
0194 if(byte_match != 0) mismatch += 1 ;
0195
0196 int num_item = a.size();
0197 for(int i=0 ; i < num_item ; i++)
0198 {
0199 int item_byte_match = CompareBytes( &a[i], &b[i], sizeof(T), out );
0200 if(item_byte_match == 0) continue ;
0201 if(out) *out << "svec::Compare " << name << " sizeof(T) " << sizeof(T) << " num_item " << num_item << " item " << i << " item_byte_match FAIL : num different bytes : " << item_byte_match << "\n" ;
0202 mismatch += 1 ;
0203 }
0204
0205 if(mismatch != 0 && out) *out << "svec::Compare " << name << " mismatch FAIL " << "\n" ;
0206 return mismatch ;
0207 }
0208
0209 template<typename T>
0210 inline int svec<T>::CompareBytes(const void* a, const void* b, unsigned num_bytes, std::ostream* out)
0211 {
0212 const char* ca = (const char*)a ;
0213 const char* cb = (const char*)b ;
0214 int mismatch = 0 ;
0215 for(int i=0 ; i < int(num_bytes) ; i++ )
0216 {
0217 bool diff = ca[i] != cb[i] ;
0218 if( diff )
0219 {
0220 if(out) *out << "svec::CompareBytes " << std::setw(3) << i << " [" << std::setw(3) << int(ca[i]) << "|" << std::setw(3) << int(cb[i]) << "]\n" ;
0221 mismatch += 1 ;
0222 }
0223 }
0224 return mismatch ;
0225 }
0226
0227
0228
0229
0230
0231 template struct svec<int>;
0232 template struct svec<unsigned>;
0233 template struct svec<float>;
0234 template struct svec<double>;
0235
0236