Exemplo n.º 1
0
Arquivo: ASMs1D.C Projeto: OPM/IFEM
bool ASMs1D::updateRotations (const Vector& displ, bool reInit)
{
  if (shareFE || nf != 6) return true;

  if (displ.size() != 6*myT.size())
  {
    std::cerr <<" *** ASMs1D::updateRotations: Invalid dimension "
	      << displ.size() <<" on displ, should be "
	      << 6*myT.size() << std::endl;
    return false;
  }

  if (reInit)
  {
    if (prevT.empty())
    {
      for (size_t i = 0; i < myT.size(); i++)
        myT[i] = Tensor(displ[6*i+3],displ[6*i+4],displ[6*i+5]);
      return true;
    }
    else
      myT = prevT; // Restore rotation tensors from previous step
  }

  for (size_t i = 0; i < myT.size(); i++)
    myT[i].preMult(Tensor(displ[6*i+3],displ[6*i+4],displ[6*i+5]));

  return true;
}
    inline void
    FixedQuadrupleListInteractionTemplate < _DihedralPotential >::
    computeVirialTensor(Tensor& w) {
      LOG4ESPP_INFO(theLogger, "compute the virial tensor of the quadruples");
    
      Tensor wlocal(0.0);
      const bc::BC& bc = *getSystemRef().bc;

      for (FixedQuadrupleList::QuadrupleList::Iterator it(*fixedquadrupleList); it.isValid(); ++it) {
        const Particle &p1 = *it->first;
        const Particle &p2 = *it->second;
        const Particle &p3 = *it->third;
        const Particle &p4 = *it->fourth;

        Real3D dist21, dist32, dist43; 

        bc.getMinimumImageVectorBox(dist21, p2.position(), p1.position());
        bc.getMinimumImageVectorBox(dist32, p3.position(), p2.position());
        bc.getMinimumImageVectorBox(dist43, p4.position(), p3.position());

        Real3D force1, force2, force3, force4;

        potential->_computeForce(force1, force2, force3, force4,
                                dist21, dist32, dist43);

        // TODO: formulas are not correct yet

        wlocal += Tensor(dist21, force1) - Tensor(dist32, force2);
      }
      // reduce over all CPUs
      Tensor wsum(0.0);
      boost::mpi::all_reduce(*mpiWorld, (double*)&wlocal, 6, (double*)&wsum, std::plus<double>());
      w += wsum;
    }
    template < typename _AngularPotential > inline void
    FixedTripleAngleListInteractionTemplate < _AngularPotential >::
    computeVirialTensor(Tensor& w) {
      LOG4ESPP_INFO(theLogger, "compute the virial tensor of the triples");

      Tensor wlocal(0.0);
      const bc::BC& bc = *getSystemRef().bc;
      for (FixedTripleAngleList::TripleList::Iterator it(*fixedtripleList); it.isValid(); ++it){
        const Particle &p1 = *it->first;
        const Particle &p2 = *it->second;
        const Particle &p3 = *it->third;
        //const Potential &potential = getPotential(0, 0);
        Real3D r12, r32;
        bc.getMinimumImageVectorBox(r12, p1.position(), p2.position());
        bc.getMinimumImageVectorBox(r32, p3.position(), p2.position());
        Real3D force12, force32;

        real currentAngle = fixedtripleList->getAngle(p1.getId(), p2.getId(), p3.getId());
        
        potential->_computeForce(force12, force32, r12, r32, currentAngle);
        wlocal += Tensor(r12, force12) + Tensor(r32, force32);
      }
      
      // reduce over all CPUs
      Tensor wsum(0.0);
      boost::mpi::all_reduce(*mpiWorld, (double*)&wlocal,6, (double*)&wsum, std::plus<double>());
      w += wsum;
    }
