MatrixDouble triangularLattice(int n, int n1) { MatrixDouble coord; int i=0, l=0, j =0; int n_pro_level = n1; int sum = n1; double y=0, dx=0; coord.resize(n); std::cout << n_pro_level << n1 << "\n"; while (i<n) { if (i==(sum)) { // Uebergang zu dem naechsten Level l++; dx = 0.5*(l%2) ; n_pro_level = n_pro_level + (l+1)%2 - l%2; sum += n_pro_level; y = y+sqrt(3)/2.; } coord[i].resize(2); coord[i][0] = dx +j; coord[i][1] = y; j = (j+1)%n_pro_level; i++; } return coord; }
void DTW::znormData(MatrixDouble &data,MatrixDouble &normData){ const UINT R = data.getNumRows(); const UINT C = data.getNumCols(); if( normData.getNumRows() != R || normData.getNumCols() != C ){ normData.resize(R,C); } for(UINT j=0; j<C; j++){ double mean = 0.0; double stdDev = 0.0; //Calculate Mean for(UINT i=0; i<R; i++) mean += data[i][j]; mean /= double(R); //Calculate Std Dev for(UINT i=0; i<R; i++) stdDev += SQR(data[i][j]-mean); stdDev = sqrt( stdDev / (R - 1.0) ); if(constrainZNorm && stdDev < 0.01){ //Normalize the data to 0 mean for(UINT i=0; i<R; i++) normData[i][j] = (data[i][j] - mean); }else{ //Normalize the data to 0 mean and standard deviation of 1 for(UINT i=0; i<R; i++) normData[i][j] = (data[i][j] - mean) / stdDev; } } }
MatrixDouble hexagonalLattice(int n, int n1) { MatrixDouble coord; int i=0, l=0, j =0; int n_pro_level = n1; int sum = n1; int dx=0; double y=0; coord.resize(n); while (i<n) { if (i==(sum)) { // Uebergang zu dem naechsten Level l++; if (sum<=n/2) { dx += l%2; n_pro_level = n_pro_level + l%2; } else { dx -= l%2; n_pro_level = n_pro_level - l%2; } sum += n_pro_level; y = y+ (1+(l+1)%2)*1/2.; } coord[i].resize(2); coord[i][0] = -dx*sqrt(3)/2.+j* sqrt(3); coord[i][1] = y; j = (j+1)%n_pro_level; i++; } return coord; }
void CProblem::set_d(){ d.resize(max_d); for (unsigned int i=0; i<max_d; i++) { d[i].resize(1); d[i][0]= max_d-i; } }
MatrixDouble triangularLattice2(int n, int n1) { MatrixDouble coord; coord.resize(n); coord[0].resize(2); coord[0][0] = 0; coord[0][1] = 0; coord[1].resize(2); coord[1][0] = 1; coord[1][1] = 0; coord[2].resize(2); coord[2][0] = 2; coord[2][1] = 0; coord[3].resize(2); coord[3][0] = 3; coord[3][1] = 0; coord[4].resize(2); coord[4][0] = 4; coord[4][1] = 0; coord[5].resize(2); coord[5][0] = 0.5; coord[5][1] = sqrt(3)/2.; coord[6].resize(2); coord[6][0] = 1.5; coord[6][1] = sqrt(3)/2.; coord[7].resize(2); coord[7][0] = 2.5; coord[7][1] = sqrt(3)/2.; coord[8].resize(2); coord[8][0] = 3.5; coord[8][1] = sqrt(3)/2.; coord[9].resize(2); coord[9][0] = 0; coord[9][1] = sqrt(3); coord[10].resize(2); coord[10][0] = 1; coord[10][1] = sqrt(3); coord[11].resize(2); coord[11][0] = 2; coord[11][1] = sqrt(3); coord[12].resize(2); coord[12][0] = 3; coord[12][1] = sqrt(3); coord[13].resize(2); coord[13][0] = 4; coord[13][1] = sqrt(3); coord[14].resize(2); coord[14][0] = 0.5; coord[14][1] = 3*sqrt(3)/2.; coord[15].resize(2); coord[15][0] = 1.5; coord[15][1] = 3*sqrt(3)/2.; coord[16].resize(2); coord[16][0] = 2.5; coord[16][1] = 3*sqrt(3)/2.; coord[17].resize(2); coord[17][0] = 3.5; coord[17][1] = 3*sqrt(3)/2.; coord[18].resize(2); coord[18][0] = 0; coord[18][1] = 2*sqrt(3); coord[19].resize(2); coord[19][0] = 1; coord[19][1] = 2*sqrt(3); coord[20].resize(2); coord[20][0] = 2; coord[20][1] = 2*sqrt(3); coord[21].resize(2); coord[21][0] = 3; coord[21][1] = 2*sqrt(3); coord[22].resize(2); coord[22][0] = 4; coord[22][1] = 2*sqrt(3); return coord; }
void CProblem::set_d_function(){ max_d = dist_linear(0); d.resize(n); for (unsigned int u=0; u<n; u++) { d[u].resize(n); for (unsigned int v=0; v<n; v++) { d[u][v] = dist_linear(distances[u][v]); } } }
void DTW::scaleData(MatrixDouble &data,MatrixDouble &scaledData){ const UINT R = data.getNumRows(); const UINT C = data.getNumCols(); if( scaledData.getNumRows() != R || scaledData.getNumCols() != C ){ scaledData.resize(R, C); } //Scale the data using the min and max values for(UINT i=0; i<R; i++) for(UINT j=0; j<C; j++) scaledData[i][j] = scale(data[i][j],rangesBuffer[j].minValue,rangesBuffer[j].maxValue,0.0,1.0); }
void CProblem::set_d_function(){ max_d = 2 + 1; d.resize(n); for (unsigned int u=0; u<n; u++) { d[u].resize(n); for (unsigned int v=0; v<u; v++) { if (distances[u][v]-1 <= 0.01) d[u][v] = 2.; else if ( distances[u][v]- sqrt(3) <= 0.01) d[u][v] = 1.; else d[u][v] = 0.; d[v][u] = d[u][v]; } d[u][u] = max_d; } }
void CProblem::coordTOdist () { distances.resize(n); //max_distance = 0.0; for (unsigned int u=0; u< n; u++) { distances[u].resize(n); for (unsigned int v=0; v<u; v++) { distances[u][v] = (sqrt( (coordinates[u][0]-coordinates[v][0])*(coordinates[u][0]-coordinates[v][0]) +(coordinates[u][1]-coordinates[v][1])*(coordinates[u][1]-coordinates[v][1]) ) ); distances[v][u] = distances[u][v]; //if (distances[u][v] > max_distance) max_distance = distances[u][v]; } distances[0][0] = 0; } }
MatrixDouble squareLattice(int n) { MatrixDouble coord; coord.resize(n); for (int i=0; i<sqrt(n); i++) { for (int j=0; j< sqrt(n); j++) { coord[i*sqrt(n)+j].resize(2); coord[i*sqrt(n)+j][0] = j; coord[i*sqrt(n)+j][1] = i; } } return coord; }
int CProblem::setProblem() { std::string line; std::fstream oFile; std::stringstream buf; //int bufInt; double bufDouble; oFile.open(fileName.c_str()); if (!oFile.is_open()) { std::cerr<< "Cannot open file!\n"; exit(1); } std::getline(oFile, line); /* number of vertices and diameter */ std::getline(oFile, line); buf<<line; buf >> n; buf >> diameter; buf.clear(); max_d = diameter+1; max_distance = max_d; std::getline(oFile, line); /* coordinates */ coordinates.resize(n); for (unsigned int i=0; i< n; i++) { coordinates[i].resize(2); std::getline(oFile, line); buf << line; buf >> bufDouble; /* because first number in line is the number of the vertex */ buf >> bufDouble; coordinates[i][0] = bufDouble; buf >> bufDouble; coordinates[i][1] = bufDouble; buf.clear(); } oFile.close(); coordTOdist(); set_d_function(); return 0; }
void DTW::smoothData(MatrixDouble &data,UINT smoothFactor,MatrixDouble &resultsData){ const UINT M = data.getNumRows(); const UINT C = data.getNumCols(); const UINT N = (UINT) floor(double(M)/double(smoothFactor)); resultsData.resize(N,C); if(smoothFactor==1 || M<smoothFactor){ resultsData = data; return; } for(UINT i=0; i<N; i++){ for(UINT j=0; j<C; j++){ double mean = 0.0; int index = i*smoothFactor; for(UINT x=0; x<smoothFactor; x++){ mean += data[index+x][j]; } resultsData[i][j] = mean/smoothFactor; } } //Add on the data that does not fit into the window if(M%smoothFactor!=0.0){ VectorDouble mean(C,0.0); for(UINT j=0; j<C; j++){ for(UINT i=N*smoothFactor; i<M; i++) mean[j] += data[i][j]; mean[j]/=M-(N*smoothFactor); } //Add one row to the end of the Matrix MatrixDouble tempMatrix(N+1,C); for(UINT i=0; i<N; i++) for(UINT j=0; j<C; j++) tempMatrix[i][j] = resultsData[i][j]; for(UINT j=0; j<C; j++) tempMatrix[N][j] = mean[j]; resultsData = tempMatrix; } }
void CProblem::set_d_function() { d.resize(n); for (unsigned int u = 0; u < n; u++) { d[u].resize(n); for (unsigned int v = 0; v < u; v++) { d[u][v] = dist_linear(distances[u][v]); d[v][u] = d[u][v]; if (d[u][v] <= max_distance && u != v) { /* save vertices for which additional constraints to be created*/ Info.numAddVar++; Info.ConstrIndex.push_back(u); Info.ConstrIndex.push_back(v); } } } Info.numVar += Info.numAddVar; std::cout << " numAddVar " << Info.numAddVar << "\n"; }
bool PrincipalComponentAnalysis::project(const MatrixDouble &data,MatrixDouble &prjData) { if( !trained ) { warningLog << "project(const MatrixDouble &data,MatrixDouble &prjData) - The PrincipalComponentAnalysis module has not been trained!" << endl; return false; } if( data.getNumCols() != numInputDimensions ) { warningLog << "project(const MatrixDouble &data,MatrixDouble &prjData) - The number of columns in the input vector (" << data.getNumCols() << ") does not match the number of input dimensions (" << numInputDimensions << ")!" << endl; return false; } MatrixDouble msData( data ); prjData.resize(data.getNumRows(),numPrincipalComponents); if( normData ) { //Mean subtract the data for(UINT i=0; i<data.getNumRows(); i++) for(UINT j=0; j<numInputDimensions; j++) msData[i][j] = (msData[i][j]-mean[j])/stdDev[j]; } else { //Mean subtract the data for(UINT i=0; i<data.getNumRows(); i++) for(UINT j=0; j<numInputDimensions; j++) msData[i][j] -= mean[j]; } //Projected Data for(UINT row=0; row<msData.getNumRows(); row++) { //For each row in the final data for(UINT i=0; i<numPrincipalComponents; i++) { //For each PC prjData[row][i]=0; for(UINT j=0; j<data.getNumCols(); j++)//For each feature prjData[row][i] += msData[row][j] * eigenvectors[j][sortedEigenvalues[i].index]; } } return true; }
int CProblem::setProblem() { std::string line; std::fstream oFile; std::stringstream buf; //int bufInt; switch (lattice) { case 0: double bufDouble; oFile.open(fileName.c_str()); if (!oFile.is_open()) { std::cerr<< "Cannot open file!\n"; exit(1); } std::getline(oFile, line); /* number of vertices and diameter */ std::getline(oFile, line); buf<<line; buf >> n; buf >> diameter; buf.clear(); std::getline(oFile, line); /* coordinates */ coordinates.resize(n); for (unsigned int i=0; i< n; i++) { coordinates[i].resize(2); std::getline(oFile, line); buf << line; buf >> bufDouble; /* because first number in line is the number of the vertex */ buf >> bufDouble; coordinates[i][0] = bufDouble; buf >> bufDouble; coordinates[i][1] = bufDouble; buf.clear(); } oFile.close(); break; case 1: n=24; coordinates = hexagonalLattice2(n, 1); // number of vertices, number of vertices in first line diameter = 7; fileName = "hexagonal_lattice.dat"; break; case 2: n=23; coordinates = triangularLattice2(n,5); // number of vertices, number of vertices in first line diameter = 6; fileName = "triangular_lattice.dat"; break; case 3: n=25; //n = 4; //diameter = 2; coordinates = squareLattice2(n); diameter = 8; fileName = "square_lattice.dat"; break; default:std::cerr << "Wrong lattice type\n"; exit (-1); } //switch coordTOdist(); set_d_function(); return 0; }
int main (int argc, const char * argv[]) { //Create an empty matrix double MatrixDouble matrix; //Resize the matrix matrix.resize( 100, 2 ); //Set all the values in the matrix to zero matrix.setAllValues( 0 ); //Loop over the data and set the values to random values UINT counter = 0; for(UINT i=0; i<matrix.getNumRows(); i++){ for(UINT j=0; j<matrix.getNumCols(); j++){ matrix[i][j] = counter++; } } //Add a new row at the very end of the matrix VectorDouble newRow(2); newRow[0] = 1000; newRow[1] = 2000; matrix.push_back( newRow ); //Print the values cout << "Matrix Data: \n"; for(UINT i=0; i<matrix.getNumRows(); i++){ for(UINT j=0; j<matrix.getNumCols(); j++){ cout << matrix[i][j] << "\t"; } cout << endl; } cout << endl; //Get the second row as a vector VectorDouble rowVector = matrix.getRowVector( 1 ); cout << "Row Vector Data: \n"; for(UINT i=0; i<rowVector.size(); i++){ cout << rowVector[i] << "\t"; } cout << endl; //Get the second column as a vector VectorDouble colVector = matrix.getColVector( 1 ); cout << "Column Vector Data: \n"; for(UINT i=0; i<colVector.size(); i++){ cout << colVector[i] << "\n"; } cout << endl; //Get the mean of each column VectorDouble mean = matrix.getMean(); cout << "Mean: \n"; for(UINT i=0; i<mean.size(); i++){ cout << mean[i] << "\n"; } cout << endl; //Get the Standard Deviation of each column VectorDouble stdDev = matrix.getStdDev(); cout << "StdDev: \n"; for(UINT i=0; i<stdDev.size(); i++){ cout << stdDev[i] << "\n"; } cout << endl; //Get the covariance matrix MatrixDouble cov = matrix.getCovarianceMatrix(); cout << "Covariance Matrix: \n"; for(UINT i=0; i<cov.getNumRows(); i++){ for(UINT j=0; j<cov.getNumCols(); j++){ cout << cov[i][j] << "\t"; } cout << endl; } cout << endl; vector< MinMax > ranges = matrix.getRanges(); cout << "Ranges: \n"; for(UINT i=0; i<ranges.size(); i++){ cout << "i: " << i << "\tMinValue: " << ranges[i].minValue << "\tMaxValue:" << ranges[i].maxValue << "\n"; } cout << endl; //Save the matrix data to a csv file matrix.save( "data.csv" ); //load the matrix data from a csv file matrix.load( "data.csv" ); return EXIT_SUCCESS; }
double DTW::computeDistance(MatrixDouble &timeSeriesA,MatrixDouble &timeSeriesB,MatrixDouble &distanceMatrix,vector< IndexDist > &warpPath){ const int M = timeSeriesA.getNumRows(); const int N = timeSeriesB.getNumRows(); const int C = timeSeriesA.getNumCols(); int i,j,k,index = 0; double totalDist,v,normFactor = 0.; warpPath.clear(); if( int(distanceMatrix.getNumRows()) != M || int(distanceMatrix.getNumCols()) != N ){ distanceMatrix.resize(M, N); } switch (distanceMethod) { case (ABSOLUTE_DIST): for(i=0; i<M; i++){ for(j=0; j<N; j++){ distanceMatrix[i][j] = 0.0; for(k=0; k< C; k++){ distanceMatrix[i][j] += fabs(timeSeriesA[i][k]-timeSeriesB[j][k]); } } } break; case (EUCLIDEAN_DIST): //Calculate Euclidean Distance for all possible values for(i=0; i<M; i++){ for(j=0; j<N; j++){ distanceMatrix[i][j] = 0.0; for(k=0; k< C; k++){ distanceMatrix[i][j] += SQR( timeSeriesA[i][k]-timeSeriesB[j][k] ); } distanceMatrix[i][j] = sqrt( distanceMatrix[i][j] ); } } break; case (NORM_ABSOLUTE_DIST): for(i=0; i<M; i++){ for(j=0; j<N; j++){ distanceMatrix[i][j] = 0.0; for(k=0; k< C; k++){ distanceMatrix[i][j] += fabs(timeSeriesA[i][k]-timeSeriesB[j][k]); } distanceMatrix[i][j]/=N; } } break; default: errorLog<<"ERROR: Unknown distance method: "<<distanceMethod<<endl; return -1; break; } //Run the recursive search function to build the cost matrix double distance = sqrt( d(M-1,N-1,distanceMatrix,M,N) ); if( isinf(distance) || isnan(distance) ){ warningLog << "DTW computeDistance(...) - Distance Matrix Values are INF!" << endl; return INFINITY; } //cout << "DIST: " << distance << endl; //The distMatrix values are negative so make them positive for(i=0; i<M; i++){ for(j=0; j<N; j++){ distanceMatrix[i][j] = fabs( distanceMatrix[i][j] ); } } //Now Create the Warp Path through the cost matrix, starting at the end i=M-1; j=N-1; totalDist = distanceMatrix[i][j]; warpPath.push_back( IndexDist(i,j,distanceMatrix[i][j]) ); //Use dynamic programming to navigate through the cost matrix until [0][0] has been reached normFactor = 1; while( true ) { if( i==0 && j==0 ) break; if( i==0 ){ j--; } else{ if( j==0 ) i--; else{ //Find the minimum cell to move to v = numeric_limits<double>::max(); index = 0; if( distanceMatrix[i-1][j] < v ){ v = distanceMatrix[i-1][j]; index = 1; } if( distanceMatrix[i][j-1] < v ){ v = distanceMatrix[i][j-1]; index = 2; } if( distanceMatrix[i-1][j-1] <= v ){ index = 3; } switch(index){ case(1): i--; break; case(2): j--; break; case(3): i--; j--; break; default: warningLog << "DTW computeDistance(...) - Could not compute a warping path for the input matrix! Dist: " << distanceMatrix[i-1][j] << " i: " << i << " j: " << j << endl; return INFINITY; break; } } } normFactor++; totalDist += distanceMatrix[i][j]; warpPath.push_back( IndexDist(i,j,distanceMatrix[i][j]) ); } return totalDist/normFactor; }
MatrixDouble squareLattice2(int n) { MatrixDouble coord; coord.resize(n); coord[0].resize(2); coord[0][0] = 0; coord[0][1] = 0; coord[22].resize(2); coord[22][0] = 1; coord[22][1] = 0; coord[19].resize(2); coord[19][0] = 2; coord[19][1] = 0; coord[11].resize(2); coord[11][0] = 3; coord[11][1] = 0; coord[8].resize(2); coord[8][0] = 4; coord[8][1] = 0; coord[5].resize(2); coord[5][0] = 0; coord[5][1] = 1; coord[2].resize(2); coord[2][0] = 1; coord[2][1] = 1; coord[24].resize(2); coord[24][0] = 2; coord[24][1] = 1; coord[16].resize(2); coord[16][0] = 3; coord[16][1] = 1; coord[13].resize(2); coord[13][0] = 4; coord[13][1] = 1; coord[10].resize(2); coord[10][0] = 0; coord[10][1] = 2; coord[7].resize(2); coord[7][0] = 1; coord[7][1] = 2; coord[4].resize(2); coord[4][0] = 2; coord[4][1] = 2; coord[21].resize(2); coord[21][0] = 3; coord[21][1] = 2; coord[18].resize(2); coord[18][0] = 4; coord[18][1] = 2; coord[15].resize(2); coord[15][0] = 0; coord[15][1] = 3; coord[12].resize(2); coord[12][0] = 1; coord[12][1] = 3; coord[9].resize(2); coord[9][0] = 2; coord[9][1] = 3; coord[1].resize(2); coord[1][0] = 3; coord[1][1] = 3; coord[23].resize(2); coord[23][0] = 4; coord[23][1] = 3; coord[20].resize(2); coord[20][0] = 0; coord[20][1] = 4; coord[17].resize(2); coord[17][0] = 1; coord[17][1] = 4; coord[14].resize(2); coord[14][0] = 2; coord[14][1] = 4; coord[6].resize(2); coord[6][0] = 3; coord[6][1] = 4; coord[3].resize(2); coord[3][0] = 4; coord[3][1] = 4; return coord; }