-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon.c
193 lines (162 loc) · 6.14 KB
/
common.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
* common.c
*
* Common functions for sequentional and parallel WL method for different magnetic systems
*
*
* programmed by:
* Makarov Aleksandr
* Andriushchenko Petr
* Shevchenko Yuriy
*
*/
// нормализация g[E]
void gupdate()
{
/* set min of g[ie] as 1 */
double gmin=10000000; // устанавливаем gmin очень большим, чтобы в системе точно найти минимум.
unsigned ie;
for (ie=0; ie<histSize; ++ie){
#ifdef DEBUG
if (ie>=histSize || ie<0) printf("Error with memory working5");
#endif
if (nonzero[ie] == 1) {
//printf("!# g[%u]=%f\n",ie,g[ie]);
if(g[ie] < gmin) {
gmin = g[ie]; // находим наименьшее значение g[E]
}
}
}
for (ie=0; ie<histSize; ++ie){
#ifdef DEBUG
if (ie>=histSize || ie<0) printf("Error with memory working5");
#endif
if (nonzero[ie] == 1) {
g[ie] += -gmin; // !! нормализация g[E], а тут =0, так как тут хранятся логарифмы.
//printf("!# g[%u]=%f\n",ie,g[ie]);
}
}
}
void dumpArrays(){
unsigned ie;
FILE *file = fopen("dump.dat", "w");
fprintf(file,"E=%e; state=",e);
for(ie=0; ie<n; ie++){
fprintf(file,"%d",spins[ie]);
}
fprintf(file,"\n");
fprintf(file,"ie E g[ie] g[ie]/n hist[ie] visit[ie]\n");
for(ie=0; ie<histSize; ie++){
if (nonzero[ie] == 1) {
fprintf(file,"%d %e %e %e %d %d\n",ie,(double)(ie+emin)/PRECISION,g[ie],g[ie]/n,hist[ie],visit[ie]);
}
}
fclose(file);
}
/// Функция чтения файла с энергиями
int readCSV(char *filename){
char c; //считанный из файла символ
char symb[100000]; //символ энергии в текстовом файле
//get system sizes
bool isFirstLine=true;
n=0;
FILE *file = fopen(filename, "r");
if (!file)
return 0;
int fpos = 1, lastFpos=0;
unsigned count_n=0;
for(c=fgetc(file);c=='\n'||c=='\r'||c=='#';c=fgetc(file)){ //пропуск комментариев
fgets(symb,100000,file);
}
fseek(file,-1,SEEK_CUR); // сдвиг курсора на один символ назад
int coursor=ftell(file); // положение курсора начала данных
do{
c = fgetc(file);
// while(c=='#'){
// do c = fgetc(file2); while (c != '\n'); // нет необходимости, только если у нас не будет комментариев прямо посреди данных, но можно оставить
// c = fgetc(file2);
// }
if (isFirstLine && c==';')
++n;
if (c=='\n'){
isFirstLine=false;
count_n++;
}
if (c==';' || c=='\n') {
if (fpos-1 != lastFpos)
++eCount;
lastFpos = fpos;
}
fpos++;
} while (c != EOF);
++n;
if(count_n!=n)
printf("!!!ERROR with number of element: Number of elements in first line does not correspond with number of lines");
// reserve memory for arrays
spins=(signed char *) malloc(n*sizeof(signed char));
a_neighbours=(unsigned short *) malloc(n*sizeof(unsigned short));
neighbours=(unsigned short *) malloc(eCount*sizeof(unsigned short));
sequencies=(unsigned int *) malloc(n*sizeof(unsigned int));
energies = (double *) malloc(eCount*sizeof(double));
// read data
fseek(file,coursor,SEEK_SET); //устанавливаем курсор в начало данных
double parsedNumber;
int numInSymb=0;
symb[0]='\0';
int row=0; //line number in file (not account the commented lines)
int col=0; //column number in line (taking to accound the ';' symbols)
int neighCount=0; //
int energyNum=0; //holds actual count of previously parsed energies
e = 0;
emax = 0; // сумма всех взаимодействий с положительным знаком
long long eTemp=0;
do {
c = fgetc(file);
if (c==';' || c=='\n' || c == EOF){ //if we found a number, process it
if (numInSymb!=0){
sscanf( symb, "%lf", &parsedNumber );
neighbours[energyNum] = col;
#ifdef DEBUG
if (energyNum>=eCount || energyNum<0) printf("Error with memory working8");
#endif
energies[energyNum] = parsedNumber;
eTemp+=round(parsedNumber*10000000);
emax += fabs(parsedNumber);
numInSymb=0;
++neighCount;
++energyNum;
}
++col;
} else {
if(c=='\r'){}
else{
symb[numInSymb] = c;
symb[numInSymb+1] = '\0';
++numInSymb;
}
}
if (c=='\n'){
#ifdef DEBUG
if (row>=n || row<0)
printf("Error with memory working9");
#endif
a_neighbours[row] = neighCount;
sequencies[row] = energyNum-neighCount;
col=0;
neighCount=0;
spins[row]=1;
++row;
}
} while (c != EOF);
emax/=2;
e=eTemp/20000000.;
emax= ((double)ceil(emax * PRECISION)) / PRECISION; // округляем значение максимальной энергии до знака точности, в большую сторону
emin = -emax;
fclose(file);
histSize = (int)((emax-emin)*PRECISION)+1; // почему резервирование этих массивов происходит именно в этой функции?
g = (double *) malloc(histSize*sizeof(double));
visit = (unsigned *) malloc(histSize*sizeof(unsigned));
hist = (unsigned *) malloc(histSize*sizeof(unsigned));
nonzero = (int *) malloc(histSize*sizeof(int));
return 1;
}