int* search(int* point, node* tree, int maxLeafsVisited, int pointDimensons) { int i; int theBestPriorityIndex; int* result; double bestDistance; double rightDistance; double leftDistance; double* leftDistanceVector = NULL; double* rightDistanceVector = NULL; queue** queueArr; int queueCounter = 0; int queueIndexer = 0; int leafsVisited = 0; queue* queueItem; node* nodeToCheck; int queueSize = maxLeafsVisited*maxLeafsVisited; double theBestPriorityVal = 0; int queueIdx; nodeToCheck = NULL; double* distanceVector = NULL; double* zeroDistanceVector; double newBestDistance; zeroDistanceVector = (double*) malloc(pointDimensons * sizeof(double)); for (i = 0; i < pointDimensons; i++) { zeroDistanceVector[i] = 0.0; } queueArr = (queue**) malloc (sizeof(queue*) * queueSize); bestDistance = 1000000000000000000000000000.0; result = (int*) malloc(pointDimensons * sizeof(int)); for (i = 0; i < queueSize; i++ ) { queueArr[i] = NULL; } // make initial node for the queue queueItem = (queue*) malloc(sizeof(queue)); queueItem->nodeToCheck = tree; queueItem->priorityVal = 0.0; queueItem->distanceVector = (double*) malloc(pointDimensons * sizeof(double)); memcpy(queueItem->distanceVector, zeroDistanceVector, pointDimensons * sizeof(double)); queueArr[queueIndexer] = queueItem; queueIndexer++; queueCounter++; while( (queueCounter > 0) && (leafsVisited < maxLeafsVisited)) { //take the node from the queue with the lowest priorityVal value theBestPriorityVal = bestDistance; theBestPriorityIndex = -1; // search for lowest value for (i = 0; i < queueIndexer; i++ ) { if (queueArr[i] != NULL) { if (queueArr[i]->priorityVal <= theBestPriorityVal ) { theBestPriorityVal = queueArr[i]->priorityVal; nodeToCheck = queueArr[i]->nodeToCheck; distanceVector = queueArr[i]->distanceVector; theBestPriorityIndex = i; } } } // all points with the possible smallest distances checked -> interrupt the loop if (theBestPriorityIndex == -1) { break; } if (nodeToCheck->isLeaf) { // TO DO calculation of the best distance and winner leaf newBestDistance = getDistance(point, nodeToCheck->leafVector, pointDimensons); if (bestDistance > newBestDistance) { bestDistance = newBestDistance; memcpy(result, nodeToCheck->leafVector, pointDimensons * sizeof(int)); } leafsVisited++; } else { // put the branches of the node into the queue leftDistanceVector = (double*) malloc(pointDimensons * sizeof(double)); rightDistanceVector = (double*) malloc(pointDimensons * sizeof(double)); // check the distance - decide where to go if(nodeToCheck->dimVal > ((double)point[nodeToCheck->dimNumber])) { // go left branch leftDistance = 0.0; memcpy(leftDistanceVector, distanceVector, pointDimensons * sizeof(double)); //--------------- memcpy(rightDistanceVector, distanceVector, pointDimensons * sizeof(double)); if (nodeToCheck->right->isLeaf) { rightDistance = 0.0; } else { rightDistance = getVectorSum(rightDistanceVector, pointDimensons); rightDistanceVector[nodeToCheck->dimNumber] = (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal) * (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal); } } else { // go right branch memcpy(leftDistanceVector, distanceVector, pointDimensons * sizeof(double)); if (nodeToCheck->left->isLeaf) { leftDistance = 0.0; } else { leftDistance = getVectorSum(leftDistanceVector, pointDimensons); leftDistanceVector[nodeToCheck->dimNumber] = (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal) * (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal); } //--------------- rightDistance = 0.0; memcpy(rightDistanceVector, distanceVector, pointDimensons * sizeof(double)); } // add two nodes to priority queue queue* leftNodeQueueItem = (queue*) malloc(sizeof(queue)); queue* rightNodeQueueItem = (queue*) malloc(sizeof(queue)); leftNodeQueueItem->nodeToCheck = nodeToCheck->left; leftNodeQueueItem->priorityVal = leftDistance; leftNodeQueueItem->distanceVector = leftDistanceVector; queueArr[queueIndexer] = leftNodeQueueItem; queueIndexer++; queueCounter++; rightNodeQueueItem->nodeToCheck = nodeToCheck->right; rightNodeQueueItem->priorityVal = rightDistance; rightNodeQueueItem->distanceVector = rightDistanceVector; queueArr[queueIndexer] = rightNodeQueueItem; queueIndexer++; queueCounter++; } queueItem = queueArr[theBestPriorityIndex]; queueArr[theBestPriorityIndex] = NULL; free(queueItem); queueCounter--; } free(queueArr); // free(queueItem); return result; }
void NeuralNetwork::predict(int times){ sourceKeys = reader->getKeys(); sourceValues = reader->getValues(); switch ( seriesType ) { case ( WITHOUT_SEASONAL_VARIATON ) : { vector<int> keys; for (unsigned int i=1;i<=sourceKeys.size();i++) keys.push_back(i); vector<double> keysMulValues; vector<int> keysPow2; for(unsigned int i=0;i<keys.size();i++) { keysMulValues.push_back(keys[i] * sourceValues[i]); keysPow2.push_back(keys[i] * keys[i]); } //coefficients double a = (getVectorSum(keysMulValues) - (getVectorSum(keys) * getVectorSum(sourceValues)) / sourceValues.size()) / (getVectorSum(keysPow2) - pow(getVectorSum(keys), 2) / sourceValues.size()); double b = getVectorSum(sourceValues) / sourceValues.size() - a * (getVectorSum(keys)) / sourceValues.size(); /* //calculation of the average relative error vector<double> avarageErrorValues; for (int i=0; i<keys.size(); i++) avarageErrorValues.push_back( (fabs(sourceValues[i] - (a * keys[i] + b)) / sourceValues[i]) * 100 ); cout << "prediction error=" <<getVectorSum(avarageErrorValues)/sourceValues.size() <<"%" <<endl; */ for(int i=0;i<times;i++) { //calculated (smoothed) value for the series keys.push_back(keys[keys.size() - 1] + 1); resultValues.push_back(a * keys[keys.size() - 1] + b); } break; } case (WITH_SEASONAL_VARIATON) : { int seasons = sourceValues.size() / partsInSeason; int seasSumAmnt = seasons * partsInSeason - partsInSeason + 1; double seasonSum [seasSumAmnt]; double seasonAver[seasSumAmnt]; for (int i = 0; i < seasSumAmnt; ++i) { seasonSum[i] = 0; for (int j = i; j < i + seasons; ++j) { seasonSum[i] += sourceValues[j]; } std::cout << "\nseas sum " << seasonSum[i]; } for (int i = 0; i < seasSumAmnt; ++i) { seasonAver[i] = seasonSum[i] / seasons; std::cout << "\nseas aver " << seasonAver[i]; } double centeredAver[seasSumAmnt-1]; for (int i = 0; i < seasSumAmnt-1; ++i) { centeredAver[i] = (seasonAver[i] + seasonAver[i+1]) / 2.0; std::cout << "\ncenter sum " << centeredAver[i]; } double seasMark[seasSumAmnt-1]; double temp [seasSumAmnt-1]; int indexes = seasons * partsInSeason - partsInSeason; for (int i = 0 ; i < indexes; ++i) { temp[i] = sourceValues[i+partsInSeason/2] / centeredAver[i]; } for (int i = 0; i < partsInSeason/2; ++i) { seasMark[i] = temp[(seasons-1)*partsInSeason- partsInSeason/2 +i]; } for (int i = partsInSeason/2; i < indexes; ++i) { seasMark[i] = temp[i - partsInSeason/2]; } double partIndexes[partsInSeason]; for (int i = 0; i < partsInSeason; ++i) { partIndexes[i] = 0; for (int j = 0; j < seasons-1; ++j) { partIndexes[i] += seasMark[partsInSeason*j + i]; } partIndexes[i] /= seasons-1; partIndexes[i] *= (0.8 + (random()%4)/10.0); std :: cout << partIndexes[i] << std::endl; } double Yx = 0, sumX= 0, xq= 0, Y= 0; std::cout << "size=" << sourceValues.size(); for (unsigned int i = 1 ; i <= sourceValues.size(); ++i ) { Yx += i * sourceValues[i-1]; std :: cout << i * sourceValues[i-1] << '\n'; sumX += i; xq += i * i; Y += sourceValues[i-1]; } std :: cout << " Yx == " << Yx << std::endl; std::cout << " sum x " << sumX << std::endl; std::cout << "xQ = " << xq << std::endl; std::cout << "Y == " << Y << std::endl; double a = 0, b = 0; a = -(Yx - (sumX*Y)/sourceValues.size())/(xq - (sumX * sumX)/sourceValues.size()); std::cout << std::endl << a << '\n'; b = Y/sourceValues.size() - a*sumX/sourceValues.size(); std::cout << std::endl << b << '\n'; for (unsigned int i = sourceValues.size(); i < sourceValues.size() + times; i++) { resultKeys .push_back(sourceKeys[i%sourceValues.size()]); resultValues.push_back((a*i+b)*partIndexes[i%partsInSeason]); } double sum = 0; int counter = 0; for (int i = 0; i < resultKeys.size(); ++i) { std::cout << resultKeys[i] << " " << resultValues[i] << std::endl; counter++; sum += resultValues[i]; if (counter == partsInSeason) { std::cout << "\nTotal : " << sum <<"\n\n"; counter = 0; sum = 0; } } break; } } }