SpikeStream Library
0.2
|
00001 //SpikeStream includes 00002 #include "Util.h" 00003 #include "NumberConversionException.h" 00004 using namespace spikestream; 00005 00006 //Qt includes 00007 #include <QDebug> 00008 #include <QTime> 00009 #include <QStringList> 00010 #include <QCoreApplication> 00011 00012 //Other includes 00013 #include <stdint.h> 00014 #include "math.h" 00015 #include <iostream> 00016 using namespace std; 00017 00018 00020 mpf_class Util::factorial (unsigned int num){ 00021 mpz_class result=1; 00022 for (unsigned int i=1; i<=num; ++i) 00023 result *= i; 00024 return result; 00025 } 00026 00027 00029 void Util::fillSelectionArray(bool* selectionArray, int arraySize, int selectionSize){ 00030 int nonSelectionSize = arraySize - selectionSize; 00031 00032 //Add zeros at start of array up to the non-selection size 00033 for(int i=0; i<nonSelectionSize; ++i) 00034 selectionArray[i] = false; 00035 00036 //Add 1s to the rest of the array 00037 for(int i=nonSelectionSize; i<arraySize; ++i) 00038 selectionArray[i] = true; 00039 } 00040 00041 00044 bool Util::getBool(const QString& str){ 00045 if(str.toLower() == "true") 00046 return true; 00047 else if (str.toLower() == "false") 00048 return false; 00049 throw NumberConversionException("Error converting '" + str + "' to boolean."); 00050 } 00051 00052 00055 bool Util::getBoolParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00056 if(!paramMap.contains(paramName)) 00057 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00058 if(paramMap[paramName] == 0.0) 00059 return false; 00060 return true; 00061 } 00062 00063 00066 float Util::getFloat(const QString& str){ 00067 bool ok = true; 00068 float newFloat = str.toFloat(&ok); 00069 if(!ok) 00070 throw NumberConversionException("Error converting '" + str + "' to float."); 00071 return newFloat; 00072 } 00073 00074 00077 int Util::getInt(const QString& str){ 00078 bool ok = true; 00079 int newInt = str.toInt(&ok); 00080 if(!ok) 00081 throw NumberConversionException("Error converting '" + str + "' to integer."); 00082 return newInt; 00083 } 00084 00085 00088 unsigned int Util::getUInt(const QString& str){ 00089 bool ok = true; 00090 unsigned int newInt = str.toUInt(&ok); 00091 if(!ok) 00092 throw NumberConversionException("Error converting '" + str + "' to unsigned integer."); 00093 return newInt; 00094 } 00095 00096 00098 QList<unsigned int> Util::getUIntList(const QString& str){ 00099 QStringList strList = str.split(",", QString::SkipEmptyParts); 00100 QList<unsigned int> uIntList; 00101 foreach(QString tmpStr, strList) 00102 uIntList.append(Util::getUInt(tmpStr.trimmed())); 00103 return uIntList; 00104 } 00105 00106 00109 double Util::getDouble(const QString& str){ 00110 bool ok = true; 00111 double newDouble = str.toDouble(&ok); 00112 if(!ok) 00113 throw NumberConversionException("Error converting '" + str + "' to double."); 00114 return newDouble; 00115 } 00116 00117 00119 double Util::getDoubleParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00120 if(!paramMap.contains(paramName)) 00121 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00122 return paramMap[paramName]; 00123 } 00124 00126 double Util::getPositiveDoubleParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00127 if(!paramMap.contains(paramName)) 00128 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00129 if(paramMap[paramName] < 0.0) 00130 throw SpikeStreamException("Parameter '" + paramName + "'' should be greater than 0: " + QString::number(paramMap[paramName])); 00131 return paramMap[paramName]; 00132 } 00133 00134 00136 float Util::getFloatParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00137 if(!paramMap.contains(paramName)) 00138 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00139 return (float)paramMap[paramName]; 00140 } 00141 00142 00144 int Util::getIntParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00145 if(!paramMap.contains(paramName)) 00146 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00147 if(rint(paramMap[paramName]) != paramMap[paramName]) 00148 throw SpikeStreamException("Parameter '" + paramName + "'' is not an integer."); 00149 return (int) paramMap[paramName]; 00150 } 00151 00152 00154 unsigned Util::getUIntParameter(const QString& paramName, QHash<QString, double>& paramMap){ 00155 if(!paramMap.contains(paramName)) 00156 throw SpikeStreamException("Parameter '" + paramName + "'' not found in parameter map."); 00157 if(rint(paramMap[paramName]) != paramMap[paramName]) 00158 throw SpikeStreamException("Parameter '" + paramName + "'' is not a whole number."); 00159 if(paramMap[paramName] < 0.0) 00160 throw SpikeStreamException("Expecting a positive number, but parameter '" + paramName + "'' is less than 0."); 00161 return (unsigned) paramMap[paramName]; 00162 } 00163 00164 00166 void Util::printParameterMap(const QHash<QString, double>& paramMap){ 00167 cout<<"--------------- Parameter map -------------"<<endl; 00168 for(QHash<QString, double>::const_iterator iter = paramMap.begin(); iter != paramMap.end(); ++iter){ 00169 cout<<"\tKey: "<<iter.key().toStdString().data()<<" value: "<<iter.value()<<endl; 00170 } 00171 cout<<endl; 00172 } 00173 00174 00177 int Util::getRandom(int min, int max){ 00178 if(max <= min) 00179 throw SpikeStreamException("Incorrect range for random number: maximum <= minimum."); 00180 00181 int randomNum = min; 00182 randomNum += Util::rUInt((max-1-min) * ((double)qrand() / (double)RAND_MAX)); 00183 return randomNum; 00184 } 00185 00186 00188 double Util::getRandomDouble(double min, double max){ 00189 if(min > max) 00190 throw SpikeStreamException("Minimum cannot be greater than maximum"); 00191 if(min == max) 00192 return min; 00193 double ranNum = (double)rand() / (double) RAND_MAX; 00194 return min + (max-min)*ranNum; 00195 } 00196 00197 00199 float Util::getRandomFloat(float min, float max){ 00200 if(min > max) 00201 throw SpikeStreamException("Minimum cannot be greater than maximum"); 00202 if(min == max) 00203 return min; 00204 float ranNum = (float)rand() / (float) RAND_MAX; 00205 return min + (max-min)*ranNum; 00206 } 00207 00208 00210 unsigned int Util::getRandomUInt(unsigned min, unsigned max){ 00211 if(min > max) 00212 throw SpikeStreamException("Minimum cannot be greater than maximum"); 00213 if(min == max) 00214 return min; 00215 return min + rand() % (max-min); 00216 } 00217 00218 00221 QString Util::getRootDirectory(){ 00222 //Get the working directory - this varies depending on the operating system 00223 QString rootDirectory = QCoreApplication::applicationDirPath(); 00224 #ifdef MAC32_SPIKESTREAM 00225 rootDirectory = rootDirectory.section("/bin", -2, -2, QString::SectionSkipEmpty); 00226 #else//Windows or Linux 00227 rootDirectory.truncate(rootDirectory.size() - 4);//Trim the "/bin" off the end 00228 #endif 00229 return rootDirectory; 00230 } 00231 00233 bool Util::isNumber(const QString& str){ 00234 //Is it a float - return true if no exception is thrown 00235 try{ 00236 getFloat(str); 00237 return true; 00238 } 00239 catch(SpikeStreamException&){} 00240 00241 //Is it a double - return true if no exception is thrown 00242 try{ 00243 getDouble(str); 00244 return true; 00245 } 00246 catch(SpikeStreamException&){} 00247 00248 //Is it an integer - return true if no exception is thrown 00249 try{ 00250 getInt(str); 00251 return true; 00252 } 00253 catch(SpikeStreamException&){} 00254 00255 //Is it an unsigned integer - return true if no exception is thrown 00256 try{ 00257 getUInt(str); 00258 return true; 00259 } 00260 catch(SpikeStreamException&){} 00261 00262 //If we have got to here no number conversion method will work on the string. 00263 return false; 00264 } 00265 00266 00268 float Util::min(float n1, float n2, float n3){ 00269 if(n1 < n2 && n1 < n3)//Is n1 the minimum? 00270 return n1; 00271 if(n2 < n3)//n1 is not the minimum, is n2 the minimum? 00272 return n2; 00273 return n3; 00274 00275 } 00276 00277 00279 void Util::printBinary(uint64_t number){ 00280 int numBits = sizeof(number) * 8; 00281 uint64_t probe = 2;// 0x8000000000000000; 00282 for(int i=0; i<numBits; ++i){ 00283 if(probe & number) 00284 cout<<"1"; 00285 else 00286 cout<<"0"; 00287 probe >>=1; 00288 } 00289 cout<<endl; 00290 } 00291 00292 00294 void Util::printBoolArray(bool arr[], int arrLen){ 00295 cout<<"Bool Array: "; 00296 for(int i=0; i< arrLen; ++i){ 00297 if(arr[i]) 00298 cout<<"1"; 00299 else 00300 cout<<"0"; 00301 } 00302 cout<<endl; 00303 } 00304 00305 00307 void Util::printByteArray(byte* byteArr, int arrLen){ 00308 cout<<"Byte array: "; 00309 for(int i=0; i< arrLen*8; ++i){ 00310 if(byteArr[i/8] & 1<<(i%8)) 00311 cout<<"1"; 00312 else 00313 cout<<"0"; 00314 } 00315 cout<<endl; 00316 } 00317 00318 00320 void Util::printByteArray(const QByteArray& byteArr){ 00321 cout<<"QByteArray: "; 00322 for(int i=0; i< byteArr.size(); ++i){ 00323 byte tmpByte = (unsigned char) byteArr.at(i); 00324 for(int j=0; j<8; ++j){ 00325 if(tmpByte & 1<<j) 00326 cout<<"1"; 00327 else 00328 cout<<"0"; 00329 } 00330 } 00331 cout<<endl; 00332 } 00333 00334 00336 double Util::rDouble(double num, int numPlaces){ 00337 double tempDoub = num * ( pow(10.0, (double)numPlaces) ); 00338 tempDoub = rint(tempDoub); 00339 tempDoub /= ( pow(10.0, (double)numPlaces) ); 00340 return tempDoub; 00341 } 00342 00343 00345 int Util::rInt(double num){ 00346 num = rint(num); 00347 return (int) num; 00348 } 00349 00350 00352 unsigned int Util::rUInt(double num){ 00353 num = rint(num); 00354 return (unsigned int) num; 00355 } 00356 00357 00359 void Util::safeCStringCopy(char target[], const char source[], int targetSize){ 00360 int newLength = strlen(source); 00361 if(newLength > targetSize){ 00362 throw SpikeStreamException("Source cstring too large for destination cstring."); 00363 } 00364 int i; 00365 for(i=0; i< newLength; ++i) //Copy everything up to newLength-1 00366 target[i] = source[i]; 00367 target[i] = '\0';//Finish string with null character 00368 } 00369 00370 00371 00374 void Util::seedRandom(int seed){ 00375 if(seed == 0){ 00376 QTime midnight(0, 0, 0); 00377 qsrand(midnight.secsTo(QTime::currentTime())); 00378 } 00379 else 00380 qsrand(seed); 00381 } 00382 00383 00385 void Util::addTraining(WeightlessNeuron& neuron, QString trainingPattern, int output){ 00386 unsigned char* byteArr; 00387 int arrLen; 00388 fillByteArray(byteArr, arrLen, trainingPattern); 00389 QByteArray qByteArr = QByteArray::fromRawData((const char*)byteArr, arrLen); 00390 neuron.addTraining(qByteArr, output); 00391 delete [] byteArr; 00392 } 00393 00394 00396 bool Util::bitsEqual(unsigned char* byteArr, QString bitPattStr, int output){ 00397 if(byteArr[0] != output) 00398 return false; 00399 00400 for(int i=0; i<bitPattStr.length(); ++i){ 00401 if(bitPattStr[i] == '1' && (byteArr[1 + i/8] & ( 1<<(i % 8) )))//1 is equal 00402 ;//do nothing 00403 else if(bitPattStr[i] == '0' && !(byteArr[1 + i/8] & ( 1<<(i % 8) )))//0 is equal 00404 ;//Do nothing 00405 else 00406 return false;//String and byte array do not match 00407 } 00408 return true; 00409 } 00410 00411 00413 void Util::fillByteArray(unsigned char*& byteArr, int& arrLen, QString byteStr){ 00414 if(byteStr.length() % 8 == 0) 00415 arrLen = byteStr.length() / 8; 00416 else 00417 arrLen = byteStr.length() / 8 + 1; 00418 byteArr = new unsigned char[arrLen]; 00419 00420 //Initialize array 00421 for(int i=0; i<arrLen; ++i) 00422 byteArr[i] = 0; 00423 00424 //Set bits corresponding to 1's in byte string 00425 for(int i=0; i<byteStr.length(); ++i){ 00426 if(byteStr[i] == '1') 00427 byteArr[i/8] |= 1<<(i % 8); 00428 } 00429 } 00430 00431 00433 void Util::setGeneralization(QHash<unsigned int, WeightlessNeuron*>& weiNeurMap, double gen){ 00434 for(QHash<unsigned int, WeightlessNeuron*>::iterator iter = weiNeurMap.begin(); iter != weiNeurMap.end(); ++iter) 00435 iter.value()->setGeneralization(gen); 00436 } 00437 00438 00440 double Util::toPositive(double num){ 00441 if (num > 0.0) 00442 return num; 00443 return num * -1.0; 00444 } 00445 00446 00448 float Util::toPositive(float num){ 00449 if (num > 0.0f) 00450 return num; 00451 return num * -1.0f; 00452 } 00453 00454 00456 int Util::toPositive(int num){ 00457 if (num >= 0) 00458 return num; 00459 return num * -1; 00460 } 00461 00462 00463