Bug Summary

File:src/pull/popcntl.c
Location:line 299, column 5
Description:Value stored to 'newpnt' is never read

Annotated Source Code

1/*
2 Teem: Tools to process and visualize scientific data and images .
3 Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago
4 Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann
5 Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License
9 (LGPL) as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 The terms of redistributing and/or modifying this software also
12 include exceptions to the LGPL that facilitate static linking.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library; if not, write to Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*/
23
24
25#include "pull.h"
26#include "privatePull.h"
27
28int
29_pullPointProcessNeighLearn(pullTask *task, pullBin *bin, pullPoint *point) {
30
31 /* sneaky: we just learn (and discard) the energy, and this function
32 will do the work of learning the neighbors */
33 _pullEnergyFromPoints(task, bin, point, NULL((void*)0));
34 return 0;
35}
36
37static double
38_pointEnergyOfNeighbors(pullTask *task, pullBin *bin, pullPoint *point,
39 double *fracNixed) {
40 double enr;
41 unsigned int ii, xx;
42 pullPoint *her;
43
44 enr = 0;
45 xx = 0;
46 for (ii=0; ii<point->neighPointNum; ii++) {
47 her = point->neighPoint[ii];
48 if (her->status & PULL_STATUS_NIXME_BIT(1<< 3)) {
49 xx += 1;
50 } else {
51 enr += _pullEnergyFromPoints(task, bin, her, NULL((void*)0));
52 }
53 }
54 *fracNixed = (point->neighPointNum
55 ? AIR_CAST(double, xx)((double)(xx))/point->neighPointNum
56 : 0);
57 return enr;
58}
59
60int
61_pullPointProcessAdding(pullTask *task, pullBin *bin, pullPoint *point) {
62 static const char me[]="_pullPointProcessAdding";
63 unsigned int npi, iter, api;
64 double noffavg[4], npos[4], enrWith, enrWithout,
65 fracNixed, newSpcDist, tmp;
66 pullPoint *newpnt;
67 int E;
68
69 task->pctx->count[pullCountAdding] += 1;
70 if (point->neighPointNum && task->pctx->targetDim
71 && task->pctx->flag.popCntlEnoughTest) {
72 unsigned int plenty, tardim;
73 tardim = task->pctx->targetDim;
74 if (task->pctx->flag.zeroZ && tardim > 1) {
75 /* GLK unsure of tardim == 1 logic here */
76 tardim -= 1;
77 }
78 plenty = (1 == tardim
79 ? 3
80 : (2 == tardim
81 ? 7
82 : (3 == tardim
83 ? 13 /* = 1 + 12
84 = 1 + coordination number of 3D sphere packing */
85 : 0 /* shouldn't get here */)));
86 /*
87 if (0 == (point->idtag % 100)) {
88 printf("!%s: #num %d >?= plenty %d\n", me, point->neighPointNum, plenty);
89 }
90 */
91 if (point->neighPointNum >= plenty) {
92 /* there's little chance that adding points will reduce energy */
93 return 0;
94 }
95 }
96 /*
97 printf("!%s: point->pos = (%g,%g,%g,%g)\n", me,
98 point->pos[0], point->pos[1], point->pos[2], point->pos[3]);
99 printf("!%s: point->neighPointNum = %u\n", me,
100 point->neighPointNum);
101 printf("!%s: task->pctx->targetDim = %u\n", me,
102 task->pctx->targetDim);
103 printf("!%s: task->pctx->flag.popCntlEnoughTest = %d\n", me,
104 task->pctx->flag.popCntlEnoughTest);
105 */
106 ELL_4V_SET(noffavg, 0, 0, 0, 0)((noffavg)[0] = (0), (noffavg)[1] = (0), (noffavg)[2] = (0), (
noffavg)[3] = (0))
;
107 for (npi=0; npi<point->neighPointNum; npi++) {
108 double off[4];
109 ELL_4V_SUB(off, point->pos, point->neighPoint[npi]->pos)((off)[0] = (point->pos)[0] - (point->neighPoint[npi]->
pos)[0], (off)[1] = (point->pos)[1] - (point->neighPoint
[npi]->pos)[1], (off)[2] = (point->pos)[2] - (point->
neighPoint[npi]->pos)[2], (off)[3] = (point->pos)[3] - (
point->neighPoint[npi]->pos)[3])
;
110 /* normalize the offset */
111 ELL_3V_SCALE(off, 1/task->pctx->sysParm.radiusSpace, off)((off)[0] = (1/task->pctx->sysParm.radiusSpace)*(off)[0
], (off)[1] = (1/task->pctx->sysParm.radiusSpace)*(off)
[1], (off)[2] = (1/task->pctx->sysParm.radiusSpace)*(off
)[2])
;
112 if (task->pctx->haveScale) {
113 off[3] /= task->pctx->sysParm.radiusScale;
114 }
115 ELL_4V_INCR(noffavg, off)((noffavg)[0] += (off)[0], (noffavg)[1] += (off)[1], (noffavg
)[2] += (off)[2], (noffavg)[3] += (off)[3])
;
116 }
117 if (point->neighPointNum) {
118 /*
119 if (0 == (point->idtag % 100)) {
120 printf("%s: len(offavg) %g >?= thresh %g\n", me,
121 ELL_4V_LEN(noffavg)/point->neighPointNum,
122 _PULL_NEIGH_OFFSET_SUM_THRESH);
123 }
124 */
125 if (ELL_4V_LEN(noffavg)(sqrt((((noffavg))[0]*((noffavg))[0] + ((noffavg))[1]*((noffavg
))[1] + ((noffavg))[2]*((noffavg))[2] + ((noffavg))[3]*((noffavg
))[3])))
/point->neighPointNum
126 < _PULL_NEIGH_OFFSET_SUM_THRESH0.2) {
127 /* we have neighbors, and they seem to be balanced well enough;
128 don't try to add */
129 return 0;
130 }
131 }
132 if (task->pctx->energySpecR->energy->well(&newSpcDist,
133 task->pctx->energySpecR->parm)) {
134 /* HEY: if we don't actually have a well, what is the point of
135 guessing a new distance? */
136 newSpcDist = _PULL_NEWPNT_DIST0.6;
137 }
138 /* compute offset (normalized) direction from current point location */
139 if (!point->neighPointNum) {
140 /* we had no neighbors, have to pretend like we did */
141 airNormalRand_r(noffavg + 0, noffavg + 1, task->rng);
142 airNormalRand_r(noffavg + 2, noffavg + 3, task->rng);
143 if (!task->pctx->flag.zeroZ) {
144 noffavg[2] = 0;
145 }
146 if (!task->pctx->haveScale) {
147 noffavg[3] = 0;
148 }
149 }
150 if (task->pctx->constraint) {
151 double proj[9], tmpvec[3];
152 _pullConstraintTangent(task, point, proj);
153 ELL_3MV_MUL(tmpvec, proj, noffavg)((tmpvec)[0] = (proj)[0]*(noffavg)[0] + (proj)[1]*(noffavg)[1
] + (proj)[2]*(noffavg)[2], (tmpvec)[1] = (proj)[3]*(noffavg)
[0] + (proj)[4]*(noffavg)[1] + (proj)[5]*(noffavg)[2], (tmpvec
)[2] = (proj)[6]*(noffavg)[0] + (proj)[7]*(noffavg)[1] + (proj
)[8]*(noffavg)[2])
;
154 ELL_3V_COPY(noffavg, tmpvec)((noffavg)[0] = (tmpvec)[0], (noffavg)[1] = (tmpvec)[1], (noffavg
)[2] = (tmpvec)[2])
;
155 }
156 ELL_4V_NORM(noffavg, noffavg, tmp)(tmp = (sqrt((((noffavg))[0]*((noffavg))[0] + ((noffavg))[1]*
((noffavg))[1] + ((noffavg))[2]*((noffavg))[2] + ((noffavg))[
3]*((noffavg))[3]))), ((noffavg)[0] = (noffavg)[0]*1.0/tmp, (
noffavg)[1] = (noffavg)[1]*1.0/tmp, (noffavg)[2] = (noffavg)[
2]*1.0/tmp, (noffavg)[3] = (noffavg)[3]*1.0/tmp))
;
157 ELL_3V_SCALE(noffavg, task->pctx->sysParm.radiusSpace, noffavg)((noffavg)[0] = (task->pctx->sysParm.radiusSpace)*(noffavg
)[0], (noffavg)[1] = (task->pctx->sysParm.radiusSpace)*
(noffavg)[1], (noffavg)[2] = (task->pctx->sysParm.radiusSpace
)*(noffavg)[2])
;
158 noffavg[3] *= task->pctx->sysParm.radiusScale;
159 ELL_4V_SCALE(noffavg, newSpcDist, noffavg)((noffavg)[0] = (noffavg)[0]*newSpcDist, (noffavg)[1] = (noffavg
)[1]*newSpcDist, (noffavg)[2] = (noffavg)[2]*newSpcDist, (noffavg
)[3] = (noffavg)[3]*newSpcDist)
;
160 /* set new point location */
161 ELL_4V_ADD2(npos, noffavg, point->pos)((npos)[0] = (noffavg)[0] + (point->pos)[0], (npos)[1] = (
noffavg)[1] + (point->pos)[1], (npos)[2] = (noffavg)[2] + (
point->pos)[2], (npos)[3] = (noffavg)[3] + (point->pos)
[3])
;
162 /*
163 printf("!%s: new test pos @ (%g,%g,%g,%g)\n", me,
164 npos[0], npos[1], npos[2], npos[3]);
165 */
166 if (!_pullInsideBBox(task->pctx, npos)) {
167 if (task->pctx->verbose > 2) {
168 printf("%s: new pnt would start (%g,%g,%g,%g) outside bbox, nope\n",
169 me, npos[0], npos[1], npos[2], npos[3]);
170 }
171 return 0;
172 }
173 /* initial pos is good, now we start getting serious */
174 newpnt = pullPointNew(task->pctx);
175 if (!newpnt) {
176 biffAddf(PULLpullBiffKey, "%s: couldn't spawn new point from %u", me, point->idtag);
177 return 1;
178 }
179 ELL_4V_COPY(newpnt->pos, npos)((newpnt->pos)[0] = (npos)[0], (newpnt->pos)[1] = (npos
)[1], (newpnt->pos)[2] = (npos)[2], (newpnt->pos)[3] = (
npos)[3])
;
180 /* set status to indicate this is an unbinned point, with no
181 knowledge of its neighbors */
182 newpnt->status |= PULL_STATUS_NEWBIE_BIT(1<< 2);
183 /* satisfy constraint if needed */
184 if (task->pctx->constraint) {
185 int constrFail;
186 if (_pullConstraintSatisfy(task, newpnt,
187 _PULL_CONSTRAINT_TRAVEL_MAX2,
188 &constrFail)) {
189 biffAddf(PULLpullBiffKey, "%s: on newbie point %u (spawned from %u)", me,
190 newpnt->idtag, point->idtag);
191 pullPointNix(newpnt); return 1;
192 }
193 if (constrFail) {
194 /* constraint satisfaction failed, which isn't an error for us,
195 we just don't try to add this point. Can do immediate nix
196 because no neighbors know about this point. */
197 pullPointNix(newpnt);
198 return 0;
199 }
200 if (!_pullInsideBBox(task->pctx, newpnt->pos)) {
201 if (task->pctx->verbose > 2) {
202 printf("%s: post constr newpnt %u (%g,%g,%g,%g) outside bbox; nope\n",
203 me, newpnt->idtag, newpnt->pos[0], newpnt->pos[1],
204 newpnt->pos[2], newpnt->pos[3]);
205 }
206 newpnt = pullPointNix(newpnt);
207 return 0;
208 }
209 }
210 /*
211 printf("!%s: new test pos @ (%g,%g,%g,%g)\n", me,
212 newpnt->pos[0], newpnt->pos[1], newpnt->pos[2], newpnt->pos[3]);
213 */
214 /* do some descent, on this point only, which (HACK!) we do by
215 changing the per-task process mode . . . */
216 task->processMode = pullProcessModeDescent;
217 E = 0;
218 for (iter=0; iter<task->pctx->iterParm.addDescent; iter++) {
219 double diff[4];
220 if (!E) E |= _pullPointProcessDescent(task, bin, newpnt,
221 /* ignoreImage; actually it is
222 this use which motivated the
223 creation of ignoreImage */
224 AIR_TRUE1);
225 if (newpnt->status & PULL_STATUS_STUCK_BIT(1<< 1)) {
226 if (task->pctx->verbose > 2) {
227 printf("%s: possible newpnt %u stuck @ iter %u; nope\n", me,
228 newpnt->idtag, iter);
229 }
230 newpnt = pullPointNix(newpnt);
231 /* if we don't change the mode back, then pullBinProcess() won't
232 know to try adding for the rest of the bins it sees, bad HACK */
233 task->processMode = pullProcessModeAdding;
234 return 0;
235 }
236 if (!_pullInsideBBox(task->pctx, newpnt->pos)) {
237 if (task->pctx->verbose > 2) {
238 printf("%s: newpnt %u went (%g,%g,%g,%g) outside bbox; nope\n",
239 me, newpnt->idtag, newpnt->pos[0], newpnt->pos[1],
240 newpnt->pos[2], newpnt->pos[3]);
241 }
242 newpnt = pullPointNix(newpnt);
243 task->processMode = pullProcessModeAdding;
244 return 0;
245 }
246 ELL_4V_SUB(diff, newpnt->pos, point->pos)((diff)[0] = (newpnt->pos)[0] - (point->pos)[0], (diff)
[1] = (newpnt->pos)[1] - (point->pos)[1], (diff)[2] = (
newpnt->pos)[2] - (point->pos)[2], (diff)[3] = (newpnt->
pos)[3] - (point->pos)[3])
;
247 ELL_3V_SCALE(diff, 1/task->pctx->sysParm.radiusSpace, diff)((diff)[0] = (1/task->pctx->sysParm.radiusSpace)*(diff)
[0], (diff)[1] = (1/task->pctx->sysParm.radiusSpace)*(diff
)[1], (diff)[2] = (1/task->pctx->sysParm.radiusSpace)*(
diff)[2])
;
248 diff[3] /= task->pctx->sysParm.radiusScale;
249 if (ELL_4V_LEN(diff)(sqrt((((diff))[0]*((diff))[0] + ((diff))[1]*((diff))[1] + ((
diff))[2]*((diff))[2] + ((diff))[3]*((diff))[3])))
> _PULL_NEWPNT_STRAY_DIST1.3) {
250 if (task->pctx->verbose > 2) {
251 printf("%s: newpnt %u went too far %g from old point %u; nope\n",
252 me, newpnt->idtag, ELL_4V_LEN(diff)(sqrt((((diff))[0]*((diff))[0] + ((diff))[1]*((diff))[1] + ((
diff))[2]*((diff))[2] + ((diff))[3]*((diff))[3])))
, point->idtag);
253 }
254 newpnt = pullPointNix(newpnt);
255 task->processMode = pullProcessModeAdding;
256 return 0;
257 }
258 /* still okay to continue descending */
259 newpnt->stepEnergy *= task->pctx->sysParm.opporStepScale;
260 }
261 /*
262 printf("!%s: new test pos @ (%g,%g,%g,%g)\n", me,
263 newpnt->pos[0], newpnt->pos[1], newpnt->pos[2], newpnt->pos[3]);
264 {
265 double posdiff[4];
266 ELL_4V_SUB(posdiff, newpnt->pos, point->pos);
267 printf("!%s: at dist %g\n", me, ELL_4V_LEN(posdiff));
268 }
269 */
270 /* now that newbie point is final test location, see if it meets
271 the live thresh, if there is one */
272 if (task->pctx->ispec[pullInfoLiveThresh]
273 && 0 > pullPointScalar(task->pctx, newpnt, pullInfoLiveThresh,
274 NULL((void*)0), NULL((void*)0))) {
275 /* didn't meet threshold */
276 newpnt = pullPointNix(newpnt);
277 task->processMode = pullProcessModeAdding;
278 return 0;
279 }
280 if (task->pctx->ispec[pullInfoLiveThresh2] /* HEY: copy & paste */
281 && 0 > pullPointScalar(task->pctx, newpnt, pullInfoLiveThresh2,
282 NULL((void*)0), NULL((void*)0))) {
283 /* didn't meet threshold */
284 newpnt = pullPointNix(newpnt);
285 task->processMode = pullProcessModeAdding;
286 return 0;
287 }
288 if (task->pctx->ispec[pullInfoLiveThresh3] /* HEY: copy & paste */
289 && 0 > pullPointScalar(task->pctx, newpnt, pullInfoLiveThresh3,
290 NULL((void*)0), NULL((void*)0))) {
291 /* didn't meet threshold */
292 newpnt = pullPointNix(newpnt);
293 task->processMode = pullProcessModeAdding;
294 return 0;
295 }
296 /* see if the new point should be nixed because its at a volume edge */
297 if (task->pctx->flag.nixAtVolumeEdgeSpace
298 && (newpnt->status & PULL_STATUS_EDGE_BIT(1<< 4))) {
299 newpnt = pullPointNix(newpnt);
Value stored to 'newpnt' is never read
300 task->processMode = pullProcessModeAdding;
301 return 0;
302 }
303 /* no problem with live thresh, test energy by first learn neighbors */
304 /* we have to add newpnt to task's add queue, just so that its neighbors
305 can see it as a possible neighbor */
306 api = airArrayLenIncr(task->addPointArr, 1);
307 task->addPoint[api] = newpnt;
308 task->processMode = pullProcessModeNeighLearn;
309 _pullEnergyFromPoints(task, bin, newpnt, NULL((void*)0));
310 /* and teach the neighbors their neighbors (possibly including newpnt) */
311 for (npi=0; npi<newpnt->neighPointNum; npi++) {
312 _pullEnergyFromPoints(task, bin, newpnt->neighPoint[npi], NULL((void*)0));
313 }
314 /* now back to the actual mode we came here with */
315 task->processMode = pullProcessModeAdding;
316 enrWith = (_pullEnergyFromPoints(task, bin, newpnt, NULL((void*)0))
317 + _pointEnergyOfNeighbors(task, bin, newpnt, &fracNixed));
318 newpnt->status |= PULL_STATUS_NIXME_BIT(1<< 3); /* turn nixme on */
319 enrWithout = _pointEnergyOfNeighbors(task, bin, newpnt, &fracNixed);
320 newpnt->status &= ~PULL_STATUS_NIXME_BIT(1<< 3); /* turn nixme off */
321 if (enrWith < enrWithout) {
322 /* energy is clearly lower *with* newpnt, so we want to add it, which
323 means keeping it in the add queue where it already is */
324 if (task->pctx->logAdd) {
325 double posdiff[4];
326 ELL_4V_SUB(posdiff, newpnt->pos, point->pos)((posdiff)[0] = (newpnt->pos)[0] - (point->pos)[0], (posdiff
)[1] = (newpnt->pos)[1] - (point->pos)[1], (posdiff)[2]
= (newpnt->pos)[2] - (point->pos)[2], (posdiff)[3] = (
newpnt->pos)[3] - (point->pos)[3])
;
327 fprintf(task->pctx->logAdd, "%u %g %g %g %g %g %g\n", newpnt->idtag,
328 ELL_3V_LEN(posdiff)(sqrt((((posdiff))[0]*((posdiff))[0] + ((posdiff))[1]*((posdiff
))[1] + ((posdiff))[2]*((posdiff))[2])))
/task->pctx->sysParm.radiusSpace,
329 AIR_ABS(posdiff[3])((posdiff[3]) > 0.0f ? (posdiff[3]) : -(posdiff[3]))/task->pctx->sysParm.radiusScale,
330 newpnt->pos[0], newpnt->pos[1], newpnt->pos[2], newpnt->pos[3]);
331 }
332 } else {
333 /* adding point is not an improvement, remove it from the add queue */
334 airArrayLenIncr(task->addPointArr, -1);
335 /* ugh, have to signal to neighbors that its no longer their neighbor.
336 HEY this is the part that is totally screwed with multiple threads */
337 task->processMode = pullProcessModeNeighLearn;
338 newpnt->status |= PULL_STATUS_NIXME_BIT(1<< 3);
339 for (npi=0; npi<newpnt->neighPointNum; npi++) {
340 _pullEnergyFromPoints(task, bin, newpnt->neighPoint[npi], NULL((void*)0));
341 }
342 task->processMode = pullProcessModeAdding;
343 newpnt = pullPointNix(newpnt);
344 }
345 return 0;
346}
347
348int
349_pullPointProcessNixing(pullTask *task, pullBin *bin, pullPoint *point) {
350 static const char me[]="_pullPointProcessNixing";
351 double enrWith, enrNeigh, enrWithout, fracNixed;
352
353 task->pctx->count[pullCountNixing] += 1;
354
355 if (0 && 289 == task->pctx->iter) {
356 fprintf(stderr__stderrp, "!%s(%04u): hello lthr %p -> %g %g %g\n", me, point->idtag,
357 task->pctx->ispec[pullInfoLiveThresh],
358 pullPointScalar(task->pctx, point, pullInfoLiveThresh, NULL((void*)0), NULL((void*)0)),
359 point->pos[0], point->pos[1]
360 );
361 }
362 /* if there's a live thresh, do we meet it? */
363 if (task->pctx->ispec[pullInfoLiveThresh]
364 && 0 > pullPointScalar(task->pctx, point, pullInfoLiveThresh,
365 NULL((void*)0), NULL((void*)0))) {
366 point->status |= PULL_STATUS_NIXME_BIT(1<< 3);
367 return 0;
368 }
369 /* HEY copy & paste */
370 if (task->pctx->ispec[pullInfoLiveThresh2]
371 && 0 > pullPointScalar(task->pctx, point, pullInfoLiveThresh2,
372 NULL((void*)0), NULL((void*)0))) {
373 point->status |= PULL_STATUS_NIXME_BIT(1<< 3);
374 return 0;
375 }
376 /* HEY copy & paste */
377 if (task->pctx->ispec[pullInfoLiveThresh3]
378 && 0 > pullPointScalar(task->pctx, point, pullInfoLiveThresh3,
379 NULL((void*)0), NULL((void*)0))) {
380 point->status |= PULL_STATUS_NIXME_BIT(1<< 3);
381 return 0;
382 }
383
384 /* if many neighbors have been nixed, then system is far from convergence,
385 so energy is not a very meaningful guide to whether to nix this point
386 NOTE that we use this function to *learn* fracNixed */
387 enrNeigh = _pointEnergyOfNeighbors(task, bin, point, &fracNixed);
388 if (fracNixed < task->pctx->sysParm.fracNeighNixedMax) {
389 /* is energy lower without us around? */
390 enrWith = enrNeigh + _pullEnergyFromPoints(task, bin, point, NULL((void*)0));
391 point->status |= PULL_STATUS_NIXME_BIT(1<< 3); /* turn nixme on */
392 enrWithout = _pointEnergyOfNeighbors(task, bin, point, &fracNixed);
393 if (enrWith <= enrWithout) {
394 /* Energy isn't distinctly lowered without the point, so keep it;
395 turn off nixing. If enrWith == enrWithout == 0, as happens to
396 isolated points, then the difference between "<=" and "<"
397 keeps the isolated points from getting nixed */
398 point->status &= ~PULL_STATUS_NIXME_BIT(1<< 3); /* turn nixme off */
399 }
400 /* else energy is certainly higher with the point, do nix it */
401 }
402
403 return 0;
404}
405
406int
407_pullIterFinishNeighLearn(pullContext *pctx) {
408 static const char me[]="_pullIterFinishNeighLearn";
409
410 /* a no-op for now */
411 AIR_UNUSED(pctx)(void)(pctx);
412 AIR_UNUSED(me)(void)(me);
413
414 return 0;
415}
416
417int
418_pullIterFinishAdding(pullContext *pctx) {
419 static const char me[]="_pullIterFinishAdding";
420 unsigned int taskIdx;
421
422 pctx->addNum = 0;
423 for (taskIdx=0; taskIdx<pctx->threadNum; taskIdx++) {
424 pullTask *task;
425 task = pctx->task[taskIdx];
426 if (task->addPointNum) {
427 unsigned int pointIdx;
428 int added;
429 for (pointIdx=0; pointIdx<task->addPointNum; pointIdx++) {
430 pullPoint *point;
431 pullBin *bin;
432 point = task->addPoint[pointIdx];
433 point->status &= ~PULL_STATUS_NEWBIE_BIT(1<< 2);
434 if (pullBinsPointMaybeAdd(pctx, point, &bin, &added)) {
435 biffAddf(PULLpullBiffKey, "%s: trouble binning new point %u", me, point->idtag);
436 return 1;
437 }
438 if (added) {
439 pctx->addNum++;
440 } else {
441 unsigned int npi, xpi;
442 if (pctx->verbose) {
443 printf("%s: decided NOT to add new point %u\n", me, point->idtag);
444 }
445 /* HEY: copied from above */
446 /* ugh, have to signal to neigs that its no longer their neighbor */
447 task->processMode = pullProcessModeNeighLearn;
448 point->status |= PULL_STATUS_NIXME_BIT(1<< 3);
449 for (npi=0; npi<point->neighPointNum; npi++) {
450 _pullEnergyFromPoints(task, bin, point->neighPoint[npi], NULL((void*)0));
451 }
452 task->processMode = pullProcessModeAdding;
453 /* can't do immediate nix for reasons GLK doesn't quite understand */
454 xpi = airArrayLenIncr(task->nixPointArr, 1);
455 task->nixPoint[xpi] = point;
456 }
457 }
458 airArrayLenSet(task->addPointArr, 0);
459 }
460 }
461 if (pctx->verbose && pctx->addNum) {
462 printf("%s: ADDED %u\n", me, pctx->addNum);
463 }
464 return 0;
465}
466
467void
468_pullNixTheNixed(pullContext *pctx) {
469 unsigned int binIdx;
470
471 pctx->nixNum = 0;
472 for (binIdx=0; binIdx<pctx->binNum; binIdx++) {
473 pullBin *bin;
474 unsigned int pointIdx;
475 bin = pctx->bin + binIdx;
476 pointIdx = 0;
477 while (pointIdx < bin->pointNum) {
478 pullPoint *point;
479 point = bin->point[pointIdx];
480 if (pctx->flag.nixAtVolumeEdgeSpace
481 && (point->status & PULL_STATUS_EDGE_BIT(1<< 4))) {
482 point->status |= PULL_STATUS_NIXME_BIT(1<< 3);
483 }
484 if (point->status & PULL_STATUS_NIXME_BIT(1<< 3)) {
485 pullPointNix(point);
486 /* copy last point pointer to this slot */
487 bin->point[pointIdx] = bin->point[bin->pointNum-1];
488 airArrayLenIncr(bin->pointArr, -1); /* will decrement bin->pointNum */
489 pctx->nixNum++;
490 } else {
491 pointIdx++;
492 }
493 }
494 }
495 return;
496}
497
498int
499_pullIterFinishNixing(pullContext *pctx) {
500 static const char me[]="_pullIterFinishNixing";
501 unsigned int taskIdx;
502
503 _pullNixTheNixed(pctx);
504 /* finish nixing the things that we decided not to add */
505 for (taskIdx=0; taskIdx<pctx->threadNum; taskIdx++) {
506 pullTask *task;
507 task = pctx->task[taskIdx];
508 if (task->nixPointNum) {
509 unsigned int xpi;
510 for (xpi=0; xpi<task->nixPointNum; xpi++) {
511 pullPointNix(task->nixPoint[xpi]);
512 }
513 airArrayLenSet(task->nixPointArr, 0);
514 }
515 }
516 if (pctx->verbose && pctx->nixNum) {
517 printf("%s: NIXED %u\n", me, pctx->nixNum);
518 }
519 return 0;
520}
521