bool LatticeReduction::isReduced(const Vector&a,const Vector&b){
  const int cut=5;
  for(int i=-cut;i<=cut;i++){
    if(modulo2(b+i*a)<modulo2(b)) return false;
  }
  return modulo2(a)<=modulo2(b) && 2.0*dotProduct(a,b)<=modulo2(a);
}
void LatticeReduction::reduceSlow(Tensor&t){
  Vector v[3];
  v[0]=t.getRow(0);
  v[1]=t.getRow(1);
  v[2]=t.getRow(2);
  reduce2(v[0],v[1],v[2]);
  double e01=dotProduct(v[0],v[1]);
  double e02=dotProduct(v[0],v[2]);
  double e12=dotProduct(v[1],v[2]);
  if(e01*e02*e12<0){
    int eps01=0; if(e01>0.0) eps01=1; else if(e01<0.0) eps01=-1;
    int eps02=0; if(e02>0.0) eps02=1; else if(e02<0.0) eps02=-1;
    Vector n=v[0]-eps01*v[1]-eps02*v[2];
    int i=0; double mx=modulo2(v[i]);
    for(int j=1;j<3;j++){
      double f=modulo2(v[j]);
      if(f>mx){
        i=j;
        mx=f;
      }
    }
    if(modulo2(n)<mx) v[i]=n;
  }
  sort(v);
  t.setRow(0,v[0]);
  t.setRow(1,v[1]);
  t.setRow(2,v[2]);
}
示例#3
0
void Pbc::buildShifts(std::vector<Vector> shifts[2][2][2])const{
  const double small=1e-28;

// clear all shifts
  for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) shifts[i][j][k].clear();

