ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapbias.c
(Generate patch)

Comparing ray/src/rt/pmapbias.c (file contents):
Revision 2.4 by greg, Tue Sep 1 16:27:52 2015 UTC vs.
Revision 2.5 by rschregle, Tue May 17 17:39:47 2016 UTC

# Line 1 | Line 1
1   #ifndef lint
2   static const char RCSid[] = "$Id$";
3   #endif
4 +
5   /*
6     ==================================================================
7     Bias compensation for photon density estimates
# Line 13 | Line 14 | static const char RCSid[] = "$Id$";
14     (c) Fraunhofer Institute for Solar Energy Systems
15     ==================================================================
16    
17 +   $Id$    
18   */
19  
20  
# Line 23 | Line 25 | static const char RCSid[] = "$Id$";
25  
26  
27  
28 < void squeuePartition (PhotonSQNode* squeue, unsigned lo,
28 > void squeuePartition (PhotonSearchQueueNode* squeue, unsigned lo,
29                        unsigned mid, unsigned hi)
30   /* REVERSE Partition squeue such that all photons in
31     squeue-hi+1..squeue-mid are farther than the median at squeue-mid+1,
# Line 33 | Line 35 | void squeuePartition (PhotonSQNode* squeue, unsigned l
35     since the queue is initially a maxheap, so reverse sorting is expected
36     to be faster. */
37   {
38 <   unsigned l, h, p;
39 <   PhotonSQNode *lp, *hp, *pp;
40 <   float pivot, dist;
39 <   Photon* photon;
38 >   unsigned                l, h, p;
39 >   PhotonSearchQueueNode   *lp, *hp, *pp, tmp;
40 >   float                   pivot;
41  
42     while (hi > lo) {
43        /* Grab pivot node in middle as an educated guess, since our
# Line 47 | Line 48 | void squeuePartition (PhotonSQNode* squeue, unsigned l
48        lp = squeue - lo + 1;
49        hp = squeue - hi + 1;
50        pp = squeue - p + 1;
51 <      pivot = pp -> dist;
51 >      pivot = pp -> dist2;
52        
53        /* l & h converge, swapping elements out of order with respect to
54           pivot node. */
55        while (l < h) {
56 <         while (lp -> dist <= pivot && l <= h && l < hi)
56 >         while (lp -> dist2 <= pivot && l <= h && l < hi)
57              ++l, --lp;
58 <         while (hp -> dist >= pivot && h >= l && h > lo)
58 >            
59 >         while (hp -> dist2 >= pivot && h >= l && h > lo)
60              --h, ++hp;
61              
62           if (l < h) {
63              /* Swap */
64 <            photon = lp -> photon;
65 <            dist = lp -> dist;
66 <            lp -> photon = hp -> photon;
67 <            lp -> dist = hp -> dist;
68 <            hp -> photon = photon;
69 <            hp -> dist = dist;
64 >            tmp.idx = lp -> idx;
65 >            tmp.dist2 = lp -> dist2;
66 >            lp -> idx = hp -> idx;
67 >            lp -> dist2 = hp -> dist2;
68 >            hp -> idx = tmp.idx;
69 >            hp -> dist2 = tmp.dist2;
70           }
71        }
72        
73        /* Swap convergence and pivot node */
74        if (p > h) {
75           /* Need this otherwise shit happens!
76 <            Since lp -> dist > hp -> dist, we swap either l or p depending
76 >            Since lp -> dist2 > hp -> dist2, we swap either l or p depending
77              on whether we're above or below p */
78           h = l;
79           hp = lp;
80        }
81        
82 <      photon = hp -> photon;
83 <      dist = hp -> dist;
84 <      hp -> photon = pp -> photon;
85 <      hp -> dist = pivot;
86 <      pp -> photon = photon;
87 <      pp -> dist = dist;
82 >      tmp.idx = hp -> idx;
83 >      tmp.dist2 = hp -> dist2;
84 >      hp -> idx = pp -> idx;
85 >      hp -> dist2 = pivot;
86 >      pp -> idx = tmp.idx;
87 >      pp -> dist2 = tmp.dist2;
88 >      
89        if (h >= mid)
90           hi = h - 1;
91 +        
92        if (h <= mid)
93           lo = h + 1;
94     }
# Line 97 | Line 101 | void squeuePartition (PhotonSQNode* squeue, unsigned l
101   void biasComp (PhotonMap* pmap, COLOR irrad)
102   /* Photon density estimate with bias compensation -- czech dis shit out! */
103   {
104 <   unsigned i, numLo, numHi, numMid;
105 <   PhotonSQNode *sq;
106 <   PhotonBCNode *hist;
107 <   float r, totalWeight = 0;
108 <   PhotonSQNode *squeueEnd;
109 <   PhotonBCNode *histEnd;
106 <   COLOR fluxLo, fluxMid, irradVar, irradAvg, p, d;
104 >   unsigned                i, numLo, numHi, numMid;
105 >   float                   r, totalWeight = 0;
106 >   COLOR                   fluxLo, fluxMid, irradVar, irradAvg, p, d;
107 >   Photon                  *photon;
108 >   PhotonSearchQueueNode   *sqn, *sqEnd;
109 >   PhotonBiasCompNode      *hist, *histEnd;
110    
111     if (!pmap -> biasCompHist) {
112        /* Allocate bias compensation history */
113 <      numHi = pmap -> maxGather - pmap -> minGather;
114 <      for (i = pmap -> minGather + 1; numHi > 1; numHi >>= 1, ++i);
115 <      pmap -> biasCompHist = (PhotonBCNode*)malloc(i * sizeof(PhotonBCNode));      
113 >      numHi = pmap -> maxGather - pmap -> minGather;
114 >      for (i = pmap -> minGather + 1; numHi > 1; numHi >>= 1, ++i);      
115 >      pmap -> biasCompHist = calloc(i, sizeof(PhotonBiasCompNode));      
116 >      
117        if (!pmap -> biasCompHist)
118           error(USER, "can't allocate bias compensation history");
119     }
120    
121 <   numLo = min(pmap -> minGather, pmap -> squeueEnd - 1);
122 <   numHi = min(pmap -> maxGather, pmap -> squeueEnd - 1);
123 <   sq = squeueEnd = pmap -> squeue + pmap -> squeueEnd - 1;
121 >   numLo = min(pmap -> minGather, pmap -> squeue.tail - 1);
122 >   numHi = min(pmap -> maxGather, pmap -> squeue.tail - 1);
123 >   sqn = sqEnd = pmap -> squeue.node + pmap -> squeue.tail - 1;
124     histEnd = pmap -> biasCompHist;
125     setcolor(fluxLo, 0, 0, 0);
126    
127     /* Partition to get numLo closest photons starting from END of queue */
128 <   squeuePartition(squeueEnd, 1, numLo + 1, numHi);
128 >   squeuePartition(sqEnd, 1, numLo + 1, numHi);
129    
130     /* Get irradiance estimates (ignoring 1 / PI) using 1..numLo photons
131        and chuck in history. Queue is traversed BACKWARDS. */
132 <   for (i = 1; i <= numLo; i++, sq--) {
133 <      /* Make sure furthest two photons are consecutive wrt distance */
134 <      squeuePartition(squeueEnd, i, i + 1, numLo + 1);
135 <      getPhotonFlux(sq -> photon, irrad);
132 >   for (i = 1; i <= numLo; i++, sqn--) {
133 >      /* Make sure furthest two photons are consecutive w.r.t. distance */
134 >      squeuePartition(sqEnd, i, i + 1, numLo + 1);
135 >      photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
136 >      getPhotonFlux(photon, irrad);
137        addcolor(fluxLo, irrad);
138        /* Average radius between furthest two photons to improve accuracy */
139 <      r = 0.25 * (sq -> dist + (sq - 1) -> dist +
140 <                  2 * sqrt(sq -> dist * (sq - 1) -> dist));
139 >      r = 0.25 * (sqn -> dist2 + (sqn - 1) -> dist2 +
140 >                  2 * sqrt(sqn -> dist2 * (sqn - 1) -> dist2));
141        /* Add irradiance and weight to history. Weights should increase
142           monotonically based on number of photons used for the estimate. */
143        histEnd -> irrad [0] = fluxLo [0] / r;
# Line 163 | Line 168 | void biasComp (PhotonMap* pmap, COLOR irrad)
168        numMid = (numLo + numHi) >> 1;
169        /* Split interval to get numMid closest photons starting from the
170           END of the queue */
171 <      squeuePartition(squeueEnd, numLo, numMid, numHi);
171 >      squeuePartition(sqEnd, numLo, numMid, numHi);
172        /* Make sure furthest two photons are consecutive wrt distance */
173 <      squeuePartition(squeueEnd, numMid, numMid + 1, numHi);
173 >      squeuePartition(sqEnd, numMid, numMid + 1, numHi);
174        copycolor(fluxMid, fluxLo);
175 <      sq = squeueEnd - numLo;
175 >      sqn = sqEnd - numLo;
176        
177        /* Get irradiance for numMid photons (ignoring 1 / PI) */
178 <      for (i = numLo; i < numMid; i++, sq--) {
179 <         getPhotonFlux(sq -> photon, irrad);
178 >      for (i = numLo; i < numMid; i++, sqn--) {
179 >         photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
180 >         getPhotonFlux(photon, irrad);
181           addcolor(fluxMid, irrad);
182        }
183        
184        /* Average radius between furthest two photons to improve accuracy */
185 <      r = 0.25 * (sq -> dist + (sq + 1) -> dist +
186 <                  2 * sqrt(sq -> dist * (sq + 1) -> dist));
185 >      r = 0.25 * (sqn -> dist2 + (sqn + 1) -> dist2 +
186 >                  2 * sqrt(sqn -> dist2 * (sqn + 1) -> dist2));
187                    
188        /* Get deviation from current average, and probability that it's due
189           to noise from gaussian distribution based on current variance. Since
# Line 208 | Line 214 | void biasComp (PhotonMap* pmap, COLOR irrad)
214              irradVar [i] = irradVar [i] / totalWeight - r * r;
215           }
216          
217 <         /* Need more photons -- recurse on [numMid, numHi] */
217 >         /* Need more photons --> recurse on [numMid, numHi] */
218           numLo = numMid;
219           copycolor(fluxLo, fluxMid);
220        }
221        else
222 <         /* Deviation is probably bias -- need fewer photons,
222 >         /* Deviation is probably bias --> need fewer photons,
223              so recurse on [numLo, numMid] */
224           numHi = numMid;
225     }  
226  
227     --histEnd;
228 +  
229     for (i = 0; i <= 2; i++) {
230        /* Estimated relative error */
231        d [i] = histEnd -> irrad [i] / irradAvg [i] - 1;
# Line 234 | Line 241 | void biasComp (PhotonMap* pmap, COLOR irrad)
241    
242     /* Update statistix */
243     r = colorAvg(d);
244 +   pmap -> rmsError += r * r;
245 +  
246     if (r < pmap -> minError)
247        pmap -> minError = r;
248 +      
249     if (r > pmap -> maxError)
250        pmap -> maxError = r;
241   pmap -> rmsError += r * r;
251    
252     if (numHi < pmap -> minGathered)
253        pmap -> minGathered = numHi;
254 +            
255     if (numHi > pmap -> maxGathered)
256        pmap -> maxGathered = numHi;
257        
# Line 251 | Line 261 | void biasComp (PhotonMap* pmap, COLOR irrad)
261  
262  
263  
264 + /* Volume bias compensation disabled (probably redundant) */
265 + #if 0
266   void volumeBiasComp (PhotonMap* pmap, const RAY* ray, COLOR irrad)
267   /* Photon volume density estimate with bias compensation -- czech dis
268     shit out! */
# Line 423 | Line 435 | void volumeBiasComp (PhotonMap* pmap, const RAY* ray,
435     pmap -> totalGathered += numMid;
436     ++pmap -> numDensity;
437   }
438 <                                
438 > #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines