Beispiel #1
0
int Solver_Core::Solve(int num_basis, double cvm_eps)
{
	timeusedForModelSaving = 0;
	modelsWritten = 0;
	algorithmStartTime  = pnow();	
	nextSaveTime = param->saveFactor * (modelsWritten+1) + floor (pow (param->saveExponential, 1));
	saveExponential = param->saveExponential;
	
	this->maxNumBasis = num_basis;

    // The convergence of CVM does not require the exact MEB on the core-set. 
    // With the recent advance of core-set approximation, the (1+epsilon/2)-MEB approximation on the core-set 
    // can guarantee the quality and the convergence of the (1+epsilon)-MEB approximation for the whole data set.
    // See [Kumar, Mitchell, and Yildirim, 2003]
    //
	// iterate on epsilons
	double epsilonFactor = EPS_SCALING;
	for(double currentEpsilon = INITIAL_EPS; currentEpsilon/epsilonFactor > cvm_eps; currentEpsilon *= epsilonFactor)
	{
		// check epsilon
		currentEpsilon = (currentEpsilon < cvm_eps ? cvm_eps : currentEpsilon);		

		// solve problem with current epsilon (warm start from the previous solution)
		double maxDistance2 = 0.0;
		int maxDistance2Idx = 0;
		double factor       = 1.0 + currentEpsilon;
		factor             *= factor;

        // The convergence of CVM does not require the exact most violating point. 
        // A violating point is enough for the convergence of CVM. 
        // Probabilistic speedup lead to a good tradeoff between convergence and complexity at each iteration
        //
		while (maxDistance2Idx != -1)
		{
			// get a probabilistic sample
			maxDistance2    = r2 * factor;
			maxDistance2Idx = -1;			
			for(int sampleIter = 0; (sampleIter < 7) && (maxDistance2Idx == -1); sampleIter++)			
				maxDistance2 = _maxDistFromSampling(maxDistance2, maxDistance2Idx);

			// check maximal distance
			if (maxDistance2Idx != -1)
			{	
				_UpdateCoreSet(maxDistance2Idx);	
#ifndef RELEASE_VER
				printf("#%d eps: %g |c|: %.10f  R: %.10f |c-x|: %.10f r: %.10f\n",coreNum, currentEpsilon, coreNorm2, r2, maxDistance2, sqrt(maxDistance2/r2)-1.0);
#endif				
				solver->Solve(coreIdx,coreNum,tempD);
				outAlpha = solver->getAlpha();				
				ComputeRadius2();
//				if (coreNum%20 < 1) info(".");				
			}
			
			
			double currentTime = pnow ();
			if ((param->saveExponential >= 0.0) && (currentTime - algorithmStartTime >= nextSaveTime + timeusedForModelSaving )) {
				modelsWritten++;
				printf( "&%d..", modelsWritten);
				nextSaveTime = param->saveFactor * (modelsWritten+1)  + pow (param->saveExponential, modelsWritten + 1);
// 				std::cout << "Algorithm time is now " << currentTime - algorithmStartTime - timeusedForModelSaving << "\n";
// 				std::cout << "  Saving model now at " << currentTime - startTime << "\n";
				double before = pnow();

				svm_model *model = Malloc(svm_model,1);
				model->param = *param;
				model->free_sv = 0;	// XXX
				model->nr_class = param->nr_classes;

				model->label = Malloc(int,model->nr_class);
				for(int i=0;i<model->nr_class;i++)
					model->label[i] = param->label[i];

				model->rho = Malloc(double,1);
				double *alpha = Malloc(double,param->prob->l);
				double THRESHOLD = 1e-5/coreNum;
				for(int i=0;i<1;i++)
					model->rho[i] = -ComputeSolution(alpha, THRESHOLD);	 //overwrite alphas!

				model->nSV = Malloc(int, model->nr_class);
				
				// assume all the nonzeros are false at the beginning,
				// we have binary classification, they will not change in the 
				// outer loop in svm.cpp

				int total_sv = 0;
				for(int i=0;i<model->nr_class;i++)
				{
					int nSV = 0;
					for(int j=0;j<param->count[i];j++) {
						if(fabs(alpha[param->start[i]+j])) {	
							++nSV;
							++total_sv;
						}
					}
					model->nSV[i] = nSV;
				}
				
				model->l = total_sv; //anzahl der sv im model

				// ASSUME PERMUTATION IS IDENTITY
				svm_node **x = Malloc(svm_node *,param->prob->l);
				int i;
				for(int i=0;i<param->prob->l;i++)
					x[i] = param->prob->x[i]; //					x[i] = param->prob->x[perm[i]];
				model->SV = Malloc(svm_node *,total_sv);

				int p = 0;
				for(int i=0;i<param->prob->l;i++) {
					if(fabs(alpha[i]) > 0.0) {
						model->SV[p++] = x[i];
					}
				}

				model->sv_coef = Malloc(double *,model->nr_class-1);
				for(int i=0;i<model->nr_class-1;i++) {
					model->sv_coef[i] = Malloc(double,total_sv);
				}

//				printf ("%d SV  class 0, %d SV  class 1\n", model->nSV[0], model->nSV[1]);
				int q = 0;
				for(int i=0;i<model->nr_class;i++)
				{
					for(int j=0;j < param->count[i];j++) {
						if(fabs(alpha[param->start[i]+j]) > 0.0) {	
							model->sv_coef[0][q++] = alpha[param->start[i]+j];// * param->prob->y[param->start[i]+j];
//							printf ("%d -- %f\n", q, alpha[param->start[i]+j]);
						}
					}
				}				
				
				p = 0;
				char tmp[1000];
				if (strlen(param->modelPath) < 2) {
					sprintf(tmp,"%s_%d",param->modelFile, (int)floor( before - algorithmStartTime - timeusedForModelSaving) ); 
				} else {
					sprintf(tmp,"%s/%d.cvm.model",param->modelPath, (int)floor( before - algorithmStartTime - timeusedForModelSaving) ) ;
				}

				model->probB = NULL;
				model->probA = NULL;
				svm_save_model(tmp, model);
				
				// just to keep compability
				FILE* fModel = fopen(tmp, "a+t");					// append mode
				fprintf(fModel, "CPU Time = %f second\n", before - algorithmStartTime - timeusedForModelSaving);
				fclose(fModel);

				
//				svm_destroy_model(model);
				//free(x);


				double after = pnow();
				timeusedForModelSaving += after - before;
			}

			// check if we are over the walltime
			if (pnow() - param->startTime >  param->wallTime + timeusedForModelSaving) {
				printf ("Hit the walltime, exiting now..\n");
				return coreNum;
			}

			
			if (IsExitOnMaxIter())
			{
				return coreNum;
				break;
			}
		}
	}	
Beispiel #2
0
/*
     Run with -build_twosided allreduce -pc_type bjacobi -sub_pc_type lu -q 16 -ksp_rtol 1.e-34 (or 1.e-14 for double precision)

     -q <q> number of spectral elements to use
     -N <N> maximum number of GLL points per element 

*/
int main(int argc,char **args)
{
  PetscErrorCode ierr;
  PetscGLL       gll;
  PetscInt       N = 80,n,q = 8,xs,xn,j,l;
  PetscReal      **A;
  Mat            K;
  KSP            ksp;
  PC             pc;
  Vec            x,b;
  PetscInt       *rows;
  PetscReal      norm,xc,yc,h;
  PetscScalar    *f;
  PetscDraw      draw;
  PetscDrawLG    lg;
  PetscDrawAxis  axis;
  DM             da;
  PetscMPIInt    rank,size;

  ierr = PetscInitialize(&argc,&args,NULL,NULL);if (ierr) return ierr;
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(NULL,NULL,"-q",&q,NULL);CHKERRQ(ierr);

  ierr = PetscDrawCreate(PETSC_COMM_WORLD,NULL,"Log(Error norm) vs Number of GLL points",0,0,500,500,&draw);CHKERRQ(ierr);
  ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
  ierr = PetscDrawLGCreate(draw,1,&lg);CHKERRQ(ierr);
  ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr);
  ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr);
  ierr = PetscDrawAxisSetLabels(axis,NULL,"Number of GLL points","Log(Error Norm)");CHKERRQ(ierr);

  for (n=4; n<N; n+=2) {

    /*
       da contains the information about the parallel layout of the elements
    */
    ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,q*(n-1)+1,1,1,NULL,&da);CHKERRQ(ierr);
    ierr = DMSetFromOptions(da);CHKERRQ(ierr);
    ierr = DMSetUp(da);CHKERRQ(ierr);
    ierr = DMDAGetInfo(da,NULL,&q,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr);
    q = (q-1)/(n-1);  /* number of spectral elements */

    /*
       gll simply contains the GLL node and weight values
    */
    ierr = PetscGLLCreate(n,PETSCGLL_VIA_LINEARALGEBRA,&gll);CHKERRQ(ierr);
    ierr = DMDASetGLLCoordinates(da,&gll);CHKERRQ(ierr);

    /*
       Creates the element stiffness matrix for the given gll
    */
    ierr = PetscGLLElementLaplacianCreate(&gll,&A);CHKERRQ(ierr);

    /*
      Scale the element stiffness and weights by the size of the element
    */
    h    = 2.0/q;
    for (j=0; j<n; j++) {
      gll.weights[j] *= .5*h;
      for (l=0; l<n; l++) {
        A[j][l] = 2.*A[j][l]/h;
      }
    }

    /*
        Create the global stiffness matrix and add the element stiffness for each local element
    */
    ierr = DMCreateMatrix(da,&K);CHKERRQ(ierr);
    ierr = MatSetOption(K,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
    ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr);
    xs   = xs/(n-1);
    xn   = xn/(n-1);
    ierr = PetscMalloc1(n,&rows);CHKERRQ(ierr);
    /*
        loop over local elements
    */
    for (j=xs; j<xs+xn; j++) {
      for (l=0; l<n; l++) rows[l] = j*(n-1)+l;
      ierr = MatSetValues(K,n,rows,n,rows,&A[0][0],ADD_VALUES);CHKERRQ(ierr);
    }
    ierr = MatAssemblyBegin(K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
    ierr = MatAssemblyEnd(K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

    ierr = MatCreateVecs(K,&x,&b);CHKERRQ(ierr);
    ierr = ComputeRhs(da,&gll,b);CHKERRQ(ierr);

    /*
        Replace the first and last rows/columns of the matrix with the identity to obtain the zero Dirichlet boundary conditions
    */
    rows[0] = 0;
    rows[1] = q*(n-1);
    ierr = MatZeroRowsColumns(K,2,rows,1.0,x,b);CHKERRQ(ierr);
    ierr = PetscFree(rows);CHKERRQ(ierr);

    ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr);
    ierr = KSPSetOperators(ksp,K,K);CHKERRQ(ierr);
    ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
    ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
    ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
    ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);

    /* compute the error to the continium problem */
    ierr = ComputeSolution(da,&gll,b);CHKERRQ(ierr);
    ierr = VecAXPY(x,-1.0,b);CHKERRQ(ierr);

    /* compute the L^2 norm of the error */
    ierr = VecGetArray(x,&f);CHKERRQ(ierr);
    ierr = PetscGLLIntegrate(&gll,f,&norm);CHKERRQ(ierr);
    ierr = VecRestoreArray(x,&f);CHKERRQ(ierr);
    norm = PetscSqrtReal(norm);
    ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"L^2 norm of the error %D %g\n",n,(double)norm);CHKERRQ(ierr);
    if (n > 10 && norm > 1.e-8) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Slower convergence than expected");
    xc   = (PetscReal)n;
    yc   = PetscLog10Real(norm);
    ierr = PetscDrawLGAddPoint(lg,&xc,&yc);CHKERRQ(ierr);
    ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);

    ierr = VecDestroy(&b);CHKERRQ(ierr);
    ierr = VecDestroy(&x);CHKERRQ(ierr);
    ierr = KSPDestroy(&ksp);CHKERRQ(ierr);
    ierr = MatDestroy(&K);CHKERRQ(ierr);
    ierr = PetscGLLElementLaplacianDestroy(&gll,&A);CHKERRQ(ierr);
    ierr = PetscGLLDestroy(&gll);CHKERRQ(ierr);
    ierr = DMDestroy(&da);CHKERRQ(ierr);
  }
  ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr);
  ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}