From 34ef45418b98e8feb3bb1cd7296109bc77e594a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=92=EF=B8=8F?= <42745482+hammerandpick@users.noreply.github.com> Date: Thu, 28 Mar 2019 09:49:13 +0100 Subject: [PATCH 1/5] added getInputDateTime(); added some file loading features; --- ConsoleAI/AINetClass.cpp | 5 ++- ConsoleAI/AINetClass.h | 1 + ConsoleAI/AINetTrainingData.cpp | 65 +++++++++++++++++++++++++++++++- ConsoleAI/AINetTrainingData.h | 1 + ConsoleAI/ConsoleAI.cpp | Bin 24388 -> 27022 bytes 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/ConsoleAI/AINetClass.cpp b/ConsoleAI/AINetClass.cpp index dfb1afe..9f923de 100644 --- a/ConsoleAI/AINetClass.cpp +++ b/ConsoleAI/AINetClass.cpp @@ -1519,7 +1519,10 @@ bool AINetClass::autoGenerateInternalNetwork() double AINetClass::getTrainingDataValue(size_t row, size_t column) { - // safeAccesstoTrainingData + /** This function is used to access the training data in a safe way + \param row select this row + \param column select this column + */ double tmpReturn=0; if (row < this->ptrAINDataContainer->getTrainingDataRowsMax()) { diff --git a/ConsoleAI/AINetClass.h b/ConsoleAI/AINetClass.h index e1e1389..709208a 100644 --- a/ConsoleAI/AINetClass.h +++ b/ConsoleAI/AINetClass.h @@ -164,6 +164,7 @@ class AINetClass // functions std::string generateFileOutput(std::string& strFileContents); std::string generateFileInput(std::string& strFileContents); + bool IsDoubleCritical(double dToBeClassified); std::string IsDoubleCritical(double dToBeClassified, std::string sText); bool recalculateInputDataPullList(); diff --git a/ConsoleAI/AINetTrainingData.cpp b/ConsoleAI/AINetTrainingData.cpp index d06a1b0..4520776 100644 --- a/ConsoleAI/AINetTrainingData.cpp +++ b/ConsoleAI/AINetTrainingData.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "CodeFromWeb.h" #include "AINetTrainingData.h" @@ -135,6 +136,66 @@ double AINetTrainingData::getTrainingDataValue(size_t column, size_t row) return dReturn; } +std::vector AINetTrainingData::getInputDateTime(size_t column) +{ + /** This function is used to convert the date and/or time to input nodes for the network. + \n\tDate an time is splitted into nodes + \param column fetch data from this line. + */ + + /** TODO: Rewrite this to a one time conversion of training data + apply as a transformation for the stored data*/ + + struct tm tmTimeTemp; + std::vector vdTime; + vdTime.clear(); + if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) + { + tmTimeTemp.tm_year = this->getTrainingDataValue(column, 1); + tmTimeTemp.tm_mon = this->getTrainingDataValue(column, 2); + tmTimeTemp.tm_mday = this->getTrainingDataValue(column, 3); + } + if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) + { + int iTimeOff = 0; + if (this->intTimeDataMode == 4) + { + // date is stored before time therefore time is with offset 3 + iTimeOff = 3; + } + tmTimeTemp.tm_hour = this->getTrainingDataValue(column, iTimeOff + 1); + tmTimeTemp.tm_min = this->getTrainingDataValue(column, iTimeOff + 2); + tmTimeTemp.tm_sec = this->getTrainingDataValue(column, iTimeOff + 3); + } + mktime(&tmTimeTemp); + if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) + { + // this is to expand the date + vdTime.push_back(1.0); // year as dummy + vdTime.push_back(tmTimeTemp.tm_mon / 12.0); // month as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_mday / 31.0); // day as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_wday / 6.0); // wday as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_yday / 366.0); // day of year (+1 for longer switching years) + vdTime.push_back(tmTimeTemp.tm_wday != 1 ? 0 : 1); // monday + vdTime.push_back(tmTimeTemp.tm_wday != 2 ? 0 : 1); // tuesday + vdTime.push_back(tmTimeTemp.tm_wday != 3 ? 0 : 1); // wednesday + vdTime.push_back(tmTimeTemp.tm_wday != 4 ? 0 : 1); //thursday + vdTime.push_back(tmTimeTemp.tm_wday != 5 ? 0 : 1); // friday + vdTime.push_back(tmTimeTemp.tm_wday != 6 ? 0 : 1); // saturday + vdTime.push_back(tmTimeTemp.tm_wday != 0 ? 0 : 1); // sunday 0=false 1=true + } + if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) + { + // now expand the time over the day + vdTime.push_back(tmTimeTemp.tm_hour / 24.0); + vdTime.push_back(tmTimeTemp.tm_min / 60.0); + vdTime.push_back(tmTimeTemp.tm_sec / 60.0); + vdTime.push_back(tmTimeTemp.tm_hour / 24 * tmTimeTemp.tm_min / 60.0 * tmTimeTemp.tm_sec / 60.0); // time as seconds of day + vdTime.push_back(tmTimeTemp.tm_hour <= 11 ? 0 : 1); // morning or evening + } + return vdTime; +} + size_t AINetTrainingData::getTrainingRowSizeT(size_t row) { /** This will return the size of the specified \p row. @@ -463,7 +524,7 @@ size_t AINetTrainingData::loadTrainingDataFile() // clear vector vdLocalVector.clear(); theFirstElement = 0; - vdLocalVector.push_back(1.0); // first element is base/threshold value and always set to 1.0 + vdLocalVector.push_back((double)this->intTimeDataMode); // first element is base/threshold value and always set to 1.0 // looking for first element if (theLine.find_first_of(",") != theLine.npos) theFirstElement = (int)theLine.find_first_of(","); @@ -599,7 +660,7 @@ std::string AINetTrainingData::TrainingDataColumnName(size_t tmpColumn, bool sho } else { - if ((tmpColumn >= 0) && (tmpColumn < vStrTrainingDataColumns.size())) + if ((tmpColumn >= 0) && (tmpColumn < this->vStrTrainingDataColumns.size())) { // read a value if it is within valid range. tmpString = this->vStrTrainingDataColumns.at(tmpColumn); diff --git a/ConsoleAI/AINetTrainingData.h b/ConsoleAI/AINetTrainingData.h index 6fb2efa..680ef0f 100644 --- a/ConsoleAI/AINetTrainingData.h +++ b/ConsoleAI/AINetTrainingData.h @@ -17,6 +17,7 @@ class AINetTrainingData size_t getNumberOfOutputNodes(); size_t getTimeMode(); double getTrainingDataValue(size_t column, size_t row); + std::vector getInputDateTime(size_t column); size_t getTrainingRowSizeT(size_t row); std::vector getNetworkTopology(); std::vector> getTrainingDataMatrix(); diff --git a/ConsoleAI/ConsoleAI.cpp b/ConsoleAI/ConsoleAI.cpp index 737c57d52e4b943f56424ab444f977a9b3d0e9f5..d71762497eb06eac6402cd0cdf19d81475639151 100644 GIT binary patch delta 1535 zcmd5+&ubG=5S|4ujV4V@bBHk{EQsyK#7(k_H1=W}wf@LTQ!AEYOq--B)~sw31uyvz zlrngbg5bqVFD<weU7Aw@sRYTa(+v5uVe1LaS|SIpJ&=GRc%9FL`JP zPhUSB(EZO-ux-&|$HOS8bP6^-`e(a=A=erJHmE`+WM8&aOJrbo6p$A1$TUU?O7nU# znirL7!rp{aVJGUgvu~HE zuRp|1xJh#JWpOMv)EMvG@$q}D?zLk%C!1QtZFZKo zXF?@~6!@D3d#12N<};M1>yYR0jZ@M(y-d?ogk-;UD$q5$jsKh2&BIb~PKRY2a-J?= z{}N<{PIEvFAMUC(zd0B3);jeb7ge_SIj?&Jp`wE-Gr`-52tQV3zM+r&5A-|VO@+Ut zpWWazjq%gzNK8<0lIm!#freIH`q(s4d0#yf7A-$ei+={fyq7-0TLr&lu#x_p5cBp3 z#ck3Oyv9NN{?^jbPvNTk)5I=q@ DyVVj} From 9752ca36a7d7e3b7ac787f36b922dd308d88fe5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=92=EF=B8=8F?= <42745482+hammerandpick@users.noreply.github.com> Date: Thu, 28 Mar 2019 09:53:03 +0100 Subject: [PATCH 2/5] Update ConsoleAI.cpp --- ConsoleAI/ConsoleAI.cpp | Bin 27022 -> 13514 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ConsoleAI/ConsoleAI.cpp b/ConsoleAI/ConsoleAI.cpp index d71762497eb06eac6402cd0cdf19d81475639151..70d67ef3317822c3eebaaa0fd0fb84f5a83c35fc 100644 GIT binary patch literal 13514 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 TaiBt$c5@tG-RhyZDh&S@clZZ* literal 27022 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 From 0749f3c4c72e85468790afee59ab58e2c7d25605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=92=EF=B8=8F?= <42745482+hammerandpick@users.noreply.github.com> Date: Fri, 29 Mar 2019 10:13:34 +0100 Subject: [PATCH 3/5] feature timing is being implemented. --- ConsoleAI/AINetClass.cpp | 3 +- ConsoleAI/AINetTrainingData.cpp | 152 +++++++++++++++++++++----------- ConsoleAI/AINetTrainingData.h | 20 +++-- ConsoleAI/ConsoleAI.cpp | 4 +- WinGUI/WinGUI.cpp | Bin 14362 -> 14318 bytes 5 files changed, 115 insertions(+), 64 deletions(-) diff --git a/ConsoleAI/AINetClass.cpp b/ConsoleAI/AINetClass.cpp index 9f923de..2b714a6 100644 --- a/ConsoleAI/AINetClass.cpp +++ b/ConsoleAI/AINetClass.cpp @@ -1040,8 +1040,7 @@ void AINetClass::connectNodes(bool bFullyConnected, size_t iRandSeed, bool bDele //variables size_t tmpTotalNumberNodes = 0; - // seeding random number generator - srand(iRandSeed); + srand((unsigned int)iRandSeed); // problems with conversion don't matter because it's random //function tmpTotalNumberNodes = this->NUMNODES(); diff --git a/ConsoleAI/AINetTrainingData.cpp b/ConsoleAI/AINetTrainingData.cpp index 4520776..01840a7 100644 --- a/ConsoleAI/AINetTrainingData.cpp +++ b/ConsoleAI/AINetTrainingData.cpp @@ -1,11 +1,11 @@ #include "pch.h" #include "stdafx.h" +#include #include // std::random_shuffle #include #include #include #include -#include #include "CodeFromWeb.h" #include "AINetTrainingData.h" @@ -92,7 +92,13 @@ size_t AINetTrainingData::getNumberOfInputNodes() /** This returns the number of input nodes from the network topology \return Number of input nodes. */ - return this->vdNetworkTopology.front(); + + size_t iReturn = this->iNumberOfInputNodes; + if (this->bHasTiming) + { + iReturn = this->iNumberOfInputNodes + this->vvTimingData.size(); + } + return iReturn; } size_t AINetTrainingData::getNumberOfOutputNodes() @@ -100,7 +106,12 @@ size_t AINetTrainingData::getNumberOfOutputNodes() /** This function returns the number of output nodes from network topology of training data file \return The number of output nodes. */ - return this->vdNetworkTopology.back(); + size_t iReturn = this->iNumberOfOutputNodes; + if (this->bHasTiming) + { + // no changes + } + return iReturn; } size_t AINetTrainingData::getTimeMode() @@ -136,62 +147,63 @@ double AINetTrainingData::getTrainingDataValue(size_t column, size_t row) return dReturn; } -std::vector AINetTrainingData::getInputDateTime(size_t column) +std::vector AINetTrainingData::getInputDateTime(size_t row) { /** This function is used to convert the date and/or time to input nodes for the network. \n\tDate an time is splitted into nodes \param column fetch data from this line. */ - /** TODO: Rewrite this to a one time conversion of training data - apply as a transformation for the stored data*/ - struct tm tmTimeTemp; std::vector vdTime; vdTime.clear(); - if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) - { - tmTimeTemp.tm_year = this->getTrainingDataValue(column, 1); - tmTimeTemp.tm_mon = this->getTrainingDataValue(column, 2); - tmTimeTemp.tm_mday = this->getTrainingDataValue(column, 3); - } - if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) + + if (row < this->vvTrainingDataMatrix.size()) // check if column is in valid range { - int iTimeOff = 0; - if (this->intTimeDataMode == 4) + if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) { - // date is stored before time therefore time is with offset 3 - iTimeOff = 3; + tmTimeTemp.tm_year = (int)this->vvTrainingDataMatrix.at(row).at(1); + tmTimeTemp.tm_mon = (int)this->vvTrainingDataMatrix.at(row).at(2); + tmTimeTemp.tm_mday = (int)this->vvTrainingDataMatrix.at(row).at(3); + } + if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) + { + int iTimeOff = 0; + if (this->intTimeDataMode == 4) + { + // date is stored before time therefore time is with offset 3 + iTimeOff = 3; + } + tmTimeTemp.tm_hour = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 1); + tmTimeTemp.tm_min = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 2); + tmTimeTemp.tm_sec = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 3); + } + mktime(&tmTimeTemp); + if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) + { + // this is to expand the date + vdTime.push_back(1.0); // year as dummy + vdTime.push_back(tmTimeTemp.tm_mon / 12.0); // month as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_mday / 31.0); // day as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_wday / 6.0); // wday as value from 0-1 + vdTime.push_back(tmTimeTemp.tm_yday / 366.0); // day of year (+1 for longer switching years) + vdTime.push_back(tmTimeTemp.tm_wday != 1 ? 0 : 1); // monday + vdTime.push_back(tmTimeTemp.tm_wday != 2 ? 0 : 1); // tuesday + vdTime.push_back(tmTimeTemp.tm_wday != 3 ? 0 : 1); // wednesday + vdTime.push_back(tmTimeTemp.tm_wday != 4 ? 0 : 1); //thursday + vdTime.push_back(tmTimeTemp.tm_wday != 5 ? 0 : 1); // friday + vdTime.push_back(tmTimeTemp.tm_wday != 6 ? 0 : 1); // saturday + vdTime.push_back(tmTimeTemp.tm_wday != 0 ? 0 : 1); // sunday 0=false 1=true + } + if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) + { + // now expand the time over the day + vdTime.push_back(tmTimeTemp.tm_hour / 24.0); + vdTime.push_back(tmTimeTemp.tm_min / 60.0); + vdTime.push_back(tmTimeTemp.tm_sec / 60.0); + vdTime.push_back(tmTimeTemp.tm_hour / 24 * tmTimeTemp.tm_min / 60.0 * tmTimeTemp.tm_sec / 60.0); // time as seconds of day + vdTime.push_back(tmTimeTemp.tm_hour <= 11 ? 0 : 1); // morning or evening } - tmTimeTemp.tm_hour = this->getTrainingDataValue(column, iTimeOff + 1); - tmTimeTemp.tm_min = this->getTrainingDataValue(column, iTimeOff + 2); - tmTimeTemp.tm_sec = this->getTrainingDataValue(column, iTimeOff + 3); - } - mktime(&tmTimeTemp); - if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) - { - // this is to expand the date - vdTime.push_back(1.0); // year as dummy - vdTime.push_back(tmTimeTemp.tm_mon / 12.0); // month as value from 0-1 - vdTime.push_back(tmTimeTemp.tm_mday / 31.0); // day as value from 0-1 - vdTime.push_back(tmTimeTemp.tm_wday / 6.0); // wday as value from 0-1 - vdTime.push_back(tmTimeTemp.tm_yday / 366.0); // day of year (+1 for longer switching years) - vdTime.push_back(tmTimeTemp.tm_wday != 1 ? 0 : 1); // monday - vdTime.push_back(tmTimeTemp.tm_wday != 2 ? 0 : 1); // tuesday - vdTime.push_back(tmTimeTemp.tm_wday != 3 ? 0 : 1); // wednesday - vdTime.push_back(tmTimeTemp.tm_wday != 4 ? 0 : 1); //thursday - vdTime.push_back(tmTimeTemp.tm_wday != 5 ? 0 : 1); // friday - vdTime.push_back(tmTimeTemp.tm_wday != 6 ? 0 : 1); // saturday - vdTime.push_back(tmTimeTemp.tm_wday != 0 ? 0 : 1); // sunday 0=false 1=true - } - if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) - { - // now expand the time over the day - vdTime.push_back(tmTimeTemp.tm_hour / 24.0); - vdTime.push_back(tmTimeTemp.tm_min / 60.0); - vdTime.push_back(tmTimeTemp.tm_sec / 60.0); - vdTime.push_back(tmTimeTemp.tm_hour / 24 * tmTimeTemp.tm_min / 60.0 * tmTimeTemp.tm_sec / 60.0); // time as seconds of day - vdTime.push_back(tmTimeTemp.tm_hour <= 11 ? 0 : 1); // morning or evening } return vdTime; } @@ -221,16 +233,16 @@ std::vector AINetTrainingData::getNetworkTopology() std::vector> AINetTrainingData::getTrainingDataMatrix() { - /** This function returns the training data as new object. This should not be used. TODO: Check and delete. - \return a new training data object. + /** This function returns the training data as new object. + \return std::vector> a new training data object. */ return this->vvTrainingDataMatrix; } std::vector>* AINetTrainingData::ptrTrainingDataMatix() { - /** This function returns the training data as new object. This should not be used. TODO: Check and delete. - \return a new training data object. + /** This function returns a pointer to training data. + \return std::vector>* pointer to training data. */ return &this->vvTrainingDataMatrix; } @@ -361,6 +373,38 @@ std::vector AINetTrainingData::splitStringToDouble(const std::string & s return strElements; } +bool AINetTrainingData::createTimingData() +{ + /** This function is used to perform the creation of timing data. + It will load the date value from the training data. + Then it will convert these data do input data for the network. + The resulting data may have a variable size. + The network topology is to be reset afterwards. + */ + this->vvTimingData.clear(); + + this->vvTimingData.reserve(this->vvTrainingDataMatrix.size()); + + if (this->intTimeDataMode > 1) + { + // there is timing data present + for (size_t i = 0; i < this->vvTrainingDataMatrix.size(); ++i) + { + this->vvTimingData.push_back(this->getInputDateTime(i)); + } + } + + if (this->vvTimingData.size() == this->vvTrainingDataMatrix.size()) + { + this->bHasTiming = true; + } + else + { + this->bHasTiming = false; + } + return this->bHasTiming; +} + void AINetTrainingData::closeTrainingDataFile(std::ifstream &ptrDataFile) { /** This function is used to close the training data file after reading. @@ -442,8 +486,10 @@ size_t AINetTrainingData::loadTrainingDataFile() } this->vdNetworkTopology = this->splitStringToSizeT(theLine, ","); + this->iNumberOfInputNodes = this->vdNetworkTopology.front(); + this->iNumberOfOutputNodes = this->vdNetworkTopology.back(); - std::vector vdLocalVector(1 + this->vdNetworkTopology.front() + this->vdNetworkTopology.back()); + std::vector vdLocalVector(1 + this->iNumberOfInputNodes + this->iNumberOfOutputNodes); std::string loadedNumber = ""; std::string tmpIsTimeData = ""; // now start looking for maxiterations in aidatafile @@ -476,7 +522,7 @@ size_t AINetTrainingData::loadTrainingDataFile() break; case 5: // Todo change this - this->dPercentVerificationData = std::min(0.0,std::max(1.0,atof(theLine.substr(0, theFirstElement).c_str()))); + this->dPercentVerificationData = std::min(0.0, std::max(1.0, atof(theLine.substr(0, theFirstElement).c_str()))); break; case 6: tmpIsTimeData = theLine.substr(0, theFirstElement); diff --git a/ConsoleAI/AINetTrainingData.h b/ConsoleAI/AINetTrainingData.h index 680ef0f..2b60e12 100644 --- a/ConsoleAI/AINetTrainingData.h +++ b/ConsoleAI/AINetTrainingData.h @@ -43,10 +43,10 @@ class AINetTrainingData /* data file variables */ bool bOptionCSVGER = false; - std::string strAIDataFileHeader = ""; std::string strAIDataFileName = ""; - size_t intTimeDataMode = 1; // 1= no specific time data mode; 2=Date; 3=Time; 4=Date and Time + + /* calculation variables */ size_t intMaxIterations = 1000; size_t intTimePreviousRows = 0; size_t intTimeNextRows = 0; @@ -56,15 +56,23 @@ class AINetTrainingData size_t intLinesRead = 4; size_t intTrainingDataColumsMax = 0; size_t intTrainingDataRowsMax = 0; - std::vector vStrTrainingDataColumns = { "unused", "Value A", "Value B", "A OR B"}; - std::vector vdNetworkTopology = { 2,2,1 }; // standard xor training data network topology + + /* data storage */ std::vector> vvTrainingDataMatrix = { {1.0,0.0,0.0,0.0},{1.0,0.0,1.0,1.0},{1.0,1.0,0.0,1.0},{1.0,1.0,1.0,1.0} }; // standard xor training data + std::vector> vvTimingData = { {0.0} }; // this is used for expanding training data to timing data. + + /* data information */ + bool bHasTiming = false; // if true timing data has to be considered + size_t intTimeDataMode = 1; // 1= no specific time data mode; 2=Date; 3=Time; 4=Date and Time + std::vector vStrTrainingDataColumns = { "unused", "Value A", "Value B", "A OR B" }; + std::vector vdNetworkTopology = { 2,2,1 }; // standard xor training data network topology + size_t iNumberOfInputNodes = 2; // this should only be change while loading of training data + size_t iNumberOfOutputNodes = 1; // this should only be change while loading of training data /* functions */ - std::vector splitStringToSizeT(const std::string & strInput, const std::string & strDelimiter); std::vector splitStringToDouble(const std::string & strInput, const std::string & strDelimiter); - + bool createTimingData(); std::string convertFromCSVGermanStyle(std::string & strFileContents); std::string convertToCSVStandardStyle(std::string & strFileContents); diff --git a/ConsoleAI/ConsoleAI.cpp b/ConsoleAI/ConsoleAI.cpp index 70d67ef..8fe0027 100644 --- a/ConsoleAI/ConsoleAI.cpp +++ b/ConsoleAI/ConsoleAI.cpp @@ -293,9 +293,7 @@ void pause() void printTrainingData(AINetClass *ptrAINC) { - /* this function is used to print training data */ - - /* print training data to standard output */ + /** This function is used to print training data to standard output. */ const std::vector> *vvTmpTrainingData = ptrAINC->getTrainingData(); std::vector vTrainingDataRow; diff --git a/WinGUI/WinGUI.cpp b/WinGUI/WinGUI.cpp index 5a2f213b59d1c716c318636d24b63ce6781d5056..2f50b12c82563a9ecaf4bbeebdd2a9f225f82c5c 100644 GIT binary patch delta 14 WcmbPL@GgJCq{%y&g*IOBG6w)S1)*pI=TArwd}Fc>oMGH^`}WE9`H$j2N23Q7u= From 5a2bddbb330a9e3b1393a741b86e47981ed25a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=92=EF=B8=8F?= <42745482+hammerandpick@users.noreply.github.com> Date: Mon, 22 Apr 2019 08:05:11 +0200 Subject: [PATCH 4/5] code rewritten --- .vscode/launch.json | 19 +++++ ConsoleAI/AINetClass.cpp | 16 ++-- ConsoleAI/AINetClass.h | 2 +- ConsoleAI/AINetTrainingData.cpp | 137 +++++++++++++++++++++++--------- ConsoleAI/AINetTrainingData.h | 23 ++++-- ConsoleAI/ConsoleAI.cpp | 1 + ConsoleAI/ConsoleAI.vcxproj | 10 +-- WinGUI/WinGUI.cpp | Bin 14318 -> 14356 bytes WinGUI/WinGUI.rc | Bin 7750 -> 8372 bytes WinGUI/WinGUI.vcxproj | 10 +-- WinGUI/resource.h | Bin 2184 -> 2274 bytes 11 files changed, 156 insertions(+), 62 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..9833637 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": true + } + ] +} \ No newline at end of file diff --git a/ConsoleAI/AINetClass.cpp b/ConsoleAI/AINetClass.cpp index 2b714a6..7f5ec83 100644 --- a/ConsoleAI/AINetClass.cpp +++ b/ConsoleAI/AINetClass.cpp @@ -143,12 +143,11 @@ size_t AINetClass::Counter(bool bIncrease ) size_t AINetClass::CurrentTrainingDataRow() { // returns current Training Data Row - size_t tmpReturn; + size_t tmpReturn = 0; size_t tmpMaxRows = this->getTrainingDataRowsMax(); if (tmpMaxRows == 0) { this->throwFailure("division by 0 iTrainingDataRowsUseMax", true); - tmpReturn= 0; } else { @@ -659,10 +658,10 @@ void AINetClass::calculateLine(size_t iTmpRow) void AINetClass::sortNetwork() { - // this function sorts the network - + /** This function is meant to sort the network, so multiple networks can be combined */ + // begin sorting at the end of the network (of course we won't sort output) - for (size_t iSort = this->getNumberOfLayers(); iSort > 1; iSort--) + for (size_t iSort = this->getNumberOfLayers(); iSort > 1; --iSort) { // reload network variables to tmp variables each layer. std::vector vdTmpValues = this->vecValues; @@ -726,7 +725,7 @@ void AINetClass::sortNetwork() { jNode = jBegin + j; this->vecWeights.at(jNode).at(iNode) = vdTmpWeights[jNode][iBegin + viSortList.at(i)]; - //todo continue + //todo continue, but what? } // sort weights from previous layer jBegin = this->getLayerStart(iSort); @@ -734,7 +733,7 @@ void AINetClass::sortNetwork() { jNode = jBegin + j; this->vecWeights.at(iNode).at(jNode) = vdTmpWeights[iBegin + viSortList.at(i)][jNode]; - //todo continue + //todo continue, but what? } } } @@ -1022,7 +1021,7 @@ void AINetClass::connectNodes(bool bFullyConnected, size_t iRandSeed, bool bDele /** This function is used to create the initial connection of nodes. \param bFullyConnected is used to link al nodes from one layer with all nodes from the previous layer. \param iRandSeed is the seed for the random number generator. - \param deleteExisting (optional) delete existing connections and reset all values. + \param bDeleteExisting (optional) delete existing connections and reset all values. */ if (!this->initializationDone) @@ -1035,6 +1034,7 @@ void AINetClass::connectNodes(bool bFullyConnected, size_t iRandSeed, bool bDele this->bHasBeenConnected = true; // first do the auto-generation if parameter is set this->autoGenerateInternalNetwork(); + // TODO allow smart connected network by removing next line of code bFullyConnected = true; //variables diff --git a/ConsoleAI/AINetClass.h b/ConsoleAI/AINetClass.h index 709208a..f4e091d 100644 --- a/ConsoleAI/AINetClass.h +++ b/ConsoleAI/AINetClass.h @@ -29,7 +29,7 @@ class AINetClass size_t getNumberOfNodesInLayer(signed int iTmpLayer); size_t getNumberOfNodesInLayer(size_t tmpLayer); size_t getNumberOfLayers(bool bOnlyHidden = false); - size_t getLayerStart(int iTmpLayer, bool falseForLayerEnd = true); + size_t getLayerStart(int tmpLayer, bool falseForLayerEnd = true); double LearningRate(); size_t TrainingDataColumns(); diff --git a/ConsoleAI/AINetTrainingData.cpp b/ConsoleAI/AINetTrainingData.cpp index 01840a7..2006914 100644 --- a/ConsoleAI/AINetTrainingData.cpp +++ b/ConsoleAI/AINetTrainingData.cpp @@ -19,7 +19,9 @@ AINetTrainingData::AINetTrainingData() AINetTrainingData::~AINetTrainingData() { - this->vvTrainingDataMatrix.clear(); + this->vvLoadedData.clear(); + this->vvTimingData.clear(); + this->vvCalculationData.clear(); this->vdNetworkTopology.clear(); } @@ -34,7 +36,7 @@ size_t AINetTrainingData::getTrainingDataRowsMax(bool bReload) if (this->intTrainingDataRowsMax == 0 || bReload) { - this->intTrainingDataRowsMax = llround((this->vvTrainingDataMatrix.size() - this->intTimeNextRows - this->intTimePreviousRows)*(1 - this->dPercentVerificationData)); + this->intTrainingDataRowsMax = llround((this->vvCalculationData.size() - this->intTimeNextRows - this->intTimePreviousRows)*(1 - this->dPercentVerificationData)); } return this->intTrainingDataRowsMax; @@ -52,9 +54,9 @@ size_t AINetTrainingData::getTrainingDataColumnsMax(bool bRecount) if ((this->intTrainingDataColumsMax == 0) || bRecount) { // crawl all date for longest column - for (size_t i = 0; i < this->vvTrainingDataMatrix.size(); ++i) + for (size_t i = 0; i < this->vvCalculationData.size(); ++i) { - size_t intTempSize = this->vvTrainingDataMatrix.at(i).size(); + size_t intTempSize = this->vvCalculationData.at(i).size(); if (intTempSize > intMaxColumns) { intMaxColumns = intTempSize; @@ -72,6 +74,7 @@ size_t AINetTrainingData::getTrainingDataBegin() { /** This function is used to calculate the start of the training data. It will skip the number of defined previous rows, which will be used in calculation. Data has to be in ascending order. */ + return (size_t)this->intTimePreviousRows; } @@ -79,6 +82,7 @@ size_t AINetTrainingData::getTrainingDataEnd() { /** This function is used to calculate the end of the training data. It will skip the number of defined next rows, which will be used in calculation. Data has to be in ascending order. */ + return (size_t)this->vdNetworkTopology.size() - (size_t)this->intTimeNextRows; } @@ -106,6 +110,7 @@ size_t AINetTrainingData::getNumberOfOutputNodes() /** This function returns the number of output nodes from network topology of training data file \return The number of output nodes. */ + size_t iReturn = this->iNumberOfOutputNodes; if (this->bHasTiming) { @@ -118,26 +123,51 @@ size_t AINetTrainingData::getTimeMode() { /** Function returns AINetTrainingData->intTimeDataMode \return 1 for none\n 2 for date \n 3 for time \n 4 for date and time */ + return this->intTimeDataMode; } -double AINetTrainingData::getTrainingDataValue(size_t column, size_t row) +double AINetTrainingData::getTrainingDataValue(size_t column, size_t row, bool bRaw) { /** This function returns the value of the training data in \p colum of \p row. \param column The colum to be returned. \param row The row to be retrned. + \param bRaw (optional) use raw data \return Value of \p column and \p row. */ + double dReturn = 0.0; - if (row < this->vvTrainingDataMatrix.size()) + if (row < this->vvCalculationData.size()) { - if (column < this->vvTrainingDataMatrix.at(row).size()) + if(bHasTiming) { - dReturn= this->vvTrainingDataMatrix.at(row).at(column); + size_t iTmpTDSize= this->vvTimingData.at(row).size(); + if (column < this->vvCalculationData.at(row).size() + iTmpTDSize) // add the timing data rows + { + if (row < iTmpTDSize) // check for timing data first + { + dReturn = this->vvTimingData.at(row).at(column); // use timing data + } + else + { + dReturn = this->vvTimingData.at(row).at(column - iTmpTDSize); // find column is iTmpTDSize too big. + } + } + else + { + std::cerr << "column out of range: " << column; + } } else { - std::cerr << "column out of range: " << column; + if (column < this->vvCalculationData.at(row).size()) + { + dReturn = this->vvCalculationData.at(row).at(column); + } + else + { + std::cerr << "column out of range: " << column; + } } } else @@ -150,33 +180,34 @@ double AINetTrainingData::getTrainingDataValue(size_t column, size_t row) std::vector AINetTrainingData::getInputDateTime(size_t row) { /** This function is used to convert the date and/or time to input nodes for the network. - \n\tDate an time is splitted into nodes - \param column fetch data from this line. + Date and time is splitted into nodes + \param row fetch data from this line. */ struct tm tmTimeTemp; + tmTimeTemp.tm_year = 2019; std::vector vdTime; vdTime.clear(); - if (row < this->vvTrainingDataMatrix.size()) // check if column is in valid range + if (row < this->vvLoadedData.size()) // check if column is in valid range { if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) { - tmTimeTemp.tm_year = (int)this->vvTrainingDataMatrix.at(row).at(1); - tmTimeTemp.tm_mon = (int)this->vvTrainingDataMatrix.at(row).at(2); - tmTimeTemp.tm_mday = (int)this->vvTrainingDataMatrix.at(row).at(3); + tmTimeTemp.tm_year = (int)this->vvLoadedData.at(row).at(1); + tmTimeTemp.tm_mon = (int)this->vvLoadedData.at(row).at(2); + tmTimeTemp.tm_mday = (int)this->vvLoadedData.at(row).at(3); } if (this->intTimeDataMode == 3 || this->intTimeDataMode == 4) { - int iTimeOff = 0; + size_t iTimeOff = 0; if (this->intTimeDataMode == 4) { // date is stored before time therefore time is with offset 3 iTimeOff = 3; } - tmTimeTemp.tm_hour = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 1); - tmTimeTemp.tm_min = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 2); - tmTimeTemp.tm_sec = (int)this->vvTrainingDataMatrix.at(row).at(iTimeOff + 3); + tmTimeTemp.tm_hour = (int)this->vvLoadedData.at(row).at(iTimeOff + 1); + tmTimeTemp.tm_min = (int)this->vvLoadedData.at(row).at(iTimeOff + 2); + tmTimeTemp.tm_sec = (int)this->vvLoadedData.at(row).at(iTimeOff + 3); } mktime(&tmTimeTemp); if (this->intTimeDataMode == 2 || this->intTimeDataMode == 4) @@ -201,7 +232,7 @@ std::vector AINetTrainingData::getInputDateTime(size_t row) vdTime.push_back(tmTimeTemp.tm_hour / 24.0); vdTime.push_back(tmTimeTemp.tm_min / 60.0); vdTime.push_back(tmTimeTemp.tm_sec / 60.0); - vdTime.push_back(tmTimeTemp.tm_hour / 24 * tmTimeTemp.tm_min / 60.0 * tmTimeTemp.tm_sec / 60.0); // time as seconds of day + vdTime.push_back((tmTimeTemp.tm_hour / 24) * (tmTimeTemp.tm_min / 60.0) * (tmTimeTemp.tm_sec / 60.0)); // time as seconds of day vdTime.push_back(tmTimeTemp.tm_hour <= 11 ? 0 : 1); // morning or evening } } @@ -216,19 +247,25 @@ size_t AINetTrainingData::getTrainingRowSizeT(size_t row) */ size_t intReturn = 0; - if (row < this->vvTrainingDataMatrix.size()) + if (row < this->vvCalculationData.size()) { - intReturn = this->vvTrainingDataMatrix.at(row).size(); + intReturn = this->vvCalculationData.at(row).size(); } return intReturn; } -std::vector AINetTrainingData::getNetworkTopology() +std::vector AINetTrainingData::getNetworkTopology(bool bFromData) { /** This function will return the topology from training data file. + \param bFromData to be set if the network topology should be loaded from the training data and not be altered by other means. \return The topology of the network from training data file. */ - return this->vdNetworkTopology; + std::vector vecTmpTopology = this->vdNetworkTopology; + if(!bFromData && this->bHasTiming) + { + vecTmpTopology.at(0) = this->vdNetworkTopology.at(0) + this->vvTimingData.size(); + } + return vecTmpTopology; } std::vector> AINetTrainingData::getTrainingDataMatrix() @@ -236,7 +273,7 @@ std::vector> AINetTrainingData::getTrainingDataMatrix() /** This function returns the training data as new object. \return std::vector> a new training data object. */ - return this->vvTrainingDataMatrix; + return this->vvCalculationData; } std::vector>* AINetTrainingData::ptrTrainingDataMatix() @@ -244,7 +281,7 @@ std::vector>* AINetTrainingData::ptrTrainingDataMatix() /** This function returns a pointer to training data. \return std::vector>* pointer to training data. */ - return &this->vvTrainingDataMatrix; + return &this->vvCalculationData; } std::string AINetTrainingData::getTrainingDataFileName() @@ -260,6 +297,7 @@ std::string AINetTrainingData::setTrainingDataFileName(std::string strFileName) /** This will set the file name of the training data file. \return String of file name. */ + // TODO: add some verification here. this->strAIDataFileName; return this->strAIDataFileName; @@ -271,6 +309,7 @@ bool AINetTrainingData::setOptionCSVGermanStyle(bool bGerStyle) \param bGerStyle if a german csv file is to be loaded this has to be set to true \return returns input parameter if set correctly. */ + this->bOptionCSVGER = bGerStyle; return this->bOptionCSVGER; } @@ -310,6 +349,7 @@ bool AINetTrainingData::setPreferredNetworkTopology(std::vector vsPref) \param vsPref is a vector with the topology as integer values from input (lowest) to output (highest) \return returns true if successfull */ + this->vdNetworkTopology = vsPref; return (this->vdNetworkTopology == vsPref); } @@ -321,6 +361,7 @@ std::vector AINetTrainingData::splitStringToSizeT(const std::string & st \param strDelimiter is string, which is used to split \p strInput into pieces. \return is returning the content of \p strInput converted into a vector of integers. */ + std::vector strElements; for (size_t stStart = 0, stEnd; stStart < strInput.length(); stStart = stEnd + strDelimiter.length()) @@ -352,6 +393,7 @@ std::vector AINetTrainingData::splitStringToDouble(const std::string & s \param strDelimiter is string, which is used to split \p strInput into pieces. \return is returning the content of \p strInput converted into a vector of doubles. */ + std::vector strElements; for (size_t stStart = 0, stEnd; stStart < strInput.length(); stStart = stEnd + strDelimiter.length()) @@ -381,26 +423,47 @@ bool AINetTrainingData::createTimingData() The resulting data may have a variable size. The network topology is to be reset afterwards. */ + this->vvTimingData.clear(); + this->vvCalculationData.clear(); + this->bHasTiming = false; - this->vvTimingData.reserve(this->vvTrainingDataMatrix.size()); + this->vvTimingData.reserve(this->vvLoadedData.size()); if (this->intTimeDataMode > 1) { // there is timing data present - for (size_t i = 0; i < this->vvTrainingDataMatrix.size(); ++i) + for (size_t i = 0; i < this->vvLoadedData.size(); ++i) { this->vvTimingData.push_back(this->getInputDateTime(i)); } } - if (this->vvTimingData.size() == this->vvTrainingDataMatrix.size()) + if (this->vvTimingData.size() == this->vvLoadedData.size()) // check if all elements have been converted. { - this->bHasTiming = true; + std::vector vdTmp; + for (size_t i = 0; i < this->vvTimingData.size(); ++i) + { + vdTmp = this->vvTimingData.at(i); // put timing-data up front + for (size_t j = 0; j < this->vvLoadedData.at(i).size(); ++j) + { + vdTmp.push_back(this->vvLoadedData.at(i).at(j)); // add loaded data + } + this->vvCalculationData.push_back(vdTmp); // now put the glued timing and loaded data into storage + } + + if (this->vvLoadedData.size() == this->vvCalculationData.size()) + { + this->bHasTiming = true; + } + else + { + //something went wrong during copy operation. + } } else { - this->bHasTiming = false; + //something went wrong during copy operation. } return this->bHasTiming; } @@ -453,8 +516,8 @@ size_t AINetTrainingData::loadTrainingDataFile() /** This function is used to load all the training data. * \return the number of unreadable lines. */ - std::string theLine = "no open file."; - int theFirstElement = 0; + std::string theLine = "no open file."; // line of text loaded from file. + size_t theFirstElement = 0; unsigned int iNumberOfLines = 0; unsigned int iNumberOfFalseLines = 0; int iTimePreviousElements = 0; // How many previous rows for calculation? @@ -464,7 +527,7 @@ size_t AINetTrainingData::loadTrainingDataFile() this->openTrainingDataFile(theAIDataFile); // clear old training data - this->vvTrainingDataMatrix.clear(); + this->vvLoadedData.clear(); if (theAIDataFile.is_open()) { @@ -522,7 +585,7 @@ size_t AINetTrainingData::loadTrainingDataFile() break; case 5: // Todo change this - this->dPercentVerificationData = std::min(0.0, std::max(1.0, atof(theLine.substr(0, theFirstElement).c_str()))); + this->dPercentVerificationData = min(0.0, max(1.0, atof(theLine.substr(0, theFirstElement).c_str()))); break; case 6: tmpIsTimeData = theLine.substr(0, theFirstElement); @@ -594,7 +657,7 @@ size_t AINetTrainingData::loadTrainingDataFile() if (vdLocalVector.size() >= 1 + this->vdNetworkTopology.front() + this->vdNetworkTopology.back()) { // counting number of lines and copying whole row to vector - this->vvTrainingDataMatrix.push_back(vdLocalVector); + this->vvLoadedData.push_back(vdLocalVector); iNumberOfLines += 1; } else @@ -603,9 +666,11 @@ size_t AINetTrainingData::loadTrainingDataFile() iNumberOfFalseLines += 1; } } + theLine = ""; } this->closeTrainingDataFile(theAIDataFile); + this->vvCalculationData = this->vvLoadedData; return iNumberOfFalseLines; } diff --git a/ConsoleAI/AINetTrainingData.h b/ConsoleAI/AINetTrainingData.h index 2b60e12..ab9fc75 100644 --- a/ConsoleAI/AINetTrainingData.h +++ b/ConsoleAI/AINetTrainingData.h @@ -1,13 +1,23 @@ #pragma once #include "CodeFromWeb.h" +/** WORKAROUND FOR WinGUI */ +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +/** END WORKAROUND FOR WinGUI */ + class AINetTrainingData { public: AINetTrainingData(); ~AINetTrainingData(); - size_t getTrainingDataRowsMax(bool bReload=false); size_t getTrainingDataColumnsMax(bool bRecount=false); size_t getTrainingDataBegin(); @@ -16,16 +26,15 @@ class AINetTrainingData size_t getNumberOfInputNodes(); size_t getNumberOfOutputNodes(); size_t getTimeMode(); - double getTrainingDataValue(size_t column, size_t row); - std::vector getInputDateTime(size_t column); + double getTrainingDataValue(size_t column, size_t row, bool bRaw = false); + std::vector getInputDateTime(size_t row); size_t getTrainingRowSizeT(size_t row); - std::vector getNetworkTopology(); + std::vector getNetworkTopology(bool bFromData = false); std::vector> getTrainingDataMatrix(); std::vector>* ptrTrainingDataMatix(); std::string getTrainingDataFileName(); std::string setTrainingDataFileName(std::string strFileName); - bool setOptionCSVGermanStyle(bool bGerStyle); bool setPreferredNetworkTopology(std::string strPref); bool setPreferredNetworkTopology(std::vector vsPref); @@ -40,7 +49,6 @@ class AINetTrainingData private: - /* data file variables */ bool bOptionCSVGER = false; std::string strAIDataFileHeader = ""; @@ -58,7 +66,8 @@ class AINetTrainingData size_t intTrainingDataRowsMax = 0; /* data storage */ - std::vector> vvTrainingDataMatrix = { {1.0,0.0,0.0,0.0},{1.0,0.0,1.0,1.0},{1.0,1.0,0.0,1.0},{1.0,1.0,1.0,1.0} }; // standard xor training data + std::vector> vvLoadedData = { {1.0,0.0,0.0,0.0},{1.0,0.0,1.0,1.0},{1.0,1.0,0.0,1.0},{1.0,1.0,1.0,1.0} }; // standard xor training data + std::vector> vvCalculationData = { {1.0,0.0,0.0,0.0},{1.0,0.0,1.0,1.0},{1.0,1.0,0.0,1.0},{1.0,1.0,1.0,1.0} }; std::vector> vvTimingData = { {0.0} }; // this is used for expanding training data to timing data. /* data information */ diff --git a/ConsoleAI/ConsoleAI.cpp b/ConsoleAI/ConsoleAI.cpp index 8fe0027..a679091 100644 --- a/ConsoleAI/ConsoleAI.cpp +++ b/ConsoleAI/ConsoleAI.cpp @@ -187,6 +187,7 @@ int main(int argc, char *argv[], char *env[]) { strFile = aincNetwork.getDataFileName(); break; } + printf("file %s selected.\n", strFile.c_str()); aincNetwork.setDataFileName(strFile); iFileErrors = ainTrainingData->loadTrainingData(strFile); } diff --git a/ConsoleAI/ConsoleAI.vcxproj b/ConsoleAI/ConsoleAI.vcxproj index 7c7b8ca..c8087a5 100644 --- a/ConsoleAI/ConsoleAI.vcxproj +++ b/ConsoleAI/ConsoleAI.vcxproj @@ -23,32 +23,32 @@ {4232F9C0-3D4E-4818-BF3C-DBCDFF0FA4FC} Win32Proj ConsoleAI - 10.0.17134.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode diff --git a/WinGUI/WinGUI.cpp b/WinGUI/WinGUI.cpp index 2f50b12c82563a9ecaf4bbeebdd2a9f225f82c5c..b9fbcf411c8f8290da506df6c2207c55ad85b0b0 100644 GIT binary patch delta 28 kcmaEtKc!#;2QzmrLn=cqLq0XBJqZUzYr@uT|7cQouXtlCUvesxE_nWC+Ik0b6GaKljD38xgQT}=x5nqFvM zC@#6?oMX-y+E=9-#3b@hbVHp;EUBjU9QbzVzKr >*4399jMH-%GB)Y`1=`l+v^} QKPt6|t?z`RiRrfU4WLCc(EtDd delta 21 dcmdnuc+6(Q8o|j4yqh+&h^%AWTqS131psCv2p9kW diff --git a/WinGUI/WinGUI.vcxproj b/WinGUI/WinGUI.vcxproj index ba22f6e..b120c5f 100644 --- a/WinGUI/WinGUI.vcxproj +++ b/WinGUI/WinGUI.vcxproj @@ -23,32 +23,32 @@ {5F59811A-E077-4C97-A055-882CB10B6115} Win32Proj WinGUI - 10.0.17134.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode diff --git a/WinGUI/resource.h b/WinGUI/resource.h index 0c97b3e1f857897949ece2286f62f08e7ae44622..90947e53bd2b1098cd63c317faf7ef1d0b9ab2a2 100644 GIT binary patch delta 36 rcmeAWd?dKRkCESv!Ji?B!IvS7!IQz2A$+nRlkQ|8R;kTijCSk*pScI* delta 12 TcmaDP*de&Vk8$$~Mk{szAB_Yl From 90ffcb8900985069812477340e779ef8b864e46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=92=EF=B8=8F?= <42745482+hammerandpick@users.noreply.github.com> Date: Mon, 22 Apr 2019 17:49:23 +0200 Subject: [PATCH 5/5] Adjustments for supporting windows UWP-Apps --- ConsoleAI/AINetClass.cpp | 11 ++++++++++- ConsoleAI/AINetClass.h | 2 ++ ConsoleAI/ConsoleAI.cpp | 3 +-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ConsoleAI/AINetClass.cpp b/ConsoleAI/AINetClass.cpp index 7f5ec83..7125a65 100644 --- a/ConsoleAI/AINetClass.cpp +++ b/ConsoleAI/AINetClass.cpp @@ -973,7 +973,8 @@ void AINetClass::saveResultingNetwork(size_t iNumber) } catch (...) { fileResultingNetwork.close(); - this->throwFailure("Error while saving data." + strerror_s(clocalerror, errno), false); + //TODO This is in conflict with Windows UWP App. + //this->throwFailure("Error while saving data." + strerror_s(clocalerror, errno), false); } } @@ -1438,6 +1439,14 @@ double AINetClass::updateWeights() return sumOfSquaredErrors; } +double AINetClass::getVersion() +{ + /** this function returns the Version of the AINetClass + \return double Version + */ + return this->dVersion; +} + double AINetClass::getNodeValue(size_t tmpNode) { // returns value of node diff --git a/ConsoleAI/AINetClass.h b/ConsoleAI/AINetClass.h index f4e091d..1e7d75f 100644 --- a/ConsoleAI/AINetClass.h +++ b/ConsoleAI/AINetClass.h @@ -53,6 +53,7 @@ class AINetClass bool IsNetworkReady(); bool autoGenerateInternalNetwork(); double updateWeights(); + double getVersion(); double getNodeValue(size_t tmpNode); void TrainingDataColumnPush_Back(std::string tmpString); void activateNetwork(); @@ -107,6 +108,7 @@ class AINetClass // Constants double E = 2.71828; + double dVersion = 0.20190422; // variables std::vector vecValues = { 0.0 }; // vector containing values including input diff --git a/ConsoleAI/ConsoleAI.cpp b/ConsoleAI/ConsoleAI.cpp index a679091..3ca604c 100644 --- a/ConsoleAI/ConsoleAI.cpp +++ b/ConsoleAI/ConsoleAI.cpp @@ -31,7 +31,6 @@ double MOMENTUM = 0.0; size_t theAIDataFilePos = 0; char theAIWeightsFileName[] = "weights.aiweights.csv"; char *cThisFileName; -const double VERSION = 0.20190221; bool optionsAuto = false; bool optionsWeightSave = false; bool optionsAllNodes = false; @@ -65,7 +64,7 @@ int main(int argc, char *argv[], char *env[]) { */ // Welcome Screen printf("Neural Network Program\n(%s)\n", argv[0]); - printf("Version:%10.8f \n\n--- OPTIONS ---", VERSION); + printf("Version:%10.8f \n\n--- OPTIONS ---", aincNetwork.getVersion()); atexit(leaveApplication);