static real ChiSquare(creal x, cint df) { real y; if( df <= 0 ) return -999; if( x <= 0 ) return 0; if( x > 1000*df ) return 1; if( df > 1000 ) { if( x < 2 ) return 0; y = 2./(9*df); y = (powx(x/df, 1/3.) - (1 - y))/sqrtx(y); if( y > 5 ) return 1; if( y < -18.8055 ) return 0; return Normal(y); } y = .5*x; if( df & 1 ) { creal sqrty = sqrtx(y); real h = Erf(sqrty); count i; if( df == 1 ) return h; y = sqrty*expx(-y)/.8862269254527579825931; for( i = 3; i < df; i += 2 ) { h -= y; y *= x/i; } y = h - y; } else { real term = expx(-y), sum = term; count i; for( i = 1; i < df/2; ++i ) sum += term *= y/i; y = 1 - sum; } return Max(0., y); }
void Camera::Update() { Vector3 f = m_center - m_eye; //normalize it //int test = XTOF(f.z); int mag = sqrtx( (int32)(MULX(f.x,f.x) + (int32)MULX(f.y,f.y) + (int32)MULX(f.z,f.z)) ); int n = DIVX(ITOX(1),mag); f.x = MULX(f.x,n); f.y = MULX(f.y,n); f.z = MULX(f.z,n); //update direction m_dir = f; Vector3 s = f ^ m_up, u = s ^ f; int matrix[16] = { s.x, u.x, -f.x, 0, s.y, u.y, -f.y, 0, s.z, u.z, -f.z, 0, 0, 0, 0, ITOX(1) }; glMultMatrixx(matrix); glTranslatex(-m_eye.x,-m_eye.y,-m_eye.z); }
static inline void BFGS(cThis *t, ccount n, real *hessian, creal *gnew, creal *g, real *p, creal dx) { Vector(real, y, NDIM); real c; count i, j; for( i = 0; i < n; ++i ) y[i] = gnew[i] - g[i]; c = dx*Dot(n, y, p); if( c < 1e-10 ) return; RenormalizeCholesky(t, n, hessian, y, 1/c); c = Dot(n, g, p); if( c >= 0 ) return; c = 1/sqrtx(-c); for( i = 0; i < n; ++i ) y[i] = c*g[i]; UpdateCholesky(t, n, hessian, y, p); for( i = 0; i < n - 1; ++i ) for( j = i + 1; j < n; ++j ) Hessian(i, j) = Hessian(j, i); }
static inline real Length(ccount n, creal *vec) { return sqrtx(Dot(n, vec, vec)); }
static Point LineSearch(This *t, ccount nfree, ccount *ifree, creal *p, creal *xini, real fini, real *x, real step, creal range, creal grad, creal ftol, creal xtol, creal gtol) { real tol = ftol, tol2 = tol + tol; Point cur = {0, fini}; XCopy(x, xini); /* don't even try if a) we'd walk backwards, b) the range to explore is too small, c) the gradient is positive, i.e. we'd move uphill */ if( step > 0 && range > tol2 && grad <= 0 ) { creal eps = RTEPS*fabsx(range) + ftol; creal mingrad = -1e-4*grad, maxgrad = -gtol*grad; real end = range + eps; real maxstep = range - eps/(1 + RTEPS); Point min = cur, v = cur, w = cur; Point a = cur, b = {end, 0}; real a1, b1 = end; /* distmin: distance along p from xini to the minimum, u: second-lowest point, v: third-lowest point, a, b: interval in which the minimum is sought. */ real distmin = 0, dist, mid, q, r, s; count i; int shift; bool first; for( first = true; ; first = false ) { if( step >= maxstep ) { step = maxstep; maxstep = maxstep*(1 + .75*RTEPS) + .75*tol; } cur.dx = (fabsx(step) >= tol) ? step : (step > 0) ? tol : -tol; dist = distmin + cur.dx; for( i = 0; i < nfree; ++i ) { ccount dim = ifree[i]; x[dim] = xini[dim] + dist*p[i]; } cur.f = Sample(t, x); if( cur.f <= min.f ) { v = w; w = min; min.f = cur.f; distmin = dist; /* shift everything to the new minimum position */ maxstep -= cur.dx; v.dx -= cur.dx; w.dx -= cur.dx; a.dx -= cur.dx; b.dx -= cur.dx; if( cur.dx < 0 ) b = w; else a = w; tol = RTEPS*fabsx(distmin) + ftol; tol2 = tol + tol; } else { if( cur.dx < 0 ) a = cur; else b = cur; if( cur.f <= w.f || w.dx == 0 ) v = w, w = cur; else if( cur.f <= v.f || v.dx == 0 || v.dx == w.dx ) v = cur; } if( distmin + b.dx <= xtol ) break; if( min.f < fini && a.f - min.f <= fabsx(a.dx)*maxgrad && (fabsx(distmin - range) > tol || maxstep < b.dx) ) break; mid = .5*(a.dx + b.dx); if( fabsx(mid) <= tol2 - .5*(b.dx - a.dx) ) break; r = q = s = 0; if( fabsx(end) > tol ) { if( first ) { creal s1 = w.dx*grad; creal s2 = w.f - min.f; s = (s1 - ((distmin == 0) ? 0 : 2*s2))*w.dx; q = 2*(s2 - s1); } else { creal s1 = w.dx*(v.f - min.f); creal s2 = v.dx*(w.f - min.f); s = s1*w.dx - s2*v.dx; q = 2*(s2 - s1); } if( q > 0 ) s = -s; q = fabsx(q); r = end; if( step != b1 || b.dx <= maxstep ) end = step; } if( distmin == a.dx ) step = mid; else if( b.dx > maxstep ) step = (step < b.dx) ? -4*a.dx : maxstep; else { real num = a.dx, den = b.dx; if( fabsx(b.dx) <= tol || (w.dx > 0 && fabsx(a.dx) > tol) ) num = b.dx, den = a.dx; num /= -den; step = (num < 1) ? .5*den*sqrtx(num) : 5/11.*den*(.1 + 1/num); } if( step > 0 ) a1 = a.dx, b1 = step; else a1 = step, b1 = b.dx; if( fabsx(s) < fabsx(.5*q*r) && s > q*a1 && s < q*b1 ) { step = s/q; if( step - a.dx < tol2 || b.dx - step < tol2 ) step = (mid > 0) ? tol : -tol; } else end = (mid > 0) ? b.dx : a.dx; } first = true; if( fabsx(distmin - range) < tol ) { distmin = range; if( maxstep > b.dx ) first = false; } for( cur.dx = distmin, cur.f = min.f, shift = -1; ; cur.dx = Max(ldexp(distmin, shift), ftol), shift <<= 1 ) { for( i = 0; i < nfree; ++i ) { ccount dim = ifree[i]; x[dim] = xini[dim] + cur.dx*p[i]; } if( !first ) cur.f = Sample(t, x); if( cur.dx + b.dx <= xtol ) { cur.dx = 0; break; } if( fini - cur.f > cur.dx*mingrad ) break; if( cur.dx <= ftol ) { cur.dx = 0; break; } first = false; } } return cur; }