コード例 #1
0
ファイル: n_body.c プロジェクト: 8l/insieme
int main() {

	// distribute bodies in space (randomly)
	for(int i=0; i<N; i++) {
		B[i].m = (i < L)?1:0;
		B[i].pos = triple_rand();
//		B[i].pos = (position) { 0, -10 + 20*(i/2), -10 + 20*(i%2) };		// for debugging!
		B[i].v   = triple_zero();
	}
	// run simulation for M steps
	#pragma omp parallel
	for(int i=0; i<M; i++) {
		
		// set forces to zero
		#pragma omp for
		for(int j=0; j<N; j++) {
			F[j] = triple_zero();
		}

		// reset private copy
		for(int j=0; j<N; j++) {
			pF[j] = triple_zero();
		}

		// compute forces for each body (very naive)
		#pragma omp for
		for(int j=0; j<min(N,L); j++) {
			for(int k=0; k<N; k++) {

				if(j!=k) {
					// comput distance vector
					triple dist = SUB(B[k].pos, B[j].pos);

					// compute absolute distance
					double r = ABS(dist);
				
					// compute strength of force (G = 1 (who cares))
					//			F = G * (m1 * m2) / r^2
					double f = (B[j].m * B[k].m) / (r*r);

					// compute current contribution to force
					//force cur = MULS(NORM(dist), f);
					double s = f / r;
					force cur = MULS(dist,s);

					// accumulate force
					pF[j] = ADD(pF[j], cur);
				}
			}
		}

		// aggregate local data
		#pragma omp critical
		for(int j=0; j<N; j++) {
			F[j] = ADD(pF[j],F[j]);
		}

		// apply forces
		#pragma omp for
		for(int j=0; j<min(N,L); j++) {
			// update speed
			//		F = m * a
			//		a = F / m		// m=1
			//		v' = v + a
			B[j].v = ADD(B[j].v, DIVS(F[j], B[j].m));

			// update position
			//		pos = pos + v * dt		// dt = 1
			B[j].pos = ADD(B[j].pos, B[j].v);
		}

/*		// debug print of positions and speed
		for(int i=0; i<N; i++) {
			printf("%2d - ", i); 
			triple_print(B[i].pos);
			printf(" - ");
			triple_print(B[i].v);
			printf("\n");
		}
		printf("\n");
*/

	}

	// check result (impulse has to be zero)
	impulse sum = triple_zero();
	for(int i=0; i<N; i++) {
		// impulse = m * v
		sum = ADD(sum, MULS(B[i].v,B[i].m));
	}
	int success = EQ(sum, triple_zero());
	printf("Verification: %s\n", ((success)?"OK":"ERR"));
	if (!success) {
		triple_print(sum); printf(" should be (0,0,0)\n");
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
コード例 #2
0
ファイル: adm_tools.c プロジェクト: Netflix/vmaf
void adm_decouple_s(const adm_dwt_band_t_s *ref, const adm_dwt_band_t_s *dis, const adm_dwt_band_t_s *r, const adm_dwt_band_t_s *a, int w, int h, int ref_stride, int dis_stride, int r_stride, int a_stride)
{
#ifdef ADM_OPT_AVOID_ATAN
    const float cos_1deg_sq = cos(1.0 * M_PI / 180.0) * cos(1.0 * M_PI / 180.0);
#endif
    const float eps = 1e-30;

    int ref_px_stride = ref_stride / sizeof(float);
    int dis_px_stride = dis_stride / sizeof(float);
    int r_px_stride = r_stride / sizeof(float);
    int a_px_stride = a_stride / sizeof(float);

    float oh, ov, od, th, tv, td;
    float kh, kv, kd, tmph, tmpv, tmpd;
#ifdef ADM_OPT_AVOID_ATAN
    float ot_dp, o_mag_sq, t_mag_sq;
#else
    float oa, ta, diff;
#endif
    int angle_flag;
    int i, j;

    for (i = 0; i < h; ++i) {
        for (j = 0; j < w; ++j) {
            oh = ref->band_h[i * ref_px_stride + j];
            ov = ref->band_v[i * ref_px_stride + j];
            od = ref->band_d[i * ref_px_stride + j];
            th = dis->band_h[i * dis_px_stride + j];
            tv = dis->band_v[i * dis_px_stride + j];
            td = dis->band_d[i * dis_px_stride + j];

            kh = DIVS(th, oh + eps);
            kv = DIVS(tv, ov + eps);
            kd = DIVS(td, od + eps);

            kh = kh < 0.0f ? 0.0f : (kh > 1.0f ? 1.0f : kh);
            kv = kv < 0.0f ? 0.0f : (kv > 1.0f ? 1.0f : kv);
            kd = kd < 0.0f ? 0.0f : (kd > 1.0f ? 1.0f : kd);

            tmph = kh * oh;
            tmpv = kv * ov;
            tmpd = kd * od;
#ifdef ADM_OPT_AVOID_ATAN
            /* Determine if angle between (oh,ov) and (th,tv) is less than 1 degree.
             * Given that u is the angle (oh,ov) and v is the angle (th,tv), this can
             * be done by testing the inequvality.
             *
             * { (u.v.) >= 0 } AND { (u.v)^2 >= cos(1deg)^2 * ||u||^2 * ||v||^2 }
             *
             * Proof:
             *
             * cos(theta) = (u.v) / (||u|| * ||v||)
             *
             * IF u.v >= 0 THEN
             *   cos(theta)^2 = (u.v)^2 / (||u||^2 * ||v||^2)
             *   (u.v)^2 = cos(theta)^2 * ||u||^2 * ||v||^2
             *
             *   IF |theta| < 1deg THEN
             *     (u.v)^2 >= cos(1deg)^2 * ||u||^2 * ||v||^2
             *   END
             * ELSE
             *   |theta| > 90deg
             * END
             */
            ot_dp = oh * th + ov * tv;
            o_mag_sq = oh * oh + ov * ov;
            t_mag_sq = th * th + tv * tv;

            angle_flag = (ot_dp >= 0.0f) && (ot_dp * ot_dp >= cos_1deg_sq * o_mag_sq * t_mag_sq);
#else
            oa = atanf(DIVS(ov, oh + eps));
            ta = atanf(DIVS(tv, th + eps));

            if (oh < 0.0f)
                oa += (float)M_PI;
            if (th < 0.0f)
                ta += (float)M_PI;

            diff = fabsf(oa - ta) * 180.0f / M_PI;
            angle_flag = diff < 1.0f;
#endif
            if (angle_flag) {
                tmph = th;
                tmpv = tv;
                tmpd = td;
            }

            r->band_h[i * r_px_stride + j] = tmph;
            r->band_v[i * r_px_stride + j] = tmpv;
            r->band_d[i * r_px_stride + j] = tmpd;

            a->band_h[i * a_px_stride + j] = th - tmph;
            a->band_v[i * a_px_stride + j] = tv - tmpv;
            a->band_d[i * a_px_stride + j] = td - tmpd;
        }
    }
}