//------------------------------------------------------------------- // This function computes the coeffeicients C_k for all clusters. //------------------------------------------------------------------- void DataAdaptiveImprovedFastGaussTransform::compute_C() { for (int i = 0; i < K*p_max_total; i++){ C[i]=0.0; } p_max_actual=-1; for(int i=0; i<N; i++){ int k=pci[i]; int source_base=i*d; int center_base=k*d; source_center_distance_square=0.0; for (int j = 0; j < d; j++){ dx[j]=(px[source_base+j]-pcc[center_base+j]); source_center_distance_square += (dx[j]*dx[j]); } pT[i]=return_p(source_center_distance_square,k); if (pT[i]>p_max_actual){ p_max_actual=pT[i]; } compute_source_center_monomials(pT[i]); double f=pq[i]*exp(-source_center_distance_square/h_square); for(int alpha=0; alpha<nchoosek(pT[i]-1+d,d); alpha++){ C[k*p_max_total+alpha]+=(f*source_center_monomials[alpha]); } } p_max_actual_total=nchoosek(p_max_actual-1+d,d); compute_constant_series(); for(int k=0; k<K; k++){ for(int alpha=0; alpha<p_max_total; alpha++){ C[k*p_max_total+alpha]*=constant_series[alpha]; } } }
DataAdaptiveImprovedFastGaussTransform::DataAdaptiveImprovedFastGaussTransform(int Dim, int NSources, int MTargets, double *pSources, double Bandwidth, double *pWeights, double *pTargets, int MaxTruncNumber, int NumClusters, int *pClusterIndex, double *pClusterCenter, double *pClusterRadii, double CutoffRadius, double epsilon, double *pGaussTransform, int *pTruncNumber ) { //Read the parameters d=Dim; N=NSources; M=MTargets; px=pSources; h=Bandwidth; pq=pWeights; py=pTargets; p_max=MaxTruncNumber; K=NumClusters; pci=pClusterIndex; pcc=pClusterCenter; pcr=pClusterRadii; r=CutoffRadius; pG=pGaussTransform; pT=pTruncNumber; eps=epsilon; //Memory allocation p_max_total=nchoosek(p_max-1+d,d); constant_series=new double[p_max_total]; source_center_monomials = new double[p_max_total]; target_center_monomials = new double[p_max_total]; dx = new double[d]; dy = new double[d]; heads = new int[d]; C=new double[K*p_max_total]; h_square=h*h; ry=new double[K]; ry_square=new double[K]; for(int i=0; i<K; i++) { ry[i]=r+pcr[i]; ry_square[i]=ry[i]*ry[i]; } }
Real moment(const size_t m) const { Real val = 0., binom = 0., moment = 0.; for (size_t i = 0; i < m; i++) { moment = exp2_*tgamma(1.+(Real)i/exp1_)*tgamma(exp2_)/tgamma(1.+exp2_+(Real)i/exp1_); binom = (Real)nchoosek(m,i); val += binom*std::pow(a_,m-i)*std::pow(b_-a_,i+1)*moment; } return val; }
ImprovedFastGaussTransformChooseParameters::ImprovedFastGaussTransformChooseParameters( int Dim, double Bandwidth, double epsilon, int MaxNumClusters ) { d=Dim; h=Bandwidth; Klimit=MaxNumClusters; eps=epsilon; R=sqrt((double)d); double h_square=h*h; r=min(R,h*sqrt((double)log(1.0f/eps))); int p_ul=200; // [Upper limit on the truncation number]I have roughly set this to 200 K=1; int p=1; double complexity_min=1e16; double rx; for(int i=0;i <Klimit;i++){ rx=pow((double)i+1,-1.0/(double)d); double rx_square=rx*rx; double n=min(i+1,pow(r/rx,(double)d)); double error=1; double temp=1; int p=0; while((error > eps) & (p <= p_ul)){ p++; double b=min(((rx+sqrt((rx_square)+(2*p*h_square)))/2),rx+r); double c=rx-b; temp=temp*(((2*rx*b)/h_square)/p); error=temp*(exp(-(c*c)/h_square)); } double complexity=(i+1)+log((double)i+1)+((1+n)*nchoosek(p-1+d,d)); //printf("d=%d r=%f K=%d rx=%f n=%f p=%d terms=%d c=%f\n",d,r,i+1,rx,n,p,nchoosek(p-1+d,d),complexity); if (complexity < complexity_min ){ complexity_min=complexity; K=i+1; p_max=p; } } }
double pskf(double mu, double divOrder){ //???????????????? double out = 0; for (int i = 0; i < divOrder - 1; i++) out = out + nchoosek(2 * i, i) * pow(((pow(1 - mu, 2)) / 4), i); out = (1 - mu*out) / 2; return 0; }
arma::uword polynomialSize( const arma::uword numberOfElements, const arma::uword polynomialOrder) { // The number of parameter combinations for the constant term. arma::uword polynomialSize = 1; // Sums up the number of parameter combinations for each degree > 0. for (arma::uword n = 1; n <= polynomialOrder; ++n) { polynomialSize += nchoosek(numberOfElements + n - 1, n); } return polynomialSize; }
int special_sum(int N, int items[]) { int **ksums = malloc((1 + N) * sizeof(int *)); int *kcount = calloc((1 + N), sizeof(int)); int i; for(i = 0; i <= N; i++) ksums[i] = malloc(nchoosek(N, i) * sizeof(int)); for(i = 1; i < (1 << N); i++) { int count = _popcnt(i); int index = kcount[count]++; int sum = item_sum(N, items, i); ksums[count][index] = sum; } for(i = 1; i < N; i++) qsort(ksums[i], kcount[i], sizeof(int), icmp); bool is_special = true; for(i = 1; i < N && is_special; i++) { // check duplicate sums int j; for(j = 1; j < kcount[i]; j++) { if(ksums[i][j] == ksums[i][j-1]) { is_special = false; break; } } // check order if(ksums[i][kcount[i]-1] >= ksums[i+1][0]) is_special = false; } int ret = 0; if(is_special) { for(i = 0; i < N; i++) ret += items[i]; } for(i = 0; i < N; i++) free(ksums[i]); free(ksums); free(kcount); return ret; }
arma::uword polynomialSize( const arma::uword numberOfElements, const arma::uword highestDegree) { if (numberOfElements == 0 || highestDegree == 0) { return 1; } // Gets initialised with the number of constant terms (degree = 0). arma::uword polynomialSize = 1; // Sums up the number of parameter combinations for each degree > 0. for (arma::uword degree = 1; degree <= highestDegree; ++degree) { const arma::uword numberOfCombinations = nchoosek(numberOfElements + degree - 1, degree); if (std::numeric_limits<decltype(polynomialSize)>::max() - polynomialSize < numberOfCombinations) { throw std::overflow_error("polynomialSize: The polynomial size will be greater than the largest supported integer."); } polynomialSize += numberOfCombinations; } return polynomialSize; }
std::vector<arma::Col<arma::uword>> multicombinations( const arma::uword numberOfElements, const arma::uword combinationsize) { std::vector<arma::Col<arma::uword>> multicombinations; arma::Col<arma::uword> indices(combinationsize, arma::fill::zeros); for (arma::uword n = 0; n < nchoosek(numberOfElements + combinationsize - 1, combinationsize); ++n) { multicombinations.push_back(indices); // Increments the indices vector, to get the next set of elements. // If the increase of the first element is out of bound (*indices(0)* >= *numberOfElements*), it is set to 0 and the next index is increased by 1. If the next index is also out of bound, it is also set to 0 and the next one is increased (and so on) ... // For example: Given 4 elements, (1, 1, 3, 3) will become (1, 2, 0, 0). ++indices(0); for (arma::uword k = 0; k < indices.n_elem - 1; ++k) { if (indices(k) > numberOfElements - 1) { indices.head(k + 2).fill(indices(k + 1) + 1); } else { break; } } } return multicombinations; }
int bipartition(int *set, int setSize, int nMax, int option, mxArray *B1, mxArray *B2) { if(option == 1) nMax = floor(nMax/2); nB = 0; for(int i = 0; i <= nMax; i++) nB = nB + nchoosek(setSize,i); int cellDims[2] = (nB,1); B1 = mxCreateCellArray (2,cellDims); B2 = mxCreateCellArray (2,cellDims); int iB = 0; //open up MATLAB engine to use the nchoosek function // TODO: !!! CAN WE USE mexCallMATLAB INSTEAD!? Engine *ep; if (!(ep = engOpen("\0"))) { fprintf(stderr, "\nCan't start MATLAB engine\n"); //return EXIT_FAILURE; } for (int i = 0; i <= nMax; i++) { B1cellPtr = mxGetCell(B1, iB); B2cellPtr = mxGetCell(B2, iB); if(i == 0) { B1cellPtr = NULL; B2cellPtr = set; //do we need memcpy here? iB++; } else { mxArray *iMATLAB = mxCreateDoubleMatrix(1, 1, mxREAL); memcpy((void *)mxGetPr(iMATLAB), (void *)i, sizeof(i)); mxArray *setSizeMATLAB = mxCreateDoubleMatrix(1, 1, mxREAL); memcpy((void *)mxGetPr(setSizeMATLAB), (void *)setSize, sizeof(setSize)); engPutVariable(ep, "i", iMATLAB); engPutVariable(ep, "setSize", setSizeMATLAB); engEvalString(ep, "C_b = nchoosek(1:setSize,i);"); int *chooseSets; mxArray *C_bmxArray = engGetVariable(ep,"C_b"); double *temp = mxGetPr(C_bmxArray); int chooseSetsSizeCols = mxGetN(C_bmxArray); int chooseSetsSizeRows = mxGetM(C_bmxArray); int chooseSetSize = chooseSetsSizeCols*chooseSetsSizeRows; int chooseSets[chooseSetSize]; for(int j = 0; j < chooseSetSize; j++) chooseSets[j] = temp[j]; for(int j = 0; j < C_bSizeRows; j++) { int chooseSetIndex = 0; int B1index = 0; int B2index = 0; for(int k =0; k < setSize; k++) { if((j + chooseSetIndex*C_bSizeRows) < chooseSetSize) && chooseSet[j + chooseSetIndex*C_bSizeRows] == set[k]) { B1cellPtr[B1index] = set[k]; chooseSetIndex++; B1index++; } else { B2cellPtr[B2index] = set[k]; B2index++; } iB++; } } mxDestroyArray(iMATLAB); mxDestroyArray(setSize); } }
size_t nchoosek(const size_t n, const size_t k) const { return ((k==0) ? 1 : (n*nchoosek(n-1,k-1))/k); }
int main(void) { int i; counts_t *items = calloc(26, sizeof(counts_t)); int *index = malloc((1 << 26)*sizeof(int)); int num_items = exhaust_fixed_density(26, 1, items, index); for(i = 0; i < num_items; i++) { // generation is in order for these, so we are guaranteed that // items[i].mask == 1 << i, so that the appropriate index for // count_without increment is i. items[i].count_without[i] = 1; } long max_total_count = 0; for(i = 1; i < 26; i++) { const int density = 1 + i; int num_new_items = nchoosek(26, density); counts_t *new_items = calloc(num_new_items, sizeof(counts_t)); int *new_index = malloc((1 << 26) * sizeof(int)); exhaust_fixed_density(26, density, new_items, new_index); int j; long total_count = 0; for(j = 0; j < num_new_items; j++) { // j indexes into the different possible masks at the current // density const uint32_t mask = new_items[j].mask; uint32_t destroyed_mask = mask; int tz = _trailz(mask); int last_item = tz; while(destroyed_mask) { destroyed_mask >>= 1 + tz; // construct previous mask by removing last_item from current // mask uint32_t prev_mask = mask ^ (1u << last_item); counts_t *prev = items + index[prev_mask]; int prev_item; for(prev_item = 0; prev_item < last_item; prev_item++) { // last_item comes lex after prev_item, so add a hit new_items[j].count_with[last_item] += prev->count_without[prev_item]; } for(prev_item = 1 + last_item; prev_item < 26; prev_item++) { // last_item comes lex before prev_item, so no hit new_items[j].count_without[last_item] += prev->count_without[prev_item]; new_items[j].count_with[last_item] += prev->count_with[prev_item]; } tz = _trailz(destroyed_mask); last_item += 1 + tz; } int k; for(k = 0; k < 26; k++) total_count += new_items[j].count_with[k]; } printf("total count at density %d: %ld\n", density, total_count); max_total_count = (total_count > max_total_count) ? total_count : max_total_count; free(items); free(index); items = new_items; index = new_index; } printf("max total count: %ld\n", max_total_count); return 0; }
void mexFunction( int nlhs, mxArray *plhs[] , int nrhs, const mxArray *prhs[] ) { double *x , *w; double sigma = 1.0 , e = 10.0; int p = 8 , K = 30; double *xc , *A_k; const int *dimsx ; int numdimsx ; int i , d , Nx ; int pd; double *dist_C , *C_k , *dx , *prods; int *indxc , *indx , *xhead , *xboxsz , *heads , *cinds; /*--------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------*/ /* -------------------------- Parse INPUT -------------------------------------- */ /*--------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------*/ if ((nrhs < 1)) { mexErrMsgTxt("Usage : v = fgt_model(x , [w] , [sigma] , [p] , [K] , [e] );"); } /* ----- Input 1 ----- */ x = mxGetPr(prhs[0]); numdimsx = mxGetNumberOfDimensions(prhs[0]); dimsx = mxGetDimensions(prhs[0]); d = dimsx[0]; Nx = dimsx[1]; K = min(Nx , K); /* ----- Input 2 ----- */ if ((nrhs < 2) || mxIsEmpty(prhs[1])) { w = (double *)mxMalloc(Nx*sizeof(double)); for (i = 0 ; i < Nx ; i++) { w[i] = 1.0; } } else { w = mxGetPr(prhs[1]); } /* ----- Input 3 ----- */ if (nrhs > 2) { sigma = (double)mxGetScalar(prhs[2]); } /* ----- Input 4 ----- */ if (nrhs > 3) { e = (double)mxGetScalar(prhs[3]); } /* ----- Input 5 ----- */ if (nrhs > 4) { K = (int)mxGetScalar(prhs[4]); if(K > Nx) { mexErrMsgTxt("K must be <= Nx"); } } else { K = (int) sqrt(Nx); } /* ----- Input 6 ----- */ if (nrhs > 5) { p = (int)mxGetScalar(prhs[5]); } /*--------------------------------------------------------------------------------*/ /*---------------------------------------,----------------------------------------*/ /* -------------------------- Parse OUTPUT ------------------------------------- */ /*--------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------*/ pd = nchoosek(p + d - 1 , d); /* ----- output 1 ----- */ plhs[0] = mxCreateDoubleMatrix(d , K , mxREAL); xc = mxGetPr(plhs[0]); plhs[1] = mxCreateDoubleMatrix(pd , K , mxREAL); A_k = mxGetPr(plhs[1]); C_k = (double *)mxMalloc(pd*sizeof(double)); dist_C = (double *)mxMalloc(Nx*sizeof(double)); dx = (double *)mxMalloc(d*sizeof(double)); prods = (double *)mxMalloc(pd*sizeof(double)); indxc = (int *)mxMalloc(K*sizeof(int)); indx = (int *)mxMalloc(Nx*sizeof(int)); xhead = (int *)mxMalloc(K*sizeof(int)); xboxsz = (int *)mxMalloc(K*sizeof(int)); heads = (int *)mxMalloc((d + 1)*sizeof(int)); cinds = (int *)mxMalloc(pd*sizeof(int)); /*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/ /* ----------------------- MAIN CALL -------------------------------------------- */ /*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/ fgt_model(x , w , sigma , p , K , e , xc , A_k , d , Nx , indxc , indx , xhead , xboxsz , dist_C , C_k , heads , cinds , dx , prods , pd); /*-----------------------------------------------*/ /*-----------------------------------------------*/ /* ------------ END of Mex File ---------------- */ /*-----------------------------------------------*/ /*-----------------------------------------------*/ mxFree(indxc); mxFree(indx); mxFree(xhead); mxFree(xboxsz); mxFree(dist_C); mxFree(C_k); mxFree(heads); mxFree(cinds); mxFree(dx); mxFree(prods); if ((nrhs < 3) || mxIsEmpty(prhs[2]) ) { mxFree(w); } }
double coded_modulation(int modulation_type, double code_rate, int decode_type, double gamma_b) { int constraint = 9; double ber; if (code_rate == 1) { switch (modulation_type) { case bpsk: case qpsk: case dbpsk: case dqpsk: case oqpsk: case t16_qam: case t64_qam: ber = uncoded_modulation(modulation_type, gamma_b); break; default: break; } } // Coded else { double d_free; vector<int> alpha_d; if (code_rate == 1.0 / 2.0) { d_free = 10; //alpha_d = { 36, 0, 211, 0, 1404, 0, 11633, 0, 77433, 0 }; alpha_d.push_back(36);alpha_d.push_back(0);alpha_d.push_back(211);alpha_d.push_back(0);alpha_d.push_back(1404); alpha_d.push_back(0);alpha_d.push_back(11633);alpha_d.push_back(0);alpha_d.push_back(77433);alpha_d.push_back(0); } else if (code_rate == 2.0 / 3.0) { d_free = 6; //alpha_d = { 3, 70, 285, 1276, 6160, 27128, 117019, 498860, 2103891, 8984123 }; alpha_d.push_back(3);alpha_d.push_back(70);alpha_d.push_back(285);alpha_d.push_back(1276);alpha_d.push_back(6160); alpha_d.push_back(27128);alpha_d.push_back(117019);alpha_d.push_back(498860);alpha_d.push_back(2103891);alpha_d.push_back(8984123); } else if (code_rate == 3.0 / 4.0) { d_free = 5; //alpha_d = { 42, 201, 1492, 10469, 62935, 379644, 2253373, 13073811, 75152755, 428005675 }; alpha_d.push_back(42);alpha_d.push_back(201);alpha_d.push_back(1492);alpha_d.push_back(10469);alpha_d.push_back(62935); alpha_d.push_back(379644);alpha_d.push_back(2253373);alpha_d.push_back(13073811);alpha_d.push_back(75152755);alpha_d.push_back(428005675); } switch (decode_type) { case hdd: case hard: { double P_e_HDD = 0; for (int d = d_free; d < d_free + constraint; d++) { double P_b = uncoded_modulation(modulation_type, code_rate*gamma_b); double p_2 = 0; for (int k_ = ceil((d + 1) / 2); k_ < d; k_++) p_2 = p_2 + nchoosek(d, k_) * pow(P_b, k_) * pow((1 - P_b), (d - k_)); if (ceil(d / 2) == d / 2) p_2 = p_2 + nchoosek(d, d / 2) * pow((P_b*(1 - P_b)), (d / 2)) / 2; P_e_HDD = P_e_HDD + alpha_d[d - d_free + 1] * p_2; ber = P_e_HDD; } } break; case soft: case sdd: { switch (modulation_type) { case bpsk: case qpsk: { double P_e_SDD = 0; for (int d = d_free; d < d_free + constraint; d++) { double p_2 = uncoded_modulation(modulation_type, code_rate*d*gamma_b); P_e_SDD = P_e_SDD + alpha_d[d - d_free] * p_2; } ber = P_e_SDD; } break; case t16_qam: { double P_e_SDD_max = 0; double P_e_SDD_min = 0; for (int d = d_free; d < d_free + constraint; d++) { double p_2_max = 0.5 * erfc(sqrt((2.0 / 5.0)*code_rate*d*gamma_b)); double p_2_min = 0.5 * erfc(sqrt((18.0 / 5.0)*code_rate*d*gamma_b)); P_e_SDD_max = alpha_d[d - d_free ] * p_2_min; P_e_SDD_min = alpha_d[d - d_free ] * p_2_max; } double P_e_SDD = 0.5 *(P_e_SDD_max + P_e_SDD_min); ber = P_e_SDD; } break; case t64_qam: { double P_e_SDD_max = 0; double P_e_SDD_min = 0; for (int d = d_free; d < d_free + constraint; d++) { double p_2_max = 0.5 * erfc(sqrt((1.0 / 7.0)*code_rate*d*gamma_b)); double p_2_min = 0.5 * erfc(sqrt((7.0) * code_rate*d*gamma_b)); P_e_SDD_max = alpha_d[d - d_free ] * p_2_min; P_e_SDD_min = alpha_d[d - d_free ] * p_2_max; } double P_e_SDD = 0.5 *(P_e_SDD_max + P_e_SDD_min); ber = P_e_SDD; } break; default: break; } break; } default: break; } } if (ber > 0.5) ber = 0.5; //ber(ber>0.5) = 0.5; return ber; }