/** * calculate a square of the distance between positions * this function is a part of the trait of ParticleSpace. * @param pos1 * @param pos2 * @return a square of the distance */ Real distance_sq( const Real3& pos1, const Real3& pos2) const { Real retval(0); const Real3& edges(edge_lengths()); for (Real3::size_type dim(0); dim < 3; ++dim) { const Real edge_length(edges[dim]); const Real diff(pos2[dim] - pos1[dim]), half(edge_length * 0.5); if (diff > half) { retval += pow_2(diff - edge_length); } else if (diff < -half) { retval += pow_2(diff + edge_length); } else { retval += pow_2(diff); } } return retval; }
void OblatePerfectEllipsoid::evalDeriv(double tau, double* G, double* deriv, double* deriv2) const { // G is defined by eq.27 in de Zeeuw(1985), except that we use // tau = {tau_deZeeuw}+{gamma_deZeeuw}, which ranges from 0 to inf. if(tau<0) throw std::invalid_argument("Error in OblatePerfectEllipsoid: " "incorrect value of tau"); double c2 = pow_2(minorAxis); double fac = mass/minorAxis*(2./M_PI); double tauc = tau/c2; double arct = 1; // value for the limiting case tau==0 if(tau > 1e-16) { double sqtc = sqrt(tauc); arct = atan(sqtc)/sqtc; } if(G) *G = fac * arct; if(deriv) *deriv = tauc > 1e-8 ? fac * 0.5 * (1 / (1+tauc) - arct) / tau : fac * (-1./3 + 2./5 * tauc) / c2; // asymptotic expansion for tau->0 if(deriv2!=NULL) *deriv2 = tauc > 1e-5 ? fac * 0.75 * (arct - (1+(5./3)*tauc) / pow_2(1+tauc)) / pow_2(tau) : fac * (2./5 - 6./7 * tauc) / pow_2(c2); }
OblatePerfectEllipsoid::OblatePerfectEllipsoid (double _mass, double major_axis, double minor_axis) : mass(_mass), coordSys(pow_2(major_axis)-pow_2(minor_axis)), minorAxis(minor_axis) { if(minor_axis<=0 || minor_axis>=major_axis) throw std::invalid_argument("Error in OblatePerfectEllipsoid: " "minor axis must be positive and strictly smaller than major axis"); }
// scaling transformation for integration over volume coord::PosCyl unscaleCoords(const double vars[], double* jac) { const double scaledr = vars[0]; const double costheta = vars[1] * 2 - 1; const double r = exp( 1/(1-scaledr) - 1/scaledr ); if(jac) *jac = (r<1e-100 || r>1e100) ? 0 : // if near r=0 or infinity, set jacobian to zero 4*M_PI * pow_3(r) * (1/pow_2(1-scaledr) + 1/pow_2(scaledr)); return coord::PosCyl( r * sqrt(1-pow_2(costheta)), r * costheta, vars[2] * 2*M_PI); }
int pow_2(int x) { if (x == 0) { return 1; } else if (x % 2) { return 2 * pow_2(x - 1); } else /* even */ { int r = pow_2(x / 2); return r * r; } }
bool test_potential(const potential::BasePotential& potential, const coord::PosVelT<coordSysT>& initial_conditions, const double total_time, const double timestep) { std::cout << potential.name()<<" "<<coordSysT::name()<<" ("<<initial_conditions<<")\n"; double ic[6]; initial_conditions.unpack_to(ic); std::vector<coord::PosVelT<coordSysT> > traj; int numsteps = orbit::integrate(potential, initial_conditions, total_time, timestep, traj, integr_eps); double avgH=0, avgLz=0, dispH=0, dispLz=0; for(size_t i=0; i<traj.size(); i++) { double H =totalEnergy(potential, traj[i]); double Lz=coord::Lz(traj[i]); avgH +=H; dispH +=pow_2(H); avgLz+=Lz; dispLz+=pow_2(Lz); if(output) { double xv[6]; coord::toPosVelCar(traj[i]).unpack_to(xv); std::cout << i*timestep<<" " <<xv[0]<<" "<<xv[1]<<" "<<xv[2]<<" "<< xv[3]<<" "<<xv[4]<<" "<<xv[5]<<" "<<H<<" "<<Lz<<" "<<potential.density(traj[i])<<"\n"; } } avgH/=traj.size(); avgLz/=traj.size(); dispH/=traj.size(); dispLz/=traj.size(); dispH= sqrt(std::max<double>(0, dispH -pow_2(avgH))); dispLz=sqrt(std::max<double>(0, dispLz-pow_2(avgLz))); bool completed = traj.size()>0.99*total_time/timestep; bool ok = dispH<eps && (dispLz<eps || !isAxisymmetric(potential)); if(completed) std::cout <<numsteps<<" steps, "; else if(numsteps>0) { std::cout <<"\033[1;33mCRASHED\033[0m after "<<numsteps<<" steps, "; // this may naturally happen in the degenerate case when an orbit with zero angular momentum // approaches the origin -- not all combinations of potential and coordinate system // can cope with this. If that happens for a non-degenerate case, this is an error. if(avgLz!=0) ok=false; } else { // this may happen for an orbit started at r==0 in some potentials where the force is singular, // otherwise it's an error if(toPosSph(initial_conditions).r != 0) { std::cout <<"\033[1;31mFAILED\033[0m, "; ok = false; } } std::cout << "E=" <<avgH <<" +- "<<dispH<<", Lz="<<avgLz<<" +- "<<dispLz<< (ok? "" : " \033[1;31m**\033[0m") << "\n"; return ok; }
void OblatePerfectEllipsoid::evalScalar(const coord::PosProlSph& pos, double* val, coord::GradProlSph* deriv, coord::HessProlSph* deriv2) const { assert(&(pos.coordsys)==&coordSys); // make sure we're not bullshited double absnu = fabs(pos.nu); double signu = pos.nu>=0 ? 1 : -1; double lmn = pos.lambda-absnu; if(absnu>coordSys.delta || pos.lambda<coordSys.delta) throw std::invalid_argument("Error in OblatePerfectEllipsoid: " "incorrect values of spheroidal coordinates"); double Glambda, dGdlambda, d2Gdlambda2, Gnu, dGdnu, d2Gdnu2; // values and derivatives of G(lambda) and G(|nu|) evalDeriv(pos.lambda, &Glambda, &dGdlambda, &d2Gdlambda2); evalDeriv(absnu, &Gnu, &dGdnu, &d2Gdnu2); double coef=(Glambda-Gnu)/pow_2(lmn); // common subexpression if(val!=NULL) *val = (absnu*Gnu - pos.lambda*Glambda) / lmn; if(deriv!=NULL) { deriv->dlambda = coef*absnu - dGdlambda*pos.lambda / lmn; deriv->dnu = (-coef*pos.lambda + dGdnu*absnu / lmn) * signu; deriv->dphi = 0; } if(deriv2!=NULL) { deriv2->dlambda2 = (2*absnu *(-coef + dGdlambda/lmn) - d2Gdlambda2*pos.lambda) / lmn; deriv2->dnu2 = (2*pos.lambda*(-coef + dGdnu /lmn) + d2Gdnu2 *absnu ) / lmn; deriv2->dlambdadnu = ((pos.lambda+absnu)*coef - (pos.lambda*dGdlambda + absnu*dGdnu) / lmn ) / lmn * signu; } }
int bin_to_int(char *pbin){ int length=0; int sum=0; length = strlen(pbin); for(int i=0; i<length-1;i++ )sum += pow_2(2,i); return(sum); }
int main(int argc, char *argv[]) { CLIENT *rpc_clnt; /* */ int int_arg; int *int_res; repeatargs rpt_arg; String *char_res; powargs pow_arg; sillypowres *pow_res; if (argc != 2) { fprintf(stderr, "usage: %s rpc-server\n", argv[0]); exit(1); } if ((rpc_clnt = clnt_create(argv[1], TEST_PROG1, TEST_VERS2, "tcp")) == NULL) { perror(argv[1]); exit(2); } fprintf(stderr, "Calling FNULL() ... "); if (fnull_2(&int_arg /* ignored */, rpc_clnt) == NULL) { perror("fnull_2"); exit(3); } fprintf(stderr, "done\n"); int_arg = 21; fprintf(stderr, "Calling DOUBLE(%d) = ", int_arg); if ((int_res = double_2(&int_arg, rpc_clnt)) == NULL) { perror("double_2"); exit(4); } fprintf(stderr, "%d\n", *int_res); rpt_arg.num = 4; rpt_arg.str = "Hi!"; fprintf(stderr, "Calling REPEAT(%d, %s) = ", rpt_arg.num, rpt_arg.str); if ((char_res = repeat_2(&rpt_arg, rpc_clnt)) == NULL) { perror("repeat_2"); exit(5); } fprintf(stderr, "%s\n", *char_res); pow_arg.x = 2.0; pow_arg.y = 4.0; fprintf(stderr, "Calling POW(%f, %f) = ", pow_arg.x, pow_arg.y); if ((pow_res = pow_2(&pow_arg, rpc_clnt)) == NULL || pow_res->res != STATUS_OK) { perror("pow_2"); exit(6); } fprintf(stderr, "%f (%s)\n", pow_res->sillypowres_u.powok.result, pow_res->sillypowres_u.powok.message); clnt_destroy(rpc_clnt); exit(0); }
double BasePotentialSphericallySymmetric::enclosedMass(const double radius) const { if(radius==INFINITY) return totalMass(); double dPhidr; evalDeriv(radius, NULL, &dPhidr); return pow_2(radius)*dPhidr; }
Real GreensFunction3D::ip_r(Real r, Real t) const { const Real D( getD() ); const Real Dt4( 4.0 * D * t ); const Real Dt4r( 1.0 / Dt4 ); const Real sqrtDt4( sqrt( Dt4 ) ); const Real sqrtDt4r( 1.0 / sqrtDt4 ); const Real num1a( exp( - pow_2( r - r0 ) * Dt4r ) ); const Real num1b( exp( - pow_2( r + r0 ) * Dt4r ) ); const Real den1( r0 * sqrt( M_PI ) ); const Real term1( sqrtDt4 * ( - num1a + num1b ) / den1 ); const Real term2( erf( ( r - r0 ) * sqrtDt4r ) ); const Real term3( erf( ( r + r0 ) * sqrtDt4r ) ); return ( term1 + term2 + term3 ) * .5; }
static const Real p_free_max(Real r, Real r0, Real t, Real D) { const Real Dt4(4.0 * D * t); const Real Dt4Pi(Dt4 * M_PI); const Real term1(exp(- pow_2(r - r0) / Dt4)); const Real term2(1.0 / sqrt(Dt4Pi * Dt4Pi * Dt4Pi)); return term1 * term2; }
static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw) { int j; unsigned m2 = 0; for (j = 0; j < outw; j++) m2 += pow_2(main_line[j] - ref_line[j]); return m2; }
static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_line, int outw) { int j; uint64_t m2 = 0; const uint16_t *main_line = (const uint16_t *) _main_line; const uint16_t *ref_line = (const uint16_t *) _ref_line; for (j = 0; j < outw; j++) m2 += pow_2(main_line[j] - ref_line[j]); return m2; }
Real GreensFunction3DRadInf::p_int_r(Real r, Real t) const { const Real kf(getkf()); const Real D(getD()); const Real sigma(getSigma()); const Real alpha(getalpha()); const Real kD(getkD()); const Real Dt(D * t); const Real kf_kD(kf + kD); const Real Dt4(4.0 * Dt); const Real sqrtDt4(sqrt(Dt4)); const Real ksigma2(2.0 * kf * sigma); const Real alphasqrtt(alpha * sqrt(t)); const Real r_r0__2s___sqrtDt4((r - 2.0 * sigma + r0) / sqrtDt4); const Real r_r0__sqrtDt4((r - r0) / sqrtDt4); const Real r0_s__sqrtDt4((r0 - sigma) / sqrtDt4); const Real term1((expm1(- pow_2(r_r0__2s___sqrtDt4 )) - expm1(- pow_2(r_r0__sqrtDt4))) * sqrt(Dt / M_PI)); const Real erf_r_r0__2s___sqrtDt4(erf(r_r0__2s___sqrtDt4)); const Real term2(kf_kD * r0 * erf(r_r0__sqrtDt4) + kf_kD * r0 * erf_r_r0__2s___sqrtDt4 + ksigma2 * (erf(r0_s__sqrtDt4) - erf_r_r0__2s___sqrtDt4)); const Real term3(kf * sigma * W(r0_s__sqrtDt4, alphasqrtt) - (kf * r + kD * (r - sigma)) * W(r_r0__2s___sqrtDt4, alphasqrtt)); const Real result((1 / r0) * (term1 + (1 / kf_kD) * ((0.5 * term2) + term3))); return result; }
double BasePotential::densitySph(const coord::PosSph &pos) const { coord::GradSph deriv; coord::HessSph deriv2; eval(pos, NULL, &deriv, &deriv2); double sintheta=sin(pos.theta); double derivr_over_r = deriv.dr/pos.r; double derivtheta_cottheta = deriv.dtheta*cos(pos.theta)/sintheta; if(sintheta==0) derivtheta_cottheta = deriv2.dtheta2; double angular_part = (deriv2.dtheta2 + derivtheta_cottheta + deriv2.dphi2/pow_2(sintheta))/pow_2(pos.r); if(pos.r==0) { if(deriv.dr==0) // otherwise should remain infinite derivr_over_r = deriv2.dr2; angular_part=0; ///!!! is this correct assumption? } double result = deriv2.dr2 + 2*derivr_over_r + angular_part; if(fabs(result) < 1e-12 * (fabs(deriv2.dr2) + fabs(2*derivr_over_r) + fabs(angular_part)) ) result = 0; // dominated by roundoff errors return result / (4*M_PI); }
void merge(int a[], int b[], int m, int n) { int a_size=m; int b_size=n; while (n != 0 && m != 0) { printf("%d %d\n",m,n); if (!(m > n)) { int t = log_2(n / m); int i = n + 1 - pow_2(t); if (a[m-1] < b[i-1]) { printf("Decreasing n\n"); n = n - pow_2(t); } else { int k = binsearch(i-1,n,a[m-1],b)+1; printf("Inserting %d into b at %d\n", a[m-1], k-1); insert(a[m-1],k-1,b_size,b); b_size++; m = m - 1; n = k; } } else /* m > n */ { int t = log_2(m / n); int i = m + 1 - pow_2(t); if (b[n-1] < a[i-1]) { printf("Decreasing m\n"); m = m - pow_2(t); } else { int k = binsearch(i-1,m,b[n-1],a)+1; printf("Inserting %d into a at %d\n", b[n-1], k-1); insert(b[n-1],k-1,a_size,a); a_size++; n = n - 1; m = k; } } } printf("%d %d\n",m,n); }
Real GreensFunction3D::p_r(Real r, Real t) const { const Real D( getD() ); const Real Dt( D * t ); const Real Dt4( 4.0 * Dt ); const Real rr04( 4.0 * r * r0 ); const Real mrr0sq_over_4Dt( - pow_2( r + r0 ) / Dt4 ); const Real num1( expm1( mrr0sq_over_4Dt ) ); const Real num2( expm1( mrr0sq_over_4Dt + rr04 / Dt4 ) ); const Real den( rr04 * sqrt( M_PI * M_PI * M_PI * Dt ) ); const Real jacobian( 2.0 * r * r * M_PI ); return jacobian * ( - num1 + num2 ) / den; }
double BasePotential::densityCyl(const coord::PosCyl &pos) const { coord::GradCyl deriv; coord::HessCyl deriv2; eval(pos, NULL, &deriv, &deriv2); double derivR_over_R = deriv.dR/pos.R; double deriv2phi_over_R2 = deriv2.dphi2/pow_2(pos.R); if(pos.R==0) { if(deriv.dR==0) // otherwise should remain infinite derivR_over_R = deriv2.dR2; deriv2phi_over_R2 = 0; } double result = (deriv2.dR2 + derivR_over_R + deriv2.dz2 + deriv2phi_over_R2); if(fabs(result) < 1e-12 * (fabs(deriv2.dR2) + fabs(derivR_over_R) + fabs(deriv2.dz2) + fabs(deriv2phi_over_R2)) ) result = 0; // dominated by roundoff errors return result / (4*M_PI); }
// return the scaled radius variable to be used as the integration limit static double scaledr_from_r(const double r) { const double y = log(r); return fabs(y)<1 ? // two cases depending on whether |y| is small or large 1/(1 + sqrt(1+pow_2(y*0.5)) - y*0.5) : // y is close to zero 0.5 + sqrt(0.25+pow_2(1/y))*math::sign(y) - 1/y; // y is large (or even +-infinity) }
static inline double get_psnr(double mse, uint64_t nb_frames, int max) { return 10.0 * log10(pow_2(max) / (mse / nb_frames)); }