#include #include #include //#include "varpar.h" #include #include #include #include #include #include "cfg.h" #include #include //HR //#define EPSILON 0.001 #define EPSILON 0.00001 //HR: Add for hash_set #if __GNUC__ < 3 && __GNUC__ >= 2 && __GNUC_MINOR__ >= 95 # include # include # define gnu_namespace std #elif __GNUC__ >= 3 # include # if __GNUC_MINOR__ == 0 # include # define gnu_namespace std # else # include # define gnu_namespace __gnu_cxx # endif #else # include # include # define gnu_namespace std #endif using namespace gnu_namespace; #include // using namespace std; #define MARK 9e99 #define LOG_ZERO -1e101 //HR: add from UpdateHR.h to deal with the problem in sum = 0 in comp_post() //call by reference to the original value //the log sum result is stored in logA #define epsilon 1.0e5 bool logSpecValEquals(double logX, double logSpecVal){ return (logX >= logSpecVal - epsilon && logX <= logSpecVal + epsilon); } void logAddComp(double & logA, double & logB){ //if(logA == MARK){ if(logSpecValEquals(logA, MARK)){ logA = logB; } //else if (logA == LOG_ZERO){ else if (logSpecValEquals(logA, LOG_ZERO)){ logA = logB; } //else if(logB == MARK){ else if(logSpecValEquals(logB, MARK)){ logA = logA; } //else if(logB == LOG_ZERO){ else if(logSpecValEquals(logB, LOG_ZERO)){ logA = logA; } //Neither logA nor logB is MARK/LOG_ZERO else{ //1 if(logA < 0 && logB < 0 ){ //1.1 //Gaurd logB-logA <= 100 to avoid that exp(logB-logA) go to inf if(logB - logA <= 100 ){ logA = logA + log( 1 + exp(logB-logA) ); } //1.2 //if logB - logA > 100, then logB > 100 + logA so that B is much bigger than A (B > e^100 * A) // So (A + B) almost = B else{ //logA = logB; //The following is the real formula,; but it is almost same as //logA = logB; logA = logB + log( exp(logA - logB) + 1); } } //2 else if(logA > 0 && logB > 0){ //always make exp(.): . > 0 if(-logB + logA <= 100){ //2.1 logA = -( -logA + log( 1 + exp(-logB+logA) ) ); } else{ //2.2 logA = -( -logB + log( 1 + exp(-logA+logB) ) ); } } //3 else if(logA < 0 && logB > 0){ //3.1 if(logA + logB > 0){ if(logA + logB <= 100){ //3.1.2 logA = -logB + log( exp(logA + logB) - 1 ); } else{ //3.1.1 logA = logA + log( 1 - exp(-logB-logA) ); } } //3.2 else if(logA + logB < 0){ if(-logA - logB <= 100){ //3.2.2 logA = -( logA + log( exp(-logB-logA) - 1) ); } else{ //3.2.1 logA = - ( -logB + log(1 - exp(logA+logB) ) ); } } //3.3 else{ logA = LOG_ZERO; } } //4 else if(logA > 0 && logB < 0){ //4.1 if(logA + logB > 0){ if(logA + logB <= 100){ //4.1.2 logA = -logA + log( exp(logB+logA) - 1); } else{ //4.1.1 logA = logB + log( 1 - exp(-logA-logB) ); } } //4.2 else if(logA + logB < 0){ if(-logA-logB <= 100){ //4.2.2 logA = -( logB + log( exp(-logA-logB) - 1) ); } else{ //4.2.1 logA = -( -logA + log(1 - exp(logB+logA)) ); } } //4.3 else{ logA = LOG_ZERO; } } } } // end of void logAddComp(double & logA, double & logB)c //HR: Note: The whole program supposes that max no. of vars = 32 and hardcord 32 //Convert the parent set to the appropriate variable set //HR:F varset_t parset2varset(int v, varset_t set){ varset_t sinkleton = 1U<(net_set s1,net_set s2); friend bool same_obj(net_set s1, net_set s2, int nof_vars); }; //HR:F /*================================================================*/ int operator<(net_set s1,net_set s2){ if(fabs(s1.score-s2.score)(net_set s1,net_set s2){ if(fabs(s1.score-s2.score)s2.score); } int operator==(net_set s1,net_set s2){ return(fabs(s1.score-s2.score)* v,net_set s, int k, int nof_vars){ list::iterator it; //HR: can improve its time //first check whether v->size() > 0 && s < v->back() //see Lav's comment bool flag=false; //HR: Refined // if( (v->size() > 0) && (s < v->back()) ){ v->push_back(s); flag=true; } else{ // for(it=v->begin();it!=v->end();it++){ if(same_obj(s,*it,nof_vars)){ // cout<<"Same object so not inserted!!!!!!!!!!!!!"<(*it)){ // cout<<"score of s:"<insert(it,s); flag=true; break; } } } if(flag==false){ v->push_back(s); } if(v->size()>k){ v->pop_back(); } //v->unique(); } /*================================================================*/ //class for bparents //HR:F //HR: (variable set, score) pair class score_network{ public: score_t scores; varset_t vset; friend int operator<(score_network s1,score_network s2); friend int operator==(score_network s1,score_network s2); friend int operator>(score_network s1,score_network s2); friend bool same_obj(score_network s1, score_network s2); }; //HR:F int operator<(score_network s1,score_network s2){ if(fabs(s1.scores-s2.scores)(score_network s1,score_network s2){ if(fabs(s1.scores-s2.scores)s2.scores); } int operator==(score_network s1,score_network s2){ return(fabs(s1.scores-s2.scores)* v,score_network s, int k) { list::iterator it; if( s < v->back()) { v->push_back(s); } else { for(it=v->begin();it!=v->end();it++) { // if(same_obj(s,*it)) // { // break; // } // else if(s>(*it)) { v->insert(it,s); break; } } } if(v->size()>k) { v->pop_back(); } } /*================================================================*/ //class for node //HR:F class node{ public: int ip; int in; score_t score; node(int x, int y, score_t z){ ip=x; in=y; score=z; } friend int operator<(node s1,node s2); friend int operator==(node s1,node s2); friend int operator>(node s1,node s2); friend bool same_obj(node s1, node s2); }; /*================================================================*/ int operator<(node s1,node s2){ if(fabs(s1.score-s2.score)(node s1,node s2){ if(fabs(s1.score-s2.score)s2.score); } int operator==(node s1,node s2){ return(fabs(s1.score-s2.score) v[],int size,int nof_vars){ list::iterator iter; for(int j=0;j* v){ vector::iterator iter; for(iter=v->begin();iter!=v->end();iter++){ cout<<"bparents "<<(*iter).vset<<","<<(*iter).scores<<" ,, "; } } void print_queue(list* v){ list::iterator iter; cout<<"fringe"<begin();iter!=v->end();iter++){ cout<<" ip "<<(*iter).ip<<", in "<<(*iter).in<<" score "<<(*iter).score; } } void print_queue(vector* v,int nof_vars){ vector::iterator iter; for(iter=v->begin();iter!=v->end();iter++){ // cout<<" "<<(*iter).bsps<<","<<(*iter).scores; cout<<"bnets "<<" Score:"<<(*iter).score<<" net "<* v,int nof_vars){ list::iterator iter; for(iter=v->begin();iter!=v->end();iter++){ // cout<<" "<<(*iter).bsps<<","<<(*iter).scores; cout<<"kbnet "<<" Score:"<<(*iter).score<<" net "<* v,node s, int k){ list::iterator it; //HR: test //bool sameObj = false; //bool inserted = false; // //if( s < v->back()){ same if( (v->size() == 0) || (s < v->back())){ v->push_back(s); } else{ for(it=v->begin();it!=v->end();it++){ //comment it out will give the different answer. Because Lav's original is wrong, it will still insert the same object. It will eventually pop the correct end > k // if(same_obj(s, *it)){ break; // sameObj = true; // cout << "s: "; // print_node(s); // cout << "*it: "; // print_node(*it); // cout << endl; // print_queue(v); } else{ // if(s>(*it)){ v->insert(it,s); //inserted = true; break; } } } //HR: test // if(sameObj == true && inserted == true){ // cout << "Error: sameObj == true && inserted = true" << endl; // cout << "s: "; // print_node(s); // print_queue(v); // } } if(v->size()>k){ //cout << "\n\nv->size()>k happens, v->pop_back()\n" << endl; v->pop_back(); } // cout<<"Inserted:"< struct hash { hash hasher_ns; size_t operator()(const net_set* ns) const { return hasher_ns((unsigned) roundl(- ns->score*10)); // wrong hash function?? } }; //end of struct } //end of namespace struct eqNetScore{ bool operator()(const net_set* ns1, const net_set* ns2) const{ return same_obj(*ns1, *ns2); } }; typedef hash_set, eqNetScore> NetScoreHashSet; NetScoreHashSet knets; //HR: Add void print_nsHashSet(NetScoreHashSet nsHSet, int nof_vars){ for(NetScoreHashSet::iterator it = nsHSet.begin(); it != nsHSet.end(); it++){ print_netscore(**it, nof_vars); } } // //=====================================================================================// /*================================================================*/ //HR:F //HR: call gettopk(&bnets,&bparents,&kbnetscore[varset],k,sink,nof_vars); void gettopk(vector* bnets, vector* bparents, list* kbnet, int k, varset_t sink,int nof_vars){ int h; int ipmax=bparents->size(); // cout<<"ipmax: "<size(); // cout<<"inmax: "< fringe; //HR: different from Algo4, here start from 0 vs. 1 node n(0,0,(bparents->at(0)).scores + (bnets->at(0)).score); insert_vec(&fringe,n,k); // print_queue(&fringe); // scanf("%d",&h); NetScoreHashSet::iterator iter1; while(!fringe.empty()){ // cout<<"Fringe not empty"<size())at(in)).net[j]; // cout<<"Net w j"<at(ip)).vset); //cout<<"net w sinkleton"<back()).score)>EPSILON)&&(score>(kbnet->back().score))){ // cout<<"score>kbnetback's score"<at(in)).net[j]; // cout<<"Net w j"<at(ip)).vset; //cout<<"net w sinkleton"<back(); //Lav insert_vec(kbnet,*netwP,k,nof_vars); //cout<<"After inserting"<at(ip+1)).scores + (bnets->at(in)).score); //cout<<"after child"<at(ip)).scores + (bnets->at(in+1)).score); //may add hash_set generated check here insert_vec(&fringe,child,k); //cout<<"Fringe after inserting"<* kbnet, int k,int nof_vars){ list::iterator it; //int j=0; //each it is one of k best for(it=kbnet->begin();it!=kbnet->end();it++){ for(int p=0;p kbnetscore[],char* dirname,int k,int nof_vars) { string str; list::iterator it; char str1[10]; int j=0; //HR: each it is the one of the k best for(it=kbnetscore[(1U<<(nof_vars))-1].begin();it!=kbnetscore[(1U<<(nof_vars))-1].end();it++){ str.assign(dirname); str.append("/"); sprintf(str1,"%d",j++); str.append(str1); str.append("net"); FILE* netf=fopen(str.c_str(),"w"); fprintf(netf,"%f \n",(*it).score); // cout<<(*it).score< kbnetscore[],char* dirname,int k,int nof_vars){ // string str; list::iterator it; int j=0; for(j=0;j<((1U<* kbnet, int k, char* dirname, int nof_vars){ //cout << "Start comp_postExact_compl()" << endl; //long double Sum=0.0; //double logSum = LOG_ZERO; list::iterator it; //HR: assume k < 5000 long double postExact[5000]; string str; char str1[32]; //cout << "dirname = " << dirname << endl; str.assign(dirname); str.append("/"); str.append("exactPD.txt"); //str.assign("exactPD.txt"); FILE *fp; fp=fopen(str.c_str(),"r"); double exactPD = 0.0; if(!feof(fp)){ char c; fscanf(fp, "%lf", &exactPD); fscanf(fp,"%c",&c); } fclose(fp); //printf("exactPD = %18.8f\n", exactPD); str.assign(dirname); str.append("/netpostExact"); fp=fopen(str.c_str(),"w"); //for each it of k best networks // for(it=kbnet->begin();it!=kbnet->end();it++){ // //HR: change it // //sum+=exp((*it).score); // logAddComp(logSum, (*it).score); //HR // } // cout << "logSum: " << logSum << endl; //HR // printf("logSum = %18.6f\n", logSum); // // // long double Sum = exp(logSum); //HR // cout << "Sum: " << exp(logSum) << endl; //HR // int i=0; //for each it of k best networks, compute equation (4) //each post[i] ( 0 <= i <= k - 1). repre post prob for i'th best network for(it=kbnet->begin();it!=kbnet->end();it++){ //post[i]=(exp((*it).score))/sum; //double logScore = (*it).score; //LOGMINUS_NEW(logScore, logSum) postExact[i]=exp( (*it).score - exactPD ); // fprintf(fp,"%Lg\n",postExact[i]); i++; } fclose(fp); //Start the update //define and init long double postProbExact[nof_vars][nof_vars]; for(int i = 0; i < nof_vars; i++){ for (int j = 0; j < nof_vars; j++){ postProbExact[i][j] = 0.0; } } int listSize = kbnet->size(); int num1 = -1; int num2 = -1; //HR: for each j of k best networks, j >=1 for(int j=0; j " << i << " \t" << postProbExact[j][i] << endl; } } } //end void comp_postExact_compl() //HR: Add //HR: Update from comp_post //Compute each edge out of nof_vars * nof_vars, instead of just the best network void comp_post_compl(list* kbnet, int k, char* dirname, int nof_vars){ //long double Sum=0.0; double logSum = LOG_ZERO; list::iterator it; //HR: assume k < 5000 long double post[5000]; string str; char str1[32]; str.assign(dirname); str.append("/netpost"); FILE *fp=fopen(str.c_str(),"w"); //for each it of k best networks for(it=kbnet->begin();it!=kbnet->end();it++){ //HR: change it //sum+=exp((*it).score); logAddComp(logSum, (*it).score); //HR } //cout << "logSum: " << logSum << endl; //HR //printf("logSum = %18.6f\n", logSum); // long double Sum = exp(logSum); //HR //cout << "Sum: " << exp(logSum) << endl; //HR // int i=0; //for each it of k best networks, compute equation (4) //each post[i] ( 0 <= i <= k - 1). repre post prob for i'th best network for(it=kbnet->begin();it!=kbnet->end();it++){ //post[i]=(exp((*it).score))/sum; //double logScore = (*it).score; //LOGMINUS_NEW(logScore, logSum) post[i]=exp( (*it).score - logSum ); // fprintf(fp,"%Lg\n",post[i]); i++; } fclose(fp); //Start the update //define and init long double postProb[nof_vars][nof_vars]; for(int i = 0; i < nof_vars; i++){ for (int j = 0; j < nof_vars; j++){ postProb[i][j] = 0.0; } } int listSize = kbnet->size(); int num1 = -1; int num2 = -1; //HR: for each j of k best networks, j >=1 for(int j=0; j " << i << " \t" << postProb[j][i] << endl; } } } //Computation of posterior probabilities - This function's call has been commented. Remove the commenting slashes if the posterior probability needs to be computed. //HR: call comp_post(&kbnetscore[nof_combs-1],k,dirname); void comp_post(list* kbnet, int k, char* dirname){ //long double Sum=0.0; double logSum = LOG_ZERO; list::iterator it; long double post[5000]; string str; char str1[32]; str.assign(dirname); str.append("/netpost"); FILE *fp=fopen(str.c_str(),"w"); //for each it of k best networks for(it=kbnet->begin();it!=kbnet->end();it++){ //HR: change it //sum+=exp((*it).score); logAddComp(logSum, (*it).score); //HR } cout << "logSum: " << logSum << endl; //HR // long double Sum = exp(logSum); //HR cout << "Sum: " << exp(logSum) << endl; //HR // int i=0; //for each it of k best networks, compute equation (4) //each post[i] ( 0 <= i <= k - 1). repre post prob for i'th best network for(it=kbnet->begin();it!=kbnet->end();it++){ //post[i]=(exp((*it).score))/sum; //double logScore = (*it).score; //LOGMINUS_NEW(logScore, logSum) post[i]=exp( (*it).score - logSum ); // fprintf(fp,"%Lg\n",post[i]); i++; } fclose(fp); ifstream indata; int n=0; int num[50][2]; int num1,num2; // char f[50][20]; long double postf[50]; str.assign(dirname); str.append("/"); str.append("arc0"); fp=fopen(str.c_str(),"r"); // fp=fopen(str.c_str(),"r"); i=0; while(!feof(fp)){ char c; //HR: for parent fscanf(fp,"%d",&num[i][0]); //HR: for var fscanf(fp,"%d",&num[i][1]); fscanf(fp,"%c",&c); //indata>>num[i][1]; //HR: // cout<<"HIIIII"<=1 for(j=1;j>num1; // indata>>num2; //HR: // cout< kbnetscore[nof_combs]" << endl; //cerr << "before list kbnetscore[nof_combs]" << endl; //HR: net_set is the (net, score) pair //HR: have not yet set each list kbnetscore[W] the size k list kbnetscore[nof_combs]; //cerr << "after list kbnetscore[nof_combs]" << endl; //cout << "after list kbnetscore[nof_combs]" << endl; list::iterator it; vector bnets; //HR: score_network is (variable set, score) pair score_network s; vector bparents; //HR: Add hash_set knets here; global may be better so that gettopk can access //NetScoreHashSet knets; // //cout << "before net_set netw" << endl; net_set netw; netw.score=0; for(int j=0;j v[],int size,int nof_vars) //cout << "print_queue(kbnetscore)" << endl; //print_queue(kbnetscore,(1U<