Beispiel #1
0
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()]);
}
Beispiel #2
0
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
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;
}
Beispiel #3
0
// 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;

}
Beispiel #5
0
	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];
			}
		}
	}
Beispiel #6
0
/*!
  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]);
  }
}
Beispiel #7
0
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
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;
Beispiel #8
0
bool QfsExists(QString name) { QFileInfo Qi(name); return Qi.exists(); }
Beispiel #9
0
void QfsUpdateInfo(qfile *file) /*- - - - - - - - - - - - - - - - - - - - - -*/
{                                 
  QFileInfo Qi(file->full_name); file->size = Qi.size();
                                 file->updated = Qi.lastModified();
                                 file->writable = QfsIsWritable(Qi);
}