Пример #1
0
double Nurbs::nFunc(int i, double u, int order, int depth)
{
    if (order > 1){

        double denominator1 = knots[i+order-1] - knots[i];
        double denominator2 = knots[i+order]-knots[i+1];

        double term1,term2;
        if (denominator1 == 0){
            term1 = 0;
        } else {
            term1 = (u-knots[i])/denominator1;
        }
        if (denominator2 == 0){
            term2 = 0;
        } else {
            term2 = (knots[i+order]-u)/denominator2;
        }

        return term1*nFunc(i,u,order-1,(depth+1)) + term2*nFunc(i+1,u, order-1,(depth+1));

    } else {
        if ((u >= knots[i])&&(u < knots[i+1])){
            return 1;
        } else {
            return 0;
        }
    }
}
Пример #2
0
Point Nurbs::getSinglePoint(double u)
{
    //if uniform, u is only defined from u_k-1 to u_m+1, so illegal u values will be replaced with closest end knots
    //for standard, u must fall within 0 and 1
    if (uniform)
    {
        if (u < knots[order-1]) u = knots[order-1];
        else if (u > knots[control_points.size()]) u = knots[control_points.size()];
    } else {
        if (u < 0) u = 0;
        else if (u > 1) u = 1.0;
    }

    Point s = Point();
    double normalising_denominator = 0;

    for (int i = 0; i < control_points.size(); i++)
    {
        double cp_coefficient = nFunc(i,u,order,0) * weights[i];
        s = s + control_points[i] * cp_coefficient;
        normalising_denominator += cp_coefficient;
    }

    s = s / normalising_denominator;

    if (s.x > right_most.x){
        right_most = s;
    }
    if (s.x < left_most.x){
        left_most = s;
    }

    if (s.y > top_most.y){
        top_most = s;
    }
    if (s.y < bottom_most.y){
        bottom_most = s;
    }

    return s;
}
Пример #3
0
    Task* create_guessing_task(std::string identifier, Log* log, Stepper* stepper, Wave* varyingWave,
			       Wave* evWave, double tol, size_t nPeriod, size_t showAllIterates, long secvar)
    {
      Task* task = new Task
	([=]() mutable
	 {
	   varyingWave->lock();
	   
	   size_t nVar(stepper->n_variables());
	   size_t nFunc(stepper->n_functions());	   
	   double t(stepper->t());
	   
	   auto f = [nVar,nFunc,stepper,nPeriod,tol,t](const double* x, double* rhs)
	   {
	     stepper->reset(t,x);
	     stepper->advance(nPeriod);
	     for(size_t i(0);i<nVar;++i)
	       rhs[i]=stepper->x()[i]-x[i];
	     for(size_t i(0);i<nVar*nVar;++i)
	       rhs[i+nVar]=stepper->jac()[i];	     
	     // subtract 1 from the diagonal of the Jacobian
	     for(size_t i(0);i<nVar;++i)
	       rhs[nVar+i*(nVar+1)]-=1.0;
	   };

	   double* x(new double[nVar]);
	   for(size_t i(0);i<nVar;++i)
	     x[i]=varyingWave->data()[i+1];
	   varyingWave->pop_back(1+nVar+nFunc);
	   bool success(false);
	   try
	     {
	       success=newton(int(nVar),x,f,false,tol);
	     }
	   catch(std::string error)
	     {
	       success=false;
	       log->push<Log::ERROR>(error);
	     }
	   if(!success)
	     {
	       log->push<Log::ERROR>("Newton iteration did not converge\n");
	     }
	   else
	     {
	       // get eigenvalue and eigenvector info
	       VecD evals,evecs;
	       VecSZ types;
	       double* jac(new double[nVar*nVar]);
	       for(size_t i(0);i<nVar*nVar;++i)
		 jac[i]=stepper->jac()[i];
	       if(secvar>=0) // in Poincare mode, restore the artificial zero-multiplier to 1
		 jac[size_t(secvar)*(nVar+1)]=1;
	       floquet(nVar,jac,evals,evecs,types);
	       evWave->push_back(&evals[0],nVar*2);
	       evWave->push_back(&evecs[0],nVar*nVar);
	       for(size_t i(0);i<types.size();++i)
		 evWave->push_back(double(types[i]));
	       delete[] jac;

	       size_t factor(showAllIterates?nPeriod:1);
	       stepper->reset(t,x);
	       for(size_t j(0);j<factor;++j)
		 {
		   try
		     {
		       stepper->advance(nPeriod/factor);
		     }
		   catch(std::string error)
		     {
		       log->push<Log::ERROR>(error);
		       success=false;
		       break;
		     }
		   varyingWave->push_back(stepper->t());
		   varyingWave->push_back(stepper->x(),nVar);
		   varyingWave->push_back(stepper->func(),nFunc);
		 }
	     }
	   delete[] x;

	   if(success)
	     log->push<Log::SUCCESS>(identifier);
	   else
	     log->push<Log::FAIL>(identifier);

	   varyingWave->unlock();
	 });
      return task;

    }  
Пример #4
0
    Task* create_guessing_task(std::string identifier, Log* log, EquationSystem* eqsys,
			       Wave* varyingWave, Wave* evWave, double tol)
    {

      size_t nVar(eqsys->n_variables());
      size_t nFunc(eqsys->n_functions());
      
      auto f_(eqsys->f());
      auto dfdx_(eqsys->dfdx());

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
      Newton::F f = eqsys->dfdx()?
	Newton::F([f_,dfdx_,nVar](const double* x, double* rhs)
		  {
		    f_(x,rhs);
		    dfdx_(x,rhs+nVar);
		  }):
	Newton::F(f_);
            
      auto ff(eqsys->func());

      bool genJac = eqsys->dfdx()?false:true;
      
      Task* task = new Task
	([nVar,nFunc,f,ff,varyingWave,evWave,tol,genJac,identifier,log]() mutable
	 {
	   varyingWave->lock();
	   double* x(new double[nVar]);
	   double* funcs(new double[nFunc]);
	   double t(varyingWave->data()[0]);
	   for(size_t i(0);i<nVar;++i)
	     x[i]=varyingWave->data()[i+1];
	   varyingWave->pop_back(1+nVar+nFunc);
	   bool success(false);
	   
	   try
	     {
	       success=newton(int(nVar),x,f,genJac,tol);
	     }
	   catch(std::string error)
	     {
	       success=false;
	       log->push<Log::ERROR>(error);
	     }
	   if(!success)
	     log->push<Log::ERROR>("Newton iteration did not converge\n");
	   else
	     {
	       // get eigenvalue and eigenvector info
	       double* rhs(new double[nVar*(nVar+1)]);
	       f(x,rhs);
	       double* jac=rhs+nVar;
	       VecD evals,evecs;
	       VecSZ types;
	       eigen(nVar,jac,evals,evecs,types);
	       evWave->push_back(&evals[0],nVar*2);
	       evWave->push_back(&evecs[0],nVar*nVar);
	       for(size_t i(0);i<types.size();++i)
		 evWave->push_back(double(types[i]));
	       /*	       for(size_t i(0),size(size_t(evWave->data_max()));i<size;++i)
			       std::cout<<evWave->data()[i]<<std::endl;*/
	       delete[] rhs;
	     }
	   varyingWave->push_back(t);
	   varyingWave->push_back(x,nVar);
	   if(nFunc)
	     {
	       ff(x,funcs);
	       varyingWave->push_back(funcs,nFunc);
	     }
	   
	   delete[] x;
	   delete[] funcs;
	   
	   if(success)
	     log->push<Log::SUCCESS>(identifier);
	   else
	     log->push<Log::FAIL>(identifier);

	   varyingWave->unlock();
	   });
      
#pragma clang diagnostic pop

      return task;
      
    }