Esempio n. 1
0
double distance2(struct point* p, struct point* p1, struct point* p2)
{
    struct point proj;
    double length2;
    double tangent;


    length2 = length_squared(p1, p2);

    if ( length2 == 0.0 ) {
        // p1 == p2
        return length_squared(p, p1);
    }

    tangent = dot(p, p1, p2);
    tangent = tangent / length2;

    if ( tangent < 0.0 ) {
        // Beyond p1
        return length_squared(p, p1);
    } else if ( tangent > 1.0 ) {
        // Beyond p2
        return length_squared(p, p2);
    }

    projection(&proj, p1, p2, tangent);

    return length_squared(p, &proj);
}
Esempio n. 2
0
  Point SphereShape::sample_point_eye(const Point& eye,
      float u1, float u2, Normal& out_n) const
  {
    float dist_squared = length_squared(eye.v);
    if(dist_squared - this->radius * this->radius < 1e-3) {
      float ray_epsilon;
      return this->sample_point(u1, u2, out_n, ray_epsilon);
    }

    float dist = sqrt(dist_squared);
    float inv_dist = 1.f / dist;
    float cos_theta_max = sqrt(dist_squared - this->radius * this->radius) * inv_dist;

    Vec3 cone_vec = uniform_cone_sample(cos_theta_max, u1, u2);
    Vector cone_z = -Vector(eye.v) * inv_dist;
    Vector cone_x, cone_y;
    coordinate_system(cone_z, cone_x, cone_y);

    Vector ray_dir = cone_x * cone_vec.x + cone_y * cone_vec.y + cone_z * cone_vec.z;
    Ray ray(eye, ray_dir);
    float t_hit;
    if(!this->solve_hit_t(ray, t_hit)) {
      t_hit = dist;
    }

    Point pt = ray.point_t(t_hit);
    out_n = Normal(pt.v) / this->radius;
    return pt;
  }
Esempio n. 3
0
void RunCommonVectorOrQuaternionTests(std::string const& typeName)
{
    RunCommonArithmeticTests<T>(typeName);

    RunPerfTest<T, T>(typeName + " operator/", [](T* value, T const& param)
    {
        *value /= param;
    });

    RunPerfTest<float, T>(typeName + " length", [](float* value, T const& param)
    {
        *value += length(param);
    });

    RunPerfTest<float, T>(typeName + " length_squared", [](float* value, T const& param)
    {
        *value += length_squared(param);
    });

    RunPerfTest<T, T>(typeName + " dot", [](T* value, T const& param)
    {
        value->x = dot(*value, param);
    });

    RunPerfTest<T, T>(typeName + " normalize", [](T* value, T& param)
    {
        auto t = param;
        param = *value;
        *value = normalize(t);
    });
}
Esempio n. 4
0
void assign_formation(const box_formation& formation, units& group)
{
    auto down = -normalize(formation.direction) * formation.spacing;
    auto right = vec2f{-down[1], down[0]};
    int w_count = formation.width / formation.spacing;
    auto lu_corner = formation.origin - right * w_count * 0.5f;
    std::vector<bool> selected(group.size(), false);
    for (int y = 0; std::count(selected.begin(), selected.end(), false) > 0; ++y)
    {
        for (int x = 0; x != w_count; ++x)
        {
            auto goal = lu_corner + down * y + right * x;
            float distance = std::numeric_limits<float>::max();
            std::size_t found = 0;
            for (std::size_t i = 0; i != group.size(); ++i)
                if (not selected[i])
                {
                    float distance2 = length_squared(group[i].position - goal);
                    if (distance2 >= distance)
                        continue;
                    distance = distance2;
                    found = i;
                }
            if (distance == std::numeric_limits<float>::max())
                return;
            group[found].target_position = goal;
            selected[found] = true;
        }
    }
}
Esempio n. 5
0
 Spectrum PointLight::sample_radiance(const Point& eye, float eye_epsilon,
     Vector& out_wi, float& out_pdf, ShadowTest& out_shadow,
     LightSample) const
 {
   out_wi = normalize(this->pt - eye);
   out_pdf = 1.f;
   out_shadow.init_point_point(eye, eye_epsilon, this->pt, 0.f);
   return this->intensity / length_squared(this->pt - eye);
 }
Esempio n. 6
0
 float SphereShape::point_eye_pdf(const Point& eye, const Vector& w) const {
   float dist_squared = length_squared(eye.v);
   if(dist_squared - this->radius * this->radius < 1e-3) {
     return Shape::point_eye_pdf(eye, w);
   }
   float dist = sqrt(dist_squared);
   float inv_dist = 1.f / dist;
   float cos_theta_max = sqrt(dist_squared - this->radius * this->radius) * inv_dist;
   return uniform_cone_pdf(cos_theta_max);
 }
sf::Vector2f QuantumField::friction(const PointMass& caller) const
{
    if (fp::not_equal(length_squared(caller.velocity), 0.f))
    {
        return unit(caller.velocity) * (-1.f) * 10.f;
    }
    else
    {
        return {0.f, 0.f};
    }
}
void TerminationCriterion::accumulate_inner( PatchData& pd, 
                                             double of_value,
                                             Vector3D* grad_array,
                                             MsqError& err )
{
  //if terminating on the norm of the gradient
  //currentGradL2NormSquared = HUGE_VAL;
  if (terminationCriterionFlag & (GRADIENT_L2_NORM_ABSOLUTE | GRADIENT_L2_NORM_RELATIVE)) 
  {
    currentGradL2NormSquared = length_squared(grad_array, pd.num_free_vertices()); // get the L2 norm
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Info -- gradient L2 norm: " << " "
                                   << RPM(std::sqrt(currentGradL2NormSquared)) << std::endl;
  }
  //currentGradInfNorm = 10e6;
  if (terminationCriterionFlag & (GRADIENT_INF_NORM_ABSOLUTE | GRADIENT_INF_NORM_RELATIVE)) 
  {
    currentGradInfNorm = Linf(grad_array, pd.num_free_vertices()); // get the Linf norm
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Info -- gradient Inf norm: " << " "
                                   << RPM(currentGradInfNorm) << std::endl;
  } 
  
  if (terminationCriterionFlag & VERTEX_MOVEMENT_RELATIVE)
  {
    maxSquaredInitialMovement = pd.get_max_vertex_movement_squared(
                               initialVerticesMemento, err );  MSQ_ERRRTN(err);
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Info -- max initial vertex movement: " << " "
                                   << RPM(maxSquaredInitialMovement) << std::endl;
  }
  
  previousOFValue = currentOFValue;
  currentOFValue = of_value;
  if (terminationCriterionFlag & OF_FLAGS) {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Info -- OF Value: " << " " << RPM(of_value) << " iterationCounter= " << iterationCounter << std::endl;
  }
  else if (grad_array) {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o OF Value: " << " " << RPM(of_value) << " iterationCounter= " << iterationCounter 
      //<< " terminationCriterionFlag= " << terminationCriterionFlag << " OF_FLAGS = " << OF_FLAGS
                                   << std::endl;
  }
  
  ++iterationCounter;
  if (timeStepFileType)
    write_timestep( pd, grad_array, err);
    
  if (plotFile.is_open()) 
    plotFile << iterationCounter 
     << '\t' << mTimer.since_birth() 
     << '\t' << of_value 
     << '\t' << std::sqrt( currentGradL2NormSquared ) 
     << '\t' << currentGradInfNorm 
     << '\t' << (maxSquaredMovement > 0.0 ? std::sqrt( maxSquaredMovement ) : 0.0)
     << '\t' << globalInvertedCount
     << std::endl;
}
Esempio n. 9
0
  float Shape::point_eye_pdf(const Point& eye, const Vector& w) const {
    DiffGeom diff_geom;
    float t_hit;
    float ray_epsilon;
    Ray ray(eye, w, 0.f);

    if(!this->hit(ray, t_hit, ray_epsilon, diff_geom)) {
      return 0.f;
    }

    return length_squared(ray.point_t(t_hit) - eye) /
      (abs_dot(w, diff_geom.nn) * this->area());
  }
Esempio n. 10
0
	void add_points(Sphere& s, u32 num, u32 stride, const void* points)
	{
		float rr = s.r*s.r;

		const char* pts = (const char*)points;
		for (u32 i = 0; i < num; ++i, pts += stride)
		{
			const Vector3& pi = *(const Vector3*)pts;

			rr = fmax(rr, length_squared(pi - s.c));
		}

		s.r = sqrtf(rr);
	}
Esempio n. 11
0
	void add_spheres(Sphere& s, u32 num, const Sphere* spheres)
	{
		for (u32 i = 0; i < num; ++i)
		{
			const Sphere& si = spheres[i];
			const f32 dist = length_squared(si.c - s.c);

			if (dist < (si.r + s.r) * (si.r + s.r))
			{
				if (si.r*si.r > s.r*s.r)
					s.r = sqrtf(dist + si.r*si.r);
			}
		}
	}
 struct point { T x, y; };ttt point<T> operator + (pca a, pca b) { return { a.x+b.x, a.y+b.y }; }ttt point<T> operator - (pca a, pca b) { return { a.x-b.x, a.y-b.y }; }ttt point<T> operator - (pca a) { return { -a.x, -a.y }; }ttt point<T> operator * (T a, pca b) { return { a*b.x, a*b.y }; }ttt std::pair<T,T> to_pair(pca a) { return { a.x, a.y }; }ttt bool operator == (pca a, pca b) { return to_pair(a) == to_pair(b); }ttt bool operator != (pca a, pca b) { return to_pair(a) != to_pair(b); }ttt bool operator <  (pca a, pca b) { return to_pair(a) <  to_pair(b); }ttt bool operator <= (pca a, pca b) { return to_pair(a) <= to_pair(b); }ttt bool operator >= (pca a, pca b) { return to_pair(a) >= to_pair(b); }ttt bool operator >  (pca a, pca b) { return to_pair(a) >  to_pair(b); }ttt T length_squared(pca p) { return p.x*p.x + p.y*p.y; }ttt double length(pca p) { return sqrt(length_squared(p)); }ttt point<T> normalized(pca a) { return (1 / length(a)) * a; }ttt T   dot(pca p, pca q) { return p.x * q.x + p.y * q.y; }ttt T cross(pca p, pca q) { return p.x * q.y - p.y * q.x; }ttt int ccw(pca a, pca b, pca c) { T x = cross(b - a, c - a); return x > 0 ? 1 : x < 0 ? -1 : 0; }
Esempio n. 13
0
float VectorT<T>::length() const
{
    return sqrt(length_squared());
}
Esempio n. 14
0
const double Vector2d::length() const{
	return sqrt(length_squared());
}
Esempio n. 15
0
void QuasiNewton::optimize_vertex_positions( PatchData& pd, MsqError& err )
{
  TerminationCriterion& term = *get_inner_termination_criterion();
  OFEvaluator& func = get_objective_function_evaluator();
  
  const double sigma = 1e-4;
  const double beta0 = 0.25;
  const double beta1 = 0.80;
  const double tol1 = 1e-8;
  const double epsilon = 1e-10;

  double norm_r; //, norm_g;
  double alpha, beta;
  double obj, objn;

  size_t i;
  
    // Initialize stuff
  const size_t nn = pd.num_free_vertices();
  double a[QNVEC], b[QNVEC], r[QNVEC];
  for (i = 0; i < QNVEC; ++i)
    r[i] = 0;
  for (i = 0; i <= QNVEC; ++i) {
    v[i].clear();
    v[i].resize( nn, Vector3D(0.0) );
    w[i].clear();
    w[i].resize( nn, Vector3D(0.0) );
  }
  d.resize( nn );
  mHess.resize( nn );  //hMesh(mesh);

  bool valid = func.update( pd, obj, v[QNVEC], mHess, err ); MSQ_ERRRTN(err);
  if (!valid) {
    MSQ_SETERR(err)("Initial objective function is not valid", MsqError::INVALID_MESH);
    return;
  }

  while (!term.terminate()) {
    pd.recreate_vertices_memento( mMemento, err ); MSQ_ERRRTN(err);
    pd.get_free_vertex_coordinates( w[QNVEC] );

    x = v[QNVEC];
    for (i = QNVEC; i--; ) {
      a[i] = r[i] * inner( &(w[i][0]), arrptr(x), nn );
      plus_eq_scaled( arrptr(x), -a[i], &v[i][0], nn );
    }
     
    solve( arrptr(d), arrptr(x) );
  
    for (i = QNVEC; i--; ) {
      b[i] = r[i] * inner( &(v[i][0]), arrptr(d), nn );
      plus_eq_scaled( arrptr(d), a[i]-b[i], &(w[i][0]), nn );
    }
    
    alpha = -inner( &(v[QNVEC][0]), arrptr(d), nn );  /* direction is negated */
    if (alpha > 0.0) {
      MSQ_SETERR(err)("No descent.", MsqError::INVALID_MESH);
      return;
    }
   
    alpha *= sigma;
    beta = 1.0;
    
    pd.move_free_vertices_constrained( arrptr(d), nn, -beta, err ); MSQ_ERRRTN(err);
    valid = func.evaluate( pd, objn, v[QNVEC], err ); 
    if (err.error_code() == err.BARRIER_VIOLATED)             
      err.clear();  // barrier violated does not represent an actual error here
    MSQ_ERRRTN(err);
    if (!valid ||
        (obj - objn < -alpha*beta - epsilon &&
         length( &(v[QNVEC][0]), nn ) >= tol1)) {
      
      if (!valid)  // function not defined at trial point
        beta *= beta0;
      else  // unacceptable iterate
        beta *= beta1;
      
      for (;;) {
        if (beta < tol1) {
          pd.set_to_vertices_memento( mMemento, err ); MSQ_ERRRTN(err);
          MSQ_SETERR(err)("Newton step not good", MsqError::INTERNAL_ERROR);
          return;
        }
      
        pd.set_free_vertices_constrained( mMemento, arrptr(d), nn, -beta, err ); MSQ_ERRRTN(err);
        valid = func.evaluate( pd, objn, err );
        if (err.error_code() == err.BARRIER_VIOLATED)             
          err.clear();  // barrier violated does not represent an actual error here
        MSQ_ERRRTN(err);
        if (!valid) // function undefined at trial point
          beta *= beta0;
        else if (obj - objn < -alpha*beta - epsilon) // unacceptlable iterate
          beta *= beta1;
        else
          break;
      }
    }
    
    for (i = 0; i < QNVEC-1; ++i) {
      r[i] = r[i+1];
      w[i].swap( w[i+1] );
      v[i].swap( v[i+1] );
    }
    w[QNVEC-1].swap( w[0] );
    v[QNVEC-1].swap( v[0] );
    
    func.update( pd, obj, v[QNVEC], mHess, err ); MSQ_ERRRTN(err);
    norm_r = length_squared( &(v[QNVEC][0]), nn );
    //norm_g = sqrt(norm_r);

    // checks stopping criterion 
    term.accumulate_patch( pd, err ); MSQ_ERRRTN(err);
    term.accumulate_inner( pd, objn, &v[QNVEC][0], err ); MSQ_ERRRTN(err);
  }
}
Esempio n. 16
0
int calc_hb(char o_str[256],int i, int j)
{
    int       l, /*ri, rj, gap,*/ h, near_h;
    
    /*char      bndtyp[3], acctyp[4], dontyp[4], space=' ';*/
    float     /*ca_d,*/ d, ha2,/*IM*/tmp_d, hd, ha, haaa_ang, daaa_ang;
    struct vect nearest, tmp_point, aromatic_axis, aa[MAXCON] /* acceptor antecedants*/;
    
    
    char buf1[20],buf2[20]; /* buffers for atomid routines */
    
    /* void find_ss()*/
    /* {*/
    /*     int i,j;*/
    /*     float d;*/
    short aromatic_flg;
    

    *o_str=0;
    
/*    if(i==203 && j==210)
    {
	printf("Testing from %s",atomid(i,buf1));
	printf(" to %s at start of calc_hb.\n",atomid(j,buf1));
    	debug=0;
    }
    else
	debug=0;
  */  

    d = length_squared( to(atom[i].p, atom[j].p) );
    if (debug==2)
	printf("don-acc distance ^2 = %f\n",d);
    
    if (d <= SQR(HBDIST))
	/* these are nearby ! */; /*IM begins*/
    else return(0);
    
    if (debug) printf("Acceptable distance\n");
    
    /* time to fill the acceptor array */
    daaa_ang= -99.9; /* reset it . . . . */
    
    aromatic_flg =  ( atom[j].aacode < TOTNAA )?(accepts[atom[j].aacode][atom[j].atmtyp] < 0):0;
    
    if (!aromatic_flg)    
    {
	for(l=0;l<MAXCON;l++)
	{
	    if (icon[j][l]>-1) 
	    {
		float daaa_tmp,aaa;
		char buf1[20],buf2[20];
		
		aa[l]=atom[icon[j][l] ].p;
		
		daaa_tmp= dot_product(
 						  to( aa[l], atom[j].p ), to( atom[i].p, atom[j].p )       ); /* = DA * A-AA * cos D-A-AA */
 			    aaa=vector_length ( to(aa[l], atom[j].p) );
 			    
 			    daaa_tmp/= aaa * sqrt( d); /* = cos D-A-AA */
 			    /* d= DA^2 */
 			    if (daaa_tmp>daaa_ang) daaa_ang=daaa_tmp; /* select lowest */
 			    if (aaa<0.8 || aaa > 6.0) 
				printf("WARNING: %5.2fA between %s and %s ((D..)A-AA bond).\n", aaa,atomid(icon[j][l],buf1),atomid(j,buf2));
 			   
 			}
 		    }
 		    if (daaa_ang > cosMIN_DAAA && daaa_ang>-99.9) 
 			if (!nnbflg)
 			    return(0);
 		    
 		    /*NB -99 was not originally used as a default whilst checking
 		      because we were wrongly trying to find a lowest possible 
 		      value */
 		    /*	printf("lowest daaa_ang %6.1f\n",daaa_ang);*/
 		}
 		else /*aromatic_hbond*/
 		{
 		    float daaa_tmp;
 		    /*if( !strncmp("4DFR/A0030-TRP CE3",atomid(j,buf1),18))
		      debug=1;*/
 		    
 		    if (debug){
 			printf("NOTE: %s is aromatic.\n",atomid(j,buf1));
 			printf("      connects to ");
 			for(l=0;l< atom[j].ncon;l++)
 			    printf("%s ",atomid(icon[j][l],buf1));
 			printf("\n");
 			
 		    }
 		    
 		    if ( accepts[atom[j].aacode][atom[j].atmtyp] != -1 )
 			printf("BUG: %s not registered as aromatic acceptor in \"aromatic_hbond\".\n",atomid(j,buf1));
 		    if ( atom[j].ncon!=2 && atom[j].ncon!=3 )
 			printf("BUG: %s has connectivity %d but is registered as aromatic.\n",atomid(j,buf1),atom[j].ncon);
 		    if ( atom[j].ncon==3 )
 		    {
 			aromatic_axis = unit_vector(
						    vector_plus( perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][1] ].p),
								vector_plus( perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][2] ].p),
									    perpendicular( atom[ icon[j][1] ].p, atom[j].p, atom[ icon[j][2] ].p) ) ) );
 			
 		    }
 		    else
 			aromatic_axis = unit_vector(perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][1] ].p));
 		    
 		    aa[0]= vector_plus( aromatic_axis, atom[j].p );
 		    aa[1]= vector_plus( float_times_vect( -1.0, aromatic_axis), atom[j].p );
 		    if (debug) printf("Perpendicular gives angles %5.3f and %5.3f with 1,2 / %d.\n",angle( atom[ icon[j][0] ].p, atom[j].p, aa[0] ), angle( atom[ icon[j][1] ].p, atom[j].p, aa[0] ) , atom[j].ncon);
 		    
 		    for(l=0;l<2;l++)
 		    {
 			daaa_tmp= dot_product( to( aa[l], atom[j].p), to( atom[i].p, atom[j].p ) ); /*=DA*A-AA*cosD-A-AA */
 			daaa_tmp /= sqrt(d); /* = cos D-A-AX */
 			if ( daaa_tmp > daaa_ang ) daaa_ang=daaa_tmp; /* select high values of cos D-A-AX ie low, better angles*/
 			if (debug) printf("Cosine of D-A-AX = %5.3f\n",daaa_tmp);
 		        if (debug) {
 			    printf("AX co-ods");
 			    printf(TF,VXYZ( aa[l] ) );
 			    printf("\n");
 			}
 			
 		    }
 		    if (daaa_ang < cosMAX_DAAX)
 		    {
 			if (debug)
 			    printf("Rejected because DAAX too high.\n");
 			if (!nnbflg)
 			    return(0);
 		    }
 		}
 		
 		