inline void
FixedTripleListTypesInteractionTemplate<_Potential>::computeVirialTensor(Tensor &w) {
  LOG4ESPP_INFO(theLogger, "compute the virial tensor for the FixedTriple List");

  Tensor wlocal(0.0);
  const bc::BC& bc = *getSystemRef().bc;
  for (FixedTripleList::TripleList::Iterator it(*fixedtripleList); it.isValid(); ++it) {
    const Particle &p1 = *it->first;
    const Particle &p2 = *it->second;
    const Particle &p3 = *it->third;
    int type1 = p1.type();
    int type2 = p2.type();
    int type3 = p3.type();
    const Potential &potential = getPotential(type1, type2, type3);
    Real3D r12, r32;
    bc.getMinimumImageVectorBox(r12, p1.position(), p2.position());
    bc.getMinimumImageVectorBox(r32, p3.position(), p2.position());
    Real3D force12, force32;
    potential._computeForce(force12, force32, r12, r32);
    wlocal += Tensor(r12, force12) + Tensor(r32, force32);
  }

  // reduce over all CPUs
  Tensor wsum(0.0);
  boost::mpi::all_reduce(*mpiWorld, wlocal, wsum, std::plus<Tensor>());
  w += wsum;
}
Exemplo n.º 5
0
poly* SAtensor(boolean alt,_index m,poly* p)
{ _index n,r=Lierank(grp); poly** adams,** q,* result;
  if (m==0) return poly_one(r);  else if (m==1) return p;

  adams=alloc_array(poly*,m+1); 
  for (n=1; n<=m; ++n) adams[n]=Adams(n,p);
  q=alloc_array(poly*,m+1);
  q[0]=poly_one(r);
  for (n=1; n<=m; ++n)
  { 
    { _index i; q[n]=Tensor(p,q[n-1]); /* the initial term of the summation */
      for (i=2; i<=n; ++i) q[n] =
        Add_pol_pol(q[n],Tensor(adams[i],q[n-i]),alt&&i%2==0);
    }
    
    { _index i; bigint* big_n=entry2bigint(n);  setshared(big_n);
      for (i=0; i<q[n]->nrows; ++i)
      { bigint** cc= &q[n]->coef[i]
             ,* c= (clrshared(*cc),isshared(*cc)) ? copybigint(*cc,NULL) : *cc;
        *cc=divq(c,big_n); setshared(*cc);
        
        { if (c->size != 0)
            error("Internal error (SAtensor): remainder from %ld.\n" ,(long)n);
          freemem(c);
        }
      }
      clrshared(big_n); freemem(big_n);
    }
  }
  result=q[m];
{ for (n=1; n<=m; ++n) freepol(adams[n]); } freearr(adams);
{ for (n=0; n<m; ++n)  freepol(q[n]); } freearr(q);
 return result;
}
Exemplo n.º 6
0
double VolumeTetrapore::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
  // Setup the histogram bead
  HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );

  // Calculate distance of atom from origin of new coordinate frame
  Vector datom=pbcDistance( origin, cpos );
  double ucontr, uder, vcontr, vder, wcontr, wder;

  // Calculate contribution from integral along bi
  bead.set( 0, len_bi, sigma );
  double upos=dotProduct( datom, bi );
  ucontr=bead.calculate( upos, uder );
  double udlen=bead.uboundDerivative( upos ); 
  double uder2 = bead.lboundDerivative( upos ) - udlen; 

  // Calculate contribution from integral along cross
  bead.set( 0, len_cross, sigma );
  double vpos=dotProduct( datom, cross );
  vcontr=bead.calculate( vpos, vder );
  double vdlen=bead.uboundDerivative( vpos );
  double vder2 = bead.lboundDerivative( vpos ) - vdlen;

  // Calculate contribution from integral along perp
  bead.set( 0, len_perp, sigma );
  double wpos=dotProduct( datom, perp );
  wcontr=bead.calculate( wpos, wder );
  double wdlen=bead.uboundDerivative( wpos );
  double wder2 = bead.lboundDerivative( wpos ) - wdlen;

  Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
  derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
  derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
  derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
  double tot = ucontr*vcontr*wcontr*jacob_det; 

  // Add reference atom derivatives
  dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
  Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
  rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
              dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives; 
  rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) + 
              dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
  rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) + 
              dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
  rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];

  vir.zero(); vir-=Tensor( cpos,derivatives );
  for(unsigned i=0;i<4;++i){
     vir -= Tensor( getPosition(i), rderiv[i] ); 
  }

  return tot;
}
Exemplo n.º 7
0
  pair<Tensor, float> computeSampleGradient(const TrainingSample &sample, NetworkContext &ctx) {
    Vector output = process(sample.input, ctx);

    ctx.layerDeltas.resize(numLayers);
    ctx.layerDeltas[ctx.layerDeltas.size() - 1] = output - sample.expectedOutput; // cross entropy error function.

    for (int i = ctx.layerDeltas.size() - 2; i >= 0; i--) {
      Matrix noBiasWeights =
          layerWeights(i+1).bottomRightCorner(layerWeights(i+1).rows(), layerWeights(i+1).cols()-1);
      ctx.layerDeltas[i] = noBiasWeights.transpose() * ctx.layerDeltas[i+1];

      assert(ctx.layerDeltas[i].rows() == ctx.layerOutputs[i].rows());
      for (unsigned r = 0; r < ctx.layerDeltas[i].rows(); r++) {
        float out = ctx.layerOutputs[i](r);
        ctx.layerDeltas[i](r) *= out * (1.0f - out);
      }
    }

    auto result = make_pair(Tensor(), 0.0f);
    for (unsigned i = 0; i < numLayers; i++) {
      auto inputs = getInputWithBias(i == 0 ? sample.input : ctx.layerOutputs[i-1]);
      result.first.AddLayer(ctx.layerDeltas[i] * inputs.transpose());
    }

    for (unsigned i = 0; i < output.rows(); i++) {
      result.second += (output(i) - sample.expectedOutput(i)) * (output(i) - sample.expectedOutput(i));
    }

    return result;
  }
