void finite_diff_grad(const M& model, stan::callbacks::interrupt& interrupt, std::vector<double>& params_r, std::vector<int>& params_i, std::vector<double>& grad, double epsilon = 1e-6, std::ostream* msgs = 0) { std::vector<double> perturbed(params_r); grad.resize(params_r.size()); for (size_t k = 0; k < params_r.size(); k++) { interrupt(); perturbed[k] += epsilon; double logp_plus = model .template log_prob<propto, jacobian_adjust_transform>(perturbed, params_i, msgs); perturbed[k] = params_r[k] - epsilon; double logp_minus = model .template log_prob<propto, jacobian_adjust_transform>(perturbed, params_i, msgs); double gradest = (logp_plus - logp_minus) / (2*epsilon); grad[k] = gradest; perturbed[k] = params_r[k]; } }
Spectrum sample(BSDFSamplingRecord &bRec, Float &pdf, const Point2 &sample) const { const Intersection& its = bRec.its; Intersection perturbed(its); perturbed.shFrame = getFrame(its); BSDFSamplingRecord perturbedQuery(perturbed, bRec.sampler, bRec.mode); perturbedQuery.wi = perturbed.toLocal(its.toWorld(bRec.wi)); perturbedQuery.typeMask = bRec.typeMask; perturbedQuery.component = bRec.component; Float temporaryPdf = (Float)0; Spectrum result = m_nested->sample(perturbedQuery, temporaryPdf, sample); if (temporaryPdf > 0) { bRec.sampledComponent = perturbedQuery.sampledComponent; bRec.sampledType = perturbedQuery.sampledType; bRec.wo = its.toLocal(perturbed.toWorld(perturbedQuery.wo)); bRec.eta = perturbedQuery.eta; if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0) return Spectrum(0.0f); pdf = temporaryPdf; } return result; }
Spectrum eval(const BSDFSamplingRecord &bRec, EMeasure measure) const { const Intersection& its = bRec.its; Intersection perturbed(its); perturbed.shFrame = getFrame(its); BSDFSamplingRecord perturbedQuery(perturbed, perturbed.toLocal(its.toWorld(bRec.wi)), perturbed.toLocal(its.toWorld(bRec.wo)), bRec.mode); if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0) return Spectrum(0.0f); perturbedQuery.sampler = bRec.sampler; perturbedQuery.typeMask = bRec.typeMask; perturbedQuery.component = bRec.component; return m_nested->eval(perturbedQuery, measure); }
template<Pb PS> bool circles_overlap(const ExactCircle<PS>& c0, const ExactCircle<PS>& c1) { return perturbed_predicate<Intersect<true >>(perturbed(c0),perturbed(c1)); }
template<Pb PS> bool has_intersections(const ExactCircle<PS>& c0, const ExactCircle<PS>& c1) { return perturbed_predicate<Intersect<true >>(perturbed(c0),perturbed(c1)) && !perturbed_predicate<Intersect<false>>(perturbed(c0),perturbed(c1)); }
template<Pb PS> uint8_t circle_circle_intersection_quadrant(const ReferenceSide side, const ExactCircle<PS>& cl, const ExactCircle<PS>& cr, const ApproxIntersection v) { assert(circle_circle_approx_intersection(cl,cr).box().intersects(v.box())); // We must evaluate the predicate // // cross(e,alpha*dc+beta*dc^perp) > 0 // alpha cross(e,dc) + beta dot(e,dc) > 0 // // where e0 = (1,0) and e1 = (0,1). This has the form // // A + B sqrt(C) > 0 // A = alpha_hat cross(e,dc) // B = dot(e,dc) // C = beta_hat^2 // // Compute predicates for both axes // const ExactCircle<PS>& c0 = cl_is_reference(side) ? cl : cr; const ExactCircle<PS>& c1 = cl_is_reference(side) ? cr : cl; const int s = cl_is_reference(side) ? -1 : 1; const bool p0 = FILTER(v.p().y-c0.center.y, perturbed_predicate_sqrt<QuadrantA<0>,QuadrantB<0>,Beta<0,1>>(s,perturbed(c0),perturbed(c1))), p1 = FILTER(c0.center.x-v.p().x, perturbed_predicate_sqrt<QuadrantA<1>,QuadrantB<1>,Beta<0,1>>(s,perturbed(c0),perturbed(c1))); // Assemble our two predicates into a quadrant return 2*!p0+(p0==p1); }