void printKMax(int * arr, int n, int k) { std::deque<int> Qi(k); int i; for (i = 0; i < k; ++i) { while ( (!Qi.empty()) && arr[i] >= arr[Qi.back()]) Qi.pop_back(); // Remove from rear Qi.push_back(i); } for ( ; i < n; ++i) { printf("%d " , arr[Qi.front()]); while ( (!Qi.empty()) && Qi.front() <= i - k) Qi.pop_front(); // Remove from front of queue while ( (!Qi.empty()) && arr[i] >= arr[Qi.back()]) Qi.pop_back(); Qi.push_back(i); } printf("%d " , arr[Qi.front()]); }
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ bool QfsIsUpToDate (qfile *file) /* check if file is up-to-date and refresh */ { /* file "writable" property regardless */ QFileInfo Qi(file->full_name); file->writable = QfsIsWritable(Qi); if (file->updated >= Qi.lastModified()) return true; file->size = Qi.size(); file->updated = Qi.lastModified(); return false; }
// TODO: Add the ability to set a maximum number of iterations inline BigInt FindFactor ( const BigInt& n, Int a, const PollardRhoCtrl& ctrl ) { if( a == 0 || a == -2 ) Output("WARNING: Problematic choice of Pollard rho shift"); BigInt tmp, gcd; BigInt one(1); auto xAdvance = [&]( BigInt& x ) { if( ctrl.numSteps == 1 ) { // TODO: Determine if there is a penalty to x *= x /* tmp = x; tmp *= x; tmp += a; x = tmp; x %= n; */ x *= x; x += a; x %= n; } else { PowMod( x, 2*ctrl.numSteps, n, x ); x += a; x %= n; } }; auto QAdvance = [&]( const BigInt& x, const BigInt& x2, BigInt& Q ) { tmp = x2; tmp -= x; Q *= tmp; Q %= n; }; Int gcdDelay = ctrl.gcdDelay; BigInt xi=ctrl.x0; BigInt x2i(xi); BigInt xiSave=xi, x2iSave=x2i; BigInt Qi(1); Int k=1, i=1; // it is okay for i to overflow since it is just for printing while( true ) { // Advance xi once xAdvance( xi ); // Advance x2i twice xAdvance( x2i ); xAdvance( x2i ); // Advance Qi QAdvance( xi, x2i, Qi ); if( k >= gcdDelay ) { GCD( Qi, n, gcd ); if( gcd > one ) { // NOTE: This was not suggested by Pollard's original paper if( gcd == n ) { if( gcdDelay == 1 ) { RuntimeError("(x) converged before (x mod p) at i=",i); } else { if( ctrl.progress ) Output("Backtracking at i=",i); i = Max( i-(gcdDelay+1), 0 ); gcdDelay = 1; xi = xiSave; x2i = x2iSave; } } else { if( ctrl.progress ) Output("Found factor ",gcd," at i=",i); return gcd; } } // NOTE: This was not suggested by Pollard's original paper k = 0; xiSave = xi; x2iSave = x2i; Qi = 1; } ++k; ++i; } }
int ModeLaplace1DQ1::eigenCheck(const Epetra_MultiVector &Q, double *lambda, double *normWeight) const { int info = 0; int qc = Q.NumVectors(); int myPid = MyComm.MyPID(); cout.precision(2); cout.setf(ios::scientific, ios::floatfield); // Check orthonormality of eigenvectors double tmp = myVerify.errorOrthonormality(&Q, M); if (myPid == 0) cout << " Maximum coefficient in matrix Q^T M Q - I = " << tmp << endl; // Print out norm of residuals myVerify.errorEigenResiduals(Q, lambda, K, M, normWeight); // Check the eigenvalues int numX = (int) ceil(sqrt(Lx*Lx*lambda[qc-1]/M_PI/M_PI)); numX = (numX > nX) ? nX : numX; int newSize = (numX-1); double *discrete = new (nothrow) double[2*newSize]; if (discrete == 0) { return -1; } double *continuous = discrete + newSize; double hx = Lx/nX; int i; for (i = 1; i < numX; ++i) { continuous[i-1] = (M_PI/Lx)*(M_PI/Lx)*i*i; discrete[i-1] = 6.0*(1.0-cos(i*(M_PI/Lx)*hx))/(2.0+cos(i*(M_PI/Lx)*hx))/hx/hx; } // Sort the eigenvalues in ascending order mySort.sortScalars(newSize, continuous); int *used = new (nothrow) int[newSize]; if (used == 0) { delete[] discrete; return -1; } mySort.sortScalars(newSize, discrete, used); int *index = new (nothrow) int[newSize]; if (index == 0) { delete[] discrete; delete[] used; return -1; } for (i=0; i<newSize; ++i) { index[used[i]] = i; } delete[] used; int nMax = myVerify.errorLambda(continuous, discrete, newSize, lambda, qc); // Define the exact discrete eigenvectors int localSize = Map->NumMyElements(); double *vQ = new (nothrow) double[(nMax+1)*localSize]; if (vQ == 0) { delete[] discrete; delete[] index; info = -1; return info; } Epetra_MultiVector Qex(View, *Map, vQ, localSize, nMax); if ((myPid == 0) && (nMax > 0)) { cout << endl; cout << " --- Relative discretization errors for exact eigenvectors ---" << endl; cout << endl; cout << " Cont. Values Disc. Values Error H^1 norm L^2 norm\n"; } for (i=1; i < numX; ++i) { if (index[i-1] < nMax) { // Form the exact discrete eigenvector double coeff = (2.0 + cos(i*M_PI/Lx*hx))*Lx/6.0; coeff = 1.0/sqrt(coeff); int ii; for (ii=0; ii<localSize; ++ii) { Qex.ReplaceMyValue(ii, index[i-1], coeff*sin(i*(M_PI/Lx)*x[ii])); } // Compute the L2 norm Epetra_MultiVector shapeInt(View, *Map, vQ + nMax*localSize, localSize, 1); Epetra_MultiVector Qi(View, Qex, index[i-1], 1); for (ii=0; ii<localSize; ++ii) { double iX = 4.0*sqrt(2.0/Lx)*sin(i*(M_PI/Lx)*x[ii])/hx* pow(sin(i*(M_PI/Lx)*0.5*hx)/(i*M_PI/Lx), 2.0); shapeInt.ReplaceMyValue(ii, 0, iX); } double normL2 = 0.0; Qi.Dot(shapeInt, &normL2); double normH1 = continuous[i-1]*(1.0 - 2.0*normL2) + discrete[i-1]; normL2 = 2.0 - 2.0*normL2; normH1+= normL2; // Print out the result if (myPid == 0) { cout << " "; cout.width(4); cout << index[i-1] << ". "; cout.setf(ios::scientific, ios::floatfield); cout.precision(8); cout << continuous[i-1] << " " << discrete[i-1] << " "; cout.precision(3); cout << fabs(discrete[i-1] - continuous[i-1])/continuous[i-1] << " "; cout << sqrt(fabs(normH1)/(continuous[i-1]+1.0)) << " "; cout << sqrt(fabs(normL2)) << endl; } } } delete[] discrete; delete[] index; // Check the angles between exact discrete eigenvectors and computed myVerify.errorSubspaces(Q, Qex, M); delete[] vQ; return info; }
void FBMReference::diagonalizeBlock( const unsigned int block, const TNT::Array2D<double> &hessian, const std::vector<Vec3> &positions, TNT::Array1D<double> &eval, TNT::Array2D<double> &evec ) { const unsigned int ConservedDegreesOfFreedom = 6; printf( "Diagonalizing Block: %d\n", block ); // 1. Determine the starting and ending index for the block // This means that the upper left corner of the block will be at (startatom, startatom) // And the lower right corner will be at (endatom, endatom) const int startatom = 3 * blockSizes[block]; int endatom = 3 * particleCount - 1 ; if( block != ( blockSizes.size() - 1 ) ) { endatom = 3 * blockSizes[block + 1] - 1; } const int size = endatom - startatom + 1; // 2. Get the block Hessian Hii // Right now I'm just doing a copy from the big Hessian // There's probably a more efficient way but for now I just want things to work.. TNT::Array2D<double> h_tilde( size, size, 0.0 ); for( int j = startatom; j <= endatom; j++ ) { for( int k = startatom; k <= endatom; k++ ) { h_tilde[k - startatom][j - startatom] = hessian[k][j]; } } // 3. Diagonalize the block Hessian only, and get eigenvectors TNT::Array1D<double> di( size, 0.0 ); TNT::Array2D<double> Qi( size, size, 0.0 ); diagonalizeSymmetricMatrix( h_tilde, di, Qi ); // sort eigenvalues by absolute magnitude std::vector<EigenvalueColumn> sortedPairs = sortEigenvalues( di ); // find geometric dof TNT::Array2D<double> Qi_gdof( size, size, 0.0 ); Vec3 pos_center( 0.0, 0.0, 0.0 ); double totalmass = 0.0; for( int j = startatom; j <= endatom; j += 3 ) { double mass = mParticleMass[ j / 3 ]; pos_center += positions[j / 3] * mass; totalmass += mass; } double norm = sqrt( totalmass ); // actual center pos_center *= 1.0 / totalmass; // create geometric dof vectors // iterating over rows and filling in values for 6 vectors as we go for( int j = 0; j < size; j += 3 ) { double atom_index = ( startatom + j ) / 3; double mass = mParticleMass[atom_index]; double factor = sqrt( mass ) / norm; // translational Qi_gdof[j][0] = factor; Qi_gdof[j + 1][1] = factor; Qi_gdof[j + 2][2] = factor; // rotational // cross product of rotation axis and vector to center of molecule // x-axis (b1=1) ja3-ka2 // y-axis (b2=1) ka1-ia3 // z-axis (b3=1) ia2-ja1 Vec3 diff = positions[atom_index] - pos_center; // x Qi_gdof[j + 1][3] = diff[2] * factor; Qi_gdof[j + 2][3] = -diff[1] * factor; // y Qi_gdof[j][4] = -diff[2] * factor; Qi_gdof[j + 2][4] = diff[0] * factor; // z Qi_gdof[j][5] = diff[1] * factor; Qi_gdof[j + 1][5] = -diff[0] * factor; } // normalize first rotational vector double rotnorm = 0.0; for( int j = 0; j < size; j++ ) { rotnorm += Qi_gdof[j][3] * Qi_gdof[j][3]; } rotnorm = 1.0 / sqrt( rotnorm ); for( int j = 0; j < size; j++ ) { Qi_gdof[j][3] = Qi_gdof[j][3] * rotnorm; } // orthogonalize rotational vectors 2 and 3 for( int j = 4; j < ConservedDegreesOfFreedom; j++ ) { // <-- vector we're orthogonalizing for( int k = 3; k < j; k++ ) { // <-- vectors we're orthognalizing against double dot_prod = 0.0; for( int l = 0; l < size; l++ ) { dot_prod += Qi_gdof[l][k] * Qi_gdof[l][j]; } for( int l = 0; l < size; l++ ) { Qi_gdof[l][j] = Qi_gdof[l][j] - Qi_gdof[l][k] * dot_prod; } } // normalize residual vector double rotnorm = 0.0; for( int l = 0; l < size; l++ ) { rotnorm += Qi_gdof[l][j] * Qi_gdof[l][j]; } rotnorm = 1.0 / sqrt( rotnorm ); for( int l = 0; l < size; l++ ) { Qi_gdof[l][j] = Qi_gdof[l][j] * rotnorm; } } // orthogonalize original eigenvectors against gdof // number of evec that survive orthogonalization int curr_evec = ConservedDegreesOfFreedom; for( int j = 0; j < size; j++ ) { // <-- vector we're orthogonalizing // to match ProtoMol we only include size instead of size + cdof vectors // Note: for every vector that is skipped due to a low norm, // we add an additional vector to replace it, so we could actually // use all size original eigenvectors if( curr_evec == size ) { break; } // orthogonalize original eigenvectors in order from smallest magnitude // eigenvalue to biggest int col = sortedPairs.at( j ).second; // copy original vector to Qi_gdof -- updated in place for( int l = 0; l < size; l++ ) { Qi_gdof[l][curr_evec] = Qi[l][col]; } // get dot products with previous vectors for( int k = 0; k < curr_evec; k++ ) { // <-- vector orthog against // dot product between original vector and previously // orthogonalized vectors double dot_prod = 0.0; for( int l = 0; l < size; l++ ) { dot_prod += Qi_gdof[l][k] * Qi[l][col]; } // subtract from current vector -- update in place for( int l = 0; l < size; l++ ) { Qi_gdof[l][curr_evec] = Qi_gdof[l][curr_evec] - Qi_gdof[l][k] * dot_prod; } } //normalize residual vector double norm = 0.0; for( int l = 0; l < size; l++ ) { norm += Qi_gdof[l][curr_evec] * Qi_gdof[l][curr_evec]; } // if norm less than 1/20th of original // continue on to next vector // we don't update curr_evec so this vector // will be overwritten if( norm < 0.05 ) { continue; } // scale vector norm = sqrt( norm ); for( int l = 0; l < size; l++ ) { Qi_gdof[l][curr_evec] = Qi_gdof[l][curr_evec] / norm; } curr_evec++; } // 4. Copy eigenpairs to big array // This is necessary because we have to sort them, and determine // the cutoff eigenvalue for everybody. // we assume curr_evec <= size for( int j = 0; j < curr_evec; j++ ) { int col = sortedPairs.at( j ).second; eval[startatom + j] = di[col]; // orthogonalized eigenvectors already sorted by eigenvalue for( int k = 0; k < size; k++ ) { evec[startatom + k][startatom + j] = Qi_gdof[k][j]; } } }
/*! Method which enables to compute a NURBS curve passing through a set of data points. The result of the method is composed by a knot vector, a set of control points and a set of associated weights. \param l_crossingPoints : The list of data points which have to be interpolated. \param l_p : Degree of the NURBS basis functions. This value need to be > 0. \param l_knots : The knot vector \param l_controlPoints : the list of control points. \param l_weights : the list of weights. */ void vpNurbs::globalCurveInterp(std::vector<vpImagePoint> &l_crossingPoints, unsigned int l_p, std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights) { if (l_p == 0) { //vpERROR_TRACE("Bad degree of the NURBS basis functions"); throw(vpException(vpException::badValue, "Bad degree of the NURBS basis functions")) ; } l_knots.clear(); l_controlPoints.clear(); l_weights.clear(); unsigned int n = (unsigned int)l_crossingPoints.size()-1; unsigned int m = n+l_p+1; double d = 0; for(unsigned int k=1; k<=n; k++) d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1); //Compute ubar std::vector<double> ubar; ubar.push_back(0.0); for(unsigned int k=1; k<n; k++) ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d); ubar.push_back(1.0); //Compute the knot vector for(unsigned int k = 0; k <= l_p; k++) l_knots.push_back(0.0); double sum = 0; for(unsigned int k = 1; k <= l_p; k++) sum = sum + ubar[k]; //Centripetal method for(unsigned int k = 1; k <= n-l_p; k++) { l_knots.push_back(sum/l_p); sum = sum - ubar[k-1] + ubar[l_p+k-1]; } for(unsigned int k = m-l_p; k <= m; k++) l_knots.push_back(1.0); vpMatrix A(n+1,n+1); vpBasisFunction* N; for(unsigned int i = 0; i <= n; i++) { unsigned int span = findSpan(ubar[i], l_p, l_knots); N = computeBasisFuns(ubar[i], span, l_p, l_knots); for (unsigned int k = 0; k <= l_p; k++) A[i][span-l_p+k] = N[k].value; delete[] N; } //vpMatrix Ainv = A.inverseByLU(); vpMatrix Ainv; A.pseudoInverse(Ainv); vpColVector Qi(n+1); vpColVector Qj(n+1); vpColVector Qw(n+1); for (unsigned int k = 0; k <= n; k++) { Qi[k] = l_crossingPoints[k].get_i(); Qj[k] = l_crossingPoints[k].get_j(); } Qw = 1; vpColVector Pi = Ainv*Qi; vpColVector Pj = Ainv*Qj; vpColVector Pw = Ainv*Qw; vpImagePoint pt; for (unsigned int k = 0; k <= n; k++) { pt.set_ij(Pi[k],Pj[k]); l_controlPoints.push_back(pt); l_weights.push_back(Pw[k]); } }
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ qfile *QfsNew (QString filename, qfile *referer) { QfsFtype new_ft = QftNIL; qfile *file; QString wildcards; if (filename == QfsELLIPSIS || filename == QfsEMPTY_NAME) new_ft = QftNOFILE; else if (filename.startsWith(QfsXEQ_PREFIX)) { new_ft = QftPSEUDO; if (!filename.endsWith(QString::fromUtf8("»"))) filename.append (QString::fromUtf8("»")); } if (new_ft) { QString pseudo_path = referer ? referer->path : QDir::currentPath(); file = new qfile_tag; file->size = 0; file->ft = new_ft; file->name = filename; file->path = pseudo_path; file->writable = true; file->full_name = pseudo_path+"/"+file->name; return file; } if (filename.startsWith('~')) filename.replace(0,1, QDir::homePath()); if (filename.contains("*") || filename.contains("?")) { int Ndir = filename.lastIndexOf("/"); wildcards = filename.mid(Ndir+1); if (Ndir < 0) filename = QString::fromUtf8("./…"); else filename = filename.left(Ndir) + QString::fromUtf8( "/…"); } QFileInfo Qi(filename); // // Convert path to absolute, using referer directory if available (otherwise // working directory will be used, which is, most likely, the last one where // some shell command was executed): // if (Qi.isRelative()) { if (referer && QDir::currentPath() != referer->path) { QDir::setCurrent(referer->path); Qi.setFile(filename); // reparse the name relative to referer's directory } Qi.makeAbsolute(); filename = Qi.filePath(); } // Some intelligence here: if filename refer to directory with micros.dir file, // use that file, otherwise assume user want to see dirlist: // if (Qi.isDir() && wildcards.isEmpty()) { QFileInfo Qmicros(filename+"/" QfsROOTFILE); if (Qmicros.exists()) filename = Qmicros.canonicalFilePath(); else { wildcards = QString::fromUtf8("*"); filename.push_back(QString::fromUtf8("/…")); } } Qi.setFile(filename); // - - - - - - - - - filename processed, creating qfile if (wildcards.isEmpty() && !Qi.isDir()) { qtxtfile *tfile = new qtxtfile; tfile->ft = QftTEXT; tfile->name = Qi.fileName(); tfile->Qf.setFileName(filename); file = tfile; } else { qdirfile *dfile = new qdirfile; dfile->ft = QftDIR; dfile->name = wildcards; dfile->QD.setPath(Qi.path()); file = dfile; } file->updated = Qi.lastModified(); file->size = Qi.size(); file->writable = QfsIsWritable(Qi); file->path = Qi.path(); file->full_name = Qi.path() + "/" + file->name; file->utf16le = false; return file; // either = new qtxtfile; } // or = new qdirfile;
bool QfsExists(QString name) { QFileInfo Qi(name); return Qi.exists(); }
void QfsUpdateInfo(qfile *file) /*- - - - - - - - - - - - - - - - - - - - - -*/ { QFileInfo Qi(file->full_name); file->size = Qi.size(); file->updated = Qi.lastModified(); file->writable = QfsIsWritable(Qi); }