Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.44 KB | None | 0 0
  1. #include <time.h>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include "Bspline.h"
  6. #include "mosek.h"
  7.  
  8. // import std namespace
  9. using namespace std;
  10. // import most common Eigen types
  11. USING_PART_OF_NAMESPACE_EIGEN;
  12.  
  13. #define ERROR 0;
  14.  
  15. int sign(double x);
  16. void writeMatrix(MatrixXd * M, FILE * pFile);
  17. void writeSparseMatrix(MatrixXd * M, FILE * pFile, int NUMANZ);
  18. void buildC(VectorXd* t,int k, int degree, vector<MatrixXd>* out );
  19. MatrixXd buildB(vector<Bspline> basis, VectorXd X);
  20. const int getNumanz(MatrixXd A);
  21. void sparseARowWise(MatrixXd* A, vector<MSKlidxt>* aptrb,
  22. vector<MSKlidxt>* aptre, MSKidxt asub[], double aval[]);
  23.  
  24. int main(int argc,char *argv[])
  25. {
  26. // nodige variabelen instellen
  27. const int t0 = 0; // vast beginpunt van het gebruikte tijdsinterval
  28. const int t1 = 10; // eindpunt van gebruikte tijdsinterval
  29. const int g = 10; // aantal knopen
  30. const int k = 3; // graad van spline
  31.  
  32. const int sizex = 2*g+k+1; // lengte van variabelenvector
  33. const int lt = g+2; // lengte van t-vector
  34.  
  35. double scal = (double) t1-t0; // scaleringsfactor, nodig bij het verwerken van de preprocessing
  36.  
  37. /*
  38. Knooppuntenrij initiäliseren
  39. ----------------------------
  40. */
  41.  
  42. double dt = (double) (t1-t0)/(g+1);
  43. VectorXd t(lt);
  44. for(int i = 0 ; i <= g+1; i++)
  45. {
  46. t(i) = t0+dt*i;
  47. }
  48. VectorXd front_boundary = VectorXd::Constant(k,t(0));
  49. VectorXd back_boundary = VectorXd::Constant(k,t(lt-1));
  50.  
  51. VectorXd ext_t(lt+2*k);
  52. ext_t.start(k) = front_boundary;
  53. ext_t.end(k) = back_boundary;
  54. ext_t.segment(k,lt) = t;
  55.  
  56. // cout<<"ext_t: \n"<<ext_t<<endl; // tijdsvector uitprinten
  57.  
  58. /*
  59. C-matrices
  60. (C : zet x = [c v] om in [ck v])
  61. (C1: zet x = [c v] om in [c1 ])
  62. (C2: zet x = [c v] om in [c2 ])
  63. --------------------------------------
  64. */
  65. vector<MatrixXd> Cs;
  66. buildC(&ext_t,k,k,&Cs);
  67.  
  68. MatrixXd C_part = Cs.at(Cs.size()-1);
  69. MatrixXd C = MatrixXd::Zero(sizex-k,sizex);
  70. C.corner(Eigen::TopLeft,g+1,g+k+1) = C_part;
  71. C.corner(Eigen::BottomRight,g,g) = MatrixXd::Identity(g,g);
  72.  
  73. // cout<<"C: \n"<<C<<endl; // C-matrix uitprinten
  74.  
  75. MatrixXd C1_part = Cs.at(0);
  76. MatrixXd C1 = MatrixXd::Zero(g+k,sizex);
  77. C1.corner(Eigen::TopLeft,g+k,g+k+1) = C1_part;
  78.  
  79. // cout<<"C1: \n"<<C1<<endl; // C1-matrix uitprinten
  80.  
  81. MatrixXd C2_part = Cs.at(1);
  82. MatrixXd C2 = MatrixXd::Zero(g+k-1,sizex);
  83. C2.corner(Eigen::TopLeft,g+k-1,g+k+1) = C2_part;
  84.  
  85. // cout<<"C2: \n"<<C2<<endl; // C2-matrix uitprinten
  86.  
  87. /*
  88. Opstellen van de splinebasis d0B, d1B en d2B (s(x) = d0B*c)
  89. -----------------------------------------------------------
  90. */
  91.  
  92. vector<Bspline> d0basis;
  93. for(int i=0; i<ext_t.size()-k-1;i++)
  94. {
  95. d0basis.push_back(Bspline(ext_t.segment(i,k+2)));
  96. }
  97. MatrixXd d0B1 = buildB(d0basis,t);
  98.  
  99. vector<Bspline> d1basis;
  100. for(int i=1; i<ext_t.size()-k-1;i++)
  101. {
  102. d1basis.push_back(Bspline(ext_t.segment(i,k+1)));
  103. }
  104. MatrixXd d1B = buildB(d1basis,t);
  105.  
  106. vector<Bspline> d2basis;
  107. for(int i=2; i<ext_t.size()-k-1;i++)
  108. {
  109. d2basis.push_back(Bspline(ext_t.segment(i,k)));
  110. }
  111. MatrixXd d2B = buildB(d2basis,t);
  112.  
  113. MatrixXd d0B = MatrixXd::Zero(lt,sizex);
  114. d0B.corner(Eigen::TopLeft,lt,g+k+1) = d0B1;
  115. MatrixXd vel = (d1B*C1)*3;
  116. MatrixXd acc = (d2B*C2)*6;
  117.  
  118. // cout<<"d0B: \n"<<d0B<<endl; // B-matrix uitprinten
  119. // cout<<"d1B: \n"<<d1B<<endl; // d1B-matrix uitprinten
  120. // cout<<"d2B: \n"<<d2B<<endl; // d1B-matrix uitprinten
  121. // cout<<"vel: \n"<<vel<<endl; // velocity-matrix uitprinten
  122. // cout<<"acc: \n"<<acc<<endl; // acceleration-matrix uitprinten
  123.  
  124. /*
  125. Beginvoorwaarden in matrixvorm instellen
  126. ----------------------------------------
  127. */
  128.  
  129. MatrixXd A1 = MatrixXd::Zero(6,sizex);
  130. // begin- en eindpunt
  131. A1(0,0) = 1;
  132. A1(1,g+k) = 1;
  133. // begin- en eindsnelheid
  134. A1.row(2) = C1.row(0);
  135. A1.row(3) = C1.row(g+k-1);
  136. // begin- en eindversnelling
  137. A1.row(4) = C2.row(0);
  138. A1.row(5) = C2.row(g+k-2);
  139.  
  140. // cout<<"A1: \n"<<A1<<endl; // A-matrix uitprinten
  141.  
  142. /*
  143. Voorwaarde norm(Ck(2:end)-Ck(1:end-1),1)<v
  144. ------------------------------------------
  145. */
  146.  
  147. MatrixXd onevw = MatrixXd::Zero(2*g,sizex-k);
  148.  
  149. onevw.corner(Eigen::TopLeft,g,g) = onevw.corner(Eigen::TopLeft,g,g)-MatrixXd::Identity(g,g);
  150. onevw.block(0,1,g,g) = onevw.block(0,1,g,g)+MatrixXd::Identity(g,g);
  151. onevw.block(0,g+1,g,g) = -MatrixXd::Identity(g,g);
  152.  
  153. onevw.corner(Eigen::BottomLeft,g,g) = onevw.corner(Eigen::BottomLeft,g,g)-MatrixXd::Identity(g,g);
  154. onevw.block(g,1,g,g) = onevw.block(g,1,g,g)+MatrixXd::Identity(g,g);
  155. onevw.block(g,g+1,g,g) = MatrixXd::Identity(g,g);
  156.  
  157. MatrixXd A2 = onevw*C;
  158.  
  159. // cout<<"onevw: \n"<<onevw<<endl;
  160. // cout<<"A2: \n" <<onevw<<endl;
  161.  
  162. /*
  163. snelheidsbeperkingen in vectorvorm
  164. ----------------------------------
  165. */
  166.  
  167. MatrixXd A4 = C1*3;
  168.  
  169. /*
  170. Data voor mosek
  171. ---------------
  172. */
  173. const int NUMCON1 = A1.rows();
  174. const int NUMCON2 = A2.rows();
  175. const int NUMCON3 =vel.rows();
  176. const int NUMCON4 = A4.rows();
  177. const int NUMCON = NUMCON1 + NUMCON2 + NUMCON3 + NUMCON4;
  178.  
  179. const int NUMANZ1 = getNumanz(A1);
  180. const int NUMANZ2 = getNumanz(A2);
  181. const int NUMANZ3 = getNumanz(5*vel+acc);
  182. const int NUMANZ4 = getNumanz(A4);
  183. const int NUMANZ = NUMANZ1 + NUMANZ2 + NUMANZ3 + NUMANZ4;
  184.  
  185. /*
  186. wegschrijven van alle berekende data
  187. -------------------------------------
  188. */
  189.  
  190. FILE * pFile;
  191. char loc[] = "..\\..\\Main_no_prepro\\Main_no_prepro\\testFile.bin";
  192. if((pFile= fopen(loc,"wb"))==NULL)
  193. {
  194. printf("Error occurred while opening \"%s\" for reading.\n", loc);
  195. return ERROR;
  196. }
  197.  
  198. fwrite (&scal , sizeof(double) , 1 , pFile );
  199. fwrite (&g , sizeof(int) , 1 , pFile );
  200. fwrite (&k , sizeof(int) , 1 , pFile );
  201. fwrite (&NUMCON , sizeof(int) , 1 , pFile );
  202. fwrite (&NUMANZ , sizeof(int) , 1 , pFile );
  203. writeSparseMatrix(&A1, pFile, NUMANZ1);
  204. writeMatrix(&A2, pFile);
  205. writeMatrix(&vel, pFile);
  206. writeMatrix(&acc, pFile);
  207. writeSparseMatrix(&A4, pFile, NUMANZ4);
  208.  
  209. fclose (pFile);
  210.  
  211. cout<<"done"<<endl;
  212. string stop;
  213. cin>>stop;
  214.  
  215. return 0;
  216. }
  217. // geef het teken terug van x:
  218. // return = 1 if x >= 0
  219. // return = -1 if x < 0
  220. int sign(double x)
  221. {
  222. if(x>=0)
  223. {return 1;}
  224. else
  225. {return -1;}
  226. }
  227.  
  228. // Schrijf een matrix weg naar het gespecifieerd bestand
  229. void writeMatrix(MatrixXd * M, FILE * pFile)
  230. {
  231. int cols = M->cols();
  232. fwrite (&cols , sizeof(int) , 1 , pFile );
  233. int rows = M->rows();
  234. fwrite (&rows , sizeof(int) , 1 , pFile );
  235. double data;
  236. for(int i=0; i<rows; i++)
  237. {
  238. for(int j=0; j<cols; j++)
  239. {
  240. data = M->coeff(i,j);
  241. fwrite (&data , sizeof(double) , 1 , pFile );
  242. }
  243. }
  244. }
  245.  
  246. // Schrijf een matrix weg naar het gespecifieerd bestand in spaarse voorstelling
  247. void writeSparseMatrix(MatrixXd * M, FILE * pFile, int NUMANZ)
  248. {
  249. // Matrix naar spaarse vorm omzetten
  250. MSKidxt (*asub) = new MSKidxt[NUMANZ];
  251. double (*aval) = new double[NUMANZ];
  252. vector<MSKlidxt> aptrb, aptre;
  253. sparseARowWise(M, &aptrb, &aptre, asub, aval);
  254.  
  255. // Wegschrijven van de eerste 2 arrays
  256. MSKidxt data1;
  257. double data2;
  258. fwrite (&NUMANZ , sizeof(int) , 1 , pFile );
  259. for(int i=0; i<NUMANZ; i++)
  260. {
  261. data1 = asub[i];
  262. fwrite (&data1 , sizeof(MSKidxt) , 1 , pFile );
  263. }
  264.  
  265. fwrite (&NUMANZ , sizeof(int) , 1 , pFile );
  266. for(int i=0; i<NUMANZ; i++)
  267. {
  268. data2 = aval[i];
  269. fwrite (&data2 , sizeof(double) , 1 , pFile );
  270. }
  271.  
  272. // Wegschrijven van de 2 vectoren
  273. MSKlidxt data;
  274. int length = aptrb.size();
  275. fwrite (&length , sizeof(int) , 1 , pFile );
  276. for(int i=0; i<length; i++)
  277. {
  278. data = aptrb.at(i);
  279. fwrite (&data , sizeof(MSKlidxt) , 1 , pFile );
  280. }
  281.  
  282. length = aptre.size();
  283. fwrite (&length , sizeof(int) , 1 , pFile );
  284. for(int i=0; i<length; i++)
  285. {
  286. data = aptre.at(i);
  287. fwrite (&data , sizeof(MSKlidxt) , 1 , pFile );
  288. }
  289. }
  290.  
  291. // Bouw de verschillende transformatiematrices C
  292. void buildC(VectorXd* t,int k, int degree, vector<MatrixXd>* out )
  293. {
  294. int g = t->size()-2*(k+1);
  295. MatrixXd C = MatrixXd::Identity(g+k+1,g+k+1);
  296.  
  297. MatrixXd Ci;
  298. VectorXd dt;
  299.  
  300. for(int i=1;i<=degree;++i)
  301. {
  302. dt = t->segment(1+k,g+k+1-i)- t->segment(i,g+k+1-i); // lengte = g+k+1-i
  303.  
  304. Ci = MatrixXd::Zero(g+k+1-i, g+k+2-i);
  305. for(int j = 0; j<g+k+1-i;++j)
  306. {
  307. Ci(j,j) = -1/dt(j);
  308. Ci(j,j+1) = 1/dt(j);
  309. // Ci(j,j) = -1/(t->coeff(1+k+j)-t->coeff(i+j));
  310. // Ci(j,j+1) = 1/(t->coeff(1+k+j)-t->coeff(i+j));
  311. }
  312. C = Ci*C;
  313. out->push_back(C);
  314. }
  315. }
  316.  
  317. // Bouw de B-matrix op met de waarde van de splinebasis op de verschillende punten in X
  318. MatrixXd buildB(vector<Bspline> basis, VectorXd X)
  319. {
  320. MatrixXd B = MatrixXd::Zero(X.size(),basis.size());
  321. for(int j=0; j< (int) basis.size();++j)
  322. {
  323. for(int i=0; i<X.size();++i)
  324. {
  325. B(i,j)= basis[j].evalBspline(X(i));
  326. }
  327. }
  328. B(X.size()-1,basis.size()-1) = 1;
  329. return B;
  330. }
  331.  
  332. // Bepaal het aantal elementen in A verschillend van nul
  333. const int getNumanz(MatrixXd A)
  334. {
  335. int count = 0;
  336. int cols = A.cols();
  337. int rows = A.rows();
  338.  
  339. for(int i=0; i<rows; i++)
  340. {
  341. for(int j=0; j<cols; j++)
  342. {
  343. if(abs(A(i,j)>0.0001))
  344. {
  345. count++;
  346. }
  347. }
  348. }
  349. return count;
  350. }
  351.  
  352. // Zet A om naar zijn spaarse vorm, geordend per rij
  353. void sparseARowWise(MatrixXd* A, vector<MSKlidxt>* aptrb,
  354. vector<MSKlidxt>* aptre, MSKidxt asub[], double aval[])
  355. {
  356. int k = 0;
  357. int count = 0;
  358. int rows = A->rows();
  359. int cols = A->cols();
  360. for(int i=0; i<A->rows();++i)
  361. {
  362. aptrb->push_back(count);
  363. for(int j=0; j<A->cols(); ++j)
  364. {
  365.  
  366. if(abs(A->coeff(i,j))>0.001)
  367. {
  368. count++;
  369. //asub[k] = j;
  370. //aval[k] = A->coeff(i,j);
  371. k++;
  372. }
  373. }
  374. aptre->push_back(count);
  375. }
  376. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement