-
Notifications
You must be signed in to change notification settings - Fork 1
/
LinearGridEstimator.c
124 lines (122 loc) · 3.3 KB
/
LinearGridEstimator.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "ext.h"
#include <gsl/gsl_combination.h>
#include <gsl/gsl_statistics.h>
#include <assert.h>
#include <cmath>
#include "LinearGridEstimator.h"
//Grid estimator initialize
GridEstimator::GridEstimator
(const int d,const real max,const real min,const int den)
{
particlecount=0;
ChoiceofAccumulator=&GridEstimator::FiniteTempAccumulator;
density=den;
depth=d;
GridMin=min;
GridMax=max;
gsl_combination *c;
size_t i;
//initialize combinations
c=gsl_combination_calloc(ParticleNumber,depth);
psize=1;
for(int k=0;k<depth;k++){
psize*=(ParticleNumber-k);
psize/=(1+k);
}
CombiLength=psize*depth;
combination=new int[psize*depth];
i=0;
do{
//memcpy(combination+i,gsl_combination_data(c),sizeof(int)*depth);
for (int jj=0;jj<depth;jj++){
*(combination+i+jj)=gsl_combination_data(c)[jj];
}
i+=depth;
}
while (gsl_combination_next (c)==GSL_SUCCESS);
assert(i==(size_t)psize*depth);
// i must be at the end of the array
gsl_combination_free(c);
//initialize position a.k.a. x-axis bin center
position=new real[density];
slice=(max-min)/density;
for(int j=0;j<density;j++){
position[j]=min+slice*j+slice/2;
}
xx=new long[density*psize]();
xf=new long[density*psize]();
if(depth==1){
if(ParticleNumber>=2)
ChoiceofAccuFunc=&GridEstimator::RelativeDensity;
else
ChoiceofAccuFunc=&GridEstimator::Density;
}
else if(depth==2){
ChoiceofAccuFunc=&GridEstimator::PairDistribution;
}
else{
ChoiceofAccuFunc=&GridEstimator::HyperRadius;
}
}
void GridEstimator::FiniteTempAccumulator(){
int i,j,k;
//k is the pointer to xx, i is the pointer to combination
for(i=0,k=0;i<CombiLength;i+=depth,k+=density){
//only accumulate the even beads
for(int kk=0;kk<N;kk+=2){
j=(int)floor(((this->*ChoiceofAccuFunc)(combination+i,kk)-GridMin)/slice);
if(j>=0&&j<density){
xx[k+j]+=1;
if(permutestatus%2){
xf[k+j]-=1;
}
else{
xf[k+j]+=1;
}
}
}
}
}
void GridEstimator::finish(){
//k is the pointer to xx, piterator is the iteration counter
int piterator,k;
FILE *fpf=NULL;
char fn[100]="";
xpf=new real[psize];
xpft=new real[psize];
if(!rank)
{
sprintf(fn,"fwave%d.dat",depth);
if((fpf=fopen(fn,"w"))==NULL){
printf("cannot open file %s\n",fn);
exit(0);
}
fprintf(fpf,"#x average std");
for(piterator=0,k=0;piterator<psize;piterator++,k+=density){
fprintf(fpf," ");
for(int i=0;i<depth-1;i++){
fprintf(fpf,"%d_",combination[piterator*depth+i]);
}
fprintf(fpf,"%d",combination[(piterator+1)*depth-1]);
}
fprintf(fpf,"\n");
}
for(int j=0;j<density;j++){
for(piterator=0,k=0;piterator<psize;piterator++,k+=density){
xpf[piterator]=(real(xf[k+j]))*2./BLOCKNUM/etemp/N/(GridMax-GridMin)*density/numprocs;
}
MPI_Reduce(xpf,xpft,psize,REALMPI,MPI_SUM,0,MPI_COMM_WORLD);
if(!rank){
fprintf(fpf,"" eLFormat "\t" eLFormat "\t" eLFormat "",position[j],gsl_stats_mean_long_double(xpft,1,psize),gsl_stats_sd_long_double(xpft,1,psize));
for(piterator=0,k=0;piterator<psize;piterator++,k+=density){
fprintf(fpf,"\t" eLFormat "",xpft[piterator]);
}
fprintf(fpf,"\n");
}
}
if(!rank){
fclose(fpf);
}
delete xpf;
delete xpft;
}