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; }
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; }
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; }
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; }
Tensor TensorFieldFunction::evaluate (const Vec3& X) const { if (pidx >= field.size() || !field[pidx]) return Tensor(3); return const_cast<TensorFieldFunction*>(this)->getValues(X); }
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; }
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) ); } }
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]; }
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; } }
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; }
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; }
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; }
// 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); }
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; }
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; }
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; }
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); }
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; }
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) ); } } }
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; }
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; }
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; }
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; } }
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; }
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; }