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
void Dialog::mkSensorModel() { QCPGraph * gr; QPen pn; double simTime = 60.0; double simStepTime = 0.1; double tempStart = 25.0; double tempCurrent = tempStart; double tempSet = 35.0; double tempDeltaPrev = 0.0; int normalFixDeep = 5; int steps = simTime / simStepTime; QVector<double> xTime(steps), yTemp(steps), yTempSet(steps); QVector<double> normalValues(normalFixDeep); normalValues.fill(0); QVector<double> tempLabels; for (int x=10; x<=50; x+=5) tempLabels.push_back(x); QVector<double> timeLabels; for (int x=0; x<=simTime; x+=5) timeLabels.push_back(x); for (int x=0; x<steps; x++) { // Calc new temp value double tempApply = 0.0; // No change double tempDelta = std::abs(tempCurrent - tempSet); double stepDir = (tempCurrent < tempSet) ? 1.0 : -1.0; if (0.1 < tempDelta) { if (tempDelta > 10) { tempApply = 0.19 * 1.0; } else { tempApply = 0.2 * (1.0 * (tempDelta/10.0) ); } // if (tempApply < 0.01) tempApply = 0.01; // qDebug() << tempApply; tempApply = tempApply * stepDir; // Calc normalzied value double lastSum = 0; for (int x=0; x<normalFixDeep; x++) lastSum += normalValues[x]; tempApply = (lastSum + tempApply) / ((double)normalFixDeep + 1.0); tempDeltaPrev = tempApply; tempCurrent = tempCurrent + tempApply; qDebug() << tempCurrent; } normalValues.push_back(tempApply); normalValues.pop_front(); xTime[x] = (double)x * simStepTime; if (10.0 == xTime[x]) tempSet = 40.0; if (40.0 == xTime[x]) tempSet = 30.0; yTempSet[x] = tempSet; yTemp[x] = tempCurrent; } gr = ui->plot->addGraph(); gr->setData(xTime, yTemp); pn.setColor(Qt::red); pn.setWidth(3); gr->setPen(pn); gr->setName("Реальное значение"); gr = ui->plot->addGraph(); gr->setData(xTime, yTempSet); pn.setColor(0x008080); pn.setWidth(1); pn.setStyle(Qt::DashLine); gr->setPen(pn); gr->setName("Конечное значение"); ui->plot->xAxis->setLabel("Время, сек"); ui->plot->xAxis->setRange(0, simTime); ui->plot->xAxis->setAutoTicks(false); ui->plot->xAxis->setTickVector(timeLabels); ui->plot->yAxis->setLabel("Температура, °C"); ui->plot->yAxis->setRange(20, 50); ui->plot->yAxis->setAutoTicks(false); ui->plot->yAxis->setTickVector(tempLabels); ui->plot->legend->setVisible(true); ui->plot->replot(); ui->plot->savePdf("graph-boiler.pdf", false, 800, 400); }
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