// enumerate all possible shifts
// since box is reduced, only 27 shifts have to be attempted
  for(int l=-1;l<=1;l++) for(int m=-1;m<=1;m++) for(int n=-1;n<=1;n++){

// int/double shift vectors
    int ishift[3]={l,m,n};
    Vector dshift(l,m,n);

// count how many components are != 0
    unsigned count=0;
    for(int s=0;s<3;s++) if(ishift[s]!=0) count++;

// skips trivial (0,0,0) and cases with three shifts
// only 18 shifts survive past this point
    if(count==0 || count==3) continue;

// check if that Wigner-Seitz face is perpendicular to the axis.
// this allows to eliminate shifts in symmetric cells.
// e.g., if one lactice vector is orthogonal to the plane spanned
// by the other two vectors, that shift should never be tried
    Vector cosdir=matmul(reduced,transpose(reduced),dshift);
    double dp=dotProduct(dshift,cosdir);
    double ref=modulo2(dshift)*modulo2(cosdir);
    if(std::fabs(ref-dp*dp)<small) continue;

// here we start pruning depending on the sign of the scaled coordinate
    for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++){

      int block[3]={2*i-1,2*j-1,2*k-1};

// skip cases where shift would bring too far from origin
      bool skip=false;
      for(int s=0;s<3;s++) if(ishift[s]*block[s]>0) skip=true;
      if(skip) continue;
      skip=true;
      for(int s=0;s<3;s++){
// check that the components of cosdir along the non-shifted directions
// have the proper sign
        if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
      }
      if(skip)continue;

// if we arrive to this point, shift is eligible and is added to the list
      shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
    }
  }
}
void LatticeReduction::reduce(Vector&a,Vector&b){
  double ma=modulo2(a);
  double mb=modulo2(b);
  while(true){
    if(mb>ma){
      Vector t(a); a=b; b=t;
      double mt(ma); ma=mb; mb=mt;
    }
    a-=b*floor(dotProduct(a,b)/modulo2(b)+0.5);
    ma=modulo2(a);
    if(mb<=ma+epsilon) break;
  }

  Vector t(a); a=b; b=t;
}
示例#5
0
void initGPIO(int nGpio, int modulo, int direction){
    switch(modulo){
        case MODULO_0:
            GPIO0_ModuleClkConfig();
            modulo0(nGpio);
        break;

        case MODULO_1:
            GPIO1_ModuleClkConfig();
            modulo1(nGpio);
        break;

        case MODULO_2:
            GPIO2_ModuleClkConfig();
            modulo2(nGpio);
        break;

        case MODULO_3:
            GPIO3_ModuleClkConfig();
            modulo3(nGpio);
        break;
    }
        /* Enabling the GPIO module. */
    GPIOModuleEnable(GPIO_INSTANCE_ADDRESS(modulo));

    /* Resetting the GPIO module. */
    //GPIOModuleReset(GPIO_INSTANCE_ADDRESS(modulo));

    /* Setting the GPIO pin as an output pin. */
    GPIODirModeSet(GPIO_INSTANCE_ADDRESS(modulo),
               GPIO_INSTANCE_PIN_NUMBER(nGpio),
               direction);
}
示例#6
0
HalfEdge* Interface::getArestaNear(QPointF p)
{
    QList<HalfEdge *> *lista = new QList<HalfEdge *>(map.values());
    //QList<HalfEdge *> *lista = kdt->find(p);

    HalfEdge *e, *best = NULL;
    QPointF p1, p2;
    double min = INF;

    double realdist2;

    for (int i = 0; i < lista->size(); i++)
    {
        e = lista->at(i);

        p1 = e->getOrigem()->getPoint();
        p2 = e->getDestino()->getPoint();

        double mod2 = modulo2(p1,p2);

        double u = ((p.x() - p1.x())*(p2.x() - p1.x())) + ((p.y() - p1.y())*(p2.y() - p1.y()));
        u = u / mod2;

        double x = p1.x() + u * (p2.x() - p1.x());
        double y = p1.y() + u * (p2.y() - p1.y());

        double dist2 = (p.x() - x)*(p.x() - x) + (p.y() - y)*(p.y() - y);

        QPointF dir = (p2 - p1)/sqrt(mod2);

        QPointF AP = p - p1;
        QPointF AB = p2 - p1;

        double proj = eProd(AP,dir);

        if (proj < 0 || proj >= sqrt(mod2))
        {
            double dist2p1 = (p1.x()-p.x())*(p1.x()-p.x()) + (p1.y()-p.y())*(p1.y()-p.y());
            double dist2p2 = (p2.x()-p.x())*(p2.x()-p.x()) + (p2.y()-p.y())*(p2.y()-p.y());

            realdist2 = MIN(dist2p1,dist2p2);
        }
        else
            realdist2 = dist2;


        if (realdist2 < min)
        {
            min = realdist2;
            best = e;
        }

    }

    delete lista;

    return best;
}
bool LatticeReduction::isReduced(const Tensor&t){
  Vector v[3];
  double m[3];
  v[0]=t.getRow(0);
  v[1]=t.getRow(1);
  v[2]=t.getRow(2);
  for(int i=0;i<3;i++) m[i]=modulo2(v[i]);
  if(!((m[0]<=m[1]) && m[1]<=m[2])) return false;
  const int cut=5;
  for(int i=-cut;i<=cut;i++){
    double mm=modulo2(v[1]+i*v[0]);
    if(mm<m[1]) return false;
    for(int j=-cut;j<=cut;j++){
      double mx=modulo2(v[2]+i*v[1]+j*v[0]);
      if(mx<m[2])return false;
    }
  }
  return true;
}
void LatticeReduction::reduceFast(Tensor&t){
  Vector v[3];
  v[0]=t.getRow(0);
  v[1]=t.getRow(1);
  v[2]=t.getRow(2);
  while(true){
    sort(v);
    reduce(v[0],v[1]);
    double b11=modulo2(v[0]);
    double b22=modulo2(v[1]);
    double b12=dotProduct(v[0],v[1]);
    double b13=dotProduct(v[0],v[2]);
    double b23=dotProduct(v[1],v[2]);
    double z=b11*b22-b12*b12;
    double y2=-(b11*b23-b12*b13)/z;
    double y1=-(b22*b13-b12*b23)/z;
    int x1min=floor(y1);
    int x1max=x1min+1;
    int x2min=floor(y2);
    int x2max=x2min+1;
    bool first=true;
    double mbest,mtrial;
    Vector trial,best;
    for(int x1=x1min;x1<=x1max;x1++)
    for(int x2=x2min;x2<=x2max;x2++){
      trial=v[2]+x2*v[1]+x1*v[0];
      mtrial=modulo2(trial);
      if(first || mtrial<mbest){
        mbest=mtrial;
        best=trial;
        first=false;
      }
    }
    if(modulo2(best)+epsilon>=modulo2(v[2])) break;
    v[2]=best;
  }
  sort(v);
  t.setRow(0,v[0]);
  t.setRow(1,v[1]);
  t.setRow(2,v[2]);
}
示例#9
0
Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const{
  Vector d=delta(v1,v2);
  if(type==unset){
  } else if(type==orthorombic) {
#ifdef __PLUMED_PBC_WHILE
    for(unsigned i=0;i<3;i++){
      while(d[i]>hdiag[i]) d[i]-=diag[i];
      while(d[i]<=mdiag[i]) d[i]+=diag[i];
    }
#else
   for(int i=0;i<3;i++) d[i]=Tools::pbc(d[i]*invBox(i,i))*box(i,i);
#endif
  } else if(type==generic) {
    Vector s=matmul(d,invReduced);
// check if images have to be computed:
//    if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)){
// NOTICE: the check in the previous line, albeit correct, is breaking many regtest
//         since it does not apply Tools::pbc in many cases. Moreover, it does not
//         introduce a significant gain. I thus leave it out for the moment.
      if(true){
// bring to -0.5,+0.5 region in scaled coordinates:
      for(int i=0;i<3;i++) s[i]=Tools::pbc(s[i]);
      d=matmul(s,reduced);
// check if shifts have to be attempted:
      if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)){
// list of shifts is specific for that "octant" (depends on signs of s[i]):
        const std::vector<Vector> & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
        Vector best(d);
        double lbest(modulo2(best));
// loop over possible shifts:
        if(nshifts) *nshifts+=myshifts.size();
        for(unsigned i=0;i<myshifts.size();i++){
          Vector trial=d+myshifts[i];
          double ltrial=modulo2(trial);
          if(ltrial<lbest){
            lbest=ltrial;
            best=trial;
          }
        }
        d=best;
      }
    }
  } else plumed_merror("unknown pbc type");
  return d;
}
示例#10
0
void Pbc::test(){
  Random r;
  r.setSeed(-20);
  for(int i=0;i<1000;i++){
// random matrix with some zero element
    Tensor box;
    for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(r.U01()>0.2){
      box[j][k]=2.0*r.U01()-1.0;
    }
    int boxtype=i%10;
    switch(boxtype){
    case 0:
// cubic
      for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(j!=k) box[j][k]=0.0;
      for(int j=1;j<3;j++) box[j][j]=box[0][0];
      break;
    case 1:
// orthorombic
      for(int j=0;j<3;j++) for(int k=0;k<3;k++) if(j!=k) box[j][k]=0.0;
      break;
    case 2:
// hexagonal
      {
      int perm=r.U01()*100;
      Vector a;
      a(0)=r.U01()*2-2; a(1)=0.0;a(2)=0.0;
      double d=r.U01()*2-2;
      Vector b(0.0,d,0.0);
      Vector c(0.0,0.5*d,sqrt(3.0)*d*0.5);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    case 3:
// bcc
      {
      int perm=r.U01()*100;
      double d=r.U01()*2-2;
      Vector a(d,d,d);
      Vector b(d,-d,d);
      Vector c(d,d,-d);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    case 4:
// fcc
      {
      int perm=r.U01()*100;
      double d=r.U01()*2-2;
      Vector a(d,d,0);
      Vector b(d,0,d);
      Vector c(0,d,d);
      box.setRow((perm+0)%3,a);
      box.setRow((perm+1)%3,b);
      box.setRow((perm+2)%3,c);
      }
      break;
    default:
// triclinic
      break;
    }

    Pbc pbc;
    pbc.setBox(box);
    std::cerr<<"( "<<boxtype<<" )\n";
    std::cerr<<"Box:";
    for(int j=0;j<3;j++) for(int k=0;k<3;k++) std::cerr<<" "<<box[j][k];
    std::cerr<<"\n";
    std::cerr<<"Determinant: "<<determinant(box)<<"\n";
    std::cerr<<"Shifts:";
    for(int j=0;j<2;j++) for(int k=0;k<2;k++) for(int l=0;l<2;l++) std::cerr<<" "<<pbc.shifts[j][k][l].size();
    std::cerr<<"\n";
    int nshifts=0;
    int ntot=10000;
    for(int j=0;j<ntot;j++){
      Vector v(r.U01()-0.5,r.U01()-0.5,r.U01()-0.5);
      v*=5;
      for(int j=0;j<3;j++) if(r.U01()>0.2) v(j)=0.0;
      Vector full(v);
      Vector fast=pbc.distance(Vector(0,0,0),v,&nshifts);
      full=fast;

      pbc.fullSearch(full);
  
     if(modulo2(fast-full)>1e-10) {
        std::cerr<<"orig "<<v[0]<<" "<<v[1]<<" "<<v[2]<<"\n";
        std::cerr<<"fast "<<fast[0]<<" "<<fast[1]<<" "<<fast[2]<<"\n";
        std::cerr<<"full "<<full[0]<<" "<<full[1]<<" "<<full[2]<<"\n";
        std::cerr<<"diff "<<modulo2(fast)-modulo2(full)<<std::endl;
        if(std::fabs(modulo2(fast)-modulo2(full))>1e-15) plumed_error();
     }
    }
    std::cerr<<"Average number of shifts: "<<double(nshifts)/double(ntot)<<"\n";
  }
}
示例#11
0
void LatticeReduction::sort(Vector v[3]){
  for(int i=0;i<3;i++) for(int j=i+1;j<3;j++) if(modulo2(v[i])>modulo2(v[j])){
    Vector x=v[i]; v[i]=v[j]; v[j]=x;
  }
  for(int i=0;i<2;i++) plumed_assert(modulo2(v[i])<=modulo2(v[i+1]));
}
示例#12
0
文件: RMSD.cpp 项目: apoma/plumed2
double RMSD::optimalAlignment(const  std::vector<double>  & align,
                                     const  std::vector<double>  & displace,
                                     const std::vector<Vector> & positions,
                                     const std::vector<Vector> & reference ,
                                     std::vector<Vector>  & derivatives, bool squared) {
  plumed_massert(displace==align,"OPTIMAL_FAST version of RMSD can only be used when displace weights are same as align weights");

  double dist(0);
  double norm(0);
  const unsigned n=reference.size();
// This is the trace of positions*positions + reference*reference
  double sum00w(0);
// This is positions*reference
  Tensor sum01w;

  derivatives.resize(n);

  Vector cpositions;
  Vector creference;

// first expensive loop: compute centers
  for(unsigned iat=0;iat<n;iat++){
    double w=align[iat];
    norm+=w;
    cpositions+=positions[iat]*w;
    creference+=reference[iat]*w;
  }
  double invnorm=1.0/norm;

  cpositions*=invnorm;
  creference*=invnorm;
  
// second expensive loop: compute second moments wrt centers
  for(unsigned iat=0;iat<n;iat++){
    double w=align[iat];
    sum00w+=(dotProduct(positions[iat]-cpositions,positions[iat]-cpositions)
            +dotProduct(reference[iat]-creference,reference[iat]-creference))*w;
    sum01w+=Tensor(positions[iat]-cpositions,reference[iat]-creference)*w;
  }

  double rr00=sum00w*invnorm;
  Tensor rr01=sum01w*invnorm;

  Matrix<double> m=Matrix<double>(4,4);
  m[0][0]=rr00+2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
  m[1][1]=rr00+2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
  m[2][2]=rr00+2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
  m[3][3]=rr00+2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
  m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
  m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
  m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
  m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
  m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
  m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
  m[1][0] = m[0][1];
  m[2][0] = m[0][2];
  m[2][1] = m[1][2];
  m[3][0] = m[0][3];
  m[3][1] = m[1][3];
  m[3][2] = m[2][3];

  vector<double> eigenvals;
  Matrix<double> eigenvecs;
  int diagerror=diagMat(m, eigenvals, eigenvecs );

  if (diagerror!=0){
    string sdiagerror;
    Tools::convert(diagerror,sdiagerror);
    string msg="DIAGONALIZATION FAILED WITH ERROR CODE "+sdiagerror;
    plumed_merror(msg);
  }

  dist=eigenvals[0];

  Matrix<double> ddist_dm(4,4);

  Vector4d q(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);

// This is the rotation matrix that brings reference to positions
// i.e. matmul(rotation,reference[iat])+shift is fitted to positions[iat]

  Tensor rotation;
  rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
  rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
  rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
  rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
  rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
  rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
  rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
  rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
  rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);

  double prefactor=2.0*invnorm;
  Vector shift=cpositions-matmul(rotation,creference);

  if(!squared) prefactor*=0.5/sqrt(dist);

// if "safe", recompute dist here to a better accuracy
  if(safe) dist=0.0;

// If safe is set to "false", MSD is taken from the eigenvalue of the M matrix
// If safe is set to "true", MSD is recomputed from the rotational matrix
// For some reason, this last approach leads to less numerical noise but adds an overhead

// third expensive loop: derivatives
  for(unsigned iat=0;iat<n;iat++){
// there is no need for derivatives of rotation and shift here as it is by construction zero
// (similar to Hellman-Feynman forces)
    Vector d(positions[iat]-shift - matmul(rotation,reference[iat]));
    derivatives[iat]= prefactor*align[iat]*d;
    if(safe) dist+=align[iat]*invnorm*modulo2(d);
  }

  if(!squared) dist=sqrt(dist);

  return dist;
}