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
Exemple #2
0
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 &currentIter,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