Exemplo n.º 8
0
Tensor TensorFieldFunction::evaluate (const Vec3& X) const
{
  if (pidx >= field.size() || !field[pidx])
    return Tensor(3);

  return const_cast<TensorFieldFunction*>(this)->getValues(X);
}
Exemplo n.º 9
0
double ContactAlignedMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  double f_dot, dot_df; 

  std::vector<double> orient0(ncomp), orient1(ncomp);
  getOrientationVector( myatoms.getIndex(0), true, orient0 );
  getOrientationVector( myatoms.getIndex(1), true, orient1 );
  double dot=0; for(unsigned k=2;k<orient0.size();++k) dot+=orient0[k]*orient1[k];
  f_dot=0.5*( 1 + dot ); dot_df=0.5; 

  // Retrieve the weight of the connection
  double weight = myatoms.getValue(0); myatoms.setValue(0,1.0); 

  if( !doNotCalculateDerivatives() ){
      Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
      double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( distance.modulo(), dfunc );
      addAtomDerivatives( 1, 0, (-dfunc)*f_dot*distance, myatoms );
      addAtomDerivatives( 1, 1, (+dfunc)*f_dot*distance, myatoms ); 
      myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) ); 

      // Add derivatives of orientation 
      for(unsigned k=2;k<orient0.size();++k){ orient0[k]*=sw*dot_df; orient1[k]*=sw*dot_df; }
      addOrientationDerivatives( 1, 0, orient1, myatoms );
      addOrientationDerivatives( 1, 1, orient0, myatoms );
  }
  return weight*f_dot;
}
Exemplo n.º 10
0
void Mapping::mergeDerivatives( const unsigned& ider, const double& df ){
  unsigned cur = getCurrentTask(), frameno=ider*getNumberOfReferencePoints() + cur;
  for(unsigned i=0;i<getNumberOfArguments();++i){
      accumulateDerivative( i, df*dfframes[frameno]*mymap->getArgumentDerivative(cur,i) );
  }
  if( getNumberOfAtoms()>0 ){
      Vector ader; Tensor tmpvir; tmpvir.zero();
      unsigned n=getNumberOfArguments(); 
      for(unsigned i=0;i<getNumberOfAtoms();++i){
          ader=mymap->getAtomDerivatives( cur, i );            
          accumulateDerivative( n, df*dfframes[frameno]*ader[0] ); n++;
          accumulateDerivative( n, df*dfframes[frameno]*ader[1] ); n++;
          accumulateDerivative( n, df*dfframes[frameno]*ader[2] ); n++;
          tmpvir += -1.0*Tensor( getPosition(i), ader );
      }
      Tensor vir; 
      if( !mymap->getVirial( cur, vir ) ) vir=tmpvir;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(0,2) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(1,2) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,0) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,1) ); n++;
      accumulateDerivative( n, df*dfframes[frameno]*vir(2,2) ); 
  }
}
Exemplo n.º 11
0
double DistanceFromContour::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
  Vector distance = getSeparation( getPosition(getNumberOfAtoms()-1), myatoms.getPosition(0) );
  std::vector<double> pp(3), der(3,0); for(unsigned j=0;j<3;++j) pp[j] = distance[j]; 

  // Now create the kernel and evaluate
  KernelFunctions kernel( pp, bw, kerneltype, false, 1.0, true );
  double newval = kernel.evaluate( pval, der, true );

  if( mybasemulticolvars[0]->isDensity() ){ 
      if( !doNotCalculateDerivatives() && derivTime ){
          MultiValue& myvals=myatoms.getUnderlyingMultiValue();
          Vector vder; unsigned basen=myvals.getNumberOfDerivatives() - 12;
          for(unsigned i=0;i<3;++i){ 
              vder[i]=der[i]; myvals.addDerivative( 1, basen+i, vder[i] ); 
          }
          myatoms.setValue( 2, der[dir] );
          addAtomDerivatives( 1, 0, -vder, myatoms );
          myatoms.addBoxDerivatives( 1, Tensor(vder,distance) );
      }
      myatoms.setValue( 0, 1.0 ); return newval; 
  }

  // This does the stuff for averaging
  myatoms.setValue( 0, newval );

  // This gets the average if we are using a phase field
  std::vector<double> cvals( mybasemulticolvars[0]->getNumberOfQuantities() );
  mybasedata[0]->retrieveValueWithIndex( tindex, false, cvals );
  return newval*cvals[0]*cvals[1]; 
}
Exemplo n.º 12
0
poly* Plethysm(entry* lambda,_index l,_index n,poly* p)
{ if (n==0) return poly_one(Lierank(grp));  else if (n==1) return p;

  { _index i,j;
    poly* sum= poly_null(Lierank(grp)),**adams=alloc_array(poly*,n+1);
    poly* chi_lambda=MN_char(lambda,l);
    for (i=1; i<=n; ++i) { adams[i]=Adams(i,p); setshared(adams[i]); }
    
    for (i=0;i<chi_lambda->nrows;i++)
    { entry* mu=chi_lambda->elm[i]; poly* prod=adams[mu[0]],*t;
      for (j=1; j<n && mu[j]>0; ++j)
        { t=prod; prod=Tensor(t,adams[mu[j]]); freepol(t); }
      sum= Addmul_pol_pol_bin(sum,prod,mult(chi_lambda->coef[i],Classord(mu,n)));
    }
    freemem(chi_lambda);
    setshared(p); /* protect |p|; it coincides with |adams[1]| */
    for (i=1; i<=n; ++i)
      { clrshared(adams[i]); freepol(adams[i]); }  freearr(adams);
  clrshared(p);

    
    { bigint* fac_n=fac(n);  setshared(fac_n); /* used repeatedly */
      for (i=0; i<sum->nrows; ++i)
      { bigint** cc= &sum->coef[i]
             ,* c= (clrshared(*cc),isshared(*cc)) ? copybigint(*cc,NULL) : *cc;
        *cc=divq(c,fac_n); setshared(*cc);
        if (c->size!=0) error("Internal error (plethysm).\n");  else freemem(c);
      }
      clrshared(fac_n); freemem(fac_n);
    }
    return sum;
  }
}
Exemplo n.º 13
0
double OrientationSphere::compute(){
   // Make sure derivatives for central atom are only calculated once
   VectorMultiColvar* vv = dynamic_cast<VectorMultiColvar*>( getBaseMultiColvar(0) );
   vv->firstcall=true;

   weightHasDerivatives=true;   // The weight has no derivatives really
   double sw, value=0, denom=0, dot, f_dot, dot_df, dfunc; Vector distance;

   getVectorForBaseTask(0, catom_orient );
   for(unsigned i=1;i<getNAtoms();++i){
      distance=getSeparation( getPositionOfCentralAtom(0), getPositionOfCentralAtom(i) );
      sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
      if( sw>=getTolerance() ){    
         getVectorForBaseTask( i, this_orient );
         // Calculate the dot product wrt to this position 
         dot=0; for(unsigned k=0;k<catom_orient.size();++k) dot+=catom_orient[k]*this_orient[k];  
         f_dot = transformDotProduct( dot, dot_df ); 
         // N.B. We are assuming here that the imaginary part of the dot product is zero
         for(unsigned k=0;k<catom_orient.size();++k){
            this_orient[k]*=sw*dot_df; catom_der[k]=sw*dot_df*catom_orient[k];
         }  

         // Set the derivatives wrt of the numerator
         addOrientationDerivatives( 0, this_orient ); 
         addOrientationDerivatives( i, catom_der );  
         addCentralAtomsDerivatives( 0, 0, f_dot*(-dfunc)*distance );
         addCentralAtomsDerivatives( i, 0, f_dot*(dfunc)*distance );
         addBoxDerivatives( f_dot*(-dfunc)*Tensor(distance,distance) );
         value += sw*f_dot;
         // Set the derivatives wrt to the numerator
         addCentralAtomsDerivatives( 0, 1, (-dfunc)*distance );
         addCentralAtomsDerivatives( i, 1, (dfunc)*distance );
         addBoxDerivativesOfWeight( (-dfunc)*Tensor(distance,distance) );
         denom += sw;
      }
   }
   
   // Now divide everything
   unsigned nder = getNumberOfDerivatives();
   for(unsigned i=0;i<nder;++i){
      setElementDerivative( i, getElementDerivative(i)/denom - (value*getElementDerivative(nder+i))/(denom*denom) );  
      setElementDerivative( nder + i, 0.0 );
   }
   weightHasDerivatives=false;   // Weight has no derivatives we just use the holder for weight to store some stuff
   return value / denom;
}
Exemplo n.º 14
0
void Colvar::setBoxDerivativesNoPbc(Value* v){
  Tensor virial;
  unsigned nat=getNumberOfAtoms();
  for(unsigned i=0;i<nat;i++) virial-=Tensor(getPosition(i),
    Vector(v->getDerivative(3*i+0),
           v->getDerivative(3*i+1),
           v->getDerivative(3*i+2)));
  setBoxDerivatives(v,virial);
}
void BondOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
  Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );

  addAtomDerivatives( 2, 0, Vector(-1.0,0,0), myatoms );
  addAtomDerivatives( 2, 1, Vector(+1.0,0,0), myatoms );
  myatoms.addBoxDerivatives( 2, Tensor(distance,Vector(-1.0,0,0)) );
  myatoms.addValue( 2, distance[0] );

  addAtomDerivatives( 3, 0, Vector(0,-1.0,0), myatoms );
  addAtomDerivatives( 3, 1, Vector(0,+1.0,0), myatoms );
  myatoms.addBoxDerivatives( 3, Tensor(distance,Vector(0,-1.0,0)) );
  myatoms.addValue( 3, distance[1] );

  addAtomDerivatives( 4, 0, Vector(0,0,-1.0), myatoms );
  addAtomDerivatives( 4, 1, Vector(0,0,+1.0), myatoms );
  myatoms.addBoxDerivatives( 4, Tensor(distance,Vector(0,0,-1.0)) );
  myatoms.addValue( 4, distance[2] );
}
inline void
FixedQuadrupleListTypesInteractionTemplate<_DihedralPotential>::
computeVirialTensor(Tensor &w, real z) {
    LOG4ESPP_INFO(theLogger, "compute the virial tensor of the quadruples");

    Tensor wlocal(0.0);
    const bc::BC &bc = *getSystemRef().bc;

    std::cout << "Warning!!! computeVirialTensor in specified volume doesn't work for "
              "FixedQuadrupleListTypesInteractionTemplate at the moment" << std::endl;

    for (FixedQuadrupleList::QuadrupleList::Iterator it(*fixedquadrupleList); it.isValid(); ++it) {
        const Particle &p1 = *it->first;
        const Particle &p2 = *it->second;
        const Particle &p3 = *it->third;
        const Particle &p4 = *it->fourth;

        longint type1 = p1.type();
        longint type2 = p2.type();
        longint type3 = p3.type();
        longint type4 = p4.type();

        const Potential &potential = getPotential(type1, type2, type3, type4);

        Real3D dist21, dist32, dist43;

        bc.getMinimumImageVectorBox(dist21, p2.position(), p1.position());
        bc.getMinimumImageVectorBox(dist32, p3.position(), p2.position());
        bc.getMinimumImageVectorBox(dist43, p4.position(), p3.position());

        Real3D force1, force2, force3, force4;

        potential.computeForce(force1, force2, force3, force4,
                               dist21, dist32, dist43);

        // TODO: formulas are not correct yet

        wlocal += Tensor(dist21, force1) - Tensor(dist32, force2);
    }
    // reduce over all CPUs
    Tensor wsum(0.0);
    boost::mpi::all_reduce(*mpiWorld, (double *) &wlocal, 6, (double *) &wsum, std::plus<double>());
    w += wsum;
}
Exemplo n.º 17
0
	TTTensor peaking_diagonals(size_t _degree, size_t _n, value_t _alpha) {
		REQUIRE(_degree >= 2, "");
		REQUIRE(_n>=2, "");
		TTTensor e1(Tensor({_n}, [](){return 1.0;}));
		TTTensor cross(Tensor({_n,_n}, [&](const std::vector<size_t> &idx){
			return 1.0/(double(idx[0]>idx[1]?idx[0]-idx[1]:idx[1]-idx[0]) + _alpha) + 1.0/(double(idx[0])+_alpha) + 1.0/(double(idx[1])+_alpha);
		}));
		
		TTTensor result(cross);
		TTTensor buffer(e1);
		while (result.degree() < _degree) {
			result = dyadic_product(result, e1);
			TTTensor tmp = dyadic_product(buffer, cross);
			result += tmp;
			result.round(0.0);
			buffer = dyadic_product(buffer, e1);
		}
		return result;
	}
Exemplo n.º 18
0
// calculator
void CoordinationBase::calculate()
{

 double ncoord=0.;
 Tensor virial;
 vector<Vector> deriv(getNumberOfAtoms());
// deriv.resize(getPositions().size());

 if(nl->getStride()>0 && invalidateList){
   nl->update(getPositions());
 }

 unsigned stride=comm.Get_size();
 unsigned rank=comm.Get_rank();
 if(serial){
   stride=1;
   rank=0;
 }else{
   stride=comm.Get_size();
   rank=comm.Get_rank();
 }

 for(unsigned int i=rank;i<nl->size();i+=stride) {                   // sum over close pairs
 
  Vector distance;
  unsigned i0=nl->getClosePair(i).first;
  unsigned i1=nl->getClosePair(i).second;

  if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue;

  if(pbc){
   distance=pbcDistance(getPosition(i0),getPosition(i1));
  } else {
   distance=delta(getPosition(i0),getPosition(i1));
  }

  double dfunc=0.;
  ncoord += pairing(distance.modulo2(), dfunc,i0,i1);

  deriv[i0] = deriv[i0] + (-dfunc)*distance ;
  deriv[i1] = deriv[i1] + dfunc*distance ;
  virial=virial+(-dfunc)*Tensor(distance,distance);
 }

 if(!serial){
   comm.Sum(ncoord);
   if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
   comm.Sum(virial);
 }

 for(unsigned i=0;i<deriv.size();++i) setAtomsDerivatives(i,deriv[i]);
 setValue           (ncoord);
 setBoxDerivatives  (virial);

}
Exemplo n.º 19
0
double ContactMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  if( !doNotCalculateDerivatives() ){
      Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
      double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).calculate( distance.modulo(), dfunc );
      addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
      addAtomDerivatives( 1, 1, (+dfunc)*distance, myatoms ); 
      myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor(distance,distance) ); 
  }
  double val=myatoms.getValue(0); myatoms.setValue(0,1.0);
  return val;
}
Exemplo n.º 20
0
Arquivo: ASMs1D.C Projeto: OPM/IFEM
bool ASMs1D::initLocalElementAxes (const Vec3& Zaxis)
{
  // Calculate local element axes for 3D beam elements
  for (size_t i = 0; i < myCS.size(); i++)
    if (MLGE[i] > 0)
    {
      Vec3 X1 = this->getCoord(1+MNPC[i].front());
      Vec3 X2 = this->getCoord(1+MNPC[i][curv->order()-1]);
      if (Zaxis.isZero())
        myCS[i] = Tensor(X2-X1,true);
      else
        myCS[i] = Tensor(X2-X1,Zaxis,false,true);
#ifdef SP_DEBUG
      std::cout <<"Local axes for beam element "<< MLGE[i]
                <<", from "<< X1 <<" to "<< X2 <<":\n"<< myCS[i];
#endif
    }

  return true;
}
Exemplo n.º 21
0
void SecondaryStructureRMSD::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
  // Retrieve the positions
  std::vector<Vector> pos( references[0]->getNumberOfAtoms() );
  const unsigned n=pos.size();
  for(unsigned i=0;i<n;++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) );

  // This does strands cutoff
  Vector distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] ); 
  if( s_cutoff2>0 ){
     if( distance.modulo2()>s_cutoff2 ){
       myvals.setValue( 0, 0.0 );
       return;
     }
  }

  // This aligns the two strands if this is required
  if( alignType!="DRMSD" && align_strands ){
     Vector origin_old, origin_new; origin_old=pos[align_atom_2];
     origin_new=pos[align_atom_1]+distance;
     for(unsigned i=15;i<30;++i){
         pos[i]+=( origin_new - origin_old );
     }
  }
  // Create a holder for the derivatives
  ReferenceValuePack mypack( 0, pos.size(), myvals ); mypack.setValIndex( 1 );
  for(unsigned i=0;i<n;++i) mypack.setAtomIndex( i, getAtomIndex(current,i) );

  // And now calculate the RMSD
  const Pbc& pbc=getPbc(); 
  unsigned closest=0; 
  double r = references[0]->calculate( pos, pbc, mypack, false );
  const unsigned rs = references.size();
  for(unsigned i=1;i<rs;++i){
    mypack.setValIndex( i+1 );
    double nr=references[i]->calculate( pos, pbc, mypack, false );
    if( nr<r ){ closest=i; r=nr; }
  }

  // Transfer everything to the value
  myvals.setValue( 0, 1.0 ); myvals.setValue( 1, r );
  if( closest>0 ) mypack.moveDerivatives( closest+1, 1 );

  if( !mypack.virialWasSet() ){
    Tensor vir;
    const unsigned cacs = colvar_atoms[current].size();
    for(unsigned i=0;i<cacs;++i){
       vir+=(-1.0*Tensor( pos[i], mypack.getAtomDerivative(i) ));
    } 
    mypack.setValIndex(1); mypack.addBoxDerivatives( vir );
  }

  return;
}
Exemplo n.º 22
0
void FacenetClassifier::create_input_tensor (long start_index, long end_index) {
	cout << "Using " << input_images.size() << " images" << endl;
	cout << "Start Index:" << start_index << " End Index:" << end_index << endl;
	Tensor input_tensor(DT_FLOAT, TensorShape({(int) (end_index - start_index), 160, 160, 3}));
	// get pointer to memory for that Tensor
	float *p = input_tensor.flat<float>().data();
	int i;
	
	for (i = 0; i < (end_index - start_index) ; i++) {
		// create a "fake" cv::Mat from it 

		Mat camera_image(160, 160, CV_32FC3, p + i*160*160*3);	
		input_images[i + start_index].convertTo(camera_image, CV_32FC3);
	}
	cout << input_tensor.DebugString() << endl;
	this->input_tensor = Tensor (input_tensor);
}
Exemplo n.º 23
0
double TopologyMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
  HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );

  // Initialise to zero density on all bins
  for(unsigned bin=0; bin<maxbins; ++bin) myatoms.setValue(bin+1,0);
  // Calculate whether or not atoms 1 and 2 are within cutoff (can use delta here as pbc are done in atom setup)
  Vector d1 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double d1_len = d1.modulo();
  d1 = d1 / d1_len;  // Convert vector into director
  AtomNumber a1 = myatoms.getAbsoluteIndex( 0 );
  AtomNumber a2 = myatoms.getAbsoluteIndex( 1 );
  for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
    AtomNumber a3 = myatoms.getAbsoluteIndex( i );
    if( a3!=a1 && a3!=a2 ) calculateForThreeAtoms( i, d1, d1_len, bead, myatoms );
  }
  // std::vector<double> binvals( 1+maxbins ); for(unsigned i=1;i<maxbins;++i) binvals[i]=myatoms.getValue(i);
  // unsigned ii; double fdf;
  //std::cout<<"HELLO DENSITY "<<myatoms.getIndex(0)<<" "<<myatoms.getIndex(1)<<" "<<transformStoredValues( binvals, ii, fdf )<<std::endl;

  // Now find the element for which the density is maximal
  unsigned vout=2; double max=myatoms.getValue( 2 );
  for(unsigned i=3; i<myatoms.getUnderlyingMultiValue().getNumberOfValues()-1; ++i) {
    if( myatoms.getValue(i)>max ) { max=myatoms.getValue(i); vout=i; }
  }
  // Calculate value and derivative of switching function between atoms 1 and 2
  double dfuncl, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ),
                                         getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( d1_len, dfuncl );
  // Transform the density
  double df, tsw = threshold_switch.calculate( max, df );
  if( !doNotCalculateDerivatives() ) {
    // Factor of d1_len is required here because d1 is normalized
    d1 *= d1_len;
    addAtomDerivatives( 2+maxbins, 0, -dfuncl*d1, myatoms );
    addAtomDerivatives( 2+maxbins, 1, dfuncl*d1, myatoms );
    myatoms.addBoxDerivatives( 2+maxbins, (-dfuncl)*Tensor(d1,d1) );
    // Update active atoms so that next bit works
    updateActiveAtoms( myatoms );
    // Now finish caclulation of derivatives
    MultiValue& myvals=myatoms.getUnderlyingMultiValue();
    for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
      unsigned ider=myvals.getActiveIndex(jd);
      myvals.addDerivative( 1, ider, sw*df*max*myvals.getDerivative( vout, ider ) + tsw*myvals.getDerivative( 2+maxbins, ider ) );
    }
  }
  return sw*tsw;
}
Exemplo n.º 24
0
void DFSClusterDiameter::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const { 
  unsigned iatom=current/getNumberOfNodes(), jatom = current - iatom*getNumberOfNodes();
  Vector distance=getSeparation( getPosition(iatom), getPosition(jatom) );
  double dd = distance.modulo(), inv = 1.0/dd ; myvals.setValue( 1, dd ); 
  if( !doNotCalculateDerivatives() ){
      myvals.addDerivative( 1, 3*iatom + 0, -inv*distance[0] );
      myvals.addDerivative( 1, 3*iatom + 1, -inv*distance[1] );
      myvals.addDerivative( 1, 3*iatom + 2, -inv*distance[2] );
      myvals.addDerivative( 1, 3*jatom + 0, +inv*distance[0] );
      myvals.addDerivative( 1, 3*jatom + 1, +inv*distance[1] );
      myvals.addDerivative( 1, 3*jatom + 2, +inv*distance[2] );
      Tensor vir = -inv*Tensor(distance,distance);
      unsigned vbase = myvals.getNumberOfDerivatives() - 9;
      for(unsigned i=0;i<3;++i){
          for(unsigned j=0;j<3;++j) myvals.addDerivative( 1, vbase+3*i+j, vir(i,j) );
      }
  }
}
Exemplo n.º 25
0
Arquivo: ASMs1D.C Projeto: OPM/IFEM
bool ASMs1D::generateTwistedFEModel (const RealFunc& twist, const Vec3& Zaxis)
{
  if (!this->generateOrientedFEModel(Zaxis))
    return false;

  // Update the local element axes for 3D beam elements
  Tensor rotX(3);
  for (size_t i = 0; i < myCS.size(); i++)
    if (MLGE[i] > 0)
    {
      Vec3 X1 = this->getCoord(1+MNPC[i].front());
      Vec3 X2 = this->getCoord(1+MNPC[i][curv->order()-1]);
      double alpha = twist(0.5*(X1+X2)); // twist angle in the element mid-point
      myCS[i] *= Tensor(alpha*M_PI/180.0,1); // rotate about local X-axis
#ifdef SP_DEBUG
      std::cout <<"Twisted axes for beam element "<< MLGE[i]
                <<", from "<< X1 <<" to "<< X2 <<":\n"<< myCS[i];
#endif
    }

  return true;
}
Exemplo n.º 26
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
  plumed_dbg_assert(!targets.empty());

  Vector distance; 
  myder.clear(); 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      const unsigned i=getAtomIndex( it->first.first );
      const unsigned j=getAtomIndex( it->first.second );

      if(nopbc) distance=delta( pos[i] , pos[j] ); 
      else      distance=pbc.distance( pos[i] , pos[j] );

      const double len = distance.modulo();
      const double diff = len - it->second;
      const double der = diff / len; 

      drmsd += diff * diff;
      myder.addAtomDerivatives( i, -der * distance );
      myder.addAtomDerivatives( j,  der * distance );
      myder.addBoxDerivatives( - der * Tensor(distance,distance) );
  }

  const double inpairs = 1./static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd * inpairs;
     idrmsd = 2.0 * inpairs;
  } else {
     drmsd = sqrt( drmsd * inpairs );
     idrmsd = inpairs / drmsd ;
  }

  myder.scaleAllDerivatives( idrmsd );

  return drmsd;
}
Exemplo n.º 27
0
double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const bool& squared ){
  plumed_dbg_assert( !targets.empty() );

  Vector distance; 
  double drmsd=0.; 
  for(std::map< std::pair <unsigned,unsigned> , double>::const_iterator it=targets.begin();it!=targets.end();++it){
      
      unsigned i=getAtomIndex( it->first.first );
      unsigned j=getAtomIndex( it->first.second );

      if(nopbc){ distance=delta( pos[i] , pos[j] ); }
      else{ distance=pbc.distance( pos[i] , pos[j] ); }

      double len = distance.modulo();
      double diff = len - it->second;

      drmsd += diff * diff;
      addAtomicDerivatives( i, -( diff / len ) * distance );
      addAtomicDerivatives( j, ( diff / len ) * distance );
      addBoxDerivatives( -( diff / len ) * Tensor(distance,distance) );
  }

  double npairs = static_cast<double>(targets.size());
  double idrmsd;

  if(squared){
     drmsd = drmsd / npairs;
     idrmsd = 2.0 / npairs;
  } else {
     drmsd = sqrt( drmsd / npairs );
     idrmsd = 1.0/( drmsd * npairs );
  }

  virial *= idrmsd; 
  for(unsigned i=0;i<getNumberOfAtoms();++i){atom_ders[i] *= idrmsd;}

  return drmsd;
}
Exemplo n.º 28
0
 static inline const Tensor
 do_string_order_many(const iTEBD<Tensor> &psi,
                      const Tensor &Opi, const Tensor &Opmiddle,
                      const Tensor &Opj, int N)
 {
   if (!psi.is_canonical()) {
     return do_string_order_many(psi.canonical_form(), Opi, Opmiddle, Opj, N);
   } else {
     Tensor v1 = psi.left_boundary(0);
     Tensor v2 = v1;
     Tensor output(N);
     Tensor nextv2;
     for (int site = 0; (site < N); ++site) {
       const Tensor &aux = psi.combined_matrix(site);
       Tensor v = propagate_right(v1, aux, site? Opj : mmult(Opi,Opj));
       if (nextv2.size()) {
         v2 = nextv2;
       } else {
         v2 = propagate_right(v2, aux);
       }
       if (!(site & 1)) {
         const Tensor &aux = psi.combined_matrix(site+1);
         nextv2 = propagate_right(v2, aux);
         v = propagate_right(v, aux);
         output.at(site) = trace(v) / trace(nextv2);
       } else {
         nextv2 = Tensor();
         output.at(site) = trace(v) / trace(v2);
       }
       if (site) {
         v1 = propagate_right(v1, aux, Opmiddle);
       } else {
         v1 = propagate_right(v1, aux, Opi);
       }
     }
     return output;
   }
 }
Exemplo n.º 29
0
double OrientationSphere::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
   // Make sure derivatives for central atom are only calculated once
   VectorMultiColvar* vv = dynamic_cast<VectorMultiColvar*>( getBaseMultiColvar(0) );
   vv->firstcall=true;

   double d2, sw, value=0, denom=0, dot, f_dot, dot_df, dfunc; 
   unsigned ncomponents=getBaseMultiColvar(0)->getNumberOfQuantities();
   unsigned nder=myatoms.getNumberOfDerivatives();
   std::vector<double> catom_orient( ncomponents ), this_orient( ncomponents ), catom_der( ncomponents ); 

   Vector catom_pos = myatoms.getPosition(0);
   getVectorForTask( myatoms.getIndex(0), true, catom_orient );
   multicolvar::CatomPack atom0; MultiValue myder0(0,0), myder1(0,0); 
   if( !doNotCalculateDerivatives() ){
       myder0.resize( ncomponents,nder ); myder1.resize(ncomponents,nder); 
       atom0=getCentralAtomPackFromInput( myatoms.getIndex(0) );
       getVectorDerivatives( myatoms.getIndex(0), true, myder0 );
   }

   for(unsigned i=1;i<myatoms.getNumberOfAtoms();++i){
      Vector& distance=myatoms.getPosition(i);  
      if ( (d2=distance[0]*distance[0])<rcut2 &&
           (d2+=distance[1]*distance[1])<rcut2 &&
           (d2+=distance[2]*distance[2])<rcut2) {
 
         sw = switchingFunction.calculateSqr( d2, dfunc );  
 
         getVectorForTask( myatoms.getIndex(i), true, this_orient );
         // Calculate the dot product wrt to this position 
         dot=0; for(unsigned k=2;k<catom_orient.size();++k) dot+=catom_orient[k]*this_orient[k];  
         f_dot = transformDotProduct( dot, dot_df ); 

         if( !doNotCalculateDerivatives() ){
             // N.B. We are assuming here that the imaginary part of the dot product is zero
             for(unsigned k=2;k<catom_orient.size();++k){
                 this_orient[k]*=sw*dot_df; catom_der[k]=sw*dot_df*catom_orient[k];
             }
             getVectorDerivatives( myatoms.getIndex(i), true, myder1 );
             mergeVectorDerivatives( 1, 2, this_orient.size(), myatoms.getIndex(0), this_orient, myder0, myatoms );  
             mergeVectorDerivatives( 1, 2, catom_der.size(), myatoms.getIndex(i), catom_der, myder1, myatoms );
             myatoms.addComDerivatives( 1, f_dot*(-dfunc)*distance, atom0 );
             addAtomDerivatives( 1, i, f_dot*(dfunc)*distance, myatoms );
             myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) );
             myder1.clearAll();
              
             myatoms.addComDerivatives( -1, (-dfunc)*distance, atom0 );
             addAtomDerivatives( -1, i, (dfunc)*distance, myatoms );
             myatoms.addTemporyBoxDerivatives( (-dfunc)*Tensor(distance,distance) );

         }
         value += sw*f_dot;
         denom += sw;
      }
   }
   double rdenom, df2, pref=calculateCoordinationPrefactor( denom, df2 );
   if( fabs(denom)>epsilon ){ rdenom = 1.0 / denom; }
   else { plumed_assert(fabs(value)<epsilon); rdenom=1.0; } 
  
   // Now divide everything
   double rdenom2=rdenom*rdenom;
   updateActiveAtoms( myatoms ); MultiValue& myvals=myatoms.getUnderlyingMultiValue();
   for(unsigned i=0;i<myvals.getNumberActive();++i){
       unsigned ider=myvals.getActiveIndex(i);
       double  dgd=myvals.getTemporyDerivative(ider);
       myvals.setDerivative( 1, ider, rdenom*(pref*myvals.getDerivative(1,ider)+value*df2*dgd) - (value*pref*dgd)*rdenom2 );
   } 

   return pref*rdenom*value;
}
Exemplo n.º 30
0
Tensor5D CVX_ADMM_MSA (SequenceSet& allSeqs, vector<int>& lenSeqs, int T2, string& dir_path) {
    // 1. initialization
    int numSeq = allSeqs.size();
    vector<Tensor4D> C (numSeq, Tensor4D(0, Tensor(T2, Matrix(NUM_DNA_TYPE,
                        vector<double>(NUM_MOVEMENT, 0.0)))));  
    vector<Tensor4D> W_1 (numSeq, Tensor4D(0, Tensor(T2, Matrix(NUM_DNA_TYPE,
                        vector<double>(NUM_MOVEMENT, 0.0)))));  
    vector<Tensor4D> W_2 (numSeq, Tensor4D(0, Tensor(T2, Matrix(NUM_DNA_TYPE,
                        vector<double>(NUM_MOVEMENT, 0.0)))));  
    vector<Tensor4D> Y (numSeq, Tensor4D(0, Tensor(T2, Matrix(NUM_DNA_TYPE,
                        vector<double>(NUM_MOVEMENT, 0.0)))));  
    tensor5D_init (C, allSeqs, lenSeqs, T2);
    tensor5D_init (W_1, allSeqs, lenSeqs, T2);
    tensor5D_init (W_2, allSeqs, lenSeqs, T2);
    tensor5D_init (Y, allSeqs, lenSeqs, T2);
    set_C (C, allSeqs);

    // 2. ADMM iteration
    int iter = 0;
    double mu = MU;
    double prev_CoZ = MAX_DOUBLE;
    while (iter < MAX_ADMM_ITER) {
        // 2a. Subprogram: FrankWolf Algorithm
        // NOTE: parallelize this for to enable parallelism
#ifdef PARRALLEL_COMPUTING
#pragma omp parallel for
#endif
        for (int n = 0; n < numSeq; n++) 
            first_subproblem (W_1[n], W_2[n], Y[n], C[n], mu, allSeqs[n]);

        // 2b. Subprogram: 
        second_subproblem (W_1, W_2, Y, mu, allSeqs, lenSeqs);
	
        // 2d. update Y: Y += mu * (W_1 - W_2)
        for (int n = 0; n < numSeq; n ++)
            tensor4D_lin_update (Y[n], W_1[n], W_2[n], mu);

        // 2e. print out tracking info
        double CoZ = 0.0;
        for (int n = 0; n < numSeq; n++) 
            CoZ += tensor4D_frob_prod(C[n], W_2[n]);
        double W1mW2 = 0.0;
        for (int n = 0; n < numSeq; n ++) {
            int T1 = W_1[n].size();
            for (int i = 0; i < T1; i ++) 
                for (int j = 0; j < T2; j ++) 
                    for (int d = 0; d < NUM_DNA_TYPE; d ++) 
                        for (int m = 0; m < NUM_MOVEMENT; m ++) {
                            double value = (W_1[n][i][j][d][m] - W_2[n][i][j][d][m]);
                            W1mW2 = max( fabs(value), W1mW2 ) ;
                        }
        }
        ///////////////////////////////////Copy from Main/////////////////////////////////////////
	int T2m = T2;
	Tensor tensor (T2m, Matrix (NUM_DNA_TYPE, vector<double>(NUM_DNA_TYPE, 0.0)));
	Matrix mat_insertion (T2m, vector<double> (NUM_DNA_TYPE, 0.0));
	for (int n = 0; n < numSeq; n ++) {
		int T1 = W_2[n].size();
		for (int i = 0; i < T1; i ++) { 
			for (int j = 0; j < T2m; j ++) {
				for (int d = 0; d < NUM_DNA_TYPE; d ++) {
					for (int m = 0; m < NUM_MOVEMENT; m ++) {
						if (m == DELETION_A or m == MATCH_A)
							tensor[j][d][dna2T3idx('A')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == DELETION_T or m == MATCH_T)
							tensor[j][d][dna2T3idx('T')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == DELETION_C or m == MATCH_C)
							tensor[j][d][dna2T3idx('C')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == DELETION_G or m == MATCH_G)
							tensor[j][d][dna2T3idx('G')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == DELETION_START or m == MATCH_START)
							tensor[j][d][dna2T3idx('*')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == DELETION_END or m == MATCH_END)
							tensor[j][d][dna2T3idx('#')] += max(0.0, W_2[n][i][j][d][m]);
						else if (m == INSERTION) 
							mat_insertion[j][d] += max(0.0, W_2[n][i][j][d][m]);
					}
				}
			}
		}
	}
	Trace trace (0, Cell(2)); // 1d: j, 2d: ATCG
	refined_viterbi_algo (trace, tensor, mat_insertion);
	
	Sequence recSeq;
	for (int i = 0; i < trace.size(); i ++) 
		if (trace[i].action != INSERTION) {
			recSeq.push_back(trace[i].acidB);
			if (trace[i].acidB == '#') break;
		}
	////////////////////////////////END copy from MAIN/////////////////////////////////////////////////////
	
	SequenceSet allModelSeqs, allDataSeqs;
        double obj_rounded = 0.0;
        for (int n = 0; n < numSeq; n ++) {
            Sequence model_seq = recSeq, data_seq = allSeqs[n];
            data_seq.erase(data_seq.begin());
            model_seq.erase(model_seq.begin());
            data_seq.erase(data_seq.end()-1);
            model_seq.erase(model_seq.end()-1);

            // align sequences locally
            Plane plane (data_seq.size()+1, Trace(model_seq.size()+1, Cell(2)));
            Trace trace (0, Cell(2));
            smith_waterman (model_seq, data_seq, plane, trace);

            // get the objective of rounded result
            for (int i = 0; i < trace.size(); i ++) {
                if (trace[i].acidA == '-' && trace[i].acidB != '-') 
                    obj_rounded += 1.0;//C_I;
                else if (trace[i].acidA != '-' && trace[i].acidB == '-') 
                    obj_rounded += 1.0;//C_D;
                else if (trace[i].acidA == trace[i].acidB) 
                    obj_rounded += 0.0;//C_M;
                else if (trace[i].acidA != trace[i].acidB) 
                    obj_rounded += 1.0;//C_MM;
            }
            
            model_seq.clear(); data_seq.clear();
            for (int i = 0; i < trace.size(); i ++) 
                model_seq.push_back(trace[i].acidA);
            for (int i = 0; i < trace.size(); i ++) 
                data_seq.push_back(trace[i].acidB);
            allModelSeqs.push_back(model_seq);
            allDataSeqs.push_back(data_seq);
        }
	//writeClusterView( dir_path+to_string(iter), allModelSeqs, allDataSeqs );
	

        // cerr << "=============================================================================" << endl;
        char COZ_val [50], w1mw2_val [50]; 
        sprintf(COZ_val, "%6f", CoZ);
        sprintf(w1mw2_val, "%6f", W1mW2);
        cerr << "ADMM_iter = " << iter 
            << ", C o Z = " << COZ_val
            << ", Wdiff_max = " << w1mw2_val
            << ", obj_rounded = " << obj_rounded
            << endl;
        // cerr << "sub1_Obj = CoW_1+0.5*mu*||W_1-Z+1/mu*Y_1||^2 = " << sub1_cost << endl;
        // cerr << "sub2_Obj = ||W_2-Z+1/mu*Y_2||^2 = " << sub2_cost << endl;

        // 2f. stopping conditions
        if (ADMM_EARLY_STOP_TOGGLE and iter > MIN_ADMM_ITER)
            if ( W1mW2 < EPS_Wdiff ) {
                cerr << "CoZ Converges. ADMM early stop!" << endl;
                break;
            }
        prev_CoZ = CoZ;
        iter ++;
    }
    cout << "W_1: " << endl;
    for (int i = 0; i < numSeq; i ++) tensor4D_dump(W_1[i]);
    cout << "W_2: " << endl;
    for (int i = 0; i < numSeq; i ++) tensor4D_dump(W_2[i]);
    return W_2;
}