//alg for calculating shading. Calls diffuseShade and SpecularShade Color RT_lights(Figure* obj, const Ray& ray, const Vec& thePoint, const Vec& normal) { Color c = Color(); for (list<Light*>::iterator iterator = lightList.begin(), end = lightList.end(); iterator != end; ++iterator) { Light* theLight = *iterator; pair<double, Figure*> inter = nearestIntersection(Ray(Vec(thePoint), theLight->getPos()), MIN_T / SHAD_RES, 1.0, EPSILON, false); if (inter.first <= 0) { Vec* toLight = thePoint.normalize(theLight->getPos()); double dotProduct = toLight->dot(normal); Vec* subt = (thePoint.sub(theLight->getPos())); double dist = abs(subt->getMag()); Color dif = diffuseShade(obj, theLight, max(dotProduct, 0.0), dist); Vec* Q = normal.scale(normal.dot(*toLight)); Vec* S = Q->sub(*toLight); Vec* S2 = S->scale(2.0); Vec* R = toLight->add(*S2); Vec* norm = ray.getNorm(); Vec* scaledNorm = norm->scale(-1.0); dotProduct = max(0.0, R->dot(*scaledNorm)); Color spec = specularShade(obj, normal, theLight, *toLight, pow(dotProduct, obj->getShininess()), ray, dist); c = c.add(dif.add(spec)); delete(toLight); delete(Q); delete(S); delete(R); delete(S2); delete(subt); delete(norm); delete(scaledNorm); } } return c; }
inline double bssrdf(const Vec& xi, const Vec& ni, const Vec& wi, const Vec& xo, const Vec& no, const Vec& wo, const int j) { // distance const Vec xoxi = xo - xi; const double r = xoxi.len(); // modified normal const Vec ni_s = (xoxi.normalized()) % ((ni % xoxi).normalized()); // directions of ray sources const double nnt = 1.0 / eta, ddn = -wi.dot(ni); const Vec wr = (wi * -nnt - ni * (ddn * nnt + sqrt(1.0 - nnt * nnt * (1.0 - ddn * ddn)))).normalized(); const Vec wv = wr - ni_s * (2.0 * wr.dot(ni_s)); // distance to real sources const double cos_beta = -sqrt((r * r - xoxi.dot(wr) * xoxi.dot(wr)) / (r * r + de[j] * de[j])); double dr; const double mu0 = -no.dot(wr); if (mu0 > 0.0) { dr = sqrt((D[j] * mu0) * ((D[j] * mu0) - de[j] * cos_beta * 2.0) + r * r); } else { dr = sqrt(1.0 / (3.0 * sigma_t[j] * 3.0 * sigma_t[j]) + r * r); } // distance to virtual source const Vec xoxv = xo - (xi + ni_s * (2.0 * A * de[j])); const double dv = xoxv.len(); // BSSRDF const double result = Sp_d(xoxi, wr, dr, no, j) - Sp_d(xoxv, wv, dv, no, j); // clamping to zero return (result < 0.0) ? 0.0 : result; }
double intersect(const Ray &r) const { // returns distance, 0 if nohit Vec op = p - r.o; // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 double t, eps = 1e-4, b = op.dot(r.d), det = b * b - op.dot(op) + rad * rad; if (det < 0) return 0; else det = sqrt(det); return (t = b - det) > eps ? t : ((t = b + det) > eps ? t : 0); }
inline double intersect(const Ray& r) const { // ray-sphere intersection returns the distance const Vec op = p - r.o; double t, b = op.dot(r.d), det = b * b - op.dot(op) + rad * rad; if (det < 0) { return 1e20; } else { det = sqrt(det); } return (t = b - det) > 1e-4 ? t : ((t = b + det) > 1e-4 ? t : 1e20); }
// directional dipole // -------------------------------- inline double Sp_d(const Vec& x, const Vec& w, const double& r, const Vec& n, const int j) { // evaluate the profile const double s_tr_r = sigma_tr[j] * r; const double s_tr_r_one = 1.0 + s_tr_r; const double x_dot_w = x.dot(w); const double r_sqr = r * r; const double t0 = Cp_norm * (1.0 / (4.0 * PI * PI)) * exp(-s_tr_r) / (r * r_sqr); const double t1 = r_sqr / D[j] + 3.0 * s_tr_r_one * x_dot_w; const double t2 = 3.0 * D[j] * s_tr_r_one * w.dot(n); const double t3 = (s_tr_r_one + 3.0 * D[j] * (3.0 * s_tr_r_one + s_tr_r * s_tr_r) / r_sqr * x_dot_w) * x.dot(n); return t0 * (Cp * t1 - Ce * (t2 - t3)); }
Number Sphere::do_intersect(const Vec & start_p, const Vec & dir) const { Vec p = start_p - center; Vec x = (-dir.dot(p)) * dir; Vec y = p + x; auto y_norm = y.norm(); if(y_norm > radius) return -1; auto x_dot = x.dot(dir); auto s = std::sqrt(radius * radius - y_norm * y_norm); auto t_norm = x_dot - s; if(t_norm < 0) t_norm += 2 * s; return t_norm; // may < 0, which means no intersection }
Vec radiance(const Ray &r, int depth, unsigned short *Xi,int E=1){ double t; // distance to intersection int id=0; // id of intersected object if (!intersect(r, t, id)) return Vec(); // if miss, return black const Sphere &obj = spheres[id]; // the hit object Vec x=r.o+r.d*t, n=(x-obj.p).norm(), nl=n.dot(r.d)<0?n:n*-1, f=obj.c; double p = f.x>f.y && f.x>f.z ? f.x : f.y>f.z ? f.y : f.z; // max refl if (++depth>5||!p) if (erand48(Xi)<p) f=f*(1/p); else return obj.e*E; if (obj.refl == DIFF){ // Ideal DIFFUSE reflection double r1=2*M_PI*erand48(Xi), r2=erand48(Xi), r2s=sqrt(r2); Vec w=nl, u=((fabs(w.x)>.1?Vec(0,1):Vec(1))%w).norm(), v=w%u; Vec d = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1-r2)).norm(); // Loop over any lights Vec e; for (int i=0; i<numSpheres; i++){ const Sphere &s = spheres[i]; if (s.e.x<=0 && s.e.y<=0 && s.e.z<=0) continue; // skip non-lights Vec sw=s.p-x, su=((fabs(sw.x)>.1?Vec(0,1):Vec(1))%sw).norm(), sv=sw%su; double cos_a_max = sqrt(1-s.rad*s.rad/(x-s.p).dot(x-s.p)); double eps1 = erand48(Xi), eps2 = erand48(Xi); double cos_a = 1-eps1+eps1*cos_a_max; double sin_a = sqrt(1-cos_a*cos_a); double phi = 2*M_PI*eps2; Vec l = su*cos(phi)*sin_a + sv*sin(phi)*sin_a + sw*cos_a; l.norm(); if (intersect(Ray(x,l), t, id) && id==i){ // shadow ray double omega = 2*M_PI*(1-cos_a_max); e = e + f.mult(s.e*l.dot(nl)*omega)*M_1_PI; // 1/pi for brdf } } return obj.e*E+e+f.mult(radiance(Ray(x,d),depth,Xi,0)); } else if (obj.refl == SPEC) // Ideal SPECULAR reflection return obj.e + f.mult(radiance(Ray(x,r.d-n*2*n.dot(r.d)),depth,Xi)); Ray reflRay(x, r.d-n*2*n.dot(r.d)); // Ideal dielectric REFRACTION bool into = n.dot(nl)>0; // Ray from outside going in? double nc=1, nt=1.5, nnt=into?nc/nt:nt/nc, ddn=r.d.dot(nl), cos2t; if ((cos2t=1-nnt*nnt*(1-ddn*ddn))<0) // Total internal reflection return obj.e + f.mult(radiance(reflRay,depth,Xi)); Vec tdir = (r.d*nnt - n*((into?1:-1)*(ddn*nnt+sqrt(cos2t)))).norm(); double a=nt-nc, b=nt+nc, R0=a*a/(b*b), c = 1-(into?-ddn:tdir.dot(n)); double Re=R0+(1-R0)*c*c*c*c*c,Tr=1-Re,P=.25+.5*Re,RP=Re/P,TP=Tr/(1-P); return obj.e + f.mult(depth>2 ? (erand48(Xi)<P ? // Russian roulette radiance(reflRay,depth,Xi)*RP:radiance(Ray(x,tdir),depth,Xi)*TP) : radiance(reflRay,depth,Xi)*Re+radiance(Ray(x,tdir),depth,Xi)*Tr); }
Vec receivedRadiance(const Ray &r, int depth, bool flag) { double t; // Distance to intersection int id = 0; // id of intersected sphere if ( !intersect(r, t, id) ) return Vec(); // if miss, return black const Sphere &obj = spheres[id]; // the hit object Vec x = r.o + r.d*t; // The intersection point Vec o = (Vec() - r.d).normalize(); // The outgoing direction (= -r.d) Vec n = (x - obj.p).normalize(); // The normal direction if ( n.dot(o) < 0 ) n = n*-1.0; /* Tips 1. Other useful quantities/variables: Vec Le = obj.e; // Emitted radiance const BRDF &brdf = obj.brdf; // Surface BRDF at x 2. Call brdf.sample() to sample an incoming direction and continue the recursion */ Vec Le = obj.e; // Emitted radiance const BRDF &brdf = obj.brdf; // Surface BRDF at x const int rrDepth = 5; const double survivalProbability = 0.9; double p = 1.0; if (depth > rrDepth) p = survivalProbability; if (rng() < p) { Vec o_i; double pdf; brdf.sample(n, o, o_i, pdf); Ray y(x, o_i.normalize()); Vec reflected = receivedRadiance(y, depth + 1, false) .mult(brdf.eval(n, o, o_i)) * (n.dot(o_i) / (pdf*p)); return Le + reflected; } return Le; }
Vec radiance(const Ray &r, int depth, unsigned short *Xi) { double t; // distance to intersection int id = 0; // id of intersected object if(!intersect(r, t, id)) return Vec(); // if miss, return black const Sphere &obj = spheres[id]; // the hit object Vec x = r.o + r.d*t, n = (x - obj.p).norm(), nl = n.dot(r.d) < 0 ? n : n*-1, f = obj.c; double p = f.x > f.y && f.x>f.z ? f.x : f.y > f.z ? f.y : f.z; // max refl if(depth > 255) return obj.e; if(++depth > 5) if(erand48(Xi) < p) f = f*(1 / p); else return obj.e; //R.R. if(obj.refl == DIFF) { // Ideal DIFFUSE reflection double r1 = 2 * M_PI*erand48(Xi), r2 = erand48(Xi), r2s = sqrt(r2); Vec w = nl, u = ((fabs(w.x) > .1 ? Vec(0, 1) : Vec(1)) % w).norm(), v = w%u; Vec d = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1 - r2)).norm(); return obj.e + f.mult(radiance(Ray(x, d), depth, Xi)); } else if(obj.refl == SPEC) // Ideal SPECULAR reflection return obj.e + f.mult(radiance(Ray(x, r.d - n * 2 * n.dot(r.d)), depth, Xi)); Ray reflRay(x, r.d - n * 2 * n.dot(r.d)); // Ideal dielectric REFRACTION bool into = n.dot(nl) > 0; // Ray from outside going in? double nc = 1, nt = 1.5, nnt = into ? nc / nt : nt / nc, ddn = r.d.dot(nl), cos2t; if((cos2t = 1 - nnt*nnt*(1 - ddn*ddn)) < 0) // Total internal reflection return obj.e + f.mult(radiance(reflRay, depth, Xi)); Vec tdir = (r.d*nnt - n*((into ? 1 : -1)*(ddn*nnt + sqrt(cos2t)))).norm(); double a = nt - nc, b = nt + nc, R0 = a*a / (b*b), c = 1 - (into ? -ddn : tdir.dot(n)); double Re = R0 + (1 - R0)*c*c*c*c*c, Tr = 1 - Re, P = .25 + .5*Re, RP = Re / P, TP = Tr / (1 - P); return obj.e + f.mult(depth > 2 ? (erand48(Xi) < P ? // Russian roulette radiance(reflRay, depth, Xi)*RP : radiance(Ray(x, tdir), depth, Xi)*TP) : radiance(reflRay, depth, Xi)*Re + radiance(Ray(x, tdir), depth, Xi)*Tr); }
int main() { double y_vals[] = {-1.5, 2, -2.5}; double z_vals[] = {3, -2, 1}; Vec<double> zeroes(3); // Vec size 3 (entries initialize to zero) Vec<double> x = Vec<double>::constantVec(3, 2.5); // Vec size 3 with all entries set to 2.5 Vec<double> y = Vec<double>(y_vals, 3); Vec<double> z(3); z.setEntries(z_vals, 3); Vec<int> ix(x); cout << "zeroes = " << zeroes << endl; cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "z = " << z << endl; cout << "ix = " << ix << endl; cout << "z[0] = " << z[0] << ", z[1] = " << z[1] << ", z[2] = " << z[2] << endl; cout << "3.5 * x = " << (3.5 * x) << endl; cout << "x / 3.5 = " << (x / 3.5) << endl; cout << "x + y = " << (x + y) << endl; cout << "x - y = " << (x - y) << endl; cout << "x.concatenate(y) = " << x.concatenate(y) << endl; cout << "x.dot(y) = " << x.dot(y) << endl; cout << "x.cross(y) = " << x.cross(y) << endl; cout << "x.norm() = " << x.norm() << endl; cout << "x.unit_vector() = " << x.unit_vector() << endl; cout << "ix.norm() = " << ix.norm() << endl; cout << "ix.norm<double>() = " << ix.norm<double>() << endl; cout << "ix.unit_vector<double>() = " << ix.unit_vector<double>() << endl; cout << "scalar_triple_product(x, y, z) = " << Vec<double>::scalar_triple_product(x, y, z) << endl; cout << "vector_triple_product(x, y, z) = " << Vec<double>::vector_triple_product(x, y, z) << endl; }
bool UVSphere::intersect(const Ray& r, float tmin, float tmax, float time, HitRecord& record)const{ Vec temp = r.origin() - center; float a = r.direction().dot(r.direction()); float b = 2 * r.direction().dot(temp); float c = temp.dot(temp) - radius * radius; float discriminant = b*b - 4*a*c; if(discriminant > 0){ discriminant = sqrt(discriminant); float t = (-b -discriminant) /(2*a); if(t < tmin) t = (-b + discriminant) / (2*a); if(t < tmin || t > tmax) return false; record.t = t; record.hit_p = r.origin() + r.direction() * t; record.reflect = reflectionCoef; record.transparency = refractionCoef; Vec n = record.normal = normalize(r.origin() + r.direction()*t - center); //calculate UV coordinates float theta = acos(n.y); float phi = atan2(n.z, n.x); if(phi < 0) phi += M_PI * 2; record.uv = Vec(phi/(2* M_PI), (M_PI - theta)/M_PI, 0); record.hit_tex = tex; return true; } return false; }
//---------------------------------------------------------------------- void BLCSSS::rwm_draw_chunk(int chunk){ clock_t start = clock(); const Selector &inc(m_->coef().inc()); int nvars = inc.nvars(); Vec full_nonzero_beta = m_->beta(); // only nonzero components // Compute information matrix for proposal distribution. For // efficiency, also compute the log-posterior of the current beta. Vec mu(inc.select(pri_->mu())); Spd siginv(inc.select(pri_->siginv())); double original_logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); const std::vector<Ptr<BinomialRegressionData> > &data(m_->dat()); int nobs = data.size(); int full_chunk_size = compute_chunk_size(); int chunk_start = chunk * full_chunk_size; int elements_remaining = nvars - chunk_start; int this_chunk_size = std::min(elements_remaining, full_chunk_size); Selector chunk_selector(nvars, false); for(int i = chunk_start; i< chunk_start + this_chunk_size; ++i) { chunk_selector.add(i); } Spd proposal_ivar = chunk_selector.select(siginv); for(int i = 0; i < nobs; ++i){ Vec x = inc.select(data[i]->x()); double eta = x.dot(full_nonzero_beta); double prob = plogis(eta); double weight = prob * (1-prob); VectorView x_chunk(x, chunk_start, this_chunk_size); // Only upper triangle is accessed. Need to reflect at end of loop. proposal_ivar.add_outer(x_chunk, weight, false); int yi = data[i]->y(); int ni = data[i]->n(); original_logpost += dbinom(yi, ni, prob, true); } proposal_ivar.reflect(); VectorView beta_chunk(full_nonzero_beta, chunk_start, this_chunk_size); if(tdf_ > 0){ beta_chunk = rmvt_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_, tdf_); }else{ beta_chunk = rmvn_ivar_mt( rng(), beta_chunk, proposal_ivar / rwm_variance_scale_factor_); } double logpost = dmvn(full_nonzero_beta, mu, siginv, 0, true); Vec full_beta(inc.expand(full_nonzero_beta)); logpost += m_->log_likelihood(full_beta, 0, 0, false); double log_alpha = logpost - original_logpost; double logu = log(runif_mt(rng())); ++rwm_chunk_attempts_; if(logu < log_alpha){ m_->set_beta(full_nonzero_beta); ++rwm_chunk_successes_; } clock_t end = clock(); rwm_chunk_times_ += double(end - start) / CLOCKS_PER_SEC; }
/** Cast reflected ray ** @param ray incoming ray ** @param pt intersection point ** @param normal normal of pt ** @return reflected ray **/ Ray reflect(Ray ray, Vec pt, Vec normal){ Vec v = ray.getOrig() - pt; v = v.normalize(); Vec dir = normal * (2 * v.dot(normal)) - v; dir = dir.normalize(); // reflected direction Ray t(pt, dir, 0, 9999, ReflectedRay); if (debugMode) { printf("reflected ray: origin = "); t.getOrig().print(); printf("reflected ray: direction = "); t.getDir().print(); } return t; }
void HardSpherePressureTracker::update_collision(Box &box, AtomID a1, AtomID a2, flt time, Vec delta_p) { if (isnan(t0)) { t0 = time; lastt = t0; return; } Vec dr = box.diff(a1->x, a2->x); collisionsum += dr.dot(delta_p); Ksum += kinetic_energy_com(*atoms); Ncollisions++; lastt = time; };
/// Kinetic energy relative to center of mass // K = ½Σmᵢvᵢ² - ½(Σmᵢvᵢ)² / (Σmᵢ) flt kinetic_energy_com(AtomGroup &atoms) { flt Ksum = 0; Vec mvsum = Vec::Zero(); flt msum = 0; for (uint i = 0; i < atoms.size(); i++) { Atom &a = atoms[i]; Vec mv = a.m * a.v; Ksum += mv.dot(a.v); mvsum += mv; msum += a.m; } return (Ksum - mvsum.squaredNorm() / msum) / 2; };
void uniformRandom(const Vec &normal, Vec &i, double &pdf) { double z = std::sqrt(rng()); double r = std::sqrt(1.0 - z * z); double phi = 2.0 * PI * rng(); double x = r * std::cos(phi); double y = r * std::sin(phi); Vec u, v, w; createLocalCoord(normal, u, v, w); i = (u * x) + (v *y) + (w*z); pdf = normal.dot(i)/ PI; }
/** Cast transmitted ray ** @param ray incoming ray ** @param pt intersection point ** @param normal normal of pt ** @param ior2 index of refraction of the object ** @return transmitted ray **/ Ray transmit(Ray ray, Vec pt, Vec normal, float ior1, float ior2){ Vec r = ray.getDir(); float alpha = ior1 / ior2; float c1 = normal.dot(r) * -1; float c2 = sqrt(1 - pow(alpha,2) * (1 - pow(c1,2))); Vec v = r * alpha + normal * (c1 * alpha - c2); Ray t(pt, v, 0, 9999, TransmittedRay); if (debugMode) { printf("transmitted ray origin: "); t.getOrig().print(); printf("transmitted ray direction: "); t.getDir().print(); } return t; }
/** Texture mapping for spheres ** @param pt intersection point ** @param n normal at pt ** @param p pigment of the object ** @return the color of pt at texture coordinate **/ Vec sphereMapping(Vec pt, Vec n, Pigment p){ Vec vn = scene.up; // unit-length vector from the center to the north pole Vec tmp[3] = {Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(0.0, 0.0, 1.0)}; Vec ve; // unit-length vector from the center to a point on the equator for (int i = 0; i<3; i++) { if (tmp[i].dot(vn) == 0) { ve = tmp[i]; break; } } Vec vp = n; // unit-length vector from the center to intersection point int s, t; float u, v, theta, phi; phi = acos(vn.dot(vp) * -1); v = phi / PI; theta = (acos(vp.dot(ve) / sin(phi))) / (2*PI); if ((vn.cross(ve)).dot(vp) > 0) u = theta; else u = 1 - theta; // find the color of pt at texture cooridnates s = (int)p.image.width * u; t = (int)p.image.height * v; if ((s < p.image.width && s >= 0) && (t < p.image.height && t >= 0)) return p.image.textures[s][t]; else return background; }
double VarRTM::PredictAUC(RTMC &m, Mat &z_bar) { VReal real,pre; for (int d = 0; d < held_out_net_.cols(); d++) { for (SpMatInIt it(held_out_net_, d); it; ++it) { double label = it.value(); Vec pi = z_bar.col(d).cwiseProduct(z_bar.col(it.index())); double prob = Sigmoid(pi.dot(m.eta)); real.push_back(label); pre.push_back(prob); } } return AUC(real,pre); }
double logit_loglike_1(const Vec & beta, bool y, const Vec &x, Vec *g, Mat *h, double mix_wgt){ double eta = x.dot(beta); double lognc = lse2(0, eta); double ans = y? eta : 0; ans -= lognc; if(g){ double p = exp(eta-lognc); g->axpy(x, mix_wgt* (y-p)); if(h){ double q = 1-p; h->add_outer( x,x, -mix_wgt * p*q);}} return mix_wgt * ans; }
void dot() { const U size = Vec::SIZE; using T = typename Vec::Scalar; T res = 0; Vec vec; for(U i = 0; i < size; i++) { T x = i * 666 + 1; vec[i] = x; res += x * x; } ANKI_TEST_EXPECT_EQ(vec.dot(vec), res); }
bool UVSphere::isIntersect(const Ray& r, float tmin, float tmax, float time)const{ Vec temp = r.origin() - center; float a = r.direction().dot(r.direction()); float b = 2 * r.direction().dot(temp); float c = temp.dot(temp) - radius * radius; float discriminant = b*b - 4*a*c; if(discriminant > 0){ discriminant = sqrt(discriminant); float t = (-b -discriminant) /(2*a); if(t < tmin) t = (-b + discriminant) / (2*a); if(t < tmin || t > tmax) return false; return true; } return false; }
//calctulates refractions. Recursively calls RT_Trace Color RT_transmit(Figure* obj, const Ray& ray, const Vec& i, const Vec& normal, bool inside, double depth) { Color returnColor = Color(0, 0, 0); if (obj->isT()) { double ratio = 0; Ray transmittedRay = Ray(); double dir = 1.0; if (!inside) { ratio = SPACE_INDEX / obj->getIOR(); } else { ratio = obj->getIOR() / SPACE_INDEX; dir = -1.0; } Vec* norm = normal.scale(dir); Vec* V = ray.getV2().normalize(ray.getV1()); double dp = norm->dot(*V); double rsqrd = pow(ratio, 2.0); double coeff = (ratio * dp) - pow(((1 - rsqrd) + (rsqrd * pow(dp, 2.0))), 0.5); Vec* scaledN = norm->scale(coeff); Vec* rV = V->scale(ratio); Vec* T = scaledN->sub(*rV); Vec* dest = i.add(*T); Vec* iCopy = new Vec(i); Ray* tranRay = new Ray(*iCopy, *dest); if (inside) { tranRay->setInside(nullptr); } else tranRay->setInside(obj); returnColor = RT_Trace(*tranRay, depth + 1); delete(scaledN); delete(rV); delete(V); delete(T); delete(dest); delete(iCopy); delete(tranRay); delete(norm); } return returnColor; }
Vec RQR_Multiply(const VECTOR &v, const SparseKalmanMatrix &RQR, const SparseVector &Z, double H) { int state_dim = Z.size(); if(v.size() != state_dim + 2) { report_error("wrong sizes in RQR_Multiply"); } // Partition v = [eta, epsilon, 0] ConstVectorView eta(v, 0, state_dim); double epsilon = v[state_dim]; // Partition this Vec RQRZ = RQR * Z.dense(); double ZRQRZ_plus_H = Z.dot(RQRZ) + H; Vec ans(v.size()); VectorView(ans, 0, state_dim) = (RQR * eta).axpy(RQRZ, epsilon); ans[state_dim] = RQRZ.dot(eta) + ZRQRZ_plus_H * epsilon; return ans; }
void ArPosteriorSampler::draw_phi_univariate() { int p = model_->phi().size(); Vec phi = model_->phi(); if (!model_->check_stationary(phi)) { report_error("ArPosteriorSampler::draw_phi_univariate was called with an " "illegal initial value of phi. That should never happen."); } const Spd &xtx(model_->suf()->xtx()); const Vec &xty(model_->suf()->xty()); for (int i = 0; i < p; ++i) { double initial_phi = phi[i]; double lo = -1; double hi = 1; // y - xb y - xb // bt xtx b - 2 bt xty + yty // bt xtx b = sum_i sum_j beta[i] beta[j] xtx[i, j] // = beta [i]^2 xtx[i,i] + 2 * sum_{j != i} beta[i] xtx[i, j] * beta[j] // - 2 * beta[i] * xty[i]; // mean is (xty[i] - sum_{j != i} ) double ivar = xtx(i, i); double mu = (xty[i] - (phi.dot(xtx.col(i)) - phi[i] * xtx(i, i))) / ivar; bool ok = false; while (!ok) { double candidate = rtrun_norm_2_mt(rng(), mu, sqrt(1.0/ivar), lo, hi); phi[i] = candidate; if (ArModel::check_stationary(phi)) { ok = true; } else { if (candidate > initial_phi) hi = candidate; else lo = candidate; } } } model_->set_phi(phi); }
Vec trace(const Ray& r, const int index, const int num_samps) { // ray-sphere intersection double t; if (!intersect(r, t)) return Vec(); // compute the intersection data const Vec x = r.o + r.d * t, n = (x - sph.p).normalized(), w = -r.d; // compute Fresnel transmittance at point of emergence const double T21 = 1.0 - fresnel(w.dot(n), eta); // integration of the BSSRDF over the surface unsigned int xi = next_rand(index); Vec result; for (int i = 0; i < num_samps; i++) { // generate a sample Vec sp, sn, sw; sample(i, Vec(hal(2, index), hal(3, index), 0.0), sp, sn); sw = Vec(1, 1, -0.5).normalized(); // directional light source const double radiance = 8.0*PI; const double cos_wi_n = sn.dot(sw); if (cos_wi_n > 0.0) { // Russian roulette (note that accept_prob can be any value in (0, 1)) const double accept_prob = exp(-(sp - x).len() * min_sigma_tr); if ((xi / rand_range) < accept_prob) { const double T12 = 1.0 - fresnel(cos_wi_n, eta); const double Li_cos = T12 * radiance * cos_wi_n / (samplePDF * accept_prob); for (int j = 0; j < 3; j++) result[j] += bssrdf(sp, sn, sw, x, n, w, j) * Li_cos; // reciprocal evaulation with the reciprocity hack //for (int j = 0; j < 3; j++) result[j] += 0.5 * (bssrdf(sp, sn, sw, x, n, w, j) + bssrdf(x, n, w, sp, sn, sw, j)) * Li_cos; } xi = next_rand(xi); } } return T21 * result / (double)num_samps; }
//calculates reflections. Recursively calls RT_Trace Color RT_reflect(Figure* obj, const Ray& ray, const Vec& i, const Vec& normal, double depth) { if (obj->isR()) { Vec* V = ray.getV2().normalize(ray.getV1()); Vec* Q = normal.scale(normal.dot(*V)); Vec* S = Q->sub(*V); Vec* S2 = S->scale(2.0); Vec* R = V->add(*S2); Vec* inter = new Vec(i); Vec* dest = R->add(*inter); Ray* theRay = new Ray(*inter, *dest); Color newColor = RT_Trace(*theRay, depth + 1).mult(obj->getRef()); delete(V); delete(Q); delete(S); delete(S2); delete(R); delete(inter); delete(dest); delete(theRay); return newColor; } else return Color(0, 0, 0); }
//---------------------------------------------------------------------- double LSB::log_model_prob(const Selector &g)const{ double num = vs_->logp(g); if(num==BOOM::negative_infinity()) return num; Ominv = g.select(pri_->siginv()); num += .5*Ominv.logdet(); if(num == BOOM::negative_infinity()) return num; Vec mu = g.select(pri_->mu()); Vec Ominv_mu = Ominv * mu; num -= .5*mu.dot(Ominv_mu); bool ok=true; iV_tilde_ = Ominv + g.select(suf()->xtx()); Mat L = iV_tilde_.chol(ok); if(!ok) return BOOM::negative_infinity(); double denom = sum(log(L.diag())); // = .5 log |Ominv| Vec S = g.select(suf()->xty()) + Ominv_mu; Lsolve_inplace(L,S); denom-= .5*S.normsq(); // S.normsq = beta_tilde ^T V_tilde beta_tilde return num-denom; }
/** Phong lighting model ** @param pt intersection point ** @param n normal of pt ** @param light pointer to the light source ** @param obj pointer to the object ** @param ray ray ** @return color calculated from local shading using phong model **/ Vec phongModel(Vec pt, Vec n, Light* light, Shape* obj, Ray ray) { float t; Vec v = ray.getOrig() - pt; v = v.normalize(); // vector to viewer Vec l = light->pos - pt; float dis = l.mag(); // distance to light source l = l.normalize(); // vector to light source Vec ir = n * (2 * n.dot(l)) - l; ir = ir.normalize(); // vector of ideal reflector Vec intensity = light->intensity; // light intensity Ray shadowRay(pt, l, 0, 9999, ShadowRay); // shadow ray to the light source float f = light->attenFac(dis); // attentuation factor Pigment p = obj->getPigment(); Vec obj_color; // object color float scalar; int tmp; if (p.type == SOLID) { obj_color = p.c1; } else if (p.type == CHECKER) { scalar = p.width; tmp = (int)(pt.x/scalar) + (int)(pt.y/scalar) + (int)(pt.z/scalar); if (tmp % 2 == 0) obj_color = p.c1; else obj_color = p.c2; } else if (p.type == TEXTURE) { if (obj->getType() == sphere) obj_color = sphereMapping(pt, n, p); } // get the surface parameters SurFinish appearance = obj->getSurFin(); float Ka = appearance.ambient; // ambient coefficient float Kd = appearance.diffuse; // diffuse coefficient float Ks = appearance.specular; // specular coefficient float shininess = appearance.shininess; // for each object in the scene, see if is blocks the light if (light->type != ambient) { for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) { if ((*its) == obj) continue; if ((*its)->getType() == sphere) { Sphere *shape = dynamic_cast<Sphere*>(*its); if (shape->intersect(shadowRay, t) && t < dis) return black; } else if((*its)->getType() == polyhedron){ Polyhedron *shape = dynamic_cast<Polyhedron*>(*its); if (shape->intersect(shadowRay, t) && t < dis) { return black; } } else if((*its)->getType() == triangleMesh){ TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its); if (shape->intersect(shadowRay, t) && shadowRay.calcDest(t).mag() < dis) return black; } } } Vec diffuse(0.0, 0.0, 0.0); Vec specular(0.0, 0.0, 0.0); // if the light is casted from front if (n.dot(l) > 0) { diffuse = intensity * (Kd * n.dot(l) * f); specular = white * (Ks * pow(v.dot(ir),shininess) * f); // update light color intensity.x = (light->type != ambient) ? diffuse.x * obj_color.x + specular.x : obj_color.x * Ka; intensity.y = (light->type != ambient) ? diffuse.y * obj_color.y + specular.y : obj_color.y * Ka; intensity.z = (light->type != ambient) ? diffuse.z * obj_color.z + specular.z : obj_color.z * Ka; } // if the light is casted from behind else { intensity.x = (light->type != ambient) ? black.x : obj_color.x * Ka; intensity.y = (light->type != ambient) ? black.y : obj_color.y * Ka; intensity.z = (light->type != ambient) ? black.z : obj_color.z * Ka; } return intensity; }
ftype angle(const Vec& a, const Vec& b) { return acos(a.dot(b) / sqrt(a.norm_sq()*b.norm_sq())); }