#define nearer(vector) { tmp_d=length_squared( to( atom[j].p, vector ) ); if (ha2>tmp_d) { ha2=tmp_d; nearest=vector; near_h = h;} }
 		
 		/* find the nearest possible H position on donor i */
 		ha2=100;
		/*	if (i==362) debug=1;
			else debug=0;*/
 		
 		if (debug && atom[i].hetflg) printf("H on %s %d  ",atom[i].resnam, atom[i].aanum);
 		if (debug) printf("%d Hs positioned\n",atom[i].nh);
 		
 		for(h=atom[i].h_ptr;h<atom[i].nh+atom[i].h_ptr;h++)
 		{
 		    if (debug)
 			printf("Hydrogen %d - type %d\n",atom[i].h_ptr,h_atm[h].typ);
 		    if (debug) printf("atom[i].nh %d, ].h_ptr %d, h %d\n",atom[i].nh,atom[i].h_ptr,h);
 		    
 		    switch (h_atm[h].typ)
 		    {
 		    case 0:
 			if (debug) printf("Atom %d (%s%s %d) has H %d missing\n",i,atom[i].atmnam,atom[i].resnam, atom[i].aanum, h);
 			/* no H present, must be HETATM */
 			;/* used to be ha2=1, cannot decide why */
 			break;
 		    case alternatives:
 			nearer( h_atm[h].a );
 			if (debug) printf("Checked alternative position: ha2 = %f\n",ha2);			    			    
 		    case fixed:
 			nearer( h_atm[h].p );
 			if (debug) printf("Checked default position: ha2 = %f\n",ha2);
 			break;
 		    case circle:
 			tmp_point= intersect(to(atom[i].p,h_atm[h].a),
 					     h_atm[h].p, atom[i].p, atom[j].p );
 			tmp_point= onto_sphere(tmp_point, h_atm[h].a,
 					       vector_length( to(h_atm[h].a, h_atm[h].p) ));
 			nearer(tmp_point);
 			tmp_point= vector_plus( tmp_point,
 					       float_times_vect(2,to(tmp_point, h_atm[h].a)));
 			nearer(tmp_point);
 			break;
 		    default:
 			printf("\nBUG: Unforseen htyp for atom %s in find_hb.\n", atomid(i,buf1));
 			printf("Please mail [email protected]\n");
			
 		    }/* end of switch*/
 		}/* end of h loop */
 		
 		if (ha2<100) /* ie if any Hydrogens have been found and
 				their positions taken.  Or, to put it 
 				another way, if it anything other than a hetatm 
 				which is flagged in .nh as having hydrogens but
 				has no positons in h_atm[].typ. */
 		{
 		    
 		    hd=vector_length( to(nearest, atom[i].p));
 		    ha=vector_length( to(nearest, atom[j].p));
 		    if (hd<0.9 || hd > 2.0) 
 		    {
 			printf("WARNING: %5.2fA between %s and %d (H).\n", hd, atomid(i,buf1),near_h-atom[i].h_ptr+1);		
 			if (debug) printf("atom[i].nh %d, ].h_ptr %d, h %d\n",atom[i].nh,atom[i].h_ptr,h);
 		    }
 		    
		    if (debug) printf("hd=%f,  ha=%f\n",hd,ha);
 		    
 		    if (!nnbflg)
 		    {
 			if (ha>MAX_HA)
 			    return(0);
 			if (debug)
 			    printf("HA length OK\n");
 			
 			if (dot_product( to(nearest, atom[i].p), 
 					to(nearest, atom[j].p) ) >= hd*ha*cosMIN_DHA)
 			    return(0);
 		    }
 		    
 		    haaa_ang=100.0; /* reset it . . . . */
 		    
 		    if (!aromatic_flg)
 		    {	
 			for(l=0;l<MAXCON;l++)
 			{
 			    if (icon[j][l]>-1) 
 			    {
 				float haaa_tmp,aaa;
 				aa[l]=atom[icon[j][l] ].p;
 				haaa_tmp= dot_product(
 						      to(atom[j].p, aa[l] ), to( atom[j].p, nearest )       );
 				aaa= vector_length( to(aa[l],atom[j].p) );
 				
 				haaa_tmp/= aaa *ha;
 				if (haaa_tmp<haaa_ang) haaa_ang=haaa_tmp; /* select lowest */
 				if (aaa<0.8 || aaa > 6.0) 
 				    printf("WARNING: %5.2fA between %s and %s ((H..)A-AA).\n", aaa,atomid(j,buf1),atomid(icon[j][l],buf2));		    
 			    }
 			}
 			if ((haaa_ang > cosMIN_HAAA && haaa_ang<100.0) && !nnbflg) 
 			    return(0);
 			else
 			    if (haaa_ang==100.0)
 				haaa_ang= -99.9;
 			/*NB -99 could not have been used as a default whilst checking
 			  because we are trying to find a lowest possible value */
 			
 			if (debug)
 			    printf("Angle OK\n");
 		    }
 		    else
 		    {
 			float haaa_tmp;
 			haaa_ang= -99; /*dealing with hAax, prefer small, ie big cosines*/
 			for(l=0;l<2;l++)
 			{
 			    
 			    haaa_tmp=dot_product( to(atom[j].p,aa[l]),to(atom[j ].p,nearest));
 			    haaa_tmp/= ha;
 			    if (debug) printf("Cosine of H-A-AX = %5.3f\n",haaa_tmp);
 			    if (haaa_tmp > haaa_ang) {
 				if (debug) printf("%5.3f > %5.3f.\n",haaa_tmp,haaa_ang);
 				
 				haaa_ang=haaa_tmp; /* select the low ie more meaningful */
 				if (debug) printf("Lowest yet.\n");
 			    }
 			    
 			}
 			if (haaa_ang < cosMAX_HAAX /* && haaa_ang<100.0 */ )
 			{
 			    if (debug) {
 				printf("Rejected because of wide HAAX angle.\n");
 				printf("Cos haaa_ang = %5.3f, cosMAX_HAAX = %5.3f.\n", haaa_ang, cosMAX_HAAX);
 			    }
 			    if (!nnbflg)
 				return(0);
 			}
 		    }
 		    
 		    
 		}/* end of 'if any Hs actually found' clause */
 		else
 		    if (d>SQR(MAX_HA+1.0))
 			if (!nnbflg)
 			    return(0); /* if the hydrogens are unfixed, knock
					 anything more than 1.0 Ang - the 
					 normal DH distance - back. */

    sprintf_hb(o_str,i,j,nearest,d,ha,daaa_ang,haaa_ang);
    return(1);
}
Esempio n. 17
0
void TrustRegion::optimize_vertex_positions( PatchData& pd, MsqError& err )
{
  TerminationCriterion& term = *get_inner_termination_criterion();
  OFEvaluator& func = get_objective_function_evaluator();
  
  const double cg_tol = 1e-2;
  const double eta_1  = 0.01;
  const double eta_2  = 0.90;
  const double tr_incr = 10;
  const double tr_decr_def = 0.25;
  const double tr_decr_undef = 0.25;
  const double tr_num_tol = 1e-6;
  const int max_cg_iter = 10000;
  
  double radius = 1000;		/* delta*delta */

 const int nn = pd.num_free_vertices();
  wVect.resize(nn); Vector3D* w = arrptr(wVect);
  zVect.resize(nn); Vector3D* z = arrptr(zVect);
  dVect.resize(nn); Vector3D* d = arrptr(dVect);
  pVect.resize(nn); Vector3D* p = arrptr(pVect);
  rVect.resize(nn); Vector3D* r = arrptr(rVect);

  double norm_r, norm_g;
  double alpha, beta, kappa;
  double rz, rzm1;
  double dMp, norm_d, norm_dp1, norm_p;
  double obj, objn;

  int cg_iter;
  bool valid;

  mHess.initialize( pd, err );  //hMesh(mesh);
  valid = func.update( pd, obj, mGrad, mHess, err ); MSQ_ERRRTN(err);
  if (!valid) {
    MSQ_SETERR(err)("Initial objective function is not valid", MsqError::INVALID_MESH);
    return;
  }
  compute_preconditioner( err ); MSQ_ERRRTN(err);
  pd.recreate_vertices_memento( mMemento, err ); MSQ_ERRRTN(err);

  while (!term.terminate() && (radius > 1e-20)) {

    norm_r = length_squared(arrptr(mGrad), nn);
    norm_g = sqrt(norm_r);

    memset(d, 0, 3*sizeof(double)*nn);
    memcpy(r, arrptr(mGrad), nn*sizeof(Vector3D)); //memcpy(r, mesh->g, 3*sizeof(double)*nn);
    norm_g *= cg_tol;

    apply_preconditioner( z, r, err); MSQ_ERRRTN(err); //prec->apply(z, r, prec, mesh);
    negate(p, z, nn);
    rz = inner(r, z, nn);

    dMp    = 0;
    norm_p = rz;
    norm_d = 0;

    cg_iter = 0;
    while ((sqrt(norm_r) > norm_g) && 
#ifdef DO_STEEP_DESC
         (norm_d > tr_num_tol) && 
#endif
         (cg_iter < max_cg_iter)) 
    {
      ++cg_iter;

      memset(w, 0, 3*sizeof(double)*nn);
      //matmul(w, mHess, p); //matmul(w, mesh, p);
      mHess.product( w, p );

      kappa = inner(p, w, nn);
      if (kappa <= 0.0) {
        alpha = (sqrt(dMp*dMp+norm_p*(radius-norm_d))-dMp)/norm_p;
        plus_eq_scaled( d, alpha, p, nn );
	break;
      }

      alpha = rz / kappa;

      norm_dp1 = norm_d + 2.0*alpha*dMp + alpha*alpha*norm_p;
      if (norm_dp1 >= radius) {
        alpha = (sqrt(dMp*dMp+norm_p*(radius-norm_d))-dMp)/norm_p;
        plus_eq_scaled( d, alpha, p, nn );
	break;
      }

      plus_eq_scaled( d, alpha, p, nn );
      plus_eq_scaled( r, alpha, w, nn );
      norm_r = length_squared(r, nn);

      apply_preconditioner( z, r, err); MSQ_ERRRTN(err); //prec->apply(z, r, prec, mesh);

      rzm1 = rz;
      rz = inner(r, z, nn);
      beta = rz / rzm1;
      times_eq_minus( p, beta, z, nn );

      dMp = beta*(dMp + alpha*norm_p);
      norm_p = rz + beta*beta*norm_p;
      norm_d = norm_dp1;
    }

#ifdef DO_STEEP_DESC    
    if (norm_d <= tr_num_tol) {
      norm_g = length(arrptr(mGrad), nn);
      double ll = 1.0;
      if (norm_g < tr_num_tol)
        break;
      if (norm_g > radius)
        ll = radius / nurm_g;
      for (int i = 0; i < nn; ++i)
        d[i] = ll * mGrad[i];
    }
#endif

    alpha = inner( arrptr(mGrad), d, nn ); // inner(mesh->g, d, nn);

    memset(p, 0, 3*sizeof(double)*nn);
    //matmul(p, mHess, d); //matmul(p, mesh, d);
    mHess.product( p, d );
    beta = 0.5*inner(p, d, nn);
    kappa = alpha + beta;

    /* Put the new point into the locations */
    pd.move_free_vertices_constrained( d, nn, 1.0, err ); MSQ_ERRRTN(err);

    valid = func.evaluate( pd, objn, err ); MSQ_ERRRTN(err); 
    if (!valid) {
      /* Function not defined at trial point */
      radius *= tr_decr_undef;
      pd.set_to_vertices_memento( mMemento, err ); MSQ_ERRRTN(err); 
      continue;
    }
      

    if ((fabs(kappa) <= tr_num_tol) && (fabs(objn - obj) <= tr_num_tol)) {
      kappa = 1;
    }
    else {
      kappa = (objn - obj) / kappa;
    }
    
    if (kappa < eta_1) {
      /* Iterate is unacceptable */
      radius *= tr_decr_def;
      pd.set_to_vertices_memento( mMemento, err ); MSQ_ERRRTN(err); 
      continue;
    }

      /* Iterate is acceptable */
    if (kappa >= eta_2) {
      /* Iterate is a very good step, increase radius */
      radius *= tr_incr;
      if (radius > 1e20) {
	radius = 1e20;
      }
    }

    func.update( pd, obj, mGrad, mHess, err );
    compute_preconditioner( err ); MSQ_ERRRTN(err);
    pd.recreate_vertices_memento( mMemento, err ); MSQ_ERRRTN(err);

    // checks stopping criterion 
    term.accumulate_patch( pd, err ); MSQ_ERRRTN(err);
    term.accumulate_inner( pd, objn, arrptr(mGrad), err ); MSQ_ERRRTN(err);
  }
}    
/*!Reset function using using a PatchData object.  This function is
  called for the inner-stopping criterion directly from the
  loop over mesh function in VertexMover.  For outer criterion,
  it is called from the reset function which takes a MeshSet object.
  This function prepares the object to be used by setting the initial
  values of some of the data members.  As examples, if needed, it resets
  the cpu timer to zero, the iteration counter to zero, and the
  initial and previous objective function values to the current
  objective function value for this patch.
  The return value for this function is similar to that of terminate().
  The function returns false if the checked criteria have not been
  satisfied, and true if they have been.  reset() only checks the
  GRADIENT_INF_NORM_ABSOLUTE, GRADIENT_L2_NORM_ABSOLUTE, and the
  QUALITY_IMPROVEMENT_ABSOLUTE criteria.  Checking these criteria
  allows the QualityImprover to skip the entire optimization if
  the initial mesh satisfies the appropriate conditions.
 */
void TerminationCriterion::reset_inner(PatchData &pd, OFEvaluator& obj_eval,
                                    MsqError &err)
{
  const unsigned long totalFlag = terminationCriterionFlag | cullingMethodFlag;
  
    // clear flag for BOUNDED_VERTEX_MOVEMENT
  vertexMovementExceedsBound = 0;
  
    // Use -1 to denote that this isn't initialized yet.
    // As all valid values must be >= 0.0, a negative
    // value indicates that it is uninitialized and is
    // always less than any valid value.
  maxSquaredMovement = -1;
  
    // Clear the iteration count.
  iterationCounter = 0;
  
    //reset the inner timer if needed
  if(totalFlag & CPU_TIME){
    mTimer.reset();
  }
   
    //GRADIENT
  currentGradInfNorm = initialGradInfNorm = 0.0;
  currentGradL2NormSquared = initialGradL2NormSquared = 0.0;
  if(totalFlag & GRAD_FLAGS)
  {
    if (!obj_eval.have_objective_function()) {
      MSQ_SETERR(err)("Error termination criteria set which uses objective "
                      "functions, but no objective function is available.",
                      MsqError::INVALID_STATE);   
      return;
    } 
    int num_vertices=pd.num_free_vertices();
    mGrad.resize( num_vertices );

      //get gradient and make sure it is valid
    bool b = obj_eval.evaluate(pd, currentOFValue, mGrad, err); MSQ_ERRRTN(err);
    if (!b) {
      MSQ_SETERR(err)("Initial patch is invalid for gradient computation.", 
                      MsqError::INVALID_STATE);
      return;
    } 

      //get the gradient norms
    if (totalFlag & (GRADIENT_INF_NORM_ABSOLUTE|GRADIENT_INF_NORM_RELATIVE))
    {
      currentGradInfNorm = initialGradInfNorm = Linf(mGrad);
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Initial gradient Inf norm: " << " "
                                     << RPM(initialGradInfNorm) << std::endl;
    }  
      
    if (totalFlag & (GRADIENT_L2_NORM_ABSOLUTE|GRADIENT_L2_NORM_RELATIVE))
    {
      currentGradL2NormSquared = initialGradL2NormSquared = length_squared(mGrad);
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Initial gradient L2 norm: " << " "
                                     << RPM(std::sqrt(initialGradL2NormSquared)) << std::endl;
    }  

      //the OFvalue comes for free, so save it
    previousOFValue=currentOFValue;
    initialOFValue=currentOFValue;
  }
  //find the initial objective function value if needed and not already
  //computed.  If we needed the gradient, we have the OF value for free.
  // Also, if possible, get initial OF value if writing plot file.  Solvers
  // often supply the OF value for subsequent iterations so by calculating
  // the initial value we can generate OF value plots.
  else if ((totalFlag & OF_FLAGS) || 
           (plotFile.is_open() && pd.num_free_vertices() && obj_eval.have_objective_function()))
  {
      //ensure the obj_ptr is not null
    if(!obj_eval.have_objective_function()){
      MSQ_SETERR(err)("Error termination criteria set which uses objective "
                      "functions, but no objective function is available.",
                      MsqError::INVALID_STATE);
      return;
    }
    
    bool b = obj_eval.evaluate(pd, currentOFValue, err); MSQ_ERRRTN(err);
    if (!b){
      MSQ_SETERR(err)("Initial patch is invalid for evaluation.",MsqError::INVALID_STATE);
      return;
    }
      //std::cout<<"\nReseting initial of value = "<<initialOFValue;
    previousOFValue=currentOFValue;
    initialOFValue=currentOFValue;
  }
  
  if (totalFlag & (GRAD_FLAGS|OF_FLAGS))
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Initial OF value: " << " " << RPM(initialOFValue) << std::endl;
  
    // Store current vertex locations now, because we'll
    // need them later to compare the current movement with.
  if (totalFlag & VERTEX_MOVEMENT_RELATIVE)
  {
    if (initialVerticesMemento)
    {
      pd.recreate_vertices_memento( initialVerticesMemento, err );
    }
    else
    {
      initialVerticesMemento = pd.create_vertices_memento( err );
    }
    MSQ_ERRRTN(err);
    maxSquaredInitialMovement = DBL_MAX;
  }
  else {
    maxSquaredInitialMovement = 0;
  }
  
  if (terminationCriterionFlag & UNTANGLED_MESH) {
    globalInvertedCount = count_inverted( pd, err );
    //if (innerOuterType==TYPE_OUTER) MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Num Inverted: " << " " << globalInvertedCount << std::endl;
    patchInvertedCount = 0;
    MSQ_ERRRTN(err);
  }

  if (timeStepFileType) {
      // If didn't already calculate gradient abive, calculate it now.
    if (!(totalFlag & GRAD_FLAGS)) {
      mGrad.resize( pd.num_free_vertices() );
      obj_eval.evaluate(pd, currentOFValue, mGrad, err);
      err.clear();
    }
    write_timestep( pd, mGrad.empty() ? 0 : arrptr(mGrad), err);
  }
    
  if (plotFile.is_open()) {
      // two newlines so GNU plot knows that we are starting a new data set
    plotFile << std::endl << std::endl;
      // write column headings as comment in data file
    plotFile << "#Iter\tCPU\tObjFunc\tGradL2\tGradInf\tMovement\tInverted" << std::endl;
      // write initial values
    plotFile << 0 
     << '\t' << mTimer.since_birth() 
     << '\t' << initialOFValue 
     << '\t' << std::sqrt( currentGradL2NormSquared ) 
     << '\t' << currentGradInfNorm 
     << '\t' << 0.0
     << '\t' << globalInvertedCount
     << std::endl;
  }
}
Esempio n. 19
0
void sprintf_hb(char * o_str, int i, int j, struct vect nearest, float d, float ha, float daaa_ang, float haaa_ang)
{
    char      bndtyp[3], acctyp[4], dontyp[4], space=' ';
    int       ca_d, ri, rj, gap;
    char buf1[20],buf2[20]; /* buffers for atomid routines */
    float     tmp;
        
    /*we have a hydrogen bond!*/
    
    bndtyp[0] = bndtyp[1] = '?';
    acctyp[3] = dontyp[3] = bndtyp[2] = '\0';
    
    if (atom[i].aacode == TOTNAA || atom[i].hetflg )
	bndtyp[0] = 'H';
    else
    {
	if (atom[i].aacode <STDAA)
	{
	    bndtyp[0] = (atom[i].atmtyp <=3) ? 'M' : 'S';
	}
	else
	{
	    bndtyp[0] = (atom[i].atmtyp <=3) ? 'm' : 's';
	}
    }
    if (atom[j].aacode == TOTNAA || atom[j].hetflg )
	bndtyp[1] = 'H';
    else
    {
	if (atom[j].aacode <STDAA)
	{
	    bndtyp[1] = (atom[j].atmtyp <=3) ? 'M' : 'S';
	}
	else
	{
	    bndtyp[1] = (atom[j].atmtyp <=3) ? 'm' : 's';
	}
    }
 		
    ri = atom[i].caindex;
    rj = atom[j].caindex;
    
    gap=find_gap( ri, rj);
		
#if 0 		
    if (atom[i].aacode==TOTNAA || (ri == -99) || !residue[ri].ca ||                       atom[j].aacode==TOTNAA || (rj == -99) || !residue[rj].ca  )
	gap = -1;
    else
    {
	gap = cagap(ri,rj);
    }
#endif 		
    if (atom[i].aacode==TOTNAA || (ri == -99) || !residue[ri].ca ||  
	atom[j].aacode==TOTNAA || (rj == -99) || !residue[rj].ca  )
	ca_d = -1.0;
    else
    {
	ca_d = length_squared( to(*(residue[ri].ca),*(residue[rj].ca)) );
	
	if (ca_d > SQR(CAWARN) && debug)
	{
	    printf("WARNING: unusual CA-CA distance of %5.2f for",sqrt(ca_d));
	    printf("%s number ??\n", (nnbflg)?" interaction":" H-bond"/*,nhb*/);
	    printf("         between %s and %s\n", atomid(i,buf1),atomid(j,buf2));
	    
	}
    }
#if 0
    printf("%4s",   brcode);
    printf("%c",    (atom[i].chnid == '-') ? space : atom[i].chnid);
    printf("%4s/",  brcode);
    printf("%c",    atom[i].chnid);
    printf("%04d",  atom[i].aanum);
    if(OMLINSERT && atom[i].hetflg)
	printf("h");
    else
	printf("%c",    atom[i].inscode);
    /* printf("%3s",   dontyp);               */
    printf("%3s",   atom[i].resnam);
    printf("%4s",   atom[i].atmnam);
    printf("%c",    atom[i].strucsum);
    printf("%c",    (atom[j].chnid == '-') ? space : atom[j].chnid);
		printf("%4s/",  brcode);
		printf("%c",    atom[j].chnid);
		printf("%04d",  atom[j].aanum);
    if(OMLINSERT && atom[j].hetflg)
	printf("h");
    else
	printf("%c",    atom[j].inscode);
    /* printf("%3s",   acctyp);               */
		printf("%3s",   atom[j].resnam);
		printf("%4s",   atom[j].atmnam);
		printf("%c",    atom[j].strucsum);
		printf("%4.1f", sqrt(d));
		printf(" %2s",   bndtyp);
    printf("%4d",   gap);
    printf("%4.1f", (ca_d <= 0.0) ? -1.0 : sqrt(ca_d));
    printf("%6.1d", 180/3.1415927*angle(atom[i].p,nearest,atom[j].p) );
    printf("%4.1d", d);
    printf("%6d\n", nhb);
		
#endif
    *o_str = 0 ; 

/*This isn't neccessary if the longoutput format is used, but if the short
  format is used, then the first output must (i) include a 'strlen' in case
  it is part of a 'long format' output, and (ii) have some way of knowing
  where to begin in case of a 'short format' output. */
    
    if (longoutflg)  
 		{
 		    /* start to output the line, *.hhb format */
 		    sprintf(o_str              , "%4s",   brcode);
 		    sprintf(o_str+strlen(o_str), "%c",    (atom[i].chnid == '-') ? space : 
 			    atom[i].chnid);
 		    sprintf(o_str+strlen(o_str), "%4s/",  brcode);
 		}
 		sprintf(o_str+strlen(o_str), "%c",    atom[i].chnid);
 		sprintf(o_str+strlen(o_str), "%04d",  atom[i].aanum);
if(OMLINSERT && atom[i].hetflg) /*v3.13*/
    sprintf(o_str+strlen(o_str), "h");
else
    sprintf(o_str+strlen(o_str), "%c",    atom[i].inscode);
		/* sprintf(o_str+strlen(o_str), "%3s",   dontyp);               */
/* Amendment. RAL 14 Jun 2012 --> */
// 		if (atom[i].aacode==Cys && atom[i].atmtyp == 5 & cssflg)
 		if (atom[i].aacode==Cys && atom[i].atmtyp == 5 && cssflg)
/* <-- Amendment. RAL 14 Jun 2012 */
 		{
 		    if (atom[i].ssflg) 
 			sprintf(o_str+strlen(o_str),"CSS");
 		    else 
 			sprintf(o_str+strlen(o_str),"CYH");    }
 		else
 		    sprintf(o_str+strlen(o_str), "%3s",   atom[i].resnam);
 		sprintf(o_str+strlen(o_str), "%4s",   atom[i].atmnam);
 		if (longoutflg)  
 		{
 		    
 		    sprintf(o_str+strlen(o_str), "%c",    atom[i].strucsum);
 		    sprintf(o_str+strlen(o_str), "%c",    (atom[j].chnid == '-') ? space : 
 			    atom[j].chnid);
 		    sprintf(o_str+strlen(o_str), "%4s/",  brcode);
 		}
 		else
 		    sprintf(o_str+strlen(o_str), " ");
 		
 		sprintf(o_str+strlen(o_str), "%c",    atom[j].chnid);
                sprintf(o_str+strlen(o_str), "%04d",  atom[j].aanum);
    if(OMLINSERT && atom[j].hetflg) /*v3.13 start*/
	sprintf(o_str+strlen(o_str),"h");
    else /*v3.13 end*/
 		sprintf(o_str+strlen(o_str), "%c",    atom[j].inscode);
 		/* sprintf(o_str+strlen(o_str), "%3s",   acctyp);               */
 		if (atom[j].aacode==Cys && atom[j].atmtyp == 5 && cssflg)
 		{
 		    if (atom[j].ssflg) 
 			sprintf(o_str+strlen(o_str),"CSS");
 		    else 
 			sprintf(o_str+strlen(o_str),"CYH");    }
 		else
 		    sprintf(o_str+strlen(o_str), "%3s",   atom[j].resnam);
 		sprintf(o_str+strlen(o_str), "%4s",   atom[j].atmnam);
 		if (longoutflg) 
 		    sprintf(o_str+strlen(o_str), "%c",    atom[j].strucsum);
 		sprintf(o_str+strlen(o_str), "%5.2f", sqrt(d));
 		if (!longoutflg) 
 		    sprintf(o_str+strlen(o_str), " ");
 		sprintf(o_str+strlen(o_str), "%2s",  bndtyp);
 		sprintf(o_str+strlen(o_str), "%4d",   gap);
 		if (!longoutflg) 
 		    sprintf(o_str+strlen(o_str), " ");
 		sprintf(o_str+strlen(o_str), "%5.2f", (ca_d <= 0.0) ? -1.0 : sqrt(ca_d));
 		if (!longoutflg) 
 		    sprintf(o_str+strlen(o_str), " ");
 		if (atom[i].nh && h_atm[atom[i].h_ptr].typ)
 		{
 		    /* if it has hydrogens and if they have been placed */
		    tmp = angle(atom[i].p,nearest,atom[j].p);
		    
 		    sprintf(o_str+strlen(o_str), "%5.1f", (180.0/3.1415927)* tmp );
		    if (!longoutflg) 
			sprintf(o_str+strlen(o_str), " ");
 		    sprintf(o_str+strlen(o_str), "%5.2f", ha);
		    if (!longoutflg)
			sprintf(o_str+strlen(o_str), " ");
 		    if (haaa_ang>-50.0)
 			sprintf(o_str+strlen(o_str),"%5.1f", 180/3.1415927* (float) acos(haaa_ang) );
 		    else
 			sprintf(o_str+strlen(o_str),"%5.1f", -1.0);
		    
 		}
 		else
 		    if (longoutflg) 
 			sprintf(o_str+strlen(o_str), "%5.1f%5.2f%5.1f", -1.0, -1.0, -1.0);
 		    else
 			sprintf(o_str+strlen(o_str), "%5.1f %5.2f %5.1f", -1.0, -1.0, -1.0);
 		if (daaa_ang>-50.0)
 		    sprintf(o_str+strlen(o_str),"%6.1f", 180/3.1415927*acos(daaa_ang) );
 		else
 		    sprintf(o_str+strlen(o_str),"%6.1f", -1.0);
		
 		if (debug)
 		{
 		    sprintf(o_str+strlen(o_str), "D " );
 		    sprintf(o_str+strlen(o_str), TF,VXYZ(atom[i].p) );
 		    sprintf(o_str+strlen(o_str), " H " );
 		    sprintf(o_str+strlen(o_str), TF,VXYZ(nearest) );
 		    sprintf(o_str+strlen(o_str), " A " );
 		    sprintf(o_str+strlen(o_str), TF, VXYZ(atom[j].p) );
 		}
 		
/* 		sprintf(o_str+strlen(o_str), "%6d\n", nhb);
		THIS IS DONE BY THE CALLING ROUTINE */

 		/* end of outputting the line, *.hhb format */

    return;

}
template <typename T> struct point { T x, y; };template <typename T> T length_squared(const point<T> & p) { return p.x*p.x + p.y*p.y; }template <typename T> double length(const point<T> & p) { return sqrt(length_squared(p)); }template <typename T> bool operator == (const point<T> & p, const point<T> & q) { return p.x == q.x and p.y == q.y; }template <typename T> bool operator != (const point<T> & p, const point<T> & q) { return not (p == q); }template <typename T> point<T> operator + (const point<T> & a, const point<T> & b) { return (point<T>) { a.x+b.x, a.y+b.y }; }template <typename T> point<T> operator - (const point<T> & a, const point<T> & b) { return (point<T>) { a.x-b.x, a.y-b.y }; }template <typename T> point<T> operator - (const point<T> & a) { return (point<T>) { -a.x, -a.y }; }template <typename T> point<T> operator * (T a, const point<T> & b) { return (point<T>) { a*b.x, a*b.y }; }template <typename T> T dot(const point<T> & p, const point<T> & q) { return p.x * q.x + p.y * q.y; }template <typename T> T cross(const point<T> & p, const point<T> & q) { return p.x * q.y - p.y * q.x; }template <typename T> double atan(const point<T> & p) { return std::atan2(p.y, p.x); }template <typename T> std::istream & operator >> (std::istream & input, point<T> & p) { return input >> p.x >> p.y; }template <typename T> std::ostream & operator << (std::ostream & output, const point<T> & p) { return output << p.x << ' ' << p.y; }template <typename T> struct point_y_x_adapter { point<T> & data; };template <typename T> point_y_x_adapter<T> point_y_x(point<T> & data) { return (point_y_x_adapter<T>){ data }; }template <typename T> std::istream & operator >> (std::istream & input, point_y_x_adapter<T> p) { return input >> p.data.y >> p.data.x; }template <typename T> std::ostream & operator << (std::ostream & output, const point_y_x_adapter<T> p) { return output << p.data.y << ' ' << p.data.x; }template <typename T> std::pair<T,T> to_pair(const point<T> & a) { return std::make_pair(a.x, a.y); }template <typename T> bool operator < (const point<T> & a, const point<T> & b) { return to_pair(a) < to_pair(b); }template <typename T> bool operator <= (const point<T> & a, const point<T> & b) { return to_pair(a) <= to_pair(b); }template <typename T> bool operator >= (const point<T> & a, const point<T> & b) { return to_pair(a) >= to_pair(b); }template <typename T> bool operator > (const point<T> & a, const point<T> & b) { return to_pair(a) > to_pair(b); }template <typename T> bool on_board(const point<T> & p, T width, T height) { return 0 <= p.x and p.x < width and 0 <= p.y and p.y < height; }template <typename T> T manhattan(const point<T> & p) { return std::abs(p.x) + std::abs(p.y); }const point<int> directions[4] = { {0,-1}, {0,1}, {-1,0}, {1,0} };
Esempio n. 21
0
 constexpr bool is_unit() const noexcept {
     return length_squared() == 1;
 }
 struct point { T x, y; };ttt point<T> operator + (cpa a, cpa b) { return { a.x+b.x, a.y+b.y }; }ttt point<T> operator - (cpa a, cpa b) { return { a.x-b.x, a.y-b.y }; }ttt point<T> operator - (cpa a) { return { -a.x, -a.y }; }ttt point<T> operator * (T a, cpa b) { return { a*b.x, a*b.y }; }ttt std::pair<T,T> to_pair(cpa a) { return { a.x, a.y }; }ttt bool operator == (cpa a, cpa b) { return to_pair(a) == to_pair(b); }ttt bool operator != (cpa a, cpa b) { return to_pair(a) != to_pair(b); }ttt bool operator <  (cpa a, cpa b) { return to_pair(a) <  to_pair(b); }ttt bool operator <= (cpa a, cpa b) { return to_pair(a) <= to_pair(b); }ttt bool operator >= (cpa a, cpa b) { return to_pair(a) >= to_pair(b); }ttt bool operator >  (cpa a, cpa b) { return to_pair(a) >  to_pair(b); }ttt T length_squared(cpa p) { return p.x*p.x + p.y*p.y; }ttt double length(cpa p) { return sqrt(length_squared(p)); }ttt T   dot(cpa p, cpa q) { return p.x * q.x + p.y * q.y; }ttt T cross(cpa p, cpa q) { return p.x * q.y - p.y * q.x; }ttt int ccw(cpa a, cpa b, cpa c) { double x = cross(b - a, c - a); return x > 0 ? 1 : x < 0 ? -1 : 0; }
Esempio n. 23
0
bool Vector2::is_normalized() const {
	// use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
	return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON);
}
Esempio n. 24
0
double Field::CalculateWlaplaceian(Vector3f r, float h) {
    return -FACTOR / pow(h, 9) * (h * h - length_squared(r)) * (3 * h * h - 7 * length_squared(r));
}
Esempio n. 25
0
 double length() const noexcept {
     return std::sqrt(length_squared());
 }
void SteepestDescent::optimize_vertex_positions(PatchData &pd, 
                                                MsqError &err)
{
  MSQ_FUNCTION_TIMER( "SteepestDescent::optimize_vertex_positions" );

  const int SEARCH_MAX = 100;
  const double c1 = 1e-4;
  //std::vector<Vector3D> unprojected(pd.num_free_vertices()); 
  std::vector<Vector3D> gradient(pd.num_free_vertices()); 
  bool feasible=true;//bool for OF values
  double min_edge_len, max_edge_len;
  double step_size=0, original_value=0, new_value=0;
  double norm_squared=0;
  PatchDataVerticesMemento* pd_previous_coords;
  TerminationCriterion* term_crit=get_inner_termination_criterion();
  OFEvaluator& obj_func = get_objective_function_evaluator();
  
    // get vertex memento so we can restore vertex coordinates for bad steps.
  pd_previous_coords = pd.create_vertices_memento( err ); MSQ_ERRRTN(err);
    // use auto_ptr to automatically delete memento when we exit this function
  std::auto_ptr<PatchDataVerticesMemento> memento_deleter( pd_previous_coords );

    // Evaluate objective function.
    //
    // Always use 'update' version when beginning optimization so that
    // if doing block coordinate descent the OF code knows the set of
    // vertices we are modifying during the optimziation (the subset
    // of the mesh contained in the current patch.)  This has to be
    // done up-front because typically an OF will just store the portion
    // of the OF value (e.g. the numeric contribution to the sum for an
    // averaging OF) for the initial patch.
  feasible = obj_func.update( pd, original_value, gradient, err ); MSQ_ERRRTN(err);
    // calculate gradient dotted with itself
  norm_squared = length_squared( gradient );
  
    //set an error if initial patch is invalid.
  if(!feasible){
    MSQ_SETERR(err)("SteepestDescent passed invalid initial patch.",
                    MsqError::INVALID_ARG);
    return;
  }

    // use edge length as an initial guess for for step size
  pd.get_minmax_edge_length( min_edge_len, max_edge_len );
  //step_size = max_edge_len / std::sqrt(norm_squared);
  //if (!finite(step_size))  // zero-length gradient
  //  return;
//  if (norm_squared < DBL_EPSILON)
//    return;
  if (norm_squared >= DBL_EPSILON)
    step_size = max_edge_len / std::sqrt(norm_squared) * pd.num_free_vertices();

    // The steepest descent loop...
    // We loop until the user-specified termination criteria are met.
  while (!term_crit->terminate()) {
    MSQ_DBGOUT(3) << "Iteration " << term_crit->get_iteration_count() << std::endl;
    MSQ_DBGOUT(3) << "  o  original_value: " << original_value << std::endl;
    MSQ_DBGOUT(3) << "  o  grad norm suqared: " << norm_squared << std::endl;

      // Save current vertex coords so that they can be restored if
      // the step was bad.
    pd.recreate_vertices_memento( pd_previous_coords, err ); MSQ_ERRRTN(err);

      // Reduce step size until it satisfies Armijo condition
    int counter = 0;
    for (;;) {
      if (++counter > SEARCH_MAX || step_size < DBL_EPSILON) {
        MSQ_DBGOUT(3) << "    o  No valid step found.  Giving Up." << std::endl;
        return;
      }
      
      // Move vertices to new positions.
      // Note: step direction is -gradient so we pass +gradient and 
      //       -step_size to achieve the same thing.
      pd.move_free_vertices_constrained( arrptr(gradient), gradient.size(), -step_size, err ); MSQ_ERRRTN(err);
      // Evaluate objective function for new vertices.  We call the
      // 'evaluate' form here because we aren't sure yet if we want to
      // keep these vertices.  Until we call 'update', we have the option
      // of reverting a block coordinate decent objective function's state
      // to that of the initial vertex coordinates.  However, for block
      // coordinate decent to work correctly, we will need to call an
      // 'update' form if we decide to keep the new vertex coordinates.
      feasible = obj_func.evaluate( pd, new_value, err ); 
      if (err.error_code() == err.BARRIER_VIOLATED) 
        err.clear();  // barrier violated does not represent an actual error here
      MSQ_ERRRTN(err);
      MSQ_DBGOUT(3) << "    o  step_size: " << step_size << std::endl;
      MSQ_DBGOUT(3) << "    o  new_value: " << new_value << std::endl;

      if (!feasible) {
        // OF value is invalid, decrease step_size a lot
        step_size *= 0.2;
      }
      else if (new_value > original_value - c1 * step_size * norm_squared) {
        // Armijo condition not met.
        step_size *= 0.5;
      }
      else {
        // Armijo condition met, stop
        break;
      }
      
      // undo previous step : restore vertex coordinates
      pd.set_to_vertices_memento( pd_previous_coords, err );  MSQ_ERRRTN(err);
    }
   
      // Re-evaluate objective function to get gradient.
      // Calling the 'update' form here incorporates the new vertex 
      // positions into the 'accumulated' value if we are doing a 
      // block coordinate descent optimization.
    obj_func.update(pd, original_value, gradient, err ); MSQ_ERRRTN(err);
    if (projectGradient) {
      //if (cosineStep) {
      //  unprojected = gradient;
      //  pd.project_gradient( gradient, err ); MSQ_ERRRTN(err);
      //  double dot = inner_product( arrptr(gradient), arrptr(unprojected), gradient.size() );
      //  double lensqr1 = length_squared( gradient );
      //  double lensqr2 = length_squared( unprojected );
      //  double cossqr = dot * dot / lensqr1 / lensqr2;
      //  step_size *= sqrt(cossqr);
      //}
      //else {
        pd.project_gradient( gradient, err ); MSQ_ERRRTN(err);
      //}      
    }
      
      // Update terination criterion for next iteration.
      // This is necessary for efficiency.  Some values can be adjusted
      // for each iteration so we don't need to re-caculate the value
      // over the entire mesh.
    term_crit->accumulate_patch( pd, err );  MSQ_ERRRTN(err);
    term_crit->accumulate_inner( pd, original_value, arrptr(gradient), err ); MSQ_ERRRTN(err); 
      
      // Calculate initial step size for next iteration using step size 
      // from this iteration
    step_size *= norm_squared;
    norm_squared = length_squared( gradient );
//    if (norm_squared < DBL_EPSILON)
//      break;
  if (norm_squared >= DBL_EPSILON)
    step_size /= norm_squared;
  }
}
Esempio n. 27
0
real_t Quat::length() const {

	return Math::sqrt(length_squared());
}
Esempio n. 28
0
void testAzElRotation()
{
    mat3d M;

    vec3d x, y, z;

    const double threshold = 0.000001;

    M = rotationFromAzElTwist(0.0, 0.0, 0.0);
    x = M*unitX;
    y = M*unitY;
    z = M*unitZ;
    assert(length_squared(unitX - x) < threshold);
    assert(length_squared(unitY - y) < threshold);
    assert(length_squared(unitZ - z) < threshold);

    M = rotationFromAzElTwist(0.0, M_PI/2.0, 0.0);
    x = M*unitX;
    y = M*unitY;
    z = M*unitZ;
    assert(length_squared(unitX - x) < threshold);
    assert(length_squared(unitZ - y) < threshold);
    assert(length_squared(-unitY - z) < threshold);

    M = rotationFromAzElTwist(M_PI, M_PI/2.0, 0.0);
    x = M*unitX;
    y = M*unitY;
    z = M*unitZ;
    assert(length_squared(-unitX - x) < threshold);
    assert(length_squared(-unitZ - y) < threshold);
    assert(length_squared(-unitY - z) < threshold);

    M = rotationFromAzElTwist(M_PI, M_PI, 0.0);
    x = M*unitX;
    y = M*unitY;
    z = M*unitZ;
    assert(length_squared(-unitX - x) < threshold);
    assert(length_squared(-unitY - y) < threshold);
    assert(length_squared(unitZ - z) < threshold);
}