int main(int argc, char *argv[]){ //--Declare variables int *a, *b, *c, i, m, n, p, range; // --Check no. of arguments if (argc < 5) { cout<< endl << endl << "\t....OOOps, INVALID No of Arguements,\n"; exit(1); }// end if //--Get input data m = atoi(argv[1]); // rows of matrix a n = atoi(argv[2]); // cols of matrix a p = atoi(argv[3]); // cols of matrix c range = atoi(argv[4]);// range of matrices a and b //--Allocate Space for Matrix a a = (int *) malloc (m * n * sizeof (int)); //--Allocate Space for Matrix b b = (int *) malloc (n * p * sizeof (int)); //--Allocate Space for Matrix c c = (int *) malloc (m * p * sizeof (int)); int * local_c = (int *) malloc(p * sizeof (int)); int pc,id; MPI::Init(argc,argv); pc = MPI::COMM_WORLD.Get_size (); id = MPI::COMM_WORLD.Get_rank (); if(id == 0){ cout<< "Siavah Katebzadeh" <<endl<<"Parallel program to generate randomly two matrices a(m by n) and b(n by p)" <<endl<<"and then computing c = a * b" <<endl<<"To compile: gcc fname.c," <<endl<<"To run: a.out m n p r (all integer)" <<endl<<"where: m is no. of rows of matrix a, n is no. of cols of matrix a, " <<endl<<"p is no. of cols of matrix c, and r is range of matrices a and b."; //--Generate and print Matrix a genMatrix(a, m, n, range); //--Generate and print Matrix b genMatrix(b, n, p, range); } MPI::COMM_WORLD.Bcast(a,n*m,MPI::INT,0); MPI::COMM_WORLD.Bcast(b,m*p,MPI::INT,0); mpyMatrix(a, b, local_c, m, n, p,id); MPI::COMM_WORLD.Gather(local_c, p, MPI::INT, c + id * p, p, MPI::INT, 0); //--Print Matrices a, b and c if( id == 0) printMatrices(a, b, c, m, n, p); MPI::Finalize (); // --free allocated spaces free (a);//free allocated space for matrix a free (b);//free allocated space for matrix b free (c);//free allocated space for matrix c return 1; } // end main
void getInverseDestroy(matrix *m, matrix *dest) { getIdentityMatrix(dest, m->R); int i; int j; int si; nType temp; for(i = 0; i < m->R; i++) { j = getMaxInRow(m, i); if(isZero(m->ptr[i][j])) { dest->R = 0; dest->C = 0; return; } temp = m->ptr[i][j]; if(temp != 1) { #ifdef DEBUG fprintf(stderr, "dividing row %d by %lf\n", i + 1, temp); #endif eop1(m, i, ((nType) 1.) / temp); eop1(dest, i, ((nType) 1.) / temp); #ifdef DEBUG printMatrices(m, dest); #endif } for(si = 0; si < m->R; si++) { if(si != i) { temp = m->ptr[si][j]; if(temp != 0) { #ifdef DEBUG fprintf(stderr, "subtracting row %d multiplied by %lf from row %d\n", i + 1, temp, si + 1); #endif eop2(m, i, temp, si); eop2(dest, i, temp, si); #ifdef DEBUG printMatrices(m, dest); #endif } } } } int k; for(k = 0; k < m->R; k++) for(i = 0; i < m->R; i++) { //0...1...0 //....j.... j = getMaxInRow(m, i); if(i != j) { #ifdef DEBUG fprintf(stderr, "swapping rows %d and %d\n", i + 1, j + 1); #endif eop3(m, i, j); eop3(dest, i, j); #ifdef DEBUG printMatrices(m, dest); #endif } } }
bool HiddenMarkovModel::train_(const vector< vector<UINT> > &obs,const UINT maxIter, UINT ¤tIter,double &newLoglikelihood){ const UINT numObs = (unsigned int)obs.size(); UINT i,j,k,t = 0; double num,denom,oldLoglikelihood = 0; bool keepTraining = true; trainingIterationLog.clear(); //Create the array to hold the data for each training instance vector< HMMTrainingObject > hmms( numObs ); //Create epislon and gamma to hold the re-estimation variables vector< vector< MatrixDouble > > epsilon( numObs ); vector< MatrixDouble > gamma( numObs ); //Resize the hmms, epsilon and gamma matrices so they are ready to be filled for(k=0; k<numObs; k++){ const UINT T = (UINT)obs[k].size(); gamma[k].resize(T,numStates); epsilon[k].resize(T); for(t=0; t<T; t++) epsilon[k][t].resize(numStates,numStates); //Resize alpha, beta and phi hmms[k].alpha.resize(T,numStates); hmms[k].beta.resize(T,numStates); hmms[k].c.resize(T); } //For each training seq, run one pass of the forward backward //algorithm then reestimate a and b using the Baum-Welch oldLoglikelihood = 0; newLoglikelihood = 0; currentIter = 0; do{ newLoglikelihood = 0.0; //Run the forwardbackward algorithm for each training example for(k=0; k<numObs; k++){ if( !forwardBackward(hmms[k],obs[k]) ){ return false; } newLoglikelihood += hmms[k].pk; } //Set the new log likelihood as the average of the observations newLoglikelihood /= numObs; trainingIterationLog.push_back( newLoglikelihood ); if( ++currentIter >= maxIter ){ keepTraining = false; trainingLog << "Max Iter Reached! Stopping Training" << endl; } if( fabs(newLoglikelihood-oldLoglikelihood) < minImprovement && currentIter > 1 ){ keepTraining = false; trainingLog << "Min Improvement Reached! Stopping Training" << endl; } //if( newLoglikelihood < oldLoglikelihood ){ cout<<"Warning: Inverted Training!\n";} trainingLog << "Iter: "<<currentIter<<" logLikelihood: "<<newLoglikelihood<<" change: "<<oldLoglikelihood - newLoglikelihood<<endl; printMatrices(); //PAUSE; oldLoglikelihood = newLoglikelihood; //Only update A, B, and Pi if needed if( keepTraining ){ //Re-estimate A for(i=0; i<numStates; i++){ //Compute the denominator of A (which is independent of j) denom = 0; for(k=0; k<numObs; k++){ for(t=0; t<obs[k].size()-1; t++){ denom += hmms[k].alpha[t][i] * hmms[k].beta[t][i] / hmms[k].c[t]; } } //Compute the numerator and also update a[i][j] if( denom > 0 ){ for(j=0; j<numStates; j++){ num = 0; for(k=0; k<numObs; k++){ for(t=0; t<obs[k].size()-1; t++){ num += hmms[k].alpha[t][i] * a[i][j] * b[j][ obs[k][t+1] ] * hmms[k].beta[t+1][j]; } } //Update a[i][j] a[i][j] = num/denom; } }else{ errorLog << "Denom is zero for A!" << endl; return false; } } //Re-estimate B bool renormB = false; for(i=0; i<numStates; i++){ for(j=0; j<numSymbols; j++){ num=0.0; denom = 0.0; for(k=0; k<numObs; k++){ const UINT T = (unsigned int)obs[k].size(); for(t=0; t<T; t++){ if( obs[k][t] == j ){ num += hmms[k].alpha[t][i] * hmms[k].beta[t][i] / hmms[k].c[t]; } denom += hmms[k].alpha[t][i] * hmms[k].beta[t][i] / hmms[k].c[t]; } } if( denom == 0 ){ errorLog << "Denominator is zero for B!" << endl; return false; } //Update b[i][j] //If there are no observations at all for a state then the probabilities will be zero which is bad //So instead we flag that B needs to be renormalized later if( num > 0 ) b[i][j] = denom > 0 ? num/denom : 1.0e-5; else{ b[i][j] = 0; renormB = true; } } } if( renormB ){ double sum; for (UINT i=0; i<numStates; i++) { sum = 0.; for (UINT k=0; k<numSymbols; k++){ b[i][k] += 1.0/numSymbols; //Add a small value to B to make sure the value will not be zero sum += b[i][k]; } for (UINT k=0; k<numSymbols; k++) b[i][k] /= sum; } } //Re-estimate Pi - only if the model type is ERGODIC, otherwise Pi[0] == 1 and everything else is 0 if (modelType==ERGODIC ){ for(k=0; k<numObs; k++){ const UINT T = (unsigned int)obs[k].size(); //Compute epsilon for(t=0; t<T-1; t++){ denom = 0.0; for(i=0; i<numStates; i++){ for(j=0; j<numStates; j++){ epsilon[k][t][i][j] = hmms[k].alpha[t][i] * a[i][j] * b[j][ obs[k][t+1] ] * hmms[k].beta[t+1][j]; denom += epsilon[k][t][i][j]; } } //Normalize Epsilon for(i=0; i<numStates; i++){ for(j=0; j<numStates; j++){ if(denom!=0) epsilon[k][t][i][j] /= denom; else{ epsilon[k][t][i][j] = 0; } } } } //Compute gamma for(t=0; t<T-1; t++){ for(i=0; i<numStates; i++){ gamma[k][t][i]= 0.0; for(j=0; j<numStates; j++) gamma[k][t][i] += epsilon[k][t][i][j]; } } } double sum = 0; for(i=0; i<numStates; i++){ sum=0.0; for(k=0; k<numObs; k++){ sum += gamma[k][0][i]; } pi[i] = sum / numObs; } } } }while(keepTraining); return true; }
int main(int argc, char *argv[]){ //--Declare variables int *a, *b, *c, i, m, n, p, range, chunk; if (argc < 5) { cout<< endl << endl << "\t....OOOps, INVALID No of Arguements,\n"; exit(1); }// end if int pc,id; MPI::Init(argc,argv); pc = MPI::COMM_WORLD.Get_size (); id = MPI::COMM_WORLD.Get_rank (); if (id == 0){ cout << "-- Siavash Katebzadeh" << endl <<"-- Parallel program to generate randomly two matrices a(m by n) and b(n by p)i" << endl <<"-- and then computing c = a * b" << endl <<"-- To compile make parallel-2, To run mpirun -n core ./bin/parallel-2 m n p r (all integer)" << endl <<"-- where: core is no. of processors, m is no. of rows of matrix a, n is no. of cols of matrix a, ....." << endl <<"-- p is no. of cols of matrix c and r is range of matrices a and b" << endl ; } //--Get input data m = atoi(argv[1]); // rows of matrix a n = atoi(argv[2]); // cols of matrix a p = atoi(argv[3]); // cols of matrix c range = atoi(argv[4]);// range of matrices a and b chunk = m / pc + (m % pc == 0 ? 0 : 1); //chunk = m / pc; //--Allocate Space for Matrix a a = (int *) malloc ((m % pc == 0 ? m : m * 2 - m % pc ) * n * sizeof (int)); //a = (int *) malloc (m * n * sizeof (int)); //--Allocate Space for Matrix b b = (int *) malloc (n * p * sizeof (int)); //--Allocate Space for Matrix c //c = (int *) malloc (m * p * sizeof (int)); c = (int *) malloc ((m % pc == 0 ? m : m * 2 - m % pc) * p * sizeof (int)); int * local_c = (int *) malloc(chunk * p * sizeof (int)); if(id == 0){ //--Generate and print Matrix a genMatrix(a, m, n, range); //--Generate and print Matrix b genMatrix(b, n, p, range); } MPI::COMM_WORLD.Bcast(a,n*m,MPI::INT,0); MPI::COMM_WORLD.Bcast(b,m*p,MPI::INT,0); mpyMatrix(a, b, local_c, m, n, p, chunk, id); MPI::COMM_WORLD.Gather(local_c,p * chunk,MPI::INT,c+(id * chunk * p) ,chunk * p,MPI::INT,0); //--Print Matrices a, b and c if( id == 0) printMatrices(a, b, c, m, n, p); MPI::Finalize (); // --free allocated spaces free (a);//free allocated space for matrix a free (b);//free allocated space for matrix b free (c);//free allocated space for matrix c free (local_c);//free allocated space for matrix c return 0; } // end main