1 : |
agomez |
1 |
#include "lengthgroup.h" |
2 : |
|
|
#include "errorhandler.h" |
3 : |
|
|
#include "gadget.h" |
4 : |
|
|
#include "global.h" |
5 : |
ulcessvp |
2 |
#include "mathfunc.h" |
6 : |
agomez |
1 |
//Constructor for length division with even increments
|
7 : |
|
|
LengthGroupDivision::LengthGroupDivision(double MinL, double MaxL, double DL) : error(0), Dl(DL) {
|
8 : |
|
|
if ((MaxL < MinL) || (MinL < 0.0) || (Dl < verysmall)) {
|
9 : |
|
|
error = 1;
|
10 : |
|
|
return;
|
11 : |
|
|
}
|
12 : |
|
|
|
13 : |
|
|
int i;
|
14 : |
|
|
minlen = MinL;
|
15 : |
|
|
maxlen = MaxL;
|
16 : |
|
|
double tmp = (maxlen - minlen) / Dl;
|
17 : |
|
|
size = int(tmp + rathersmall);
|
18 : |
|
|
if (size == 0) {
|
19 : |
|
|
error = 1;
|
20 : |
|
|
return;
|
21 : |
|
|
}
|
22 : |
|
|
|
23 : |
|
|
meanlength.resize(size, 0.0);
|
24 : |
|
|
minlength.resize(size, 0.0);
|
25 : |
|
|
for (i = 0; i < size; i++) {
|
26 : |
|
|
minlength[i] = minlen + (Dl * i);
|
27 : |
|
|
meanlength[i] = minlength[i] + (Dl * 0.5);
|
28 : |
|
|
}
|
29 : |
|
|
}
|
30 : |
|
|
|
31 : |
|
|
//Constructor for length division with uneven increments
|
32 : |
|
|
LengthGroupDivision::LengthGroupDivision(const DoubleVector& Breaks) : error(0), Dl(0.0) {
|
33 : |
|
|
if ((Breaks.Size() < 2) || (Breaks[0] < 0.0)) {
|
34 : |
|
|
error = 1;
|
35 : |
|
|
return;
|
36 : |
|
|
}
|
37 : |
|
|
|
38 : |
|
|
int i;
|
39 : |
|
|
size = Breaks.Size() - 1;
|
40 : |
|
|
minlen = Breaks[0];
|
41 : |
|
|
maxlen = Breaks[size];
|
42 : |
|
|
Dl = Breaks[1] - Breaks[0];
|
43 : |
|
|
meanlength.resize(size, 0.0);
|
44 : |
|
|
minlength.resize(size, 0.0);
|
45 : |
|
|
|
46 : |
|
|
for (i = 0; i < size; i++) {
|
47 : |
|
|
//JMB first some error checks ...
|
48 : |
|
|
if ((Breaks[i] > Breaks[i + 1]) || (isEqual(Breaks[i], Breaks[i + 1]))) {
|
49 : |
|
|
error = 1;
|
50 : |
|
|
return;
|
51 : |
|
|
}
|
52 : |
|
|
//... and check to see if the step lengths are actually equal
|
53 : |
|
|
if (!isZero(Dl) && !isSmall(Breaks[i + 1] - Breaks[i] - Dl))
|
54 : |
|
|
Dl = 0.0;
|
55 : |
|
|
}
|
56 : |
|
|
|
57 : |
|
|
//finally store the mean and minimum lengths for the length division
|
58 : |
|
|
if (isZero(Dl)) {
|
59 : |
|
|
for (i = 0; i < size; i++) {
|
60 : |
|
|
minlength[i] = Breaks[i];
|
61 : |
|
|
meanlength[i] = 0.5 * (Breaks[i] + Breaks[i + 1]);
|
62 : |
|
|
}
|
63 : |
|
|
} else {
|
64 : |
|
|
for (i = 0; i < size; i++) {
|
65 : |
|
|
minlength[i] = minlen + (Dl * i);
|
66 : |
|
|
meanlength[i] = minlength[i] + (Dl * 0.5);
|
67 : |
|
|
}
|
68 : |
|
|
}
|
69 : |
|
|
}
|
70 : |
|
|
|
71 : |
|
|
LengthGroupDivision::LengthGroupDivision(const LengthGroupDivision& l)
|
72 : |
|
|
: error(l.error), size(l.size), Dl(l.Dl), minlen(l.minlen), maxlen(l.maxlen),
|
73 : |
|
|
meanlength(l.meanlength), minlength(l.minlength) {
|
74 : |
|
|
}
|
75 : |
|
|
|
76 : |
|
|
int LengthGroupDivision::numLengthGroup(double len) const {
|
77 : |
|
|
//check if len equals the minimum length
|
78 : |
|
|
if (isSmall(minlen - len))
|
79 : |
|
|
return 0;
|
80 : |
|
|
|
81 : |
|
|
//check if len equals the maximum length
|
82 : |
|
|
if (isSmall(maxlen - len))
|
83 : |
|
|
return size - 1;
|
84 : |
|
|
|
85 : |
|
|
int i;
|
86 : |
|
|
for (i = 0; i < size; i++)
|
87 : |
|
|
if ((isSmall(minlength[i] - len)) || ((minlength[i] < len) && (len < this->maxLength(i))))
|
88 : |
|
|
return i;
|
89 : |
|
|
|
90 : |
|
|
//failed to find length group that matches len
|
91 : |
|
|
return -1;
|
92 : |
|
|
}
|
93 : |
|
|
|
94 : |
|
|
double LengthGroupDivision::minLength(int i) const {
|
95 : |
|
|
if (i >= size)
|
96 : |
|
|
return minlength[size - 1];
|
97 : |
|
|
return minlength[i];
|
98 : |
|
|
}
|
99 : |
|
|
|
100 : |
|
|
double LengthGroupDivision::maxLength(int i) const {
|
101 : |
|
|
if (i >= (size - 1))
|
102 : |
|
|
return maxlen;
|
103 : |
|
|
return minlength[i + 1];
|
104 : |
|
|
}
|
105 : |
|
|
|
106 : |
|
|
int LengthGroupDivision::Combine(const LengthGroupDivision* const addition) {
|
107 : |
|
|
if ((minlen > addition->minLength(addition->numLengthGroups() - 1))
|
108 : |
|
|
|| (this->minLength(size - 1) < addition->minLength()))
|
109 : |
|
|
return 0;
|
110 : |
|
|
|
111 : |
|
|
int i, j;
|
112 : |
|
|
i = j = 0;
|
113 : |
|
|
if (((minlen < addition->minLength()) || (isEqual(minlen, addition->minLength()))) &&
|
114 : |
|
|
((this->minLength(size - 1) > addition->minLength(addition->numLengthGroups() - 1)) ||
|
115 : |
|
|
(isEqual(this->minLength(size - 1), addition->minLength(addition->numLengthGroups() - 1))))) {
|
116 : |
|
|
|
117 : |
|
|
//only check if the divisions are the same in the overlapping region.
|
118 : |
|
|
while (this->minLength(i) < addition->minLength())
|
119 : |
|
|
i++;
|
120 : |
|
|
for (j = 0; j < addition->numLengthGroups(); j++) {
|
121 : |
|
|
if (!(isEqual(this->minLength(i + j), addition->minLength(j)))) {
|
122 : |
|
|
error = 1;
|
123 : |
|
|
return 0;
|
124 : |
|
|
}
|
125 : |
|
|
}
|
126 : |
|
|
return 1;
|
127 : |
|
|
}
|
128 : |
|
|
|
129 : |
|
|
double tempmin = min(minlen, addition->minLength());
|
130 : |
|
|
double tempmax = max(maxlen, addition->maxLength());
|
131 : |
|
|
DoubleVector lower, middle;
|
132 : |
|
|
|
133 : |
|
|
if ((minlen > addition->minLength()) || (isEqual(minlen, addition->minLength()))) {
|
134 : |
|
|
for (; minlen > addition->minLength(i); i++) {
|
135 : |
|
|
lower.resize(1, addition->minLength(i));
|
136 : |
|
|
middle.resize(1, addition->meanLength(i));
|
137 : |
|
|
}
|
138 : |
|
|
for (; j - i < size && j < addition->numLengthGroups(); j++) {
|
139 : |
|
|
if (!(isEqual(this->minLength(j - i), addition->minLength(j)))) {
|
140 : |
|
|
error = 1;
|
141 : |
|
|
return 0;
|
142 : |
|
|
}
|
143 : |
|
|
lower.resize(1, this->minLength(j - i));
|
144 : |
|
|
middle.resize(1, this->meanLength(j - i));
|
145 : |
|
|
}
|
146 : |
|
|
if (j - i >= size) {
|
147 : |
|
|
for (; j < addition->numLengthGroups(); j++) {
|
148 : |
|
|
lower.resize(1, addition->minLength(j));
|
149 : |
|
|
middle.resize(1, addition->meanLength(j));
|
150 : |
|
|
}
|
151 : |
|
|
} else {
|
152 : |
|
|
for (; j - i < size; j++) {
|
153 : |
|
|
lower.resize(1, this->minLength(j - i));
|
154 : |
|
|
middle.resize(1, this->meanLength(j - i));
|
155 : |
|
|
}
|
156 : |
|
|
}
|
157 : |
|
|
|
158 : |
|
|
} else {
|
159 : |
|
|
for (; this->minLength(i) < addition->minLength(); i++) {
|
160 : |
|
|
lower.resize(1, this->minLength(i));
|
161 : |
|
|
middle.resize(1, this->meanLength(i));
|
162 : |
|
|
}
|
163 : |
|
|
for (j = 0; j < addition->numLengthGroups(); j++) {
|
164 : |
|
|
lower.resize(1, addition->minLength(j));
|
165 : |
|
|
middle.resize(1, addition->meanLength(j));
|
166 : |
|
|
}
|
167 : |
|
|
}
|
168 : |
|
|
|
169 : |
|
|
//set this to the new division
|
170 : |
|
|
if (!(isEqual(Dl, addition->dl())))
|
171 : |
|
|
Dl = 0.0;
|
172 : |
|
|
for (i = 0; i < size; i++) {
|
173 : |
|
|
minlength[i] = lower[i];
|
174 : |
|
|
meanlength[i] = middle[i];
|
175 : |
|
|
}
|
176 : |
|
|
size = lower.Size();
|
177 : |
|
|
for (; i < size; i++) {
|
178 : |
|
|
minlength.resize(1, lower[i]);
|
179 : |
|
|
meanlength.resize(1, middle[i]);
|
180 : |
|
|
}
|
181 : |
|
|
minlen = tempmin;
|
182 : |
|
|
maxlen = tempmax;
|
183 : |
|
|
return 1;
|
184 : |
|
|
}
|
185 : |
|
|
|
186 : |
|
|
void LengthGroupDivision::Print(ofstream& outfile) const {
|
187 : |
|
|
int i;
|
188 : |
|
|
outfile << "Length group division with " << size << " length groups from " << minlen
|
189 : |
|
|
<< " up to " << maxlen << endl << TAB;
|
190 : |
|
|
for (i = 0; i < size; i++)
|
191 : |
|
|
outfile << minlength[i] << sep;
|
192 : |
|
|
outfile << maxlen << endl;
|
193 : |
|
|
}
|
194 : |
|
|
|
195 : |
|
|
void LengthGroupDivision::printError() const {
|
196 : |
|
|
handle.logMessage(LOGWARN, "Minimum length of length group division is", this->minLength());
|
197 : |
|
|
handle.logMessage(LOGWARN, "Maximum length of length group division is", this->maxLength());
|
198 : |
|
|
}
|
199 : |
|
|
|
200 : |
|
|
int checkLengthGroupStructure(const LengthGroupDivision* finer,
|
201 : |
|
|
const LengthGroupDivision* coarser) {
|
202 : |
|
|
|
203 : |
|
|
int c, f;
|
204 : |
|
|
double minlength, maxlength;
|
205 : |
|
|
|
206 : |
|
|
//check to see if the intersection is empty
|
207 : |
|
|
minlength = max(coarser->minLength(), finer->minLength());
|
208 : |
|
|
maxlength = min(coarser->maxLength(), finer->maxLength());
|
209 : |
|
|
if ((minlength > maxlength) || isSmall(maxlength - minlength)) {
|
210 : |
|
|
handle.logMessage(LOGWARN, "Error when checking length structure - empty intersection");
|
211 : |
|
|
finer->printError();
|
212 : |
|
|
coarser->printError();
|
213 : |
|
|
return 0;
|
214 : |
|
|
}
|
215 : |
|
|
|
216 : |
|
|
//if the length groups have the same dl then no need to check any further
|
217 : |
|
|
if (isSmall(finer->dl() - coarser->dl()))
|
218 : |
|
|
return 1;
|
219 : |
|
|
|
220 : |
|
|
//now we need to check the length grouping for the intersection
|
221 : |
|
|
for (f = finer->numLengthGroup(minlength); f < finer->numLengthGroup(maxlength); f++) {
|
222 : |
|
|
c = coarser->numLengthGroup(finer->minLength(f));
|
223 : |
|
|
if (c == -1) {
|
224 : |
|
|
handle.logMessage(LOGWARN, "Error when checking length structure for the following lengthgroups");
|
225 : |
|
|
finer->printError();
|
226 : |
|
|
coarser->printError();
|
227 : |
|
|
return 0;
|
228 : |
|
|
}
|
229 : |
|
|
|
230 : |
|
|
if ((coarser->minLength(c) > (finer->minLength(f) + rathersmall)) ||
|
231 : |
|
|
(finer->maxLength(f) > (coarser->maxLength(c) + rathersmall))) {
|
232 : |
|
|
|
233 : |
|
|
handle.logMessage(LOGWARN, "Error when checking length structure for length group", f);
|
234 : |
|
|
finer->printError();
|
235 : |
|
|
coarser->printError();
|
236 : |
|
|
return 0;
|
237 : |
|
|
}
|
238 : |
|
|
}
|
239 : |
|
|
return 1;
|
240 : |
|
|
}
|
241 : |
ulcessvp |
2 |
|
242 : |
|
|
|
243 : |
|
|
double* const LengthGroupDivision::meanlengthvecPow_initilize(
|
244 : |
|
|
int maxlengthgroupgrowth, double tmpPower) const
|
245 : |
|
|
{
|
246 : |
|
|
|
247 : |
|
|
double * meanlength_vectorPow = new double[size + maxlengthgroupgrowth];
|
248 : |
|
|
double aux;
|
249 : |
|
|
int lgroup;
|
250 : |
|
|
for (lgroup = 0; lgroup < size; lgroup++)
|
251 : |
|
|
meanlength_vectorPow[lgroup] = pow(meanLength(lgroup), tmpPower);
|
252 : |
|
|
aux = meanlength_vectorPow[size-1];
|
253 : |
|
|
for (lgroup = size; lgroup < size+maxlengthgroupgrowth; lgroup++)
|
254 : |
|
|
meanlength_vectorPow[lgroup] = aux;
|
255 : |
|
|
|
256 : |
|
|
return meanlength_vectorPow;
|
257 : |
|
|
}
|