Advertisement
Guest User

Untitled

a guest
Apr 26th, 2019
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 77.16 KB | None | 0 0
  1. /*ES-RNN-E: Exponential Smoothing Recurrent Neural Network hybrid, Ensemble of specialists. Prediction Intervals forecast.
  2. Slawek Smyl,  Jan-May 2017.
  3.  
  4. Dilated LSTMs, with optional shortcuts, attention. Non-seasonal, single, or double seasonal.
  5. It is meant to be used for all types of series from M4 competition, except Monthly and Quarterly (for performance reasons - Ensamble of Specilists is slower).
  6. The program uses and requires Dynet NN library(https://github.com/clab/dynet); can be compiled and run on Windows, Linux, and Mac.
  7.  
  8. In contradistinction to ES-RNN, each executable uses all series, but in a similar manner repeating the whole learning process BIG_LOOP times (by default 3).
  9. Invocation should pass BIG_LOOP offset
  10. so e.g. create a script with following lines on Windows
  11. start <this_executable> 0
  12. start <this_executable> 10
  13. start <this_executable> 20
  14. start <this_executable> 30
  15. on 4-core computer.
  16. In this setup, learning and fitting would be repeated 4*3 times, probably unnecessarily too many, 6-8 independent runs should be enough for a good ensemble.
  17. Therefore if running on say 8 core machine , one can extend the above script to 8 concurrent executions and reduce BIG_LOOP to 1.
  18. (Creating final forecasts is done in a supplied R script)
  19.  
  20. There are four blocks of parameters below, one active (starting with //PARAMS--------------) and three inactive.
  21. These blocks are as they were during the final forecasting run. You need comment/uncomment to have one block of interest active.
  22. */
  23.  
  24.  
  25. //#define USE_ODBC
  26. //define USE_ODBC if you want to
  27. // 1. run the program in backtesting mode (which means you also need to set LBACK>0 below. Read the comment below.
  28. // 2. save forecasts to a datatabase. Mysql and SQL Server were tested. The table creation and some other scripts should be found in \sql directory of the source code.
  29. // Of course setting up ODBC is not that simple, :-), e.g. you need to create DSN=slawek, that points to a database with the output table.
  30. // Saving to the db is convenient, but not necessary - all forecasts are always saved to as csv files in automatically created subdirectory (sorry sometimes two directories, so you have to copy :-)) of OUTPUT_DIR
  31. //If saving to database you need to modify run varaible, for each new run, otherwise you will get the table key error.
  32.  
  33. #include "dynet/dynet.h"
  34. #include "dynet/training.h"
  35. #include "dynet/expr.h"
  36. #include "dynet/io.h"
  37. #include "dynet/model.h"
  38. #include "dynet/nodes.h"
  39. #include "dynet/expr.h"
  40. #include "dynet/lstm.h"
  41. #include "slstm.h" //my implementation of dilated LSTMs
  42.  
  43.  
  44. #if defined USE_ODBC        
  45.   #if defined _WINDOWS
  46.     #include <windows.h>
  47.   #endif  
  48.   #include <sqlext.h>
  49.   #include <sql.h>
  50. #endif
  51.  
  52. #include <ctime>
  53. #include <numeric>
  54. #include <array>
  55. //#include <iostream>
  56. #include <fstream>
  57. #include <sstream>
  58. #include <algorithm>  
  59. #include <math.h>
  60.  
  61. using namespace std;
  62. using namespace dynet;
  63.  
  64. //string DATA_DIR = "f:\\progs\\data\\M4DataSet\\"; //with the competition data csvs
  65. string DATA_DIR="/home/user/projects/M4-methods/Dataset/";
  66. //string OUTPUT_DIR = "f:\\progs\\data\\M4\\";
  67. string OUTPUT_DIR="/home/user/Downloads/";
  68.  
  69. int LBACK = 0; //LBACK 0 means final mode: learning on all data and forecasting. LBACK=1 would move back by OUTPUT_SIZE, and forecast last known OUTPUT_SIZE points, for backtesting. LBACK could be a larger integer, but then number of series shrinks.
  70.  
  71.  
  72. //PARAMS--------------
  73.  
  74. string VARIABLE = "Hourly";
  75. const string run0 = "(1,4)(24,168) LR=0.01, {25,3e-3f} EPOCHS=37, LVP=10, CSP=0";
  76. const string runL = "alpha5L " + run0;
  77. const string runH = "alpha5H " + run0;
  78.  
  79. //#define USE_RESIDUAL_LSTM
  80. //#define USE_ATTENTIVE_LSTM
  81. const bool ADD_NL_LAYER = false;
  82.  
  83. const int SEASONALITY_NUM = 2;//0 means no seasonality, for Yearly; 1 - single seasonality for Daily(7), Weekly(52); 2 - dual seaonality for Hourly (24,168)
  84. const int SEASONALITY = 24;
  85. const int SEASONALITY2 = 168;
  86. vector<vector<unsigned>> dilations = { { 1,4 },{ 24, 168 } };
  87.  
  88. const float INITIAL_LEARNING_RATE = 0.01f;
  89. const map<int, float> LEARNING_RATES = { { 20,1e-3f } }; //at which epoch we manually set them up to what
  90. const float PER_SERIES_LR_MULTIP = 1;
  91. const int NUM_OF_TRAIN_EPOCHS = 37;
  92.  
  93. float LEVEL_VARIABILITY_PENALTY = 10;  //Multiplier for L" penalty against wigglines of level vector.
  94. const float C_STATE_PENALTY = 0;
  95.  
  96. const unsigned int STATE_HSIZE = 40;
  97.  
  98. const unsigned int INPUT_SIZE = 24;
  99. const unsigned int OUTPUT_SIZE = 48;
  100.  
  101. const int MIN_INP_SEQ_LEN = 0;
  102. const int MIN_SERIES_LENGTH = OUTPUT_SIZE + INPUT_SIZE + MIN_INP_SEQ_LEN + 2;  //this is compared to n==(total length - OUTPUT_SIZE). Total length may be truncated by LBACK
  103. const int MAX_SERIES_LENGTH = 53 * SEASONALITY2 + MIN_SERIES_LENGTH;  //==all
  104. const int TOPN = 4;
  105.  
  106.  
  107. /*
  108. string VARIABLE = "Weekly";
  109. const string run0 = "Att 4/5 (1,52) LR=1e-3 {15,3e-4f} EPOCHS=31, LVP=100 6y";
  110. const string runL = "alpha5L " + run0;
  111. const string runH = "alpha5H " + run0;
  112.  
  113. //#define USE_RESIDUAL_LSTM
  114. #define USE_ATTENTIVE_LSTM
  115. const bool ADD_NL_LAYER = false;
  116.  
  117. const int SEASONALITY_NUM = 1; //0 means no seasonality, for Yearly; 1 - single seasonality for Daily(7), Weekly(52); 2 - dual seaonality for Hourly (24,168)
  118. const int SEASONALITY = 52;
  119. const int SEASONALITY2 = 0;
  120. vector<vector<unsigned>> dilations = { { 1, 52 } };
  121.  
  122. const float INITIAL_LEARNING_RATE = 1e-3;
  123. const map<int, float> LEARNING_RATES = { { 15,3e-4f } }; //at which epoch we manually set them up to what
  124. const float PER_SERIES_LR_MULTIP = 1;
  125. const int NUM_OF_TRAIN_EPOCHS = 31;
  126.  
  127. float LEVEL_VARIABILITY_PENALTY = 100;  //Multiplier for L" penalty against wigglines of level vector.
  128. const float C_STATE_PENALTY = 0;
  129.  
  130. const unsigned int STATE_HSIZE = 40;
  131.  
  132. const unsigned int INPUT_SIZE = 10;
  133. const unsigned int OUTPUT_SIZE = 13;
  134.  
  135. const int MIN_INP_SEQ_LEN = 0;
  136. const int MIN_SERIES_LENGTH = OUTPUT_SIZE + INPUT_SIZE + MIN_INP_SEQ_LEN + 2;  //this is compared to n==(total length - OUTPUT_SIZE). Total length may be truncated by LBACK
  137.                                                                                //#Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  138.                                                                                //#81     380     935    1023    1604    2598
  139. const int MAX_SERIES_LENGTH = 6 * SEASONALITY + MIN_SERIES_LENGTH;
  140. const int TOPN = 4;
  141. */
  142.  
  143. /*
  144.  
  145. string VARIABLE = "Daily";
  146. const string run0 = "4/5 (1,3)(7,14) LR=3e-4 {13,1e-4f} EPOCHS=21, LVP=100 13w";
  147. const string runL = "alpha5L " + run0;
  148. const string runH = "alpha5H " + run0;
  149.  
  150. //#define USE_RESIDUAL_LSTM
  151. //#define USE_ATTENTIVE_LSTM
  152. const bool ADD_NL_LAYER=false;
  153.  
  154. const int SEASONALITY_NUM = 1; //0 means no seasonality, for Yearly; 1 - single seasonality for Daily(7), Weekly(52); 2 - dual seaonality for Hourly (24,168)
  155. const int SEASONALITY = 7;
  156. const int SEASONALITY2 = 0;
  157. vector<vector<unsigned>> dilations = { { 1,3 },{ 7, 14 } };
  158.  
  159. const float INITIAL_LEARNING_RATE = 3e-4;
  160. const map<int, float> LEARNING_RATES = { { 13,1e-4f } }; //at which epoch we manually set them up to what
  161. const float PER_SERIES_LR_MULTIP = 1;
  162. const int NUM_OF_TRAIN_EPOCHS = 21;
  163.  
  164. float LEVEL_VARIABILITY_PENALTY = 100;  //Multiplier for L" penalty against wigglines of level vector.
  165. const float C_STATE_PENALTY = 0;
  166.  
  167. const unsigned int STATE_HSIZE = 40;
  168.  
  169. const unsigned int INPUT_SIZE = 7;
  170. const unsigned int OUTPUT_SIZE = 14;
  171.  
  172. const int MIN_INP_SEQ_LEN = 0;
  173. const int MIN_SERIES_LENGTH = OUTPUT_SIZE + INPUT_SIZE + MIN_INP_SEQ_LEN + 2;  //this is compared to n==(total length - OUTPUT_SIZE). Total length may be truncated by LBACK
  174.                                                                                //#Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  175.                                                                                //##93     323    2940    2357    4197    9919
  176. const int MAX_SERIES_LENGTH = 13 * SEASONALITY + MIN_SERIES_LENGTH;
  177. const int TOPN = 4;
  178. */
  179.  
  180. /*
  181. string VARIABLE = "Yearly";
  182. const string run0 = "Att NL 4/5 (1,6) LR=1e-4 {17,3e-5}{22,1e-5} EPOCHS=29, 60*";
  183. const string runL = "alpha5L " + run0;
  184. const string runH = "alpha5H " + run0;
  185.  
  186. //#define USE_RESIDUAL_LSTM
  187. #define USE_ATTENTIVE_LSTM
  188. const bool ADD_NL_LAYER = true;
  189.  
  190. const int SEASONALITY_NUM = 0; //0 means no seasonality
  191. const int SEASONALITY = 1; //for no seasonality, set it to 1, important
  192. const int SEASONALITY2 = 0;
  193. vector<vector<unsigned>> dilations = { { 1,6 } };
  194.  
  195. const float INITIAL_LEARNING_RATE = 1e-4;
  196. const map<int, float> LEARNING_RATES = { { 17,3e-5 },{ 22,1e-5 } }; //at which epoch we manually set them up to what
  197. const float PER_SERIES_LR_MULTIP = 1;
  198. const int NUM_OF_TRAIN_EPOCHS = 29;
  199.  
  200. float LEVEL_VARIABILITY_PENALTY = 0;  //Multiplier for L penalty against wigglines of level vector.
  201. const float C_STATE_PENALTY = 0;
  202.  
  203. const unsigned int STATE_HSIZE = 30;
  204.  
  205. const unsigned int INPUT_SIZE = 4;
  206. const unsigned int OUTPUT_SIZE = 6;
  207.  
  208. const int MIN_INP_SEQ_LEN = 0;
  209. const int MIN_SERIES_LENGTH = OUTPUT_SIZE + INPUT_SIZE + MIN_INP_SEQ_LEN + 2;  //this is compared to n==(total length - OUTPUT_SIZE). Total length may be truncated by LBACK
  210.                                                                                //#Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  211.                                                                                //#13.00   20.00   29.00   31.32   40.00  835.00
  212. const int MAX_SERIES_LENGTH = 60 + MIN_SERIES_LENGTH;
  213. const int TOPN = 4;
  214. */
  215.  
  216. const float ALPHA = 0.05;
  217. const float TAUL = ALPHA / 2;
  218. const float TAUH = 1 - TAUL;
  219. const float ALPHA_MULTIP = 2 / ALPHA;
  220.  
  221. const int BIG_LOOP = 3;
  222. const int NUM_OF_NETS = 5;
  223. const unsigned ATTENTION_HSIZE = STATE_HSIZE;
  224.  
  225. #if defined _DEBUG
  226.   const int MAX_NUM_OF_SERIES = 20;
  227. #else
  228.   const int MAX_NUM_OF_SERIES = -1;
  229. #endif // _DEBUG
  230.  
  231. const unsigned int NUM_OF_CATEGORIES = 6;
  232. const int AVERAGING_LEVEL = 5;
  233. const float EPS=1e-6;
  234.  
  235. const float NOISE_STD=0.001;
  236. const int FREQ_OF_TEST=1;
  237. const float GRADIENT_CLIPPING=50;
  238. const float BIG_FLOAT=1e38;//numeric_limits<float>::max();
  239. const bool PRINT_DIAGN = false;
  240.  
  241. string INPUT_PATH = DATA_DIR + VARIABLE + "-train.csv";
  242. string INFO_INPUT_PATH = DATA_DIR + "M4-info.csv";
  243.  
  244.  
  245. Expression squash(Expression& x) {
  246.   return log(x);
  247. }
  248. float squash(float x) {
  249.   return log(x);
  250. }
  251.  
  252. Expression expand(Expression& x) {
  253.   return exp(x);
  254. }
  255. float expand(float x) {
  256.   return exp(x);
  257. }
  258.  
  259.  
  260. #if defined USE_ODBC
  261.   void HandleDiagnosticRecord(SQLHANDLE      hHandle,
  262.     SQLSMALLINT    hType,
  263.     RETCODE        RetCode);
  264.  
  265.   #if defined _WINDOWS
  266.     WCHAR* pwszConnStr = L"DSN=slawek";
  267.   #else
  268.     SQLCHAR* pwszConnStr = (SQLCHAR*) "DSN=slawek";
  269.   #endif  
  270.   #define TRYODBC(h, ht, x)   {   RETCODE rc = x;\
  271.                                 if (rc != SQL_SUCCESS) \
  272.                                 { \
  273.                                     HandleDiagnosticRecord (h, ht, rc); \
  274.                                 } \
  275.                                 if (rc == SQL_ERROR) \
  276.                                 { \
  277.                                     fprintf(stderr, "Error in " #x "\n"); \
  278.                                     if (hStmt)    { \
  279.                                                                             SQLFreeHandle(SQL_HANDLE_STMT, hStmt); \
  280.                                                                         } \
  281.                                                                         if (hDbc)    { \
  282.                                                                             SQLDisconnect(hDbc); \
  283.                                                                             SQLFreeHandle(SQL_HANDLE_DBC, hDbc); \
  284.                                                                         } \
  285.                                                                         if (hEnv)    { \
  286.                                                                                 SQLFreeHandle(SQL_HANDLE_ENV, hEnv); \
  287.                                                                         } \
  288.                                                                         exit(-1); \
  289.                                 }  \
  290.                             }
  291.  
  292. #endif
  293.  
  294. struct M4TS {//storing series data
  295.   vector < float> categories_vect;
  296.   vector<float> vals;
  297.   vector<float> testVals;//empty, unless LBACK>0
  298.   float meanAbsSeasDiff;
  299.   int n;
  300.  
  301.   M4TS(string category, stringstream  &line_stream) {
  302.     array<float, NUM_OF_CATEGORIES> categories = { 0,0,0,0,0,0 };
  303.     if (category == "Demographic")
  304.       categories[0] = 1;
  305.     else if (category == "Finance")
  306.       categories[1] = 1;
  307.     else if (category == "Industry")
  308.       categories[2] = 1;
  309.     else if (category == "Macro")
  310.       categories[3] = 1;
  311.     else if (category == "Micro")
  312.       categories[4] = 1;
  313.     else if (category == "Other")
  314.       categories[5] = 1;
  315.     else {
  316.       cerr << "unknown category?";
  317.       exit(-1);
  318.     }
  319.     for (int i = 0; i < NUM_OF_CATEGORIES; i++)
  320.       categories_vect.push_back(categories[i]);
  321.  
  322.     string tmp_str;
  323.     while(getline(line_stream, tmp_str, ',' )) {
  324.       string val_str;
  325.       for (const auto c : tmp_str) {
  326.         if (c != '\"') {//remove quotes
  327.           val_str.push_back(c);
  328.         }
  329.       }
  330.       if (val_str.size() == 0)
  331.         break;
  332.       float val=(atof(val_str.c_str()));
  333.       vals.push_back(val);
  334.     }
  335.  
  336.     meanAbsSeasDiff = 0;
  337.     float sumf = 0;
  338.     for (int ip = SEASONALITY; ip<vals.size(); ip++) {
  339.       float diff = vals[ip] - vals[ip - SEASONALITY];
  340.       sumf += abs(diff);
  341.     }
  342.     if (sumf>0)
  343.       meanAbsSeasDiff = sumf / (vals.size() - SEASONALITY);
  344.  
  345.     if (LBACK > 0) {  //extract last OUTPUT_SIZE points as the test values
  346.       if (vals.size() > LBACK*OUTPUT_SIZE) {
  347.         auto first = vals.begin() + vals.size() - LBACK*OUTPUT_SIZE;
  348.         auto pastLast = vals.begin() + vals.size() - (LBACK-1)*OUTPUT_SIZE;
  349.         vector<float> input_vect(first, pastLast); //[first,pastLast)
  350.         testVals= input_vect;
  351.         vals.resize(vals.size() - LBACK*OUTPUT_SIZE); //remove last LBACK*OUTPUT_SIZE elements
  352.         n = vals.size();
  353.       } else
  354.         n = 0;
  355.     } else {
  356.       n = vals.size();
  357.     }
  358.     if (n > MAX_SERIES_LENGTH) {//chop long series
  359.       vals.erase(vals.begin(), vals.begin() + (n-MAX_SERIES_LENGTH)); //remove some early data
  360.       n = vals.size();
  361.     }
  362.   }
  363.   M4TS(){};
  364. };
  365.  
  366. #if defined USE_ODBC        
  367. void HandleDiagnosticRecord(SQLHANDLE      hHandle,
  368.   SQLSMALLINT    hType,
  369.   RETCODE        RetCode);
  370. #endif
  371.  
  372. struct AdditionalParams {//Per series, important
  373.     Parameter levSm;
  374.     Parameter sSm;
  375.     array<Parameter, SEASONALITY> initSeasonality;
  376.     Parameter sSm2;
  377.     array<Parameter, SEASONALITY2> initSeasonality2;
  378. };
  379. struct AdditionalParamsF {//Used for storing diagnostics
  380.     float levSm;
  381.     float sSm;
  382.     array<float, SEASONALITY> initSeasonality;
  383.     float sSm2;
  384.     array<float, SEASONALITY2> initSeasonality2;
  385.     vector<float> levels;
  386.     vector<float> seasons;
  387.     vector<float> seasons2;
  388. };
  389.  
  390.  
  391. array<int, NUM_OF_NETS> perfToRanking (array<float, NUM_OF_NETS> perf_arr) {
  392.   array<int, NUM_OF_NETS> index;
  393.  
  394.   for (int itop=0; itop<TOPN; itop++) {
  395.     float currMin=BIG_FLOAT; int indexOfMin=-1;
  396.     for (int i=0; i<NUM_OF_NETS; i++) {
  397.       if (perf_arr[i]<currMin) {
  398.         currMin=perf_arr[i];
  399.         indexOfMin=i;
  400.       }
  401.     }
  402.     index[itop]=indexOfMin;
  403.     perf_arr[indexOfMin]=BIG_FLOAT;
  404.   }
  405.   return index;
  406. }
  407.  
  408. //loss function
  409. Expression MSIS(const Expression& out_ex, const Expression& actuals_ex) {
  410.   vector<Expression> losses;
  411.   for (unsigned int indx = 0; indx<OUTPUT_SIZE; indx++) {
  412.     auto forecL = pick(out_ex, indx);
  413.     auto forecH = pick(out_ex, indx+ OUTPUT_SIZE);
  414.     auto actual = pick(actuals_ex, indx);
  415.     float actualf= as_scalar(actual.value());
  416.  
  417.     Expression loss= forecH - forecL;
  418.     if (actualf< as_scalar(forecL.value()))
  419.       loss=loss+(forecL - actual)*ALPHA_MULTIP;
  420.     if (actualf > as_scalar(forecH.value()))
  421.       loss = loss + (actual - forecH)*ALPHA_MULTIP;
  422.     losses.push_back(loss);
  423.   }
  424.   return sum(losses) / OUTPUT_SIZE;
  425. }
  426.  
  427. // weighted quantile Loss
  428. float wQuantLoss(vector<float>& out_vect, vector<float>& actuals_vect, float tau, int offset) {//used just for diagnostics, if if LBACK>0 and PERCENTILE!=50
  429.   float sumf = 0; float suma = 0;
  430.   for (unsigned int indx = 0; indx<OUTPUT_SIZE; indx++) {
  431.     auto forec = out_vect[indx+ offset];
  432.     auto actual = actuals_vect[indx];
  433.     suma += abs(actual);
  434.     if (actual > forec)
  435.       sumf = sumf + (actual - forec)*tau;
  436.     else
  437.       sumf = sumf + (actual - forec)*(tau - 1);
  438.   }
  439.   return sumf / suma * 200;
  440. }
  441.  
  442. float errorFunc(vector<float>& out_vect, vector<float>& actuals_vect, float meanAbsSeasDiff) {
  443.   float sumf=0;
  444.   for (unsigned int indx = 0; indx<OUTPUT_SIZE; indx++) {
  445.     auto forecL = out_vect[indx];
  446.     auto forecH = out_vect[indx + OUTPUT_SIZE];
  447.     auto actualf = actuals_vect[indx];
  448.  
  449.     float loss = forecH - forecL;
  450.     if (actualf< forecL)
  451.       loss = loss + (forecL - actualf)*ALPHA_MULTIP;
  452.     if (actualf > forecH)
  453.       loss = loss + (actualf - forecH)*ALPHA_MULTIP;
  454.     sumf+=loss;
  455.   }
  456.   return sumf / (OUTPUT_SIZE*meanAbsSeasDiff);
  457. }
  458.  
  459.  
  460.  
  461. int main(int argc, char** argv) {
  462.   dynet::initialize(argc, argv);
  463.  
  464.   int ibigOffset = 0;
  465.   if (argc == 2)
  466.     ibigOffset = atoi(argv[1]);
  467.    
  468.   cout<<VARIABLE<<" "<<runL<<endl;
  469.   cout << runH << " Lback=" << LBACK << endl;
  470.   cout << "ibigOffset:"<< ibigOffset<<endl;
  471.  
  472.   if (SEASONALITY_NUM <= 0 && LEVEL_VARIABILITY_PENALTY > 0) {
  473.     cout<<"Warning. LEVEL_VARIABILITY_PENALTY has to be equal zero if SEASONALITY_NUM==0"<<endl;
  474.     LEVEL_VARIABILITY_PENALTY=0;
  475.   }
  476.  
  477.   time_t rawtime;
  478.   struct tm * timeinfo;
  479.   char buffer[80];
  480.  
  481.   time(&rawtime);
  482.   timeinfo = localtime(&rawtime);
  483.  
  484.   strftime(buffer, sizeof(buffer), "%Y-%m-%d_%I_%M", timeinfo);
  485.   std::string timestamp_str(buffer);
  486.  
  487.   ostringstream convert2;
  488.   convert2 << int(ALPHA * 100);
  489.  
  490.   #if defined _WINDOWS
  491.     OUTPUT_DIR = OUTPUT_DIR + "\\" + VARIABLE+ timestamp_str;
  492.     if (LBACK==0)
  493.       OUTPUT_DIR = OUTPUT_DIR+"Final\\";
  494.     OUTPUT_DIR = OUTPUT_DIR + convert2.str();
  495.     string exec = string("mkdir ") + OUTPUT_DIR;//so occasionaly, if the programs do not start within the same minute, you may find more than one output dir created. After the run just manullay put them together.
  496.   #else
  497.     OUTPUT_DIR = OUTPUT_DIR + "/" + VARIABLE + timestamp_str;
  498.     if (LBACK == 0)
  499.       OUTPUT_DIR = OUTPUT_DIR + "Final/";
  500.     OUTPUT_DIR = OUTPUT_DIR + convert2.str();
  501.     string exec = string("mkdir -p ") + OUTPUT_DIR;
  502.   #endif
  503.   system(exec.c_str());
  504.  
  505.   if (LBACK == 0)
  506.     cout << "Doing final of " << VARIABLE << " into " << OUTPUT_DIR << endl;
  507.  
  508. #if defined USE_ODBC
  509.   time_t t = time(0);   // get time now
  510.   struct tm * now = localtime(&t);
  511.   TIMESTAMP_STRUCT now_ts;
  512.   now_ts.year= now->tm_year+1900;
  513.   now_ts.month=now->tm_mon+1;
  514.   now_ts.day=now->tm_mday;
  515.   now_ts.hour=now->tm_hour;
  516.   now_ts.minute=now->tm_min;
  517.   now_ts.second=now->tm_sec;
  518.   now_ts.fraction=0; //reportedly needed
  519.  
  520.   const int OFFSET_TO_FIRST_ACTUAL=5;
  521.   string insertQuery_str = "insert into M72nn(run, LBack, ibig, series, epoch ";
  522.   for (int iq = 1; iq <= OUTPUT_SIZE; iq++) {
  523.     stringstream ss;
  524.     ss << iq;
  525.     string iq_str = ss.str();
  526.     insertQuery_str = insertQuery_str +", actual"+iq_str+", forec" + iq_str;
  527.   }
  528.   insertQuery_str = insertQuery_str +", trainingError, variable, n, dateTimeOfPrediction) \
  529.    values(? , ? , ? , ? , ? ";
  530.   for (int iq = 1; iq <= OUTPUT_SIZE; iq++) {
  531.     insertQuery_str = insertQuery_str + ",?,?";
  532.   }
  533.   insertQuery_str = insertQuery_str + ",?,?,?,?)";
  534.   #if defined _WINDOWS  
  535.   wstring insertQuery(insertQuery_str.begin(), insertQuery_str.end());
  536.   SQLWCHAR* sqlQuery = (SQLWCHAR*)insertQuery.c_str();
  537.   #else
  538.   SQLCHAR* sqlQuery =(SQLCHAR*)insertQuery_str.c_str();
  539.   #endif
  540.  
  541.   SQLHENV  hEnv = NULL;
  542.   SQLHDBC  hDbc = NULL;
  543.   SQLHSTMT hStmt = NULL, hInsertStmt = NULL;
  544.  
  545.   if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) == SQL_ERROR) {
  546.     fprintf(stderr, "Unable to allocate an environment handle\n");
  547.     exit(-1);
  548.   }
  549.   TRYODBC(hEnv,
  550.     SQL_HANDLE_ENV,
  551.     SQLSetEnvAttr(hEnv,
  552.       SQL_ATTR_ODBC_VERSION,
  553.       (SQLPOINTER)SQL_OV_ODBC3,
  554.       0));
  555.  
  556.   // Allocate a connection
  557.   TRYODBC(hEnv,
  558.     SQL_HANDLE_ENV,
  559.     SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));
  560.  
  561.   TRYODBC(hDbc,
  562.     SQL_HANDLE_DBC,
  563.     SQLDriverConnect(hDbc,
  564.       NULL,
  565.       pwszConnStr,
  566.       SQL_NTS,
  567.       NULL,
  568.       0,
  569.       NULL,
  570.       SQL_DRIVER_COMPLETE));
  571.   fprintf(stderr, "Connected!\n");
  572.  
  573.   TRYODBC(hDbc,
  574.     SQL_HANDLE_DBC,
  575.     SQLSetConnectAttr(hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER));
  576.  
  577.   TRYODBC(hDbc,
  578.     SQL_HANDLE_DBC,
  579.     SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hInsertStmt));
  580.  
  581.   TRYODBC(hInsertStmt,
  582.     SQL_HANDLE_STMT,
  583.     SQLPrepare(hInsertStmt, sqlQuery, SQL_NTS));
  584.  
  585.   SQLLEN nullTerminatedStringOfRun = SQL_NTS;
  586.   SQLLEN nullTerminatedStringOfSeries = SQL_NTS;
  587.   SQLLEN nullTerminatedStringOfVariable = SQL_NTS;
  588.  
  589.   TRYODBC(hInsertStmt,
  590.     SQL_HANDLE_STMT,
  591.     SQLBindParameter(hInsertStmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&LBACK, 0, NULL));
  592.  
  593.   // variable, n, dateTimeOfPrediction
  594.   TRYODBC(hInsertStmt,
  595.     SQL_HANDLE_STMT,
  596.     SQLBindParameter(hInsertStmt, OFFSET_TO_FIRST_ACTUAL+2*OUTPUT_SIZE+2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLCHAR*)VARIABLE.c_str(), 0, &nullTerminatedStringOfVariable));
  597.  
  598.   TRYODBC(hInsertStmt,
  599.     SQL_HANDLE_STMT,
  600.     SQLBindParameter(hInsertStmt, OFFSET_TO_FIRST_ACTUAL + 2 * OUTPUT_SIZE + 4, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, 0, 0, &now_ts, sizeof(TIMESTAMP_STRUCT), NULL));
  601. #endif
  602.    
  603.   random_device rd;     // only used once to initialise (seed) engine
  604.   mt19937 rng(rd());    // random-number engine used (Mersenne-Twister in this case)
  605.  
  606.   vector<string> series_vect;
  607.   unordered_map<string, M4TS> allSeries_map(30000);//max series in one chunk would be 24k for yearly series
  608.   unordered_map<string, string> seriesCategories_map(120000);//100k series
  609.  
  610.   ifstream infoFile(INFO_INPUT_PATH);
  611.   string line;
  612.   getline(infoFile, line); //header
  613.   while (getline(infoFile, line)) {
  614.     //cout << string( line)<<endl;
  615.     stringstream  line_stream(line);
  616.     string series; string category;
  617.  
  618.     getline(line_stream, series, ',');
  619.     getline(line_stream, category, ',');
  620.     seriesCategories_map[series] = category;
  621.   }
  622.  
  623.   ifstream file (INPUT_PATH);
  624.   getline(file, line); //header
  625.   while ( getline ( file, line) ) {
  626.     stringstream  line_stream(line);
  627.     string series0;  string series;
  628.     getline(line_stream, series0, ',' );
  629.     for (const auto c : series0) {
  630.       if (!ispunct(c)) {
  631.         series.push_back(c);
  632.       }
  633.     }
  634.  
  635.     string category = seriesCategories_map[series];
  636.     M4TS m4Obj(category, line_stream);
  637.     if (m4Obj.n >= MIN_SERIES_LENGTH) {
  638.       series_vect.push_back(series);
  639.       if (m4Obj.meanAbsSeasDiff==0) {
  640.         cout<<"Warning, flat series:"<<series<<endl;
  641.         m4Obj.meanAbsSeasDiff= m4Obj.testVals[0]/100;
  642.       }
  643.       allSeries_map[series] = m4Obj;
  644.     }
  645.     if (MAX_NUM_OF_SERIES>0 && series_vect.size()>=MAX_NUM_OF_SERIES)
  646.       break;
  647.   }
  648.   cout << "num of series:" << series_vect.size() << endl;
  649.  
  650.   unsigned int series_len=(unsigned int)series_vect.size();
  651.   uniform_int_distribution<int> uniOnSeries(0,series_len-1);  // closed interval [a, b]
  652.   uniform_int_distribution<int> uniOnNets(0,NUM_OF_NETS-1);  // closed interval [a, b]
  653.  
  654.   unordered_map<string, array<array<vector<float>, AVERAGING_LEVEL+1>, NUM_OF_NETS>> testResults_map((int)series_len*1.5);//per series, etc...
  655.   unordered_map<string, vector<float>> finalResults_map((int)series_len*1.5);//per series
  656.   set<string> diagSeries;
  657.  
  658.   unordered_map<string, array<int, NUM_OF_NETS>> netRanking_map;
  659.   for (int ibig=0; ibig<BIG_LOOP; ibig++) {
  660.     int ibigDb= ibigOffset+ibig;
  661.     string outputPathL = OUTPUT_DIR + '/'+ VARIABLE + "_" + to_string(ibigDb)+"_LLB"+ to_string(LBACK)+ ".csv";
  662.     string outputPathH = OUTPUT_DIR + '/' + VARIABLE + "_" + to_string(ibigDb) + "_HLB" + to_string(LBACK) + ".csv";
  663.     vector<float> perfValid_vect;
  664.     int epochOfLastChangeOfLRate = -1;
  665.    
  666. #if defined USE_ODBC        
  667.     TRYODBC(hInsertStmt,
  668.       SQL_HANDLE_STMT,
  669.       SQLBindParameter(hInsertStmt, 3, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&ibigDb, 0, NULL));
  670. #endif
  671.  
  672.     //create nets
  673.     array<ParameterCollection, NUM_OF_NETS> paramsCollection_arr;//per net
  674.     array<ParameterCollection, NUM_OF_NETS> perSeriesParamsCollection_arr;//per net
  675.     array<AdamTrainer*, NUM_OF_NETS> trainers_arr;
  676.     array<AdamTrainer*, NUM_OF_NETS> perSeriesTrainers_arr;
  677.    
  678.  
  679.     #if defined USE_RESIDUAL_LSTM
  680.       array<vector<ResidualDilatedLSTMBuilder>, NUM_OF_NETS> rnnStack_arr;
  681.     #elif defined USE_ATTENTIVE_LSTM
  682.       array<vector<AttentiveDilatedLSTMBuilder>, NUM_OF_NETS> rnnStack_arr;
  683.     #else
  684.       array<vector<DilatedLSTMBuilder>, NUM_OF_NETS> rnnStack_arr;
  685.     #endif
  686.  
  687.     array<Parameter, NUM_OF_NETS> MLPW_parArr;
  688.     array<Parameter, NUM_OF_NETS> MLPB_parArr;
  689.     array<Parameter, NUM_OF_NETS> adapterW_parArr;
  690.     array<Parameter, NUM_OF_NETS> adapterB_parArr;
  691.    
  692.     //this is not a history, this is the real stuff
  693.     unordered_map<string, array<AdditionalParams, NUM_OF_NETS>* > additionalParams_mapOfArr((int)series_len*1.5); //per series, per net
  694.     for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  695.       string series=*iter;
  696.       additionalParams_mapOfArr[series]=new array<AdditionalParams, NUM_OF_NETS>();
  697.     }
  698.    
  699.     for (int inet=0; inet<NUM_OF_NETS; inet++) {
  700.       ParameterCollection& pc=paramsCollection_arr[inet];
  701.       ParameterCollection& perSeriesPC=perSeriesParamsCollection_arr[inet];
  702.      
  703.       trainers_arr[inet]=new AdamTrainer (pc, INITIAL_LEARNING_RATE, 0.9, 0.999, EPS);
  704.       trainers_arr[inet]->clip_threshold = GRADIENT_CLIPPING;
  705.       perSeriesTrainers_arr[inet]=new AdamTrainer (perSeriesPC, INITIAL_LEARNING_RATE*PER_SERIES_LR_MULTIP, 0.9, 0.999, EPS);
  706.       perSeriesTrainers_arr[inet]->clip_threshold = GRADIENT_CLIPPING;
  707.            
  708.     auto& rNNStack=rnnStack_arr[inet];
  709.     #if defined USE_RESIDUAL_LSTM
  710.       rNNStack.emplace_back(ResidualDilatedLSTMBuilder(dilations[0], INPUT_SIZE + NUM_OF_CATEGORIES, STATE_HSIZE, pc));
  711.       for (int il = 1; il<dilations.size(); il++)
  712.         rNNStack.emplace_back(ResidualDilatedLSTMBuilder(dilations[il], STATE_HSIZE, STATE_HSIZE, pc));
  713.     #elif defined USE_ATTENTIVE_LSTM
  714.       rNNStack.emplace_back(AttentiveDilatedLSTMBuilder(dilations[0], INPUT_SIZE + NUM_OF_CATEGORIES, STATE_HSIZE, ATTENTION_HSIZE, pc));
  715.       for (int il = 1; il<dilations.size(); il++)
  716.         rNNStack.emplace_back(AttentiveDilatedLSTMBuilder(dilations[il], STATE_HSIZE, STATE_HSIZE, ATTENTION_HSIZE, pc));
  717.     #else
  718.       rNNStack.emplace_back(DilatedLSTMBuilder(dilations[0], INPUT_SIZE + NUM_OF_CATEGORIES, STATE_HSIZE, pc));
  719.       for (int il = 1; il<dilations.size(); il++)
  720.         rNNStack.emplace_back(DilatedLSTMBuilder(dilations[il], STATE_HSIZE, STATE_HSIZE, pc));
  721.     #endif
  722.    
  723.       if (ADD_NL_LAYER) {
  724.         MLPW_parArr[inet] = pc.add_parameters({ STATE_HSIZE, STATE_HSIZE });
  725.         MLPB_parArr[inet] = pc.add_parameters({ STATE_HSIZE });
  726.       }
  727.       adapterW_parArr[inet]=pc.add_parameters({OUTPUT_SIZE*2, STATE_HSIZE});
  728.       adapterB_parArr[inet]=pc.add_parameters({OUTPUT_SIZE*2});
  729.      
  730.       for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  731.         string series=*iter;
  732.         array<AdditionalParams, NUM_OF_NETS>*  additionalParams_arr=additionalParams_mapOfArr[series];
  733.         additionalParams_arr->at(inet).levSm=perSeriesPC.add_parameters({1}, 0.5);//per series, per net
  734.         if (SEASONALITY_NUM > 0) {
  735.           additionalParams_arr->at(inet).sSm = perSeriesPC.add_parameters({ 1 }, 0.5);
  736.           for (int isea = 0; isea<SEASONALITY; isea++)
  737.             additionalParams_arr->at(inet).initSeasonality[isea] = perSeriesPC.add_parameters({ 1 }, 0.5);
  738.         }
  739.         if (SEASONALITY_NUM > 1) {
  740.           additionalParams_arr->at(inet).sSm2 = perSeriesPC.add_parameters({ 1 }, 0.5);
  741.           for (int isea = 0; isea<SEASONALITY2; isea++)
  742.             additionalParams_arr->at(inet).initSeasonality2[isea] = perSeriesPC.add_parameters({ 1 }, 0.5);
  743.         }
  744.       }
  745.     }//seting up, through nets
  746.    
  747.     //history of params. Series->[NUM_OF_NETS,NUM_OF_TRAIN_EPOCHS]
  748.     unordered_map<string, array<array<AdditionalParamsF, NUM_OF_TRAIN_EPOCHS>, NUM_OF_NETS>*> historyOfAdditionalParams_map((int)series_len*1.5);
  749.     for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  750.       string series=*iter;
  751.       historyOfAdditionalParams_map[series]=new array<array<AdditionalParamsF, NUM_OF_TRAIN_EPOCHS>, NUM_OF_NETS>();
  752.     }
  753.    
  754.     //first assignment. Yes, we are using vector , so the very first time the duplicates are possible. But a set can't be sorted
  755.     array<vector<string>, NUM_OF_NETS> seriesAssignment;//every net has an array
  756.     for (int j=0; j<NUM_OF_NETS/2; j++)
  757.       for (int i=0; i<series_len; i++) {
  758.         int inet=uniOnNets(rng);
  759.         seriesAssignment[inet].push_back(series_vect[i]);
  760.       }
  761.    
  762.     //nesting: ibig
  763.     for (int iEpoch=0; iEpoch<NUM_OF_TRAIN_EPOCHS; iEpoch++) {
  764.       #if defined USE_ODBC
  765.         TRYODBC(hInsertStmt,
  766.         SQL_HANDLE_STMT,
  767.         SQLBindParameter(hInsertStmt, 5, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&iEpoch, 0, NULL));
  768.       #endif
  769.    
  770.       unordered_map<string, array<float, NUM_OF_NETS>> netPerf_map;
  771.       for (int inet=0; inet<NUM_OF_NETS; inet++) {  //Parellalize here, if you can :-)
  772.         //initialize perf matrix
  773.         for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  774.           string series=*iter;
  775.           netPerf_map[series][inet]=BIG_FLOAT;
  776.         }
  777.        
  778.         ParameterCollection& pc=paramsCollection_arr[inet];      
  779.         auto& trainer=trainers_arr[inet];
  780.         ParameterCollection& perSeriesPC=perSeriesParamsCollection_arr[inet];
  781.         auto& perSeriesTrainer=perSeriesTrainers_arr[inet];
  782.        
  783.         if (LEARNING_RATES.find(iEpoch) != LEARNING_RATES.end()) {
  784.                 trainer->learning_rate = LEARNING_RATES.at(iEpoch);
  785.                 if (inet==0)
  786.                   cout << "changing LR to:" << trainer->learning_rate << endl;
  787.                 perSeriesTrainer->learning_rate = LEARNING_RATES.at(iEpoch)*PER_SERIES_LR_MULTIP;
  788.         }
  789.  
  790.         auto& rNNStack=rnnStack_arr[inet];
  791.         Parameter& MLPW_par = MLPW_parArr[inet];
  792.         Parameter& MLPB_par = MLPB_parArr[inet];
  793.         Parameter& adapterW_par=adapterW_parArr[inet];
  794.         Parameter& adapterB_par=adapterB_parArr[inet];
  795.        
  796.         vector<string> oneNetAssignments=seriesAssignment[inet];
  797.         random_shuffle (oneNetAssignments.begin(), oneNetAssignments.end());
  798.        
  799.         vector<float> epochLosses;
  800.         vector<float> forecLosses; vector<float> levVarLosses; vector<float> stateLosses;
  801.         for (auto iter = oneNetAssignments.begin() ; iter != oneNetAssignments.end(); ++iter) {
  802.           string series=*iter;
  803.           auto m4Obj=allSeries_map[series];
  804.        
  805.           ComputationGraph cg;
  806.           for (int il=0; il<dilations.size(); il++) {
  807.             rNNStack[il].new_graph(cg);
  808.             rNNStack[il].start_new_sequence();
  809.           }
  810.          
  811.           AdditionalParams& additionalParams=additionalParams_mapOfArr[series]->at(inet);
  812.           array<AdditionalParamsF, NUM_OF_TRAIN_EPOCHS>& historyOfAdditionalParams_arr=historyOfAdditionalParams_map[series]->at(inet);
  813.  
  814.                     Expression MLPW_ex,MLPB_ex;
  815.           if (ADD_NL_LAYER)  {
  816.             MLPW_ex = parameter(cg, MLPW_par);
  817.             MLPB_ex = parameter(cg, MLPB_par);
  818.           }
  819.           Expression adapterW_ex=parameter(cg, adapterW_par);
  820.           Expression adapterB_ex=parameter(cg, adapterB_par);
  821.  
  822.           Expression levSmSerNet0_ex= parameter(cg, additionalParams.levSm);
  823.           Expression levSm_ex = logistic(levSmSerNet0_ex);
  824.  
  825.           vector<Expression> season_exVect;//vector, because we do not know how long the series is
  826.           Expression sSm_ex;
  827.           if (SEASONALITY_NUM > 0) {
  828.             Expression sSmSerNet0_ex= parameter(cg, additionalParams.sSm);
  829.             sSm_ex = logistic(sSmSerNet0_ex);
  830.            
  831.             for (int isea = 0; isea<SEASONALITY; isea++) {
  832.               Expression sSerNet0 = parameter(cg, additionalParams.initSeasonality[isea]);  //per series, per net
  833.               Expression s1_ex = exp(sSerNet0);
  834.               season_exVect.push_back(s1_ex);//Expression is a simple struct, without any storage management, so the auto copy constructor works OK.            
  835.             }
  836.             season_exVect.push_back(season_exVect[0]);
  837.           }
  838.  
  839.           vector<Expression> season2_exVect;//vector, because we do not know how long the series is
  840.           Expression sSm2_ex;
  841.           if (SEASONALITY_NUM > 1) {
  842.             Expression sSm2SerNet0_ex= parameter(cg, additionalParams.sSm2);
  843.             sSm2_ex = logistic(sSm2SerNet0_ex);
  844.            
  845.             for (int isea = 0; isea<SEASONALITY2; isea++) {
  846.               Expression sSer2Net0 = parameter(cg, additionalParams.initSeasonality2[isea]);  //per series, per net
  847.               Expression s2_ex = exp(sSer2Net0);
  848.               season2_exVect.push_back(s2_ex);//Expression is a simple struct, without any storage management, so the auto copy constructor works OK.            
  849.             }
  850.             season2_exVect.push_back(season2_exVect[0]);
  851.           }
  852.  
  853.               vector<Expression> logDiffOfLevels_vect;
  854.           vector<Expression> levels_exVect;
  855.           if (SEASONALITY_NUM == 0) {
  856.             levels_exVect.push_back(input(cg, m4Obj.vals[0]));
  857.             for (int i = 1; i<m4Obj.vals.size(); i++) {
  858.               Expression newLevel_ex = levSm_ex*m4Obj.vals[i] + (1 - levSm_ex)*levels_exVect[i - 1];
  859.               levels_exVect.push_back(newLevel_ex);
  860.             }
  861.           }
  862.           else if (SEASONALITY_NUM == 1) {
  863.             Expression lev = cdiv(input(cg, m4Obj.vals[0]), season_exVect[0]);
  864.             levels_exVect.push_back(lev);
  865.             for (int i = 1; i<m4Obj.vals.size(); i++) {//Exponential Smoothing-style deseasonalization and smoothing
  866.               Expression newLevel_ex = m4Obj.vals[i] * cdiv(levSm_ex, season_exVect[i]) + (1 - levSm_ex)*levels_exVect[i - 1];
  867.               levels_exVect.push_back(newLevel_ex);
  868.               Expression diff_ex = log(cdiv(newLevel_ex, levels_exVect[i - 1])); //penalty for wiggliness of level
  869.               logDiffOfLevels_vect.push_back(diff_ex);
  870.  
  871.               Expression newSeason_ex = m4Obj.vals[i] * cdiv(sSm_ex, newLevel_ex) + (1 - sSm_ex)*season_exVect[i];
  872.               season_exVect.push_back(newSeason_ex);
  873.             }
  874.  
  875.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  876.             if (OUTPUT_SIZE>SEASONALITY) {
  877.               unsigned long startSeasonalityIndx = season_exVect.size() - SEASONALITY;
  878.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY); i++)
  879.                 season_exVect.push_back(season_exVect[startSeasonalityIndx + i]);
  880.             }
  881.           }
  882.           else if (SEASONALITY_NUM == 2) {
  883.             Expression lev = cdiv(input(cg, m4Obj.vals[0]), season_exVect[0] * season2_exVect[0]);
  884.             levels_exVect.push_back(lev);
  885.             for (int i = 1; i<m4Obj.vals.size(); i++) {
  886.               Expression newLevel_ex = m4Obj.vals[i] * cdiv(levSm_ex, season_exVect[i] * season2_exVect[i]) + (1 - levSm_ex)*levels_exVect[i - 1];
  887.               levels_exVect.push_back(newLevel_ex);
  888.               Expression diff_ex = log(cdiv(newLevel_ex, levels_exVect[i - 1]));
  889.               logDiffOfLevels_vect.push_back(diff_ex);
  890.  
  891.               Expression newSeason_ex = m4Obj.vals[i] * cdiv(sSm_ex, newLevel_ex*season2_exVect[i]) + (1 - sSm_ex)*season_exVect[i];
  892.               season_exVect.push_back(newSeason_ex);
  893.               Expression newSeason2_ex = m4Obj.vals[i] * cdiv(sSm2_ex, newLevel_ex*season_exVect[i]) + (1 - sSm2_ex)*season2_exVect[i];
  894.               season2_exVect.push_back(newSeason2_ex);
  895.             }
  896.  
  897.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  898.             if (OUTPUT_SIZE>SEASONALITY) {
  899.               unsigned long startSeasonalityIndx = season_exVect.size() - SEASONALITY;
  900.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY); i++)
  901.                 season_exVect.push_back(season_exVect[startSeasonalityIndx + i]);
  902.             }
  903.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  904.             if (OUTPUT_SIZE>SEASONALITY2) {
  905.               unsigned long startSeasonalityIndx = season2_exVect.size() - SEASONALITY2;
  906.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY2); i++)
  907.                 season2_exVect.push_back(season2_exVect[startSeasonalityIndx + i]);
  908.             }
  909.           }
  910.           else {
  911.             cerr<<"SEASONALITY_NUM="<< SEASONALITY_NUM;
  912.             exit(-1);
  913.           }
  914.              
  915.           Expression levelVarLoss_ex;
  916.           if (LEVEL_VARIABILITY_PENALTY > 0) {
  917.             vector<Expression> levelVarLoss_v;
  918.             for (int i = 1; i<logDiffOfLevels_vect.size(); i++) {
  919.               Expression diff_ex = logDiffOfLevels_vect[i] - logDiffOfLevels_vect[i - 1];
  920.               levelVarLoss_v.push_back(diff_ex*diff_ex);
  921.             }
  922.             levelVarLoss_ex = average(levelVarLoss_v);
  923.           }
  924.                
  925.           Expression inputSeasonality_ex; Expression inputSeasonality2_ex;
  926.           Expression outputSeasonality_ex; Expression outputSeasonality2_ex;
  927.           vector<Expression> losses;//losses of steps through single time series
  928.           for (int i=INPUT_SIZE-1; i<(m4Obj.n- OUTPUT_SIZE); i++) {
  929.             vector<float>::const_iterator first = m4Obj.vals.begin() + i + 1 - INPUT_SIZE;
  930.             vector<float>::const_iterator pastLast = m4Obj.vals.begin() + i + 1; //not including the last one
  931.             vector<float> input_vect(first, pastLast); //[first,pastLast)
  932.  
  933.             first = m4Obj.vals.begin() + i + 1;
  934.             pastLast = m4Obj.vals.begin() + i + 1 + OUTPUT_SIZE;
  935.             vector<float> labels_vect(first, pastLast);  //[first,pastLast)
  936.  
  937.             Expression input1_ex = input(cg, { INPUT_SIZE }, input_vect);
  938.             Expression labels1_ex = input(cg, { OUTPUT_SIZE }, labels_vect);
  939.  
  940.             if (SEASONALITY_NUM > 0 ) {
  941.                     vector<Expression>::const_iterator firstE = season_exVect.begin() +i+1-INPUT_SIZE;
  942.                     vector<Expression>::const_iterator pastLastE = season_exVect.begin() +i+1; //not including the last one
  943.                     vector<Expression> inputSeasonality_exVect(firstE, pastLastE);  //[first,pastLast)
  944.                     inputSeasonality_ex=concatenate(inputSeasonality_exVect);
  945.  
  946.               firstE = season_exVect.begin() + i + 1;
  947.               pastLastE = season_exVect.begin() + i + 1 + OUTPUT_SIZE;
  948.               vector<Expression> outputSeasonality_exVect(firstE, pastLastE);  //[first,pastLast)
  949.               outputSeasonality_ex = concatenate(outputSeasonality_exVect);
  950.  
  951.               input1_ex = cdiv(input1_ex, inputSeasonality_ex); // input deseasonalization
  952.               labels1_ex = cdiv(labels1_ex, outputSeasonality_ex); //output deseasonalization
  953.             }
  954.             if (SEASONALITY_NUM > 1) {
  955.               vector<Expression>::const_iterator firstE = season2_exVect.begin() + i + 1 - INPUT_SIZE;
  956.               vector<Expression>::const_iterator pastLastE = season2_exVect.begin() + i + 1; //not including the last one
  957.               vector<Expression> inputSeasonality2_exVect(firstE, pastLastE);  //[first,pastLast)
  958.               inputSeasonality2_ex = concatenate(inputSeasonality2_exVect);
  959.  
  960.               firstE = season2_exVect.begin() + i + 1;
  961.               pastLastE = season2_exVect.begin() + i + 1 + OUTPUT_SIZE;
  962.               vector<Expression> outputSeasonality2_exVect(firstE, pastLastE);  //[first,pastLast)
  963.               Expression outputSeasonality2_ex = concatenate(outputSeasonality2_exVect);
  964.  
  965.               input1_ex = cdiv(input1_ex, inputSeasonality2_ex); //input deseasonalization
  966.               labels1_ex = cdiv(labels1_ex, outputSeasonality2_ex); //output deseasonalization
  967.             }
  968.  
  969.             vector<Expression> joinedInput_ex;
  970.             joinedInput_ex.emplace_back(noise(squash(cdiv(input1_ex, levels_exVect[i])), NOISE_STD)); //input normalization+noise
  971.             joinedInput_ex.emplace_back(input(cg, { NUM_OF_CATEGORIES }, m4Obj.categories_vect));
  972.             Expression input_ex = concatenate(joinedInput_ex);
  973.  
  974.             Expression labels_ex = squash(cdiv(labels1_ex, levels_exVect[i]));//output normalization
  975.  
  976.             Expression rnn_ex;
  977.             try {
  978.               rnn_ex = rNNStack[0].add_input(input_ex);
  979.               for (int il=1; il<dilations.size(); il++)
  980.                 rnn_ex=rnn_ex+rNNStack[il].add_input(rnn_ex); //resNet-style
  981.             }  catch (exception& e) {
  982.               cerr<<"cought exception 2 while doing "<<series<<endl;
  983.               cerr << e.what() << endl;
  984.               cerr<<as_vector(input_ex.value())<<endl;
  985.             }
  986.             Expression out_ex;
  987.             if (ADD_NL_LAYER) {
  988.               out_ex=MLPW_ex*rnn_ex+MLPB_ex;
  989.               out_ex = adapterW_ex*tanh(out_ex)+adapterB_ex;
  990.             } else
  991.               out_ex=adapterW_ex*rnn_ex+adapterB_ex;
  992.  
  993.             Expression loss_ex=MSIS(out_ex, labels_ex);
  994.             //Expression loss_ex = pinBallLoss(out_ex, labels_ex);
  995.             if (i>=INPUT_SIZE+MIN_INP_SEQ_LEN)
  996.                 losses.push_back(loss_ex);
  997.           }//through points of a series
  998.  
  999.           Expression forecLoss_ex= average(losses);
  1000.                 Expression loss_exp = forecLoss_ex;
  1001.                
  1002.           float levVarLoss=0;
  1003.           if (LEVEL_VARIABILITY_PENALTY > 0) {
  1004.             Expression levelVarLossP_ex = levelVarLoss_ex*LEVEL_VARIABILITY_PENALTY;
  1005.             levVarLoss = as_scalar(levelVarLossP_ex.value());
  1006.             levVarLosses.push_back(levVarLoss);
  1007.             loss_exp= loss_exp + levelVarLossP_ex;
  1008.           }
  1009.  
  1010.           float cStateLoss=0;
  1011.           if (C_STATE_PENALTY>0) {
  1012.             vector<Expression> cStateLosses_vEx;
  1013.             for (int irnn = 0; irnn < rNNStack.size(); irnn++)
  1014.               for (int it = 0; it<rNNStack[irnn].c.size(); it++) {  //first index is time
  1015.                 auto& state_ex = rNNStack[irnn].c[it][0]; //c-state of first layer in a chunk at time it
  1016.                 Expression penalty_ex = square(state_ex);
  1017.                 cStateLosses_vEx.push_back(mean_elems(penalty_ex));
  1018.               }
  1019.           Expression cStateLossP_ex = average(cStateLosses_vEx)*C_STATE_PENALTY;
  1020.           cStateLoss = as_scalar(cStateLossP_ex.value());
  1021.           stateLosses.push_back(cStateLoss);
  1022.           loss_exp = loss_exp + cStateLossP_ex;
  1023.         }
  1024.          
  1025.         float loss = as_scalar(cg.forward(loss_exp));
  1026.         epochLosses.push_back(loss);//losses of all series in one epoch
  1027.  
  1028.         float forecastLoss = loss - levVarLoss - cStateLoss;
  1029.           forecLosses.push_back(forecastLoss);
  1030.        
  1031.           cg.backward(loss_exp);
  1032.           try {
  1033.             trainer->update();//update shared weights
  1034.             perSeriesTrainer->update();//update params of this series only
  1035.           } catch (exception& e) {//it may happen occasionally. I believe it is due to not robust enough implementation of squashing functions in Dynet. When abs(x)>35 NAs appear.
  1036.           //so the code below is trying to produce some diagnostics, hopefully useful when setting LEVEL_VARIABILITY_PENALTY and  C_STATE_PENALTY.
  1037.             cerr<<"cought exception while doing "<<series<<endl;
  1038.             cerr << e.what() << endl;
  1039.            
  1040.             float minSeason=BIG_FLOAT;
  1041.             for (int isea = 0; isea < season_exVect.size(); isea++) {
  1042.               float val= as_scalar(season_exVect[isea].value());
  1043.               //cout << " " << val;
  1044.               if (val<minSeason)
  1045.                 minSeason=val;
  1046.             }  
  1047.             cout << "min season:"<<minSeason<<endl;
  1048.  
  1049.             minSeason = BIG_FLOAT;
  1050.             for (int isea = 0; isea < season2_exVect.size(); isea++) {
  1051.               float val = as_scalar(season2_exVect[isea].value());
  1052.               //cout << " " << val;
  1053.               if (val<minSeason)
  1054.                 minSeason = val;
  1055.             }
  1056.             cout << "min season2:"<<minSeason<<endl;
  1057.  
  1058.             float minLevel = BIG_FLOAT;
  1059.             for (int isea = 0; isea < levels_exVect.size(); isea++) {
  1060.               float val = as_scalar(levels_exVect[isea].value());
  1061.               //cout << " " << val;
  1062.               if (val<minLevel)
  1063.                 minLevel = val;
  1064.             }
  1065.             cout << "min level:"<<minLevel<<endl;
  1066.  
  1067.             float maxAbs = 0; int timeOfMax = 0; int layerOfMax = 0; int chunkOfMax=0;
  1068.             for (int irnn = 0; irnn < rNNStack.size(); irnn++) {
  1069.               auto state_vEx= rNNStack[irnn].c;//(time,layers)
  1070.               for (int it = 0; it < state_vEx.size(); it++) {  //through time
  1071.                 for (int il = 0; il < state_vEx[it].size(); il++) {//through layers. Each layer has two states: c and h
  1072.                   auto state=as_vector(state_vEx[it][il].value());
  1073.                   for (int iv = 0; iv < state.size(); iv++) {
  1074.                     if (abs(state[iv]) > maxAbs) {
  1075.                       maxAbs = abs(state[iv]);
  1076.                       timeOfMax=it;
  1077.                       layerOfMax=il;
  1078.                       chunkOfMax= irnn;
  1079.                     }
  1080.                   }
  1081.                 } //through layers/states
  1082.               } //through time
  1083.             }  //through chunks
  1084.  
  1085.             cout << "levSm:" << as_scalar(levSm_ex.value()) << endl;
  1086.             if (SEASONALITY_NUM > 0)
  1087.               cout << "sSm:" << as_scalar(sSm_ex.value()) << endl;
  1088.             if (SEASONALITY_NUM > 1)
  1089.               cout << "sSm2:" << as_scalar(sSm2_ex.value()) << endl;
  1090.             cout << "max abs:" << maxAbs <<" at time:"<< timeOfMax<<" at layer:"<< layerOfMax<<" and chunk:"<< chunkOfMax<<endl;
  1091.  
  1092.             //diagSeries.insert(series);
  1093.             pc.reset_gradient();
  1094.             perSeriesPC.reset_gradient();
  1095.           }
  1096.  
  1097.           //diagnostics saving
  1098.           AdditionalParamsF histAdditionalParams;
  1099.           histAdditionalParams.levSm=as_scalar(levSm_ex.value());
  1100.           if (iEpoch == 1 || iEpoch == NUM_OF_TRAIN_EPOCHS / 2 || iEpoch == NUM_OF_TRAIN_EPOCHS - 1) {
  1101.             for (int iv = 0; iv<levels_exVect.size(); iv++) {
  1102.               histAdditionalParams.levels.push_back(as_scalar(levels_exVect[iv].value()));
  1103.             }
  1104.           }
  1105.  
  1106.           if (SEASONALITY_NUM > 0) {
  1107.             histAdditionalParams.sSm=as_scalar(sSm_ex.value());
  1108.             for (int isea = 0; isea<SEASONALITY; isea++)
  1109.               histAdditionalParams.initSeasonality[isea] = as_scalar(season_exVect[isea].value());
  1110.  
  1111.             if (iEpoch == 1 || iEpoch == NUM_OF_TRAIN_EPOCHS / 2 || iEpoch == NUM_OF_TRAIN_EPOCHS - 1) {
  1112.               for (int iv = 0; iv<season_exVect.size(); iv++) {
  1113.                 histAdditionalParams.seasons.push_back(as_scalar(season_exVect[iv].value()));
  1114.               }
  1115.             }
  1116.           }
  1117.          
  1118.           if (SEASONALITY_NUM > 1) {
  1119.             histAdditionalParams.sSm2 = as_scalar(sSm2_ex.value());
  1120.                 for (int isea=0; isea<SEASONALITY2; isea++)
  1121.                     histAdditionalParams.initSeasonality2[isea]=as_scalar(season2_exVect[isea].value());  
  1122.                
  1123.             if (iEpoch == 1 || iEpoch == NUM_OF_TRAIN_EPOCHS / 2 || iEpoch == NUM_OF_TRAIN_EPOCHS - 1) {
  1124.               for (int iv = 0; iv<season2_exVect.size(); iv++) {
  1125.                 histAdditionalParams.seasons2.push_back(as_scalar(season2_exVect[iv].value()));
  1126.               }
  1127.             }
  1128.           }    
  1129.  
  1130.           historyOfAdditionalParams_arr[iEpoch]=histAdditionalParams;
  1131.         }//through series
  1132.  
  1133.         float averageLoss = accumulate( epochLosses.begin(), epochLosses.end(), 0.0)/epochLosses.size();
  1134.         cout << ibig << " " << iEpoch << " " << inet << " count:" << oneNetAssignments.size() << " loss:" << averageLoss * 100;
  1135.         if (LEVEL_VARIABILITY_PENALTY > 0 || C_STATE_PENALTY > 0) {
  1136.           float averageForecLoss = accumulate(forecLosses.begin(), forecLosses.end(), 0.0) / forecLosses.size();
  1137.           cout << " forec loss:" << averageForecLoss * 100;
  1138.         }
  1139.         if (LEVEL_VARIABILITY_PENALTY > 0) {
  1140.           float averagelevVarLoss = accumulate(levVarLosses.begin(), levVarLosses.end(), 0.0) / levVarLosses.size();
  1141.           cout << " levVar loss:" << averagelevVarLoss * 100;
  1142.         }
  1143.         if (C_STATE_PENALTY > 0) {
  1144.           float averageStateLoss = accumulate(stateLosses.begin(), stateLosses.end(), 0.0) / stateLosses.size();
  1145.           cout << " state loss:" << averageStateLoss * 100;
  1146.         }
  1147.         cout<<endl;
  1148.       }//through nets. This should be done in parallel. One day it will, when Dynet allows it.
  1149.  
  1150.  
  1151.       //Validation. We just save outputs of all nets on all series
  1152.       //We can't attach validation to training, because training happens across subset of series*nets, and we need to store results from all of these combinations, for future use
  1153.       //level: epoch, but we do not use the epoch value, we overwrite
  1154.       for (int inet=0; inet<NUM_OF_NETS; inet++) { //through _all_ nets. Paralellize here.
  1155.         auto& rNNStack=rnnStack_arr[inet];
  1156.         Parameter& MLPW_par = MLPW_parArr[inet];
  1157.         Parameter& MLPB_par = MLPB_parArr[inet];
  1158.         Parameter& adapterW_par=adapterW_parArr[inet];
  1159.         Parameter& adapterB_par=adapterB_parArr[inet];
  1160.  
  1161.         for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {//through _all_ series.
  1162.           string series=*iter;
  1163.           auto m4Obj=allSeries_map[series];
  1164.  
  1165.           ComputationGraph cg;
  1166.           for (int il=0; il<dilations.size(); il++) {
  1167.             rNNStack[il].new_graph(cg);
  1168.             rNNStack[il].start_new_sequence();
  1169.           }
  1170.          
  1171.           AdditionalParams& additionalParams=additionalParams_mapOfArr[series]->at(inet);
  1172.           Expression MLPW_ex, MLPB_ex;
  1173.           if (ADD_NL_LAYER) {
  1174.             MLPW_ex = parameter(cg, MLPW_par);
  1175.             MLPB_ex = parameter(cg, MLPB_par);
  1176.           }
  1177.           Expression adapterW_ex=parameter(cg, adapterW_par);
  1178.           Expression adapterB_ex=parameter(cg, adapterB_par);
  1179.  
  1180.           Expression levSmSerNet0_ex = parameter(cg, additionalParams.levSm);
  1181.           Expression levSm_ex = logistic(levSmSerNet0_ex);
  1182.          
  1183.           vector<Expression> season_exVect;//vector, because we do not know how long the series is
  1184.           Expression sSm_ex;
  1185.           if (SEASONALITY_NUM > 0) {
  1186.             Expression sSmSerNet0_ex= parameter(cg, additionalParams.sSm);
  1187.             sSm_ex = logistic(sSmSerNet0_ex);
  1188.  
  1189.             for (int isea = 0; isea<SEASONALITY; isea++) {
  1190.               Expression sSerNet0 = parameter(cg, additionalParams.initSeasonality[isea]);  //per series, per net
  1191.               Expression s1_ex = exp(sSerNet0);
  1192.               season_exVect.push_back(s1_ex);//Expression is a simple struct, without any storage management, so the auto copy constructor works OK.
  1193.             }
  1194.             season_exVect.push_back(season_exVect[0]);
  1195.           }
  1196.  
  1197.           vector<Expression> season2_exVect;//vector, because we do not know how long the series is
  1198.           Expression sSm2_ex;
  1199.           if (SEASONALITY_NUM > 1) {
  1200.             Expression sSm2SerNet0_ex= parameter(cg, additionalParams.sSm2);
  1201.             sSm2_ex = logistic(sSm2SerNet0_ex);
  1202.  
  1203.             for (int isea = 0; isea<SEASONALITY2; isea++) {
  1204.               Expression sSer2Net0 = parameter(cg, additionalParams.initSeasonality2[isea]);  //per series, per net
  1205.               Expression s2_ex = exp(sSer2Net0);
  1206.               season2_exVect.push_back(s2_ex);//Expression is a simple struct, without any storage management, so the auto copy constructor works OK.
  1207.             }
  1208.             season2_exVect.push_back(season2_exVect[0]);
  1209.           }
  1210.  
  1211.           vector<Expression> levels_exVect;
  1212.           if (SEASONALITY_NUM == 0) {
  1213.             levels_exVect.push_back(input(cg, m4Obj.vals[0]));
  1214.             for (int i = 1; i<m4Obj.vals.size(); i++) {
  1215.               Expression newLevel_ex = levSm_ex*m4Obj.vals[i] + (1 - levSm_ex)*levels_exVect[i - 1];
  1216.               levels_exVect.push_back(newLevel_ex);
  1217.             }
  1218.           }
  1219.           else if (SEASONALITY_NUM == 1) {
  1220.             Expression lev = cdiv(input(cg, m4Obj.vals[0]), season_exVect[0]);
  1221.             levels_exVect.push_back(lev);
  1222.             for (int i = 1; i<m4Obj.vals.size(); i++) {//if lback>0 then this is shortened, so it always contains data awe have right to access
  1223.               Expression newLevel_ex = m4Obj.vals[i] * cdiv(levSm_ex, season_exVect[i]) + (1 - levSm_ex)*levels_exVect[i - 1];
  1224.               levels_exVect.push_back(newLevel_ex);
  1225.  
  1226.               Expression newSeason_ex = m4Obj.vals[i] * cdiv(sSm_ex, newLevel_ex) + (1 - sSm_ex)*season_exVect[i];
  1227.               season_exVect.push_back(newSeason_ex);
  1228.             }
  1229.  
  1230.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  1231.             if (OUTPUT_SIZE>SEASONALITY) {
  1232.               unsigned long startSeasonalityIndx = season_exVect.size() - SEASONALITY;
  1233.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY); i++)
  1234.                 season_exVect.push_back(season_exVect[startSeasonalityIndx + i]);
  1235.             }
  1236.           }
  1237.           else if (SEASONALITY_NUM == 2) {
  1238.             Expression lev = cdiv(input(cg, m4Obj.vals[0]), season_exVect[0] * season2_exVect[0]);
  1239.             levels_exVect.push_back(lev);
  1240.             for (int i = 1; i<m4Obj.vals.size(); i++) {
  1241.               Expression newLevel_ex = m4Obj.vals[i] * cdiv(levSm_ex, season_exVect[i] * season2_exVect[i]) + (1 - levSm_ex)*levels_exVect[i - 1];
  1242.               levels_exVect.push_back(newLevel_ex);
  1243.  
  1244.               Expression newSeason_ex = m4Obj.vals[i] * cdiv(sSm_ex, newLevel_ex*season2_exVect[i]) + (1 - sSm_ex)*season_exVect[i];
  1245.               season_exVect.push_back(newSeason_ex);
  1246.               Expression newSeason2_ex = m4Obj.vals[i] * cdiv(sSm2_ex, newLevel_ex*season_exVect[i]) + (1 - sSm2_ex)*season2_exVect[i];
  1247.               season2_exVect.push_back(newSeason2_ex);
  1248.             }
  1249.  
  1250.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  1251.             if (OUTPUT_SIZE>SEASONALITY) {
  1252.               unsigned long startSeasonalityIndx = season_exVect.size() - SEASONALITY;
  1253.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY); i++)
  1254.                 season_exVect.push_back(season_exVect[startSeasonalityIndx + i]);
  1255.             }
  1256.             //if prediction horizon is larger than seasonality, so we need to repeat some of the seasonality factors
  1257.             if (OUTPUT_SIZE>SEASONALITY2) {
  1258.               unsigned long startSeasonalityIndx = season2_exVect.size() - SEASONALITY2;
  1259.               for (int i = 0; i<(OUTPUT_SIZE - SEASONALITY2); i++)
  1260.                 season2_exVect.push_back(season2_exVect[startSeasonalityIndx + i]);
  1261.             }
  1262.           }
  1263.           else {
  1264.             cerr<<"SEASONALITY_NUM="<< SEASONALITY_NUM;
  1265.             exit(-1);
  1266.           }
  1267.  
  1268.  
  1269.           Expression inputSeasonality_ex; Expression inputSeasonality2_ex;
  1270.           Expression outputSeasonality_ex; Expression outputSeasonality2_ex;
  1271.           vector<Expression> losses;//losses of steps through single time series
  1272.           Expression out_ex;//we declare it here, bcause the last one will be the forecast
  1273.           for (int i=INPUT_SIZE-1; i<m4Obj.n; i++) {
  1274.             vector<float>::const_iterator first = m4Obj.vals.begin() + i + 1 - INPUT_SIZE;
  1275.             vector<float>::const_iterator pastLast = m4Obj.vals.begin() + i + 1; //not including the last one
  1276.             vector<float> input_vect(first, pastLast); //[first,pastLast)
  1277.             Expression input1_ex = input(cg, { INPUT_SIZE }, input_vect);
  1278.  
  1279.             if (SEASONALITY_NUM > 0 ) {
  1280.                     vector<Expression>::const_iterator firstE = season_exVect.begin() +i+1-INPUT_SIZE;
  1281.                     vector<Expression>::const_iterator pastLastE = season_exVect.begin() +i+1; //not including the last one
  1282.                     vector<Expression> inputSeasonality_exVect(firstE, pastLastE);  //[first,pastLast)
  1283.                     inputSeasonality_ex=concatenate(inputSeasonality_exVect);
  1284.               input1_ex = cdiv(input1_ex, inputSeasonality_ex); // input deseasonalization
  1285.             }
  1286.             if (SEASONALITY_NUM > 1) {
  1287.               vector<Expression>::const_iterator firstE = season2_exVect.begin() + i + 1 - INPUT_SIZE;
  1288.               vector<Expression>::const_iterator pastLastE = season2_exVect.begin() + i + 1; //not including the last one
  1289.               vector<Expression> inputSeasonality2_exVect(firstE, pastLastE);  //[first,pastLast)
  1290.               inputSeasonality2_ex = concatenate(inputSeasonality2_exVect);
  1291.               input1_ex = cdiv(input1_ex, inputSeasonality2_ex); //input deseasonalization
  1292.             }
  1293.  
  1294.             vector<Expression> joinedInput_ex;
  1295.             joinedInput_ex.emplace_back(noise(squash(cdiv(input1_ex, levels_exVect[i])), NOISE_STD)); //input normalization+noise
  1296.             joinedInput_ex.emplace_back(input(cg, { NUM_OF_CATEGORIES }, m4Obj.categories_vect));
  1297.             Expression input_ex = concatenate(joinedInput_ex);
  1298.  
  1299.             Expression rnn_ex;
  1300.             try {
  1301.               rnn_ex = rNNStack[0].add_input(input_ex);
  1302.               for (int il=1; il<dilations.size(); il++)
  1303.                 rnn_ex=rnn_ex+rNNStack[il].add_input(rnn_ex);
  1304.             }  catch (exception& e) {
  1305.               cerr<<"cought exception 2 while doing "<<series<<endl;
  1306.               cerr << e.what() << endl;
  1307.               cerr<<as_vector(input_ex.value())<<endl;
  1308.             }
  1309.             if (ADD_NL_LAYER) {
  1310.               out_ex=MLPW_ex*rnn_ex+MLPB_ex;
  1311.               out_ex = adapterW_ex*tanh(out_ex)+adapterB_ex;
  1312.             } else
  1313.               out_ex=adapterW_ex*rnn_ex+adapterB_ex;
  1314.  
  1315.             if (i<(m4Obj.n- OUTPUT_SIZE)) {//calc perf on training area
  1316.               vector<float>::const_iterator first = m4Obj.vals.begin() + i + 1;
  1317.               vector<float>::const_iterator pastLast = m4Obj.vals.begin() + i + 1 + OUTPUT_SIZE;
  1318.               vector<float> labels_vect(first, pastLast);  //[first,pastLast)
  1319.               Expression labels1_ex = input(cg, { OUTPUT_SIZE }, labels_vect);
  1320.  
  1321.               if (SEASONALITY_NUM > 0) {
  1322.                 vector<Expression>::const_iterator firstE = season_exVect.begin() + i + 1;
  1323.                 vector<Expression>::const_iterator pastLastE = season_exVect.begin() + i + 1 + OUTPUT_SIZE;
  1324.                 vector<Expression> outputSeasonality_exVect(firstE, pastLastE);  //[first,pastLast)
  1325.                 outputSeasonality_ex = concatenate(outputSeasonality_exVect);
  1326.                 labels1_ex = cdiv(labels1_ex, outputSeasonality_ex); //output deseasonalization
  1327.               }
  1328.               if (SEASONALITY_NUM > 1) {
  1329.                 vector<Expression>::const_iterator firstE = season2_exVect.begin() + i + 1;
  1330.                 vector<Expression>::const_iterator pastLastE = season2_exVect.begin() + i + 1 + OUTPUT_SIZE;//checking if enough elements is in the vecor was done a few pe
  1331.                 vector<Expression> outputSeasonality2_exVect(firstE, pastLastE);  //[first,pastLast)
  1332.                 Expression outputSeasonality2_ex = concatenate(outputSeasonality2_exVect);
  1333.                 labels1_ex = cdiv(labels1_ex, outputSeasonality2_ex); //output deseasonalization
  1334.               }
  1335.               Expression labels_ex = squash(cdiv(labels1_ex, levels_exVect[i]));//output normalization
  1336.  
  1337.               //Expression loss_ex = pinBallLoss(out_ex, labels_ex);
  1338.               Expression loss_ex = MSIS(out_ex, labels_ex);
  1339.               if (i>=INPUT_SIZE+MIN_INP_SEQ_LEN)
  1340.                       losses.push_back(loss_ex);  //training area losses
  1341.             }
  1342.            
  1343.             if (i==(m4Obj.n-1)) {//validation loss
  1344.                 out_ex=expand(out_ex)*levels_exVect[i];//back to original scale
  1345.                             if (SEASONALITY_NUM > 0 ) {
  1346.                 vector<Expression>::const_iterator firstE = season_exVect.begin() + i + 1;
  1347.                 vector<Expression>::const_iterator pastLastE = season_exVect.begin() + i + 1 + OUTPUT_SIZE;
  1348.                 vector<Expression> outputSeasonality_exVect(firstE, pastLastE);  //[first,pastLast)
  1349.                 for (int ios=0; ios<OUTPUT_SIZE; ios++)
  1350.                   outputSeasonality_exVect.push_back(outputSeasonality_exVect[ios]);//we are duplicating it, as we deal with two outputs
  1351.                 outputSeasonality_ex = concatenate(outputSeasonality_exVect);
  1352.                 out_ex = cmult(out_ex, outputSeasonality_ex);//reseasonalize
  1353.               }
  1354.                 if (SEASONALITY_NUM > 1 ) {
  1355.                 vector<Expression>::const_iterator firstE = season2_exVect.begin() + i + 1;
  1356.                 vector<Expression>::const_iterator pastLastE = season2_exVect.begin() + i + 1 + OUTPUT_SIZE;
  1357.                 vector<Expression> outputSeasonality2_exVect(firstE, pastLastE);  //[first,pastLast)
  1358.                 for (int ios = 0; ios<OUTPUT_SIZE; ios++)
  1359.                   outputSeasonality2_exVect.push_back(outputSeasonality2_exVect[ios]);//we are duplicating it, as we deal with two outputs
  1360.                 Expression outputSeasonality2_ex = concatenate(outputSeasonality2_exVect);
  1361.                     out_ex = cmult(out_ex, outputSeasonality2_ex);//reseasonalize
  1362.               }
  1363.                 //we do not need the matching label here, because we do not bother calculate valid losses of each net across all series.
  1364.                 //We care about best and topn performance
  1365.             }
  1366.           }//end of going through all point of a series
  1367.          
  1368.           Expression loss_exp = average(losses);
  1369.           float loss = as_scalar(cg.forward(loss_exp));//training loss of a single series
  1370.           netPerf_map[series][inet]=loss;
  1371.          
  1372.           //unordered_map<string, array<array<array<vector<float>, AVERAGING_LEVEL+1>, NUM_OF_NETS>, BIG_LOOP>> testResults_map((int)series_len*1.5);//per series, big loop, etc...
  1373.           //No epoch here, because this will just reflect the current (latest) situation - the last few epochs
  1374.           vector<float> out_vect=as_vector(out_ex.value());
  1375.           testResults_map[series][inet][iEpoch%AVERAGING_LEVEL]=out_vect;
  1376.           if (iEpoch>=AVERAGING_LEVEL && iEpoch % FREQ_OF_TEST==0) {
  1377.             vector<float> firstForec=testResults_map[series][inet][0];
  1378.             testResults_map[series][inet][AVERAGING_LEVEL]=firstForec;
  1379.             for (int ii=1; ii<AVERAGING_LEVEL; ii++) {
  1380.               vector<float> nextForec=testResults_map[series][inet][ii];
  1381.               for (int iii=0; iii<2*OUTPUT_SIZE; iii++)
  1382.                 testResults_map[series][inet][AVERAGING_LEVEL][iii]+=nextForec[iii];
  1383.             }
  1384.             for (int iii=0; iii<2*OUTPUT_SIZE; iii++)
  1385.               testResults_map[series][inet][AVERAGING_LEVEL][iii]/=AVERAGING_LEVEL;
  1386.           } //time to average
  1387.         }//through series
  1388.       } //through nets
  1389.      
  1390.       if (iEpoch>0 && iEpoch % FREQ_OF_TEST==0) {
  1391.         //now that we have saved outputs of all nets on all series, let's calc how best and topn combinations performed during current epoch.
  1392.         vector<float> bestEpochLosses;
  1393.         vector<float> bestEpochAvgLosses;
  1394.         vector<float> topnEpochLosses;
  1395.         vector<float> topnEpochAvgLosses;
  1396.         vector<float> bestEpochLossesL;
  1397.         vector<float> bestEpochAvgLossesL;
  1398.         vector<float> topnEpochLossesL;
  1399.         vector<float> topnEpochAvgLossesL;
  1400.         vector<float> bestEpochLossesH;
  1401.         vector<float> bestEpochAvgLossesH;
  1402.         vector<float> topnEpochLossesH;
  1403.         vector<float> topnEpochAvgLossesH;
  1404.        
  1405.         for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  1406.           string series=*iter;
  1407.           auto m4Obj=allSeries_map[series];
  1408.  
  1409. #if defined USE_ODBC        
  1410.           TRYODBC(hInsertStmt,
  1411.             SQL_HANDLE_STMT,
  1412.             SQLBindParameter(hInsertStmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLCHAR*)series.c_str(), 0, &nullTerminatedStringOfSeries));
  1413.  
  1414.           TRYODBC(hInsertStmt,
  1415.             SQL_HANDLE_STMT,
  1416.             SQLBindParameter(hInsertStmt, OFFSET_TO_FIRST_ACTUAL + 2 * OUTPUT_SIZE + 3, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&m4Obj.n, 0, NULL));
  1417. #endif
  1418.          
  1419.           float avgLoss;
  1420.           vector<float> avgLatest;
  1421.           vector<float> avgAvg;
  1422.          
  1423.           for (int itop=0; itop<TOPN; itop++) {
  1424.             int inet=netRanking_map[series][itop];
  1425.            
  1426.             if (itop==0) {
  1427.               if (LBACK > 0) {
  1428.                 float qLoss = errorFunc(testResults_map[series][inet][iEpoch%AVERAGING_LEVEL], m4Obj.testVals, m4Obj.meanAbsSeasDiff);
  1429.                 bestEpochLosses.push_back(qLoss);
  1430.  
  1431.                 qLoss=wQuantLoss(testResults_map[series][inet][iEpoch%AVERAGING_LEVEL], m4Obj.testVals, TAUL, 0);
  1432.                 bestEpochLossesL.push_back(qLoss);
  1433.  
  1434.                 qLoss = wQuantLoss(testResults_map[series][inet][iEpoch%AVERAGING_LEVEL], m4Obj.testVals, TAUH, OUTPUT_SIZE);
  1435.                 bestEpochLossesH.push_back(qLoss);
  1436.               }
  1437.               avgLatest=testResults_map[series][inet][iEpoch%AVERAGING_LEVEL];  //used later for calculating topn loss
  1438.              
  1439.               if (iEpoch>=AVERAGING_LEVEL) {
  1440.                 if (LBACK > 0) {
  1441.                   float qLoss = errorFunc(testResults_map[series][inet][AVERAGING_LEVEL], m4Obj.testVals, m4Obj.meanAbsSeasDiff);
  1442.                   bestEpochAvgLosses.push_back(qLoss);
  1443.  
  1444.                   qLoss = wQuantLoss(testResults_map[series][inet][AVERAGING_LEVEL], m4Obj.testVals, TAUL, 0);
  1445.                   bestEpochAvgLossesL.push_back(qLoss);
  1446.  
  1447.                   qLoss = wQuantLoss(testResults_map[series][inet][AVERAGING_LEVEL], m4Obj.testVals, TAUH, OUTPUT_SIZE);
  1448.                   bestEpochAvgLossesH.push_back(qLoss);
  1449.                 }
  1450.                 avgAvg=testResults_map[series][inet][AVERAGING_LEVEL];
  1451.               }
  1452.             } else {
  1453.               for (int iii=0; iii<2*OUTPUT_SIZE; iii++) {
  1454.                 avgLatest[iii]+=testResults_map[series][inet][iEpoch%AVERAGING_LEVEL][iii];//calculate current topn
  1455.                 if (iEpoch>=AVERAGING_LEVEL)
  1456.                   avgAvg[iii]+=testResults_map[series][inet][AVERAGING_LEVEL][iii];
  1457.               }
  1458.             }
  1459.           }//through topn
  1460.          
  1461.           for (int iii=0; iii<2*OUTPUT_SIZE; iii++)
  1462.               avgLatest[iii]/=TOPN;
  1463.  
  1464.           if (LBACK > 0) {
  1465.             float qLoss = errorFunc(avgLatest, m4Obj.testVals, m4Obj.meanAbsSeasDiff);
  1466.             topnEpochLosses.push_back(qLoss);
  1467.  
  1468.             qLoss = wQuantLoss(avgLatest, m4Obj.testVals, TAUL, 0);
  1469.             topnEpochLossesL.push_back(qLoss);
  1470.  
  1471.             qLoss = wQuantLoss(avgLatest, m4Obj.testVals, TAUH, OUTPUT_SIZE);
  1472.             topnEpochLossesH.push_back(qLoss);
  1473.           }
  1474.          
  1475.           if (iEpoch>=AVERAGING_LEVEL) {
  1476.             for (int iii = 0; iii<2*OUTPUT_SIZE; iii++)
  1477.               avgAvg[iii] /= TOPN;
  1478.  
  1479.             finalResults_map[series] = avgAvg;
  1480.  
  1481.             if (LBACK > 0) {
  1482. #if defined USE_ODBC        
  1483.               TRYODBC(hInsertStmt,
  1484.                 SQL_HANDLE_STMT,
  1485.                 SQLBindParameter(hInsertStmt, OFFSET_TO_FIRST_ACTUAL + 2 * OUTPUT_SIZE + 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, (SQLPOINTER)&avgLoss, 0, NULL));
  1486.          
  1487.               for (int iv=0; iv<2; iv++)  {
  1488.                 if (iv==0)
  1489.                   TRYODBC(hInsertStmt,
  1490.                     SQL_HANDLE_STMT,
  1491.                     SQLBindParameter(hInsertStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLCHAR*)runL.c_str(), 0, &nullTerminatedStringOfRun))
  1492.                 else                                                      
  1493.                   TRYODBC(hInsertStmt,
  1494.                     SQL_HANDLE_STMT,
  1495.                     SQLBindParameter(hInsertStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLCHAR*)runH.c_str(), 0, &nullTerminatedStringOfRun));
  1496.                
  1497.                 for (int iii=0; iii<OUTPUT_SIZE; iii++) {              
  1498.                   int ipos=OFFSET_TO_FIRST_ACTUAL + 1 + 2*iii;
  1499.                   TRYODBC(hInsertStmt,
  1500.                       SQL_HANDLE_STMT,
  1501.                       SQLBindParameter(hInsertStmt, ipos, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, (SQLPOINTER)&m4Obj.testVals[iii], 0, NULL));
  1502.  
  1503.                   TRYODBC(hInsertStmt,
  1504.                       SQL_HANDLE_STMT,
  1505.                       SQLBindParameter(hInsertStmt, ipos+1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, (SQLPOINTER)&avgAvg[iii+iv*OUTPUT_SIZE], 0, NULL));
  1506.                 }
  1507.                 TRYODBC(hInsertStmt,
  1508.                  SQL_HANDLE_STMT,
  1509.                  SQLExecute(hInsertStmt));                
  1510.               }
  1511. #endif              
  1512.               float qLoss = errorFunc(avgAvg, m4Obj.testVals, m4Obj.meanAbsSeasDiff);
  1513.               topnEpochAvgLosses.push_back(qLoss);
  1514.  
  1515.               qLoss = wQuantLoss(avgAvg, m4Obj.testVals, TAUL, 0);
  1516.               topnEpochAvgLossesL.push_back(qLoss);
  1517.  
  1518.               qLoss = wQuantLoss(avgAvg, m4Obj.testVals, TAUH, OUTPUT_SIZE);
  1519.               topnEpochAvgLossesH.push_back(qLoss);
  1520.             }
  1521.           }
  1522.         }//through series
  1523.         if (LBACK > 0) {
  1524.           float bestEpochLoss=accumulate( bestEpochLosses.begin(), bestEpochLosses.end(), 0.0)/bestEpochLosses.size();
  1525.           float topnEpochLoss=accumulate( topnEpochLosses.begin(), topnEpochLosses.end(), 0.0)/topnEpochLosses.size();
  1526.           float bestEpochLossL = accumulate(bestEpochLossesL.begin(), bestEpochLossesL.end(), 0.0) / bestEpochLossesL.size();
  1527.           float topnEpochLossL = accumulate(topnEpochLossesL.begin(), topnEpochLossesL.end(), 0.0) / topnEpochLossesL.size();
  1528.           float bestEpochLossH = accumulate(bestEpochLossesH.begin(), bestEpochLossesH.end(), 0.0) / bestEpochLossesH.size();
  1529.           float topnEpochLossH = accumulate(topnEpochLossesH.begin(), topnEpochLossesH.end(), 0.0) / topnEpochLossesH.size();
  1530.           cout<<ibig<<" "<<iEpoch<<" VALID best:"<<bestEpochLoss<<" L:"<< bestEpochLossL<<" H:"<< bestEpochLossH<<
  1531.             " topn:"<<topnEpochLoss<<" L:"<< topnEpochLossL<<" H:"<< topnEpochLossH;
  1532.           if (iEpoch>=AVERAGING_LEVEL) {
  1533.             float bestEpochAvgLoss=accumulate( bestEpochAvgLosses.begin(), bestEpochAvgLosses.end(), 0.0)/bestEpochAvgLosses.size();
  1534.             float topnEpochAvgLoss=accumulate( topnEpochAvgLosses.begin(), topnEpochAvgLosses.end(), 0.0)/topnEpochAvgLosses.size();
  1535.             float bestEpochAvgLossL = accumulate(bestEpochAvgLossesL.begin(), bestEpochAvgLossesL.end(), 0.0) / bestEpochAvgLossesL.size();
  1536.             float topnEpochAvgLossL = accumulate(topnEpochAvgLossesL.begin(), topnEpochAvgLossesL.end(), 0.0) / topnEpochAvgLossesL.size();
  1537.             float bestEpochAvgLossH = accumulate(bestEpochAvgLossesH.begin(), bestEpochAvgLossesH.end(), 0.0) / bestEpochAvgLossesH.size();
  1538.             float topnEpochAvgLossH = accumulate(topnEpochAvgLossesH.begin(), topnEpochAvgLossesH.end(), 0.0) / topnEpochAvgLossesH.size();
  1539.             cout<<" bestAvg:"<<bestEpochAvgLoss<<" L:"<< bestEpochAvgLossL<<" H:"<< bestEpochAvgLossH<<
  1540.               " topnAvg:"<<topnEpochAvgLoss<<" L:"<< bestEpochAvgLossL<<" H:"<< bestEpochAvgLossH<<endl;
  1541.           } else
  1542.             cout<<endl;
  1543.         }
  1544.       }//time to report
  1545.      
  1546.       //assign
  1547.       for (int inet=0; inet<NUM_OF_NETS; inet++)
  1548.         seriesAssignment[inet].clear();
  1549.       for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  1550.         string series=*iter;
  1551.         //unordered_map<string, array<int, NUM_OF_NETS>> netRanking_map
  1552.         netRanking_map[series]=perfToRanking(netPerf_map[series]);
  1553.        
  1554.         for (int itop=0; itop<TOPN; itop++) {
  1555.           int inet=netRanking_map[series][itop];
  1556.           seriesAssignment[inet].push_back(series); //every net has a set
  1557.         }
  1558.       }
  1559.      
  1560.       //check and fix degenerations
  1561.       for (int inet=0; inet<NUM_OF_NETS; inet++) {
  1562.         if (seriesAssignment[inet].size()==0) {
  1563.           cout<<"Resetting "<<inet<<endl;
  1564.           for (int i=0; i<series_len/2; i++) {
  1565.             int irand=uniOnSeries(rng);
  1566.             seriesAssignment[inet].push_back(series_vect[irand]);
  1567.           }
  1568.         }
  1569.       }
  1570. #if defined USE_ODBC  
  1571.       TRYODBC(hDbc,
  1572.       SQL_HANDLE_DBC,
  1573.       SQLEndTran(
  1574.         SQL_HANDLE_DBC,
  1575.         hDbc,
  1576.         SQL_COMMIT));
  1577. #endif
  1578.     }//through epochs of RNN
  1579.    
  1580.     //some diagnostic info
  1581.     set<string> diagSeries;
  1582.     for (int i=0; i<1; i++) {//add a few normal ones
  1583.       int irand=uniOnSeries(rng);
  1584.       diagSeries.insert(series_vect[irand]);
  1585.     }
  1586.     for(auto series : diagSeries) {
  1587.       cout<<endl<<series<<endl;
  1588.      
  1589.       cout<<"lSm:"<<endl;
  1590.       for (int inet=0; inet<NUM_OF_NETS; inet++) {
  1591.         cout<<"inet:"<<inet<<" ";
  1592.         auto& historyOfAdditionalParams_arr=historyOfAdditionalParams_map[series]->at(inet);
  1593.         for (int iEpoch=0; iEpoch<NUM_OF_TRAIN_EPOCHS; iEpoch++)
  1594.             cout<<historyOfAdditionalParams_arr[iEpoch].levSm<<" ";
  1595.         cout<<endl;
  1596.       }
  1597.      
  1598.       if (SEASONALITY_NUM > 0 ) {
  1599.         cout<<"sSm:"<<endl;
  1600.         for (int inet=0; inet<NUM_OF_NETS; inet++) {
  1601.           cout<<"inet:"<<inet<<" ";
  1602.             auto& historyOfAdditionalParams_arr=historyOfAdditionalParams_map[series]->at(inet);
  1603.           for (int iEpoch=0; iEpoch<NUM_OF_TRAIN_EPOCHS; iEpoch++)
  1604.             cout<<historyOfAdditionalParams_arr[iEpoch].sSm<<" ";
  1605.           cout<<endl;
  1606.         }
  1607.       }  
  1608.      
  1609.       if (SEASONALITY_NUM > 1 ) {
  1610.         cout<<"sSm2:"<<endl;
  1611.         for (int inet=0; inet<NUM_OF_NETS; inet++) {
  1612.           cout<<"inet:"<<inet<<" ";
  1613.           auto& historyOfAdditionalParams_arr=historyOfAdditionalParams_map[series]->at(inet);
  1614.           for (int iEpoch=0; iEpoch<NUM_OF_TRAIN_EPOCHS; iEpoch++)
  1615.             cout<<historyOfAdditionalParams_arr[iEpoch].sSm2<<" ";
  1616.         cout<<endl;
  1617.         }
  1618.       }
  1619.      
  1620.       for (int inet = 0; inet<NUM_OF_NETS; inet++) {
  1621.         cout<<"inet:"<<inet<<" ";
  1622.         auto& historyOfAdditionalParams_arr = historyOfAdditionalParams_map[series]->at(inet);
  1623.         for (int iEpoch = 0; iEpoch<NUM_OF_TRAIN_EPOCHS; iEpoch++) {
  1624.           if (historyOfAdditionalParams_arr[iEpoch].levels.size()>0) {
  1625.             cout << "levels:" << iEpoch<<" ";
  1626.             for (int iv = 0; iv<historyOfAdditionalParams_arr[iEpoch].levels.size(); iv++)
  1627.               cout << historyOfAdditionalParams_arr[iEpoch].levels[iv] << ", ";
  1628.             cout << endl;
  1629.             if (SEASONALITY_NUM > 0 ) {
  1630.               cout << "seasons:" << iEpoch<<" ";
  1631.               for (int iv = 0; iv<historyOfAdditionalParams_arr[iEpoch].levels.size(); iv++)
  1632.                 cout << historyOfAdditionalParams_arr[iEpoch].seasons[iv] << ", ";
  1633.               cout << endl;
  1634.             }
  1635.             if (SEASONALITY_NUM > 1 ) {
  1636.               cout << "seasons2:" << iEpoch<<" ";
  1637.               for (int iv = 0; iv<historyOfAdditionalParams_arr[iEpoch].levels.size(); iv++)
  1638.                 cout << historyOfAdditionalParams_arr[iEpoch].seasons2[iv] << ", ";
  1639.               cout << endl;
  1640.             }
  1641.           }
  1642.         }
  1643.       }
  1644.     }//end of diag printing
  1645.    
  1646.     //save the forecast to outputFile
  1647.     ofstream outputFile;
  1648.     outputFile.open(outputPathL);
  1649.     for (auto iter = series_vect.begin(); iter != series_vect.end(); ++iter) {
  1650.       string series = *iter;
  1651.       outputFile<< series;
  1652.       for (int io=0; io<OUTPUT_SIZE; io++)
  1653.         outputFile << ", " << finalResults_map[series][io];
  1654.       outputFile<<endl;
  1655.     }
  1656.     outputFile.close();
  1657.    
  1658.     outputFile.open(outputPathH);
  1659.     for (auto iter = series_vect.begin(); iter != series_vect.end(); ++iter) {
  1660.       string series = *iter;
  1661.       outputFile << series;
  1662.       for (int io = 0; io<OUTPUT_SIZE; io++)
  1663.         outputFile << ", " << finalResults_map[series][io+OUTPUT_SIZE];
  1664.       outputFile << endl;
  1665.     }
  1666.     outputFile.close();
  1667.    
  1668.     //delete    
  1669.     for (int inet = 0; inet<NUM_OF_NETS; inet++) {
  1670.       delete trainers_arr[inet];
  1671.       perSeriesTrainers_arr[inet];
  1672.     }
  1673.  
  1674.     for (auto iter = series_vect.begin() ; iter != series_vect.end(); ++iter) {
  1675.       string series=*iter;
  1676.       delete additionalParams_mapOfArr[series];
  1677.       delete historyOfAdditionalParams_map[series];
  1678.     }
  1679.     additionalParams_mapOfArr.clear();
  1680.     historyOfAdditionalParams_map.clear();
  1681.   }//big loop
  1682. }//main
  1683.  
  1684.  
  1685. #if defined USE_ODBC
  1686.   #if defined _WINDOWS
  1687.     void HandleDiagnosticRecord(SQLHANDLE      hHandle,
  1688.       SQLSMALLINT    hType,
  1689.       RETCODE        RetCode)
  1690.     {
  1691.       SQLSMALLINT iRec = 0;
  1692.       SQLINTEGER  iError;
  1693.       WCHAR       wszMessage[1000];
  1694.       WCHAR       wszState[SQL_SQLSTATE_SIZE + 1];
  1695.  
  1696.  
  1697.       if (RetCode == SQL_INVALID_HANDLE)
  1698.       {
  1699.         fwprintf(stderr, L"Invalid handle!\n");
  1700.         return;
  1701.       }
  1702.  
  1703.       while (SQLGetDiagRec(hType,
  1704.         hHandle,
  1705.         ++iRec,
  1706.         wszState,
  1707.         &iError,
  1708.         wszMessage,
  1709.         (SQLSMALLINT)(sizeof(wszMessage) / sizeof(WCHAR)),
  1710.         (SQLSMALLINT *)NULL) == SQL_SUCCESS)
  1711.       {
  1712.           fwprintf(stderr, L"[%5.5s] %s (%d)\n", wszState, wszMessage, iError);
  1713.         }
  1714.     }
  1715.   #else
  1716.     void HandleDiagnosticRecord(SQLHANDLE      hHandle,
  1717.       SQLSMALLINT    hType,
  1718.       RETCODE        RetCode)
  1719.     {
  1720.       SQLSMALLINT iRec = 0;
  1721.       SQLINTEGER  iError;
  1722.       SQLCHAR       wszMessage[1000];
  1723.       SQLCHAR       wszState[SQL_SQLSTATE_SIZE + 1];
  1724.  
  1725.  
  1726.       if (RetCode == SQL_INVALID_HANDLE)
  1727.       {
  1728.         fwprintf(stderr, L"Invalid handle!\n");
  1729.         return;
  1730.       }
  1731.  
  1732.       while (SQLGetDiagRec(hType,
  1733.         hHandle,
  1734.         ++iRec,
  1735.         wszState,
  1736.         &iError,
  1737.         wszMessage,
  1738.         1000,
  1739.         NULL) == SQL_SUCCESS)
  1740.       {
  1741.           fwprintf(stderr, L"[%5.5s] %s (%d)\n", wszState, wszMessage, iError);
  1742.       }
  1743.     }
  1744.   #endif
  1745. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement