#include #include #include"math.h" #include"Arguments.h" #include"Model.h" #include"Engine.h" #define LOGADD_NEW(logA, logB) if(logA == MARK) logA = logB; else if (logA == LOG_ZERO) logA = logB; else if (logB == LOG_ZERO) logA = logA; else logA = logA + log(1+exp(logB-logA)); //#define LOGMINUS(la,lb) if(la>8e99||lb-la>100) la=lb;else la+=log(1-exp(lb-la)); #define LOGMINUS_NEW(logA, logB) if(logA == MARK) logA = logB; else if (logA == LOG_ZERO) logA = logB; else if (logB == LOG_ZERO) logA = logA; else logA = logA + log(1-exp(logB-logA)); #define epsilon 1.0e5 bool logSpecValEquals(double logX, double logSpecVal){ return (logX >= logSpecVal - epsilon && logX <= logSpecVal + epsilon); } //call by reference to the original value //the log sum result is stored in logA //replace LOGADD_NEW(logA, logB) //Pre: if neither logA nor logB is MARK/LOG_ZERO, then logA < 0 && logB < 0 void logAdd_New(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; } //Nither logA nor logB is MARK/LOG_ZERO //logA < 0 && logB < 0 else{ //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); } } }// end of void logAdd_New(double & logA, double & logB) //Pre: // (logA != MARK) and (if logB != LOG_ZERO then logA !=LOG_ZERO) and (logA < 0); (i.e. logA has been assigned some value) // if logB != MARK/LOG_ZERO, then logA >= logB void logMinus_New(double & logA, double & logB){ //if(logA == MARK){ if(logSpecValEquals(logA, MARK)){ cerr << "Error: logMinus_New(double & logA, double & logB): logA == MARK\n"; exit(1); } //else if (logA == LOG_ZERO && logB != LOG_ZERO){ else if (logSpecValEquals(logA, LOG_ZERO) && ! logSpecValEquals(logB, LOG_ZERO)){ cerr << "Error: logMinus_New(double & logA, double & logB): logA == LOG_ZERO && logB != LOG_ZERO\n"; exit(1); } //else if(logB == MARK){ else if(logSpecValEquals(logB, MARK)){ logA = logA; } //else if(logB == LOG_ZERO){ else if(logSpecValEquals(logB, LOG_ZERO)){ logA = logA; } //Nither logA nor logB is MARK/LOG_ZERO //logA >= logB else{ if(logA == logB){ logA = LOG_ZERO; } //logA > logB else{ if(logA > logB){ logA = logA + log(1 - exp(logB-logA)); } //if logA < logB //Note: this is the case which only occurs in // sub_h_Fast_Details() and sub_RR_Fast_Details() for the testing; it should not happen generally else{ cerr << "Warning: logMinus_New(double & logA, double & logB): logA < logB" << endl; logA = -( logB + log(1 - exp(logA-logB)) ); } } } } // end of void logMinus_New(double & logA, double & logB) //Add: modified from void logMinus_New(double & logA, double & logB) //Only for void sub_RR_Fast_TSize() and void sub_h_Fast_TSize() //Pre: // (logA != MARK) and // (logB != MARK) and // both logA >= logB and logA < logB are allowed // Post: // if logA < logB, then return LOG_ZERO bound // ow, return the correctly exact answer void logMinus_New_NonnegRes(double & logA, double & logB){ //if(logA == MARK){ if(logSpecValEquals(logA, MARK)){ cerr << "Error: logMinus_New_NonnegRes(double & logA, double & logB): logA == MARK\n"; exit(1); } //else if(logB == MARK){ else if(logSpecValEquals(logB, MARK)){ cerr << "Error: logMinus_New_NonnegRes(double & logA, double & logB): logB == MARK\n"; exit(1); } //else if(logB == LOG_ZERO){ else if(logSpecValEquals(logB, LOG_ZERO)){ logA = logA; } //Nither logA nor logB is MARK/LOG_ZERO //logA >= logB else{ if(logA == logB){ logA = LOG_ZERO; } //logA > logB else{ if(logA > logB){ logA = logA + log(1 - exp(logB-logA)); } //if logA < logB, return LOG_ZERO as the bound //Note: this is the case which only occurs in // sub_h_Fast_TSize() and sub_RR_Fast_TSize(); else{ logA = LOG_ZERO; } } } } // end of void logMinus_New_NonnegRes(double & logA, double & logB) //call by reference to the original value //the log sum result is stored in logA 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; } //Nither 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) //#include //forward double * hFunc; double * hFuncNume; //backward //AA_S = new double [S+1]; double * AA_S; double * RRFunc; double * RRFuncNume; //mixIndegree double * Eta_U; double ** KFunc; //In_Out double * RRFuncInOut; //ofstream totalOfMixEta("debugEngineMixForEta_U.txt"); void printIntArr(int * TSet, int leng){ for(int ind = 0; ind < leng; ind++){ cout << "Set[" << ind << "]=" << TSet[ind] << endl; } } int binIntLen(int S){ int SSetLen = 0; while(S > 0){ if(S & 1){ SSetLen++; } S >>= 1; } return SSetLen; } void binIntToDecIntArr(int S, int ones, int *SSet){ int posFromLeft = 0; int ind = 0; while(S > 0){ if(S & 1){ SSet[ind++] = posFromLeft; } S >>= 1; posFromLeft++; } //printIntArr(SSet, ones); } //HR: Compute F(S, T) double compute_f(int nh, int S, int T, int sizeofT, int *TSet, double * h, double ** alpha){ double result_f = MARK; double result_h = h[S-T]; //LOGADD(result_f, result_h); result_f = result_h; if (result_f == LOG_ZERO){ return result_f; } for(int index = 0; index < sizeofT; index++){ int j = TSet[index]; double result_A = alpha[j][S-T]; //result_f += result_A; if (result_A == LOG_ZERO){ return LOG_ZERO; } else{ result_f += result_A; } } return result_f; } //HR: Compute: \sum_{k=1}^{|S|} (-1)^{k+1} \sum{T \subset S, |T|=k} F(S,T) void rec_compute_sum_F_S_T( int d, int nh, int S, int ones, int * SSet, int T, int sizeofT, int * TSet, double * h, double ** alpha, double & sumOdd, double & sumEven) { if(d < nh){ rec_compute_sum_F_S_T(d+1, nh, S, ones, SSet, T, sizeofT, TSet, h, alpha, sumOdd, sumEven); //the binary repre of S has 1 in d'th position (starting from 0) from right if(((S>>d) & 1) == 1){ TSet[sizeofT] = d; rec_compute_sum_F_S_T(d+1, nh, S, ones, SSet, (T | (1< 0 double sumOdd = MARK; double sumEven = MARK; compute_sum_F_S_T(nh, S, ones, SSet, h, alpha, sumOdd, sumEven); //if sumEven has been assigned some value instead of MARK if(sumEven != MARK){ logMinus_New(sumOdd, sumEven); //LOGMINUS_NEW(sumOdd, sumEven); } h[S] = sumOdd; //cout << "h[" << S << "] = " << h[S] << endl; //cout << endl; } } // end sub_h_Fast() //HR: // Compute h void compute_h_Fast(int nh, double * h, double ** alpha){ int * SSet = new int[nh]; sub_h_Fast(0, nh, 0, 0, SSet, h, alpha); delete [] SSet; } // end compute_h_Fast() //HR: Compute: \sum_{k=1}^{|S|} (-1)^{k+1} \sum{T \subset S, |T|=k} F(S,T) void compute_sum_F_S_T_Iter(int nh, int S, double * h, double ** alpha, double & sumOdd, double & sumEven){ //all the subsets T of S, expect that T = 0 (empty set) for(int T = 1; T <= S; T++){ //if T is the subset of S if((S|T) == S){ int TSetLen = binIntLen(T); int * TSet = new int[TSetLen]; binIntToDecIntArr(T, TSetLen, TSet); double result_F = compute_f(nh, S, T, TSetLen, TSet, h, alpha); //sizeofT is odd if(TSetLen % 2 == 1){ logAdd_New(sumOdd, result_F); //LOGADD_NEW(sumOdd, result_F); } else{ logAdd_New(sumEven, result_F); //LOGADD_NEW(sumEven, result_F); } delete[] TSet; } } } //HR: // Compute h by iteration instead of recursion void compute_h_Iter(int nh, double * h, double ** alpha){ // h[0] = 0; //h[S]: S: from 1 to (1<>d) & 1) == 1){ TSet[sizeofT] = d; rec_compute_sum_RF_S_T_TSize(d+1, nh, S, ones, SSet, (T | (1<>d) & 1) == 1){ TSet[sizeofT] = d; rec_compute_sum_F_S_T_Details(d+1, nh, S, ones, SSet, (T | (1< 0 double sumOdd = MARK; double sumEven = MARK; if(S < (1 << nh) - 1 ){ compute_sum_F_S_T(nh, S, ones, SSet, h, alpha, sumOdd, sumEven); } //S == (1 << nh) - 1 else{ compute_sum_F_S_T_Details(nh, S, ones, SSet, h, alpha, sumOdd, sumEven, FSum); } //if sumEven has been assigned some value instead of MARK if(sumEven != MARK){ logMinus_New(sumOdd, sumEven); //LOGMINUS_NEW(sumOdd, sumEven); } h[S] = sumOdd; //cout << "h[" << S << "] = " << h[S] << endl; //cout << endl; } } void compute_h_Fast_Details(int nh, double * h, double ** alpha, double * FSum){ int * SSet = new int[nh]; sub_h_Fast_Details(0, nh, 0, 0, SSet, h, alpha, FSum); delete [] SSet; } //HR: Compute: \sum_{k=1}^{|S|} (-1)^{k+1} \sum{T \subset S, |T|=k} F(S,T) void rec_compute_sum_F_S_T_TSize( int d, int nh, int S, int ones, int * SSet, int T, int sizeofT, int * TSet, double * h, double ** alpha, double & sumOdd, double & sumEven, int TSize) { if(d < nh){ rec_compute_sum_F_S_T_TSize(d+1, nh, S, ones, SSet, T, sizeofT, TSet, h, alpha, sumOdd, sumEven, TSize); //the binary repre of S has 1 in d'th position (starting from 0) from right if(((S>>d) & 1) == 1){ TSet[sizeofT] = d; rec_compute_sum_F_S_T_TSize(d+1, nh, S, ones, SSet, (T | (1< 0 double sumOdd = MARK; double sumEven = MARK; compute_sum_F_S_T_TSize(nh, S, ones, SSet, h, alpha, sumOdd, sumEven, TSize); //if sumEven has been assigned some value instead of MARK if(sumEven != MARK){ logMinus_New_NonnegRes(sumOdd, sumEven); //logMinus_New(sumOdd, sumEven); //LOGMINUS_NEW(sumOdd, sumEven); } h[S] = sumOdd; //cout << "h[" << S << "] = " << h[S] << endl; //cout << endl; } } // end sub_h_Fast_TSize() //HR: // Compute h void compute_h_Fast_TSize(int nh, double * h, double ** alpha, int TSize){ int * SSet = new int[nh]; sub_h_Fast_TSize(0, nh, 0, 0, SSet, h, alpha, TSize); delete [] SSet; } // end compute_h_Fast_TSize() void rec_compute_sum_RF_S_T_Details( int d, int nh, int S, int ones, int * SSet, int T, int sizeofT, int * TSet, double * RR, double ** alpha, double & sumOdd, double & sumEven, double * RFSum) { if(d < nh){ rec_compute_sum_RF_S_T_Details(d+1, nh, S, ones, SSet, T, sizeofT, TSet, RR, alpha, sumOdd, sumEven, RFSum); //the binary repre of S has 1 in d'th position (starting from 0) from right if(((S>>d) & 1) == 1){ TSet[sizeofT] = d; rec_compute_sum_RF_S_T_Details(d+1, nh, S, ones, SSet, (T | (1< 0 to represent negative prob result_K_v = - sumOdd; //cerr<<"K_v[" << U << "]" << result_K_v << endl; } } K_v[U] = result_K_v; delete[] TSet; delete[] Eta_U; } void init_all_K_v(int d, int S, double * K_v, double value, int ones, int nh){ //cerr<<" d: "<>d) & 1) == 1){ USet[USetLen] = d; rec_compute_all_K_v(d+1, nh, UMax, UMaxSetLen, UMaxSet, (U | (1<