Example #1
0
    void DropOff::step(){
        switch(currentPhase){
            case SETUP:    
                Serial.println("Setup");
                setup();
                break;
            case EXTENSION:
                Serial.println("Extension");
                extension();
                break;
            case RELEASE: 
                Serial.println("Realease");
                release();
                break;
            case RETRACTION:
                Serial.println("Retraction");
                retraction();
                break;
            case ONE_EIGHTY_P1:
                Serial.println("180 P1");
                oneEightyP1();
                break;
            case ONE_EIGHTY_P2:
                Serial.println("180 P2");
                oneEightyP2();
                break;

        }
    }
Example #2
0
RcppExport SEXP  particleSwarm(SEXP YList1, SEXP n1, SEXP p1, SEXP r1,
                      SEXP mtype1,SEXP retraction1,
                      SEXP f1,
                      SEXP control1){
BEGIN_RCPP
  //Initialization of functions and control parameters
  Function obej(f1);
  List control(control1);
  IntegerVector retraction(retraction1);
  int iterMax=as< int>(control["iterMax"]);
  double phi1=as< double>(control["phi1"]);
  double phi2=as< double>(control["phi2"]);
  double omega=as< double>(control["omega"]);
  //controlling parameter: number of particles and number of parallel threads
  int particle_num=as< int>(control["particleNum"]);
  int thread_num=as< int>(control["threadNum"]);
  //double alpha=as< double>(control["alpha"]); 
  
  // Initialization of Data points
  IntegerVector n(n1),p(p1),r(r1);
  CharacterVector mtype(mtype1);
  int prodK=n.size();// size of product manifold
  
  //global best position
  vector< manifold*>  manifoldYG;
  int k;
  List YList(YList1), YList_temp(YList1);
  
//  omp_set_num_threads(thread_num);

//  int dim=0;
//  for(k=0;k<prodK;k++) dim+=n[k]+p[k];
//  const int particle_num=dim; //dimension needs to be changed;

//present and historical best postion of each particle
  vector< vector< manifold*> >  manifoldYP(particle_num), manifoldYB(particle_num);   
  
  
  int iter=0; // outer loop
  double objValue;
  
  //individual current and best value
  vector<double> objValue_p(particle_num,0.0), objValue_b(particle_num,0.0);
    

 //initiating particle_num size of particles and velocities;
  int outter_num;
//  #pragma omp parallel for schedule(static) private(k) shared(manifoldYB, manifoldYG,manifoldYP,prodK)
  for(outter_num=0;outter_num<particle_num;outter_num++){
    for(k=0;k<prodK;k++){
      SEXP yTemp2=YList[k];
       NumericMatrix yTemp(yTemp2);
       std::string typeTemp=as< std::string>(mtype[k]);     
       if(typeTemp=="stiefel"){
          manifoldYP[outter_num].push_back(new stiefel(n[k],p[k],r[k],
                                    yTemp,retraction[k]));                   
          manifoldYB[outter_num].push_back(new stiefel(n[k],p[k],r[k],
                                    yTemp,retraction[k]));                        
          if(outter_num==0)  manifoldYG.push_back(new stiefel(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));                          
       }
       else if(typeTemp=="grassmannQ"){
         manifoldYP[outter_num].push_back(new grassmannQ(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new grassmannQ(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new grassmannQ(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));                                     
       }else if(typeTemp=="grassmannSub"){
         manifoldYP[outter_num].push_back(new grassmannSub(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new grassmannSub(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new grassmannSub(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));  
     }else if(typeTemp=="fixedRank"){
           manifoldYP[outter_num].push_back(new fixRank(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
           manifoldYB[outter_num].push_back(new fixRank(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new fixRank(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));    

       }else if(typeTemp=="fixedRankSym"){
           manifoldYP[outter_num].push_back(new fixRankSym(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
           manifoldYB[outter_num].push_back(new fixRankSym(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new fixRankSym(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));
       }else if(typeTemp=="fixedRankPSD"){
           manifoldYP[outter_num].push_back(new fixRankPSD(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
           manifoldYB[outter_num].push_back(new fixRankPSD(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new fixRankPSD(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));
      }else if(typeTemp=="spectahedron"){
           manifoldYP[outter_num].push_back(new spectahedron(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
           manifoldYB[outter_num].push_back(new spectahedron(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new spectahedron(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));
      }else if(typeTemp=="elliptope"){
           manifoldYP[outter_num].push_back(new elliptope(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
           manifoldYB[outter_num].push_back(new elliptope(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new elliptope(n[k],p[k],r[k],
                                                     yTemp,retraction[k]));
      }else if(typeTemp=="sphere"){
         manifoldYP[outter_num].push_back(new sphere(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new sphere(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new sphere(n[k],p[k],r[k],
                                                     yTemp,retraction[k])); 
       }
       else if(typeTemp=="oblique"){
         manifoldYP[outter_num].push_back(new oblique(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new oblique(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new oblique(n[k],p[k],r[k],
                                                     yTemp,retraction[k])); 
       }  
       else if(typeTemp=="specialLinear"){
         manifoldYP[outter_num].push_back(new specialLinear(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new specialLinear(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new specialLinear(n[k],p[k],r[k],
                                                     yTemp,retraction[k])); 
       }
       else if(typeTemp=="projective"){
         manifoldYP[outter_num].push_back(new projective(n[k],p[k],r[k],
                                    yTemp,retraction[k]));
         manifoldYB[outter_num].push_back(new projective(n[k],p[k],r[k],
                                    yTemp,retraction[k]));     
          if(outter_num==0)  manifoldYG.push_back(new projective(n[k],p[k],r[k],
                                                     yTemp,retraction[k])); 
       }
       manifoldYP[outter_num][k]->set_particle();  
       *manifoldYB[outter_num][k]=*manifoldYP[outter_num][k];  
     //  if(outter_num==0)  *manifoldYG[k]=*manifoldYP[outter_num][k];
    }    
  } 
  

  //initialising the global-value position
  for(k=0;k<prodK;k++) YList[k]=manifoldYG[k]->get_Y();
  if(prodK>1){
    objValue=as< double>(obej(YList));
  }else{
    objValue=as< double>(obej(YList[0]));
  }
  double best_objValue=objValue;
  int best_pos=-1;
  for(outter_num=0;outter_num<particle_num;outter_num++){
    for(k=0;k<prodK;k++)  YList_temp[k]=manifoldYP[outter_num][k]->get_Y();
      if(prodK>1){
        objValue_b[outter_num]=as< double>(obej(YList_temp));
      }else{
        objValue_b[outter_num]=as< double>(obej(YList_temp[0]));
      }
      if(objValue_b[outter_num]<best_objValue) {
        best_objValue=objValue_b[outter_num];
	     	best_pos=outter_num;
      }  
  }
  
  if(best_pos>-1){
	for(k=0;k<prodK;k++) manifoldYG[k]->set_Y(manifoldYP[best_pos][k]->get_Y());
	objValue=best_objValue;
  }


  //specific arguments of particleSwarm;
  //double omega=1.0;  //can be added to arguments later;
  //double phi1=2,phi2=2; //can be added to arguments later;
  
  arma::mat velocity;
  //R01 and R02 are uniform (0,1) distributed numbers;
  srand (time(NULL));
  double R01=0.5,R02=0.5;
  //int thread_num;
  //int subthread_num=0,subthread_num_1=0; //to test whether parallelism happens;

  //begin iteration  
  while(iter<iterMax){
    iter++;

	#pragma omp parallel shared(manifoldYG,objValue,manifoldYB,manifoldYP) \
	   shared(objValue_p,objValue_b,prodK,obej) \
       firstprivate(velocity) \
       private(R01,R02,k) 
{ 
 
//      #pragma omp for schedule(static)
        for(outter_num=0;outter_num<particle_num;outter_num++){
          srand(int(time(NULL)));// ^ omp_get_thread_num());
         //  List YList_parallel(prodK);
           
           //begin updating each component
            for(k=0;k<prodK;k++){
              R01=((double) rand() / (RAND_MAX+1));
              R02=((double) rand() / (RAND_MAX+1));
 
			         //velocity update
              velocity=omega*manifoldYP[outter_num][k]->get_descD();
              velocity+=phi1*R01*(manifoldYB[outter_num][k]->get_Y()-
                                   manifoldYP[outter_num][k]->get_Y());
              velocity+=phi2*R02*(manifoldYG[k]->get_Y()-
                                    manifoldYP[outter_num][k]->get_Y());
             // Rcpp::Rcout<<1<<endl;
			        //project onto tangent space
              manifoldYP[outter_num][k]->evalGradient(velocity,"particleSwarm");
             //Rcpp::Rcout<<2<<endl;
              manifoldYP[outter_num][k]->retract(1,"particleSwarm",true);
              //Rcpp::Rcout<<3<<endl;
              manifoldYP[outter_num][k]->vectorTrans();
              //Rcpp::Rcout<<4<<endl;
              manifoldYP[outter_num][k]->acceptY();
              //Rcpp::Rcout<<5<<endl;
              //YList_parallel[k]=manifoldYP[outter_num][k]->getY();
                     
            }//update each component

//			#pragma omp critical
//			{
//              if(prodK>1){
//                objValue_p[outter_num]=as< double>(obej(YList_temp)); 
//              }else{
//                objValue_p[outter_num]=as< double>(obej(YList_temp[0]));
//              }
//			}
//
//			//if present is better than individual historical best
//            if(objValue_p[outter_num]<objValue_b[outter_num]){ 
//               objValue_b[outter_num]=objValue_p[outter_num];
//               for(k=0;k<prodK;k++) *manifoldYB[outter_num][k]
//                          =*manifoldYP[outter_num][k];
//            }

         }// iteration over particles;
  
	} //out of parallel region; 
  
  
  
    for(outter_num=0;outter_num<particle_num;outter_num++){
    for(k=0;k<prodK;k++)  YList_temp[k]=manifoldYP[outter_num][k]->get_Y();
      if(prodK>1){
        objValue_p[outter_num]=as< double>(obej(YList_temp));
      }else{
        objValue_p[outter_num]=as< double>(obej(YList_temp[0]));
      }
        		//if present is better than individual historical best
            if(objValue_p[outter_num]<objValue_b[outter_num]){ 
               objValue_b[outter_num]=objValue_p[outter_num];
               for(k=0;k<prodK;k++) *manifoldYB[outter_num][k]
                          =*manifoldYP[outter_num][k];
            }
  }

     //check and update global optimal value
	 best_objValue=objValue;
	 best_pos=-1;
	 for(outter_num=0;outter_num<particle_num;outter_num++){
	     if(objValue_b[outter_num]<best_objValue){
			best_pos=outter_num;
			best_objValue=objValue_b[outter_num];
		 }
	 }
	 if(best_pos>-1){
		for(k=0;k<prodK;k++) manifoldYG[k]->set_Y(manifoldYP[best_pos][k]->get_Y());
		objValue=best_objValue;
	 }

}// outer iteration




  for(k=0;k<prodK;k++) YList[k]=manifoldYG[k]->get_Y();  
  return List::create(Named("optY")=YList,
              Named("optValue")=objValue);
          //    Named("NumIter")=iter);
END_RCPP
}//end of function
RcppExport SEXP  steepestDescent(SEXP YList1, SEXP n1, SEXP p1, SEXP r1,
                      SEXP mtype1,SEXP retraction1,
                      SEXP f1, SEXP f2,
                      SEXP control1){
BEGIN_RCPP
  //Initialization of functions and control parameters
  Function obej(f1);
  Function grad(f2);
  List control(control1);
  IntegerVector retraction(retraction1);
  int iterMax=as< int>(control["iterMax"]);
  int iterSubMax=as< int>(control["iterSubMax"]);
  double tol=as< double>(control["tol"]);
  double sigma=as< double>(control["sigma"]);
  double beta=as< double>(control["beta"]);
  double alpha=as< double>(control["alpha"]);

  
  // Initialization of Data points
  IntegerVector n(n1),p(p1),r(r1);
  CharacterVector mtype(mtype1);
  int prodK=n.size();// size of product manifold
  vector< manifold*>  manifoldY;
  int k;
  List YList(YList1);
  for(k=0;k<prodK;k++){
    SEXP yTemp2=YList[k];
     NumericMatrix yTemp(yTemp2);
     std::string typeTemp=as< std::string>(mtype[k]);
     if(typeTemp=="stiefel"){
        manifoldY.push_back(new stiefel(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }
     else if(typeTemp=="grassmannQ"){
       manifoldY.push_back(new grassmannQ(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="grassmannSub"){
       manifoldY.push_back(new grassmannSub(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="fixedRank"){
       manifoldY.push_back(new fixRank(n[k],p[k],r[k],
                                  yTemp,retraction[k]));

     }else if(typeTemp=="fixedRankPSD"){
       manifoldY.push_back(new fixRankPSD(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="elliptope"){
       manifoldY.push_back(new elliptope(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="spectahedron"){
       manifoldY.push_back(new spectahedron(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="sphere"){
       manifoldY.push_back(new sphere(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="fixedRankSym"){
       manifoldY.push_back(new fixRankSym(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="oblique"){
       manifoldY.push_back(new oblique(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="specialLinear"){
       manifoldY.push_back(new specialLinear(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }else if(typeTemp=="projective"){
       manifoldY.push_back(new projective(n[k],p[k],r[k],
                                  yTemp,retraction[k]));
     }        

  }
    
  //define other varibles
	int iter=0,iterInner=0; // outer loop, inner loop control
  bool flag=true,first=true;
  double objValue,objValue_temp,objValue_outer,eDescent,objDesc,stepsize;
  //value of objective function
  //eDescent: expected descent amount
  //largest obj descent amount
//  Function expm(f3);
  arma::mat gradF;  //gradient in ambient space
  
  if(prodK>1){
    objValue=as< double>(obej(YList));
  }else{
    objValue=as< double>(obej(YList[0]));
  }
  //begin iteration
  while(iter<iterMax && flag){
    //gradient of objective funtion
    iter++;
    objDesc=-1;
    objValue_outer=objValue;
    for(k=0;k<prodK;k++){
        if(prodK>1){
          gradF=as< arma::mat>(grad(YList,k+1));
        }else{
          gradF=as< arma::mat>(grad(YList[0]));
        }
        //gradient on the stiefel manifold
       manifoldY[k]->evalGradient(gradF,"steepest");
        stepsize=alpha/beta;
        eDescent=sigma/beta*(manifoldY[k]->get_eDescent());
        first=true;
        
        iterInner=0;
        do{//choose appropirate step size according to Armijo rule
          iterInner++;
          stepsize=stepsize*beta;
          eDescent=eDescent*beta;
          YList[k]=manifoldY[k]->retract(stepsize,"steepest",first);
          if(prodK>1){
            objValue_temp=as< double>(obej(YList));
          }else{
            objValue_temp=as< double>(obej(YList[0]));
          }
          first=false;
        }while((objValue-objValue_temp)<eDescent && iterInner<iterSubMax);
        //step size iteration
        //if a stepsize is accepted, update current location
        manifoldY[k]->acceptY();
        objValue=objValue_temp;
    }// iteration over product component
    objDesc=objValue_outer-objValue;
    if(tol>objDesc) flag=false;
  }// outer iteration
  return List::create(Named("optY")=YList,
              Named("optValue")=objValue,
              Named("NumIter")=iter);
END_RCPP
}//end of function