cmscp_sparseInfo.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. #include "cmscp_sparseInfo.h"
  2. /* 定义函数 */
  3. void intRcsToCcs(int* ptrRow, int* idxCol, int* valueRcs, int numRow, int numCol, int* idxRow, int* ptrCol, int* valueCcs)
  4. {
  5. // 函数功能:整数型RCS(行压缩)格式转CCS(列压缩)
  6. // 输入:RCS的稀疏信息
  7. // ptrRow:压缩的行坐标,各行首元素所在valueRcs的位置
  8. // idxCol:列坐标
  9. // valueRcs:非零元素值
  10. // 输出:
  11. // 输出:CCS的稀疏信息
  12. // ptrCol:压缩的列坐标,各列首元素所在valueCcs的位置
  13. // idxRow:行坐标
  14. // valueCcs:非零元素值
  15. // 谢磊:2022 / 6 / 25编写
  16. // 声明变量
  17. int numNz, * w, cntNz, i, j, k, q;
  18. // 分配内存
  19. w = (int*)malloc(numCol * sizeof(int)); // 临时变量
  20. // 计算CCS格式的ptrCol
  21. // 计算每列非零元个数
  22. numNz = ptrRow[numRow]; // 非零元素个数
  23. intVecFillin(w, numCol, 0); // 给w赋0
  24. if (numNz)
  25. {
  26. for (cntNz = 0; cntNz < numNz; cntNz++)
  27. {
  28. j = idxCol[cntNz];
  29. w[j]++;// 用于统计每列的非零元个数
  30. }
  31. // 将每列非零元个数累加
  32. ptrCol[0] = 0;
  33. for (j = 0; j < numCol; j++)
  34. {
  35. ptrCol[j + 1] = ptrCol[j] + w[j];
  36. }
  37. // 计算CCS格式的idxRow,valueCcs
  38. copyIntVec(ptrCol, w, numCol, 0); // 当前元素所在列的起始点位置
  39. if (valueRcs == NULL) // 只转化坐标,不对valueRcs操作
  40. {
  41. for (i = 0; i < numRow; i++)
  42. {
  43. for (k = ptrRow[i]; k < ptrRow[i + 1]; k++)
  44. {
  45. j = idxCol[k];
  46. q = w[j]++;
  47. idxRow[q] = i;
  48. }
  49. }
  50. }
  51. else
  52. {
  53. for (i = 0; i < numRow; i++)
  54. {
  55. for (k = ptrRow[i]; k < ptrRow[i + 1]; k++)
  56. {
  57. j = idxCol[k];
  58. q = w[j]++;
  59. idxRow[q] = i;
  60. valueCcs[q] = valueRcs[k];
  61. }
  62. }
  63. }
  64. // 释放内存
  65. free(w);
  66. }
  67. }
  68. void floatRcsToCcs(int* ptrRow, int* idxCol, double* valueRcs, int numRow, int numCol, int* idxRow, int* ptrCol, double* valueCcs)
  69. {
  70. // 函数功能:浮点型RCS(行压缩)格式转CCS(列压缩)
  71. // 输入:RCS的稀疏信息
  72. // ptrRow:压缩的行坐标,各行首元素所在valueRcs的位置
  73. // idxCol:列坐标
  74. // valueRcs:非零元素值
  75. // 输出:
  76. // 输出:CCS的稀疏信息
  77. // ptrCol:压缩的列坐标,各列首元素所在valueCcs的位置
  78. // idxRow:行坐标
  79. // valueCcs:非零元素值
  80. // 谢磊:2022 / 6 / 25编写
  81. // 声明变量
  82. int numNz, * w, cntNz, i, j, k, q;
  83. // 分配内存
  84. w = (int*)malloc(numCol * sizeof(int)); // 临时变量
  85. // 计算CCS格式的ptrCol
  86. // 计算每列非零元个数
  87. numNz = ptrRow[numRow]; // 非零元素个数
  88. intVecFillin(w, numCol, 0); // 给w赋0
  89. if (numNz)
  90. {
  91. for (cntNz = 0; cntNz < numNz; cntNz++)
  92. {
  93. j = idxCol[cntNz];
  94. w[j]++;// 用于统计每列的非零元个数
  95. }
  96. // 将每列非零元个数累加
  97. ptrCol[0] = 0;
  98. for (j = 0; j < numCol; j++)
  99. {
  100. ptrCol[j + 1] = ptrCol[j] + w[j];
  101. }
  102. // 计算CCS格式的idxRow,valueCcs
  103. copyIntVec(ptrCol, w, numCol, 0); // 当前元素所在列的起始点位置
  104. if (valueRcs == NULL) // 只转化坐标,不对valueRcs操作
  105. {
  106. for (i = 0; i < numRow; i++)
  107. {
  108. for (k = ptrRow[i]; k < ptrRow[i + 1]; k++)
  109. {
  110. j = idxCol[k];
  111. q = w[j]++;
  112. idxRow[q] = i;
  113. }
  114. }
  115. }
  116. else
  117. {
  118. for (i = 0; i < numRow; i++)
  119. {
  120. for (k = ptrRow[i]; k < ptrRow[i + 1]; k++)
  121. {
  122. j = idxCol[k];
  123. q = w[j]++;
  124. idxRow[q] = i;
  125. valueCcs[q] = valueRcs[k];
  126. }
  127. }
  128. }
  129. free(w);
  130. }
  131. }
  132. void intDematNzPos(int* demat, int numRow, int numCol, int** ptrRow0, int** idxCol0, int** idxRow0, int** ptrCol0) {
  133. // 函数功能:获取稠密矩阵的非零元位置(包含分配相应变量的内存空间)
  134. // 输入:
  135. // demat:无连续函数稀疏信息的结构体
  136. // numRow:demat的行数
  137. // numCol:demat的列数
  138. // 输出:
  139. // ptrRow0, idxCol0:行压缩格式存储的行列坐标的指针变量的地址
  140. // idxRow0, ptrCol0:列压缩格式存储的行列坐标
  141. // 假设函数的自变量按照[x, u, p]排序
  142. // 谢磊:2022 / 6 / 25编写
  143. // 声明变量
  144. int numNz, i, j, dematij, * numNzRow, cntNz, * ptrRow, * idxCol, * idxRow, * ptrCol;
  145. // 统计非零元个数
  146. numNz = 0;
  147. for (i = 0; i < numRow; i++)
  148. {
  149. for (j = 0; j < numCol; j++)
  150. {
  151. if (demat[i + numRow * j]) // 判断demat的第ij个元素是否为1
  152. {
  153. numNz++;
  154. }
  155. }
  156. }
  157. // 分配内存
  158. if (numNz)
  159. {
  160. ptrRow = (int*)malloc((numRow + 1) * sizeof(int));// 用于存储每行中第1个非零元素在idxCol中的位置
  161. idxCol = (int*)malloc(numNz * sizeof(int));// 非零元素列坐标
  162. idxRow = (int*)malloc(numNz * sizeof(int));// 非零元素行坐标
  163. ptrCol = (int*)malloc((numCol + 1) * sizeof(int));// 用于存储每列中第1个非零元素在idxCol中的位置
  164. numNzRow = (int*)malloc(numRow * sizeof(int));// 用于统计每行的非零元个数
  165. cntNz = 0;
  166. for (i = 0; i < numRow; i++)
  167. {
  168. numNzRow[i] = 0;
  169. for (j = 0; j < numCol; j++)
  170. {
  171. dematij = demat[i + numRow * j];
  172. if (dematij)
  173. {
  174. numNzRow[i] = numNzRow[i] + 1;
  175. idxCol[cntNz++] = j;
  176. }
  177. }
  178. }
  179. ptrRow[0] = 0;
  180. for (i = 0; i < numRow; i++)
  181. {
  182. ptrRow[i + 1] = ptrRow[i] + numNzRow[i];
  183. }
  184. // Rcs转化为Ccs格式
  185. intRcsToCcs(ptrRow, idxCol, NULL, numRow, numCol, idxRow, ptrCol, NULL);
  186. free(numNzRow);
  187. }
  188. else
  189. {
  190. ptrRow = (int*)malloc((numRow + 1) * sizeof(int));
  191. intVecFillin(ptrRow, numRow + 1, 0);
  192. idxCol = NULL;
  193. idxRow = NULL;
  194. ptrCol = (int*)malloc((numCol + 1) * sizeof(int));
  195. intVecFillin(ptrCol, numCol + 1, 0);
  196. }
  197. // 输出稀疏信息
  198. *ptrRow0 = ptrRow;
  199. *idxCol0 = idxCol;
  200. *idxRow0 = idxRow;
  201. *ptrCol0 = ptrCol;
  202. }
  203. void mallocSparseInfo(cmscp_sparseInfo** sparseInfo0, int numPhase) {
  204. // 函数功能:用函数给sparseInfo分配空间
  205. // 输入:
  206. // sparseInfo的结构体地址:sparseInfo0 = &sparseInfo
  207. // 段数:numPhase
  208. // 输出:
  209. // 分配好的内存的sparseInfo
  210. // 谢磊:2022 / 6 / 25编写
  211. // 声明变量
  212. cmscp_sparseInfo* sparseInfo;
  213. // 1级分配
  214. sparseInfo = (cmscp_sparseInfo*)malloc(numPhase * sizeof(cmscp_sparseInfo));
  215. // 2级分配
  216. sparseInfo->contNzPos = (cmscp_nzPos_cont**)malloc(numPhase * sizeof(cmscp_nzPos_cont*));
  217. sparseInfo->objEventNzPos = (cmscp_nzPos_endp**)malloc(numPhase * sizeof(cmscp_nzPos_endp*));
  218. sparseInfo->endpNzPos = (cmscp_nzPos_endp**)malloc(numPhase * sizeof(cmscp_nzPos_endp*));
  219. sparseInfo->linkNzPos = (cmscp_nzPos_link**)malloc(numPhase * sizeof(cmscp_nzPos_link*));
  220. // 3级和4级分配
  221. int iphase;
  222. for (iphase = 0; iphase < numPhase; iphase++) {
  223. // 3级分配
  224. sparseInfo->contNzPos[iphase] = (cmscp_nzPos_cont*)malloc(sizeof(cmscp_nzPos_cont));
  225. sparseInfo->objEventNzPos[iphase] = (cmscp_nzPos_endp*)malloc(sizeof(cmscp_nzPos_endp));
  226. sparseInfo->endpNzPos[iphase] = (cmscp_nzPos_endp*)malloc(sizeof(cmscp_nzPos_endp));
  227. // 4级分配
  228. sparseInfo->contNzPos[iphase]->state = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  229. sparseInfo->contNzPos[iphase]->state->idxCol = NULL;
  230. sparseInfo->contNzPos[iphase]->state->idxRow = NULL;
  231. sparseInfo->contNzPos[iphase]->state->ptrCol = NULL;
  232. sparseInfo->contNzPos[iphase]->state->ptrRow = NULL;
  233. sparseInfo->contNzPos[iphase]->control = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  234. sparseInfo->contNzPos[iphase]->control->idxCol = NULL;
  235. sparseInfo->contNzPos[iphase]->control->idxRow = NULL;
  236. sparseInfo->contNzPos[iphase]->control->ptrCol = NULL;
  237. sparseInfo->contNzPos[iphase]->control->ptrRow = NULL;
  238. sparseInfo->contNzPos[iphase]->parameter = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  239. sparseInfo->contNzPos[iphase]->parameter->idxCol = NULL;
  240. sparseInfo->contNzPos[iphase]->parameter->idxRow = NULL;
  241. sparseInfo->contNzPos[iphase]->parameter->ptrCol = NULL;
  242. sparseInfo->contNzPos[iphase]->parameter->ptrRow = NULL;
  243. sparseInfo->objEventNzPos[iphase]->iniTime = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  244. sparseInfo->objEventNzPos[iphase]->iniTime->idxCol = NULL;
  245. sparseInfo->objEventNzPos[iphase]->iniTime->idxRow = NULL;
  246. sparseInfo->objEventNzPos[iphase]->iniTime->ptrCol = NULL;
  247. sparseInfo->objEventNzPos[iphase]->iniTime->ptrRow = NULL;
  248. sparseInfo->objEventNzPos[iphase]->finTime = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  249. sparseInfo->objEventNzPos[iphase]->finTime->idxCol = NULL;
  250. sparseInfo->objEventNzPos[iphase]->finTime->idxRow = NULL;
  251. sparseInfo->objEventNzPos[iphase]->finTime->ptrCol = NULL;
  252. sparseInfo->objEventNzPos[iphase]->finTime->ptrRow = NULL;
  253. sparseInfo->objEventNzPos[iphase]->iniState = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  254. sparseInfo->objEventNzPos[iphase]->iniState->idxCol = NULL;
  255. sparseInfo->objEventNzPos[iphase]->iniState->idxRow = NULL;
  256. sparseInfo->objEventNzPos[iphase]->iniState->ptrCol = NULL;
  257. sparseInfo->objEventNzPos[iphase]->iniState->ptrRow = NULL;
  258. sparseInfo->objEventNzPos[iphase]->finState = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  259. sparseInfo->objEventNzPos[iphase]->finState->idxCol = NULL;
  260. sparseInfo->objEventNzPos[iphase]->finState->idxRow = NULL;
  261. sparseInfo->objEventNzPos[iphase]->finState->ptrCol = NULL;
  262. sparseInfo->objEventNzPos[iphase]->finState->ptrRow = NULL;
  263. sparseInfo->objEventNzPos[iphase]->parameter = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  264. sparseInfo->objEventNzPos[iphase]->parameter->idxCol = NULL;
  265. sparseInfo->objEventNzPos[iphase]->parameter->idxRow = NULL;
  266. sparseInfo->objEventNzPos[iphase]->parameter->ptrCol = NULL;
  267. sparseInfo->objEventNzPos[iphase]->parameter->ptrRow = NULL;
  268. sparseInfo->endpNzPos[iphase]->iniTime = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  269. sparseInfo->endpNzPos[iphase]->iniTime->idxCol = NULL;
  270. sparseInfo->endpNzPos[iphase]->iniTime->idxRow = NULL;
  271. sparseInfo->endpNzPos[iphase]->iniTime->ptrCol = NULL;
  272. sparseInfo->endpNzPos[iphase]->iniTime->ptrRow = NULL;
  273. sparseInfo->endpNzPos[iphase]->finTime = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  274. sparseInfo->endpNzPos[iphase]->finTime->idxCol = NULL;
  275. sparseInfo->endpNzPos[iphase]->finTime->idxRow = NULL;
  276. sparseInfo->endpNzPos[iphase]->finTime->ptrCol = NULL;
  277. sparseInfo->endpNzPos[iphase]->finTime->ptrRow = NULL;
  278. sparseInfo->endpNzPos[iphase]->iniState = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  279. sparseInfo->endpNzPos[iphase]->iniState->idxCol = NULL;
  280. sparseInfo->endpNzPos[iphase]->iniState->idxRow = NULL;
  281. sparseInfo->endpNzPos[iphase]->iniState->ptrCol = NULL;
  282. sparseInfo->endpNzPos[iphase]->iniState->ptrRow = NULL;
  283. sparseInfo->endpNzPos[iphase]->finState = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  284. sparseInfo->endpNzPos[iphase]->finState->idxCol = NULL;
  285. sparseInfo->endpNzPos[iphase]->finState->idxRow = NULL;
  286. sparseInfo->endpNzPos[iphase]->finState->ptrCol = NULL;
  287. sparseInfo->endpNzPos[iphase]->finState->ptrRow = NULL;
  288. sparseInfo->endpNzPos[iphase]->parameter = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  289. sparseInfo->endpNzPos[iphase]->parameter->idxCol = NULL;
  290. sparseInfo->endpNzPos[iphase]->parameter->idxRow = NULL;
  291. sparseInfo->endpNzPos[iphase]->parameter->ptrCol = NULL;
  292. sparseInfo->endpNzPos[iphase]->parameter->ptrRow = NULL;
  293. if (iphase < numPhase - 1) {
  294. // 3级分配
  295. sparseInfo->linkNzPos[iphase] = (cmscp_nzPos_link*)malloc(sizeof(cmscp_nzPos_link));
  296. // 4级分配
  297. sparseInfo->linkNzPos[iphase]->leftTf = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  298. sparseInfo->linkNzPos[iphase]->leftTf->idxCol = NULL;
  299. sparseInfo->linkNzPos[iphase]->leftTf->idxRow = NULL;
  300. sparseInfo->linkNzPos[iphase]->leftTf->ptrCol = NULL;
  301. sparseInfo->linkNzPos[iphase]->leftTf->ptrRow = NULL;
  302. sparseInfo->linkNzPos[iphase]->leftStatef = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  303. sparseInfo->linkNzPos[iphase]->leftStatef->idxCol = NULL;
  304. sparseInfo->linkNzPos[iphase]->leftStatef->idxRow = NULL;
  305. sparseInfo->linkNzPos[iphase]->leftStatef->ptrCol = NULL;
  306. sparseInfo->linkNzPos[iphase]->leftStatef->ptrRow = NULL;
  307. sparseInfo->linkNzPos[iphase]->leftParameter = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  308. sparseInfo->linkNzPos[iphase]->leftParameter->idxCol = NULL;
  309. sparseInfo->linkNzPos[iphase]->leftParameter->idxRow = NULL;
  310. sparseInfo->linkNzPos[iphase]->leftParameter->ptrCol = NULL;
  311. sparseInfo->linkNzPos[iphase]->leftParameter->ptrRow = NULL;
  312. sparseInfo->linkNzPos[iphase]->rightT0 = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  313. sparseInfo->linkNzPos[iphase]->rightT0->idxCol = NULL;
  314. sparseInfo->linkNzPos[iphase]->rightT0->idxRow = NULL;
  315. sparseInfo->linkNzPos[iphase]->rightT0->ptrCol = NULL;
  316. sparseInfo->linkNzPos[iphase]->rightT0->ptrRow = NULL;
  317. sparseInfo->linkNzPos[iphase]->rightState0 = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  318. sparseInfo->linkNzPos[iphase]->rightState0->idxCol = NULL;
  319. sparseInfo->linkNzPos[iphase]->rightState0->idxRow = NULL;
  320. sparseInfo->linkNzPos[iphase]->rightState0->ptrCol = NULL;
  321. sparseInfo->linkNzPos[iphase]->rightState0->ptrRow = NULL;
  322. sparseInfo->linkNzPos[iphase]->rightParameter = (cmscp_nzPos*)malloc(sizeof(cmscp_nzPos));
  323. sparseInfo->linkNzPos[iphase]->rightParameter->idxCol = NULL;
  324. sparseInfo->linkNzPos[iphase]->rightParameter->idxRow = NULL;
  325. sparseInfo->linkNzPos[iphase]->rightParameter->ptrCol = NULL;
  326. sparseInfo->linkNzPos[iphase]->rightParameter->ptrRow = NULL;
  327. }
  328. }
  329. // 输出sparseInfo
  330. *sparseInfo0 = sparseInfo;
  331. }
  332. void sparseInfoObjEvent(cmscp_sparseInfo** sparseInfo0, cmscp_trajInfo** refTraj, cmscp_setup* setup)
  333. {
  334. // 函数功能:获取目标函数和事件函数稀疏信息
  335. // 输入:
  336. // sparseInfo0:无目标函数和事件约束稀疏信息的结构体的地址
  337. // refTraj:参考轨迹
  338. // setup:问题设置参数
  339. // 输出:
  340. // sparseInfo:存储有目标函数和事件约束稀疏信息的结构体
  341. // 假设目标函数和事件约束函数的自变量按照
  342. // [{x0, xf, t0, tf, p}_1, ..., { x0,xf,t0,tf,p }_iphase, ..., { x0,xf,t0,tf,p }_numPhase]排序
  343. // 谢磊:2022 / 4 / 28编写
  344. // 变量声明
  345. cmscp_dimension* dimension;
  346. int numPhase, numObjEventOutput, cntCol, iphase, numState, numParameter, * objEventOutputv,
  347. * ptrRow, * idxCol, * idxRow, * ptrCol;
  348. cmscp_nzPos_endp** nzPosInfo;
  349. intDemat* objEventDependMatrix;
  350. // 分配空间
  351. objEventDependMatrix = (intDemat*)malloc(sizeof(intDemat));
  352. // 1-> 基本参数
  353. dimension = setup->dimension;// 问题维数
  354. numPhase = setup->numPhase;// 阶段数
  355. nzPosInfo = (*sparseInfo0)->objEventNzPos;// 存放稀疏信息的结构体
  356. // 2-> 获取雅可比矩阵相关性矩阵
  357. if (strcmp(setup->sparseModel, "autoSparse") == 0)
  358. {
  359. }
  360. else
  361. {
  362. setup->functions->objEventDepend(objEventDependMatrix);
  363. }
  364. numObjEventOutput = objEventDependMatrix->m;
  365. // 3-> 以列和行压缩格式记录各个分块非零元位置
  366. // 统计非零元个数,用于分配内存
  367. cntCol = 0;// objEventDependMatrix矩阵中列位置计数变量
  368. for (iphase = 0; iphase < numPhase; iphase++)
  369. {
  370. numState = dimension->phase[iphase]->state;
  371. numParameter = dimension->phase[iphase]->parameter;
  372. // 初始状态部分
  373. // 稀疏矩阵
  374. objEventOutputv = objEventDependMatrix->v + numObjEventOutput * cntCol;
  375. // 获取非零元素位置
  376. intDematNzPos(objEventOutputv, numObjEventOutput, numState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  377. // 保存矩阵稀疏信息
  378. nzPosInfo[iphase]->iniState->numRow = numObjEventOutput;
  379. nzPosInfo[iphase]->iniState->numCol = numState;
  380. nzPosInfo[iphase]->iniState->idxRow = idxRow;
  381. nzPosInfo[iphase]->iniState->ptrCol = ptrCol;
  382. nzPosInfo[iphase]->iniState->ptrRow = ptrRow;
  383. nzPosInfo[iphase]->iniState->idxCol = idxCol;
  384. // 更新objEventDependMatrix矩阵列计数变量
  385. cntCol = cntCol + numState;
  386. // 终端状态部分
  387. // 稀疏矩阵
  388. objEventOutputv = objEventDependMatrix->v + numObjEventOutput * cntCol;
  389. // 获取非零元素位置
  390. intDematNzPos(objEventOutputv, numObjEventOutput, numState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  391. // 保存矩阵稀疏信息
  392. nzPosInfo[iphase]->finState->numRow = numObjEventOutput;
  393. nzPosInfo[iphase]->finState->numCol = numState;
  394. nzPosInfo[iphase]->finState->idxRow = idxRow;
  395. nzPosInfo[iphase]->finState->ptrCol = ptrCol;
  396. nzPosInfo[iphase]->finState->ptrRow = ptrRow;
  397. nzPosInfo[iphase]->finState->idxCol = idxCol;
  398. // 更新objEventDependMatrix矩阵列计数变量
  399. cntCol = cntCol + numState;
  400. // 初始时刻部分
  401. // 稠密矩阵
  402. objEventOutputv = objEventDependMatrix->v + numObjEventOutput * cntCol;
  403. // 获取非零元素位置
  404. intDematNzPos(objEventOutputv, numObjEventOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  405. // 保存矩阵稀疏信息
  406. nzPosInfo[iphase]->iniTime->numRow = numObjEventOutput;
  407. nzPosInfo[iphase]->iniTime->numCol = 1;
  408. nzPosInfo[iphase]->iniTime->idxRow = idxRow;
  409. nzPosInfo[iphase]->iniTime->ptrCol = ptrCol;
  410. nzPosInfo[iphase]->iniTime->ptrRow = ptrRow;
  411. nzPosInfo[iphase]->iniTime->idxCol = idxCol;
  412. // 更新objEventDependMatrix矩阵列计数变量
  413. cntCol = cntCol + 1;
  414. // 终端时刻部分
  415. // 稠密矩阵
  416. objEventOutputv = objEventDependMatrix->v + numObjEventOutput * cntCol;
  417. // 获取非零元素位置
  418. intDematNzPos(objEventOutputv, numObjEventOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  419. // 保存矩阵稀疏信息
  420. nzPosInfo[iphase]->finTime->numRow = numObjEventOutput;
  421. nzPosInfo[iphase]->finTime->numCol = 1;
  422. nzPosInfo[iphase]->finTime->idxRow = idxRow;
  423. nzPosInfo[iphase]->finTime->ptrCol = ptrCol;
  424. nzPosInfo[iphase]->finTime->ptrRow = ptrRow;
  425. nzPosInfo[iphase]->finTime->idxCol = idxCol;
  426. // 更新objEventDependMatrix矩阵列计数变量
  427. cntCol = cntCol + 1;
  428. // 静态参数变量部分
  429. // 稠密矩阵
  430. objEventOutputv = objEventDependMatrix->v + numObjEventOutput * cntCol;
  431. // 获取非零元素位置
  432. intDematNzPos(objEventOutputv, numObjEventOutput, numParameter, &ptrRow, &idxCol, &idxRow, &ptrCol);
  433. // 保存矩阵稀疏信息
  434. nzPosInfo[iphase]->parameter->numRow = numObjEventOutput;
  435. nzPosInfo[iphase]->parameter->numCol = numParameter;
  436. nzPosInfo[iphase]->parameter->idxRow = idxRow;
  437. nzPosInfo[iphase]->parameter->ptrCol = ptrCol;
  438. nzPosInfo[iphase]->parameter->ptrRow = ptrRow;
  439. nzPosInfo[iphase]->parameter->idxCol = idxCol;
  440. // 更新objEventDependMatrix矩阵列计数变量
  441. cntCol = cntCol + numParameter;
  442. }
  443. // 释放空间
  444. free(objEventDependMatrix->v);
  445. free(objEventDependMatrix);
  446. }
  447. void sparseInfoCont(cmscp_sparseInfo** sparseInfo0, cmscp_trajInfo** refTraj, cmscp_setup* setup)
  448. {
  449. // 函数功能:获取连续函数列和行压缩格式稀疏信息
  450. // 输入:
  451. // sparseInfo0:无连续函数稀疏信息的结构体
  452. // refTraj:参考轨迹
  453. // setup:问题设置参数
  454. // 输出:
  455. // sparseInfo:存储有连续函数稀疏信息的结构体
  456. // 假设函数的自变量按照 [x,u,p]排序
  457. // 谢磊:2022 / 6 / 25编写
  458. // 变量声明
  459. cmscp_dimension* dimension;
  460. int numPhase, numContOutput, cntCol, iphase, numState, numParameter, * contOutputv,
  461. * ptrRow, * idxCol, * idxRow, * ptrCol, numControl;
  462. cmscp_nzPos_cont** nzPosInfo;
  463. intDemat* contDependMatrix;
  464. // 分配空间
  465. contDependMatrix = (intDemat*)malloc(sizeof(intDemat));
  466. // 1-> 基本参数
  467. dimension = setup->dimension;// 问题维数
  468. numPhase = setup->numPhase;// 阶段数
  469. nzPosInfo = (*sparseInfo0)->contNzPos;// 存放稀疏信息的结构体
  470. // 2-> 以列压缩格式记录各段中各个分块非零元位置
  471. for ( iphase = 0; iphase < numPhase; iphase++)
  472. {
  473. // % 2.1. 维数信息
  474. numState = dimension->phase[iphase]->state;
  475. numControl = dimension->phase[iphase]->control;
  476. numParameter = dimension->phase[iphase]->parameter;
  477. // 2.2.获取雅可比矩阵相关性矩阵
  478. if (strcmp(setup->sparseModel, "autoSparse") == 0)
  479. {
  480. }
  481. else
  482. {
  483. setup->functions->contDepend(contDependMatrix, iphase, setup);
  484. }
  485. numContOutput = contDependMatrix->m;
  486. // 2.3. 以列压缩格式记录各个分块非零元位置
  487. // 2.3.1. 状态部分 (dCont/dx)包括动力学和路径约束
  488. cntCol = 0; // contOutput列计数变量
  489. // 稠密矩阵
  490. contOutputv = contDependMatrix->v + numContOutput * cntCol;
  491. // 获取非零元素位置
  492. intDematNzPos(contOutputv, numContOutput, numState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  493. // 保存矩阵稀疏信息
  494. nzPosInfo[iphase]->state->numRow = numContOutput;
  495. nzPosInfo[iphase]->state->numCol = numState;
  496. nzPosInfo[iphase]->state->idxRow = idxRow;
  497. nzPosInfo[iphase]->state->ptrCol = ptrCol;
  498. nzPosInfo[iphase]->state->ptrRow = ptrRow;
  499. nzPosInfo[iphase]->state->idxCol = idxCol;
  500. // 2.3.2.控制部分 (dCont / du)包括动力学和路径约束
  501. cntCol = cntCol + numState; // contOutput列计数变量
  502. // 稠密矩阵
  503. contOutputv = contDependMatrix->v + numContOutput * cntCol;
  504. // 获取非零元素位置
  505. intDematNzPos(contOutputv, numContOutput, numControl, &ptrRow, &idxCol, &idxRow, &ptrCol);
  506. // 保存矩阵稀疏信息
  507. nzPosInfo[iphase]->control->numRow = numContOutput;
  508. nzPosInfo[iphase]->control->numCol = numControl;
  509. nzPosInfo[iphase]->control->idxRow = idxRow;
  510. nzPosInfo[iphase]->control->ptrCol = ptrCol;
  511. nzPosInfo[iphase]->control->ptrRow = ptrRow;
  512. nzPosInfo[iphase]->control->idxCol = idxCol;
  513. // 2.3.2.控制部分 (dCont / du)包括动力学和路径约束
  514. cntCol = cntCol + numControl; // contOutput列计数变量
  515. // 稠密矩阵
  516. contOutputv = contDependMatrix->v + numContOutput * cntCol;
  517. // 获取非零元素位置
  518. intDematNzPos(contOutputv, numContOutput, numParameter, &ptrRow, &idxCol, &idxRow, &ptrCol);
  519. // 保存矩阵稀疏信息
  520. nzPosInfo[iphase]->parameter->numRow = numContOutput;
  521. nzPosInfo[iphase]->parameter->numCol = numParameter;
  522. nzPosInfo[iphase]->parameter->idxRow = idxRow;
  523. nzPosInfo[iphase]->parameter->ptrCol = ptrCol;
  524. nzPosInfo[iphase]->parameter->ptrRow = ptrRow;
  525. nzPosInfo[iphase]->parameter->idxCol = idxCol;
  526. // 释放contDependMatrix底层空间
  527. free(contDependMatrix->v);
  528. }
  529. // 释放contDependMatrix空间
  530. free(contDependMatrix);
  531. }
  532. void sparseInfoEndp(cmscp_sparseInfo** sparseInfo0, cmscp_trajInfo** refTraj, cmscp_setup* setup)
  533. {
  534. // 函数功能:获取端点函数列和行压缩格式稀疏信息
  535. // 输入:
  536. // sparseInfo0:无端点函数稀疏信息的结构体指针的地址
  537. // refTraj:参考轨迹
  538. // setup:问题设置参数
  539. // 输出:
  540. // sparseInfo:端点函数有连续函数稀疏信息的结构体
  541. // 假设函数的自变量按照[x0,xf, t0, tf, 排序
  542. // 谢磊:2022 / 6 / 25编写
  543. // 变量声明
  544. cmscp_dimension* dimension;
  545. int numPhase, numEndpOutput, cntCol, iphase, numState, numParameter, * endpOutputv,
  546. * ptrRow, * idxCol, * idxRow, * ptrCol;
  547. cmscp_nzPos_endp** nzPosInfo;
  548. intDemat* endpDependMatrix;
  549. // 分配空间
  550. endpDependMatrix = (intDemat*)malloc(sizeof(intDemat));
  551. // 1-> 基本参数
  552. dimension = setup->dimension;// 问题维数
  553. numPhase = setup->numPhase;// 阶段数
  554. nzPosInfo = (*sparseInfo0)->endpNzPos;// 存放稀疏信息的结构体
  555. // 2-> 以列压缩格式记录各段中各个分块非零元位置
  556. for (iphase = 0; iphase < numPhase; iphase++)
  557. {
  558. // % 2.1. 维数信息
  559. numState = dimension->phase[iphase]->state;
  560. numParameter = dimension->phase[iphase]->parameter;
  561. // 2.2.获取雅可比矩阵相关性矩阵
  562. if (strcmp(setup->sparseModel, "autoSparse") == 0)
  563. {
  564. }
  565. else
  566. {
  567. setup->functions->endpDepend(endpDependMatrix, iphase, setup);
  568. }
  569. numEndpOutput = endpDependMatrix->m;
  570. // 2.3. 以列压缩格式记录各个分块非零元位置
  571. // 2.3.1. 初始状态部分 (dEndp/dx0)
  572. cntCol = 0; // endpOutput列计数变量
  573. // 稠密矩阵
  574. endpOutputv = endpDependMatrix->v + numEndpOutput * cntCol;
  575. // 获取非零元素位置
  576. intDematNzPos(endpOutputv, numEndpOutput, numState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  577. // 保存矩阵稀疏信息
  578. nzPosInfo[iphase]->iniState->numRow = numEndpOutput;
  579. nzPosInfo[iphase]->iniState->numCol = numState;
  580. nzPosInfo[iphase]->iniState->idxRow = idxRow;
  581. nzPosInfo[iphase]->iniState->ptrCol = ptrCol;
  582. nzPosInfo[iphase]->iniState->ptrRow = ptrRow;
  583. nzPosInfo[iphase]->iniState->idxCol = idxCol;
  584. // 2.3.2.终端状态部分 (dEndp/dxf)
  585. cntCol = cntCol + numState; // endpOutput列计数变量
  586. // 稠密矩阵
  587. endpOutputv = endpDependMatrix->v + numEndpOutput * cntCol;
  588. // 获取非零元素位置
  589. intDematNzPos(endpOutputv, numEndpOutput, numState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  590. // 保存矩阵稀疏信息
  591. nzPosInfo[iphase]->finState->numRow = numEndpOutput;
  592. nzPosInfo[iphase]->finState->numCol = numState;
  593. nzPosInfo[iphase]->finState->idxRow = idxRow;
  594. nzPosInfo[iphase]->finState->ptrCol = ptrCol;
  595. nzPosInfo[iphase]->finState->ptrRow = ptrRow;
  596. nzPosInfo[iphase]->finState->idxCol = idxCol;
  597. // 2.3.3.初始时刻部分 (dEndp/dt0)
  598. cntCol = cntCol + numState; // endpOutput列计数变量
  599. // 稠密矩阵
  600. endpOutputv = endpDependMatrix->v + numEndpOutput * cntCol;
  601. // 获取非零元素位置
  602. intDematNzPos(endpOutputv, numEndpOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  603. // 保存矩阵稀疏信息
  604. nzPosInfo[iphase]->iniTime->numRow = numEndpOutput;
  605. nzPosInfo[iphase]->iniTime->numCol = 1;
  606. nzPosInfo[iphase]->iniTime->idxRow = idxRow;
  607. nzPosInfo[iphase]->iniTime->ptrCol = ptrCol;
  608. nzPosInfo[iphase]->iniTime->ptrRow = ptrRow;
  609. nzPosInfo[iphase]->iniTime->idxCol = idxCol;
  610. // 2.3.4.终端时刻部分 (dEndp/dtf)
  611. cntCol = cntCol + 1; // endpOutput列计数变量
  612. // 稠密矩阵
  613. endpOutputv = endpDependMatrix->v + numEndpOutput * cntCol;
  614. // 获取非零元素位置
  615. intDematNzPos(endpOutputv, numEndpOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  616. // 保存矩阵稀疏信息
  617. nzPosInfo[iphase]->finTime->numRow = numEndpOutput;
  618. nzPosInfo[iphase]->finTime->numCol = 1;
  619. nzPosInfo[iphase]->finTime->idxRow = idxRow;
  620. nzPosInfo[iphase]->finTime->ptrCol = ptrCol;
  621. nzPosInfo[iphase]->finTime->ptrRow = ptrRow;
  622. nzPosInfo[iphase]->finTime->idxCol = idxCol;
  623. // 2.3.5.静态参数部分 (dEndp/dp)
  624. cntCol = cntCol + 1; // endpOutput列计数变量
  625. // 稠密矩阵
  626. endpOutputv = endpDependMatrix->v + numEndpOutput * cntCol;
  627. // 获取非零元素位置
  628. intDematNzPos(endpOutputv, numEndpOutput, numParameter, &ptrRow, &idxCol, &idxRow, &ptrCol);
  629. // 保存矩阵稀疏信息
  630. nzPosInfo[iphase]->parameter->numRow = numEndpOutput;
  631. nzPosInfo[iphase]->parameter->numCol = numParameter;
  632. nzPosInfo[iphase]->parameter->idxRow = idxRow;
  633. nzPosInfo[iphase]->parameter->ptrCol = ptrCol;
  634. nzPosInfo[iphase]->parameter->ptrRow = ptrRow;
  635. nzPosInfo[iphase]->parameter->idxCol = idxCol;
  636. // 释放endpDependMatrix底层空间
  637. free(endpDependMatrix->v);
  638. }
  639. // 释放endpDependMatrix空间
  640. free(endpDependMatrix);
  641. }
  642. void sparseInfoLink(cmscp_sparseInfo** sparseInfo0, cmscp_trajInfo** refTraj, cmscp_setup* setup)
  643. {
  644. // 函数功能:获取衔接函数列和行压缩格式稀疏信息
  645. // 输入:
  646. // sparseInfo0:无衔接函数稀疏信息的结构体指针的地址
  647. // refTraj:参考轨迹
  648. // setup:问题设置参数
  649. // 输出:
  650. // sparseInfo:衔接函数有连续函数稀疏信息的结构体
  651. // 假设函数的自变量按照[x0,xf, t0, tf, 排序
  652. // 谢磊:2022 / 6 / 25编写
  653. // 变量声明
  654. cmscp_dimension* dimension;
  655. int numPhase, numLinkOutput, cntCol, iphase, * linkOutputv,
  656. * ptrRow, * idxCol, * idxRow, * ptrCol, numLeftState, numRightState, numLeftParameter, numRightParameter;
  657. cmscp_nzPos_link** nzPosInfo;
  658. intDemat* linkDependMatrix;
  659. // 分配空间
  660. linkDependMatrix = (intDemat*)malloc(sizeof(intDemat));
  661. // 1-> 基本参数
  662. dimension = setup->dimension;// 问题维数
  663. numPhase = setup->numPhase;// 阶段数
  664. nzPosInfo = (*sparseInfo0)->linkNzPos;// 存放稀疏信息的结构体
  665. // 2-> 以列压缩格式记录各段中各个分块非零元位置
  666. for (iphase = 0; iphase < numPhase-1; iphase++)
  667. {
  668. // % 2.1. 维数信息
  669. numLeftState = dimension->phase[iphase]->state;
  670. numRightState = dimension->phase[iphase+1]->state;
  671. numLeftParameter = dimension->phase[iphase]->parameter;
  672. numRightParameter = dimension->phase[iphase+1]->parameter;
  673. void* linkDepend1;
  674. // 2.2.获取雅可比矩阵相关性矩阵
  675. if (strcmp(setup->sparseModel, "autoSparse") == 0)
  676. {
  677. }
  678. else
  679. {
  680. linkDepend1 = sparseInfoEndp;
  681. //linkDepend1(linkDependMatrix, iphase, setup);
  682. setup->functions->linkDepend(linkDependMatrix, iphase, setup);
  683. }
  684. numLinkOutput = linkDependMatrix->m;
  685. // 2.3. 以列压缩格式记录各个分块非零元位置
  686. // 2.3.1. 左侧状态部分 (dLink/dLeftStatef)
  687. cntCol = 0; // linkOutput列计数变量
  688. // 稠密矩阵
  689. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  690. // 获取非零元素位置
  691. intDematNzPos(linkOutputv, numLinkOutput, numLeftState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  692. // 保存矩阵稀疏信息
  693. nzPosInfo[iphase]->leftStatef->numRow = numLinkOutput;
  694. nzPosInfo[iphase]->leftStatef->numCol = numLeftState;
  695. nzPosInfo[iphase]->leftStatef->idxRow = idxRow;
  696. nzPosInfo[iphase]->leftStatef->ptrCol = ptrCol;
  697. nzPosInfo[iphase]->leftStatef->ptrRow = ptrRow;
  698. nzPosInfo[iphase]->leftStatef->idxCol = idxCol;
  699. // 2.3.2. 左侧时间部分 (dLink/dLeftTf)
  700. cntCol = cntCol + numLeftState; // linkOutput列计数变量
  701. // 稠密矩阵
  702. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  703. // 获取非零元素位置
  704. intDematNzPos(linkOutputv, numLinkOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  705. // 保存矩阵稀疏信息
  706. nzPosInfo[iphase]->leftTf->numRow = numLinkOutput;
  707. nzPosInfo[iphase]->leftTf->numCol = 1;
  708. nzPosInfo[iphase]->leftTf->idxRow = idxRow;
  709. nzPosInfo[iphase]->leftTf->ptrCol = ptrCol;
  710. nzPosInfo[iphase]->leftTf->ptrRow = ptrRow;
  711. nzPosInfo[iphase]->leftTf->idxCol = idxCol;
  712. // 2.3.3. 左侧静态参数部分 (dLink/dLeftParameter)
  713. cntCol = cntCol + 1; // linkOutput列计数变量
  714. // 稠密矩阵
  715. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  716. // 获取非零元素位置
  717. intDematNzPos(linkOutputv, numLinkOutput, numLeftParameter, &ptrRow, &idxCol, &idxRow, &ptrCol);
  718. // 保存矩阵稀疏信息
  719. nzPosInfo[iphase]->leftParameter->numRow = numLinkOutput;
  720. nzPosInfo[iphase]->leftParameter->numCol = numLeftParameter;
  721. nzPosInfo[iphase]->leftParameter->idxRow = idxRow;
  722. nzPosInfo[iphase]->leftParameter->ptrCol = ptrCol;
  723. nzPosInfo[iphase]->leftParameter->ptrRow = ptrRow;
  724. nzPosInfo[iphase]->leftParameter->idxCol = idxCol;
  725. // 2.3.4. 右侧状态部分 (dLink/drightState0)
  726. cntCol = cntCol + numLeftParameter; // linkOutput列计数变量
  727. // 稠密矩阵
  728. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  729. // 获取非零元素位置
  730. intDematNzPos(linkOutputv, numLinkOutput, numRightState, &ptrRow, &idxCol, &idxRow, &ptrCol);
  731. // 保存矩阵稀疏信息
  732. nzPosInfo[iphase]->rightState0->numRow = numLinkOutput;
  733. nzPosInfo[iphase]->rightState0->numCol = numRightState;
  734. nzPosInfo[iphase]->rightState0->idxRow = idxRow;
  735. nzPosInfo[iphase]->rightState0->ptrCol = ptrCol;
  736. nzPosInfo[iphase]->rightState0->ptrRow = ptrRow;
  737. nzPosInfo[iphase]->rightState0->idxCol = idxCol;
  738. // 2.3.5. 右侧时间部分 (dLink/drightT0)
  739. cntCol = cntCol + numRightState; // linkOutput列计数变量
  740. // 稠密矩阵
  741. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  742. // 获取非零元素位置
  743. intDematNzPos(linkOutputv, numLinkOutput, 1, &ptrRow, &idxCol, &idxRow, &ptrCol);
  744. // 保存矩阵稀疏信息
  745. nzPosInfo[iphase]->rightT0->numRow = numLinkOutput;
  746. nzPosInfo[iphase]->rightT0->numCol = 1;
  747. nzPosInfo[iphase]->rightT0->idxRow = idxRow;
  748. nzPosInfo[iphase]->rightT0->ptrCol = ptrCol;
  749. nzPosInfo[iphase]->rightT0->ptrRow = ptrRow;
  750. nzPosInfo[iphase]->rightT0->idxCol = idxCol;
  751. // 2.3.5. 右侧静态参数部分 (dLink/dRightParameter)
  752. cntCol = cntCol + 1; // linkOutput列计数变量
  753. // 稠密矩阵
  754. linkOutputv = linkDependMatrix->v + numLinkOutput * cntCol;
  755. // 获取非零元素位置
  756. intDematNzPos(linkOutputv, numLinkOutput, numRightParameter, &ptrRow, &idxCol, &idxRow, &ptrCol);
  757. // 保存矩阵稀疏信息
  758. nzPosInfo[iphase]->rightParameter->numRow = numLinkOutput;
  759. nzPosInfo[iphase]->rightParameter->numCol = numRightParameter;
  760. nzPosInfo[iphase]->rightParameter->idxRow = idxRow;
  761. nzPosInfo[iphase]->rightParameter->ptrCol = ptrCol;
  762. nzPosInfo[iphase]->rightParameter->ptrRow = ptrRow;
  763. nzPosInfo[iphase]->rightParameter->idxCol = idxCol;
  764. // 释放linkDependMatrix底层空间
  765. free(linkDependMatrix->v);
  766. }
  767. // 释放linkDependMatrix空间
  768. free(linkDependMatrix);
  769. }
  770. void getSparseInfo(cmscp_sparseInfo** sparseInfo0, cmscp_trajInfo** refTraj, cmscp_setup* setup) {
  771. // 函数功能:获取目标函数和事件函数稀疏信息
  772. // 输入:
  773. // sparseInfo:无目标函数和事件约束稀疏信息的结构体
  774. // refTraj:参考轨迹
  775. // setup:问题设置参数
  776. // 输出:
  777. // sparseInfo:存储有目标函数和事件约束稀疏信息的结构体
  778. // 假设目标函数和事件约束函数的自变量按照
  779. // [{x0, xf, t0, tf, p}_1, ..., { x0,xf,t0,tf,p }_iphase, ..., { x0,xf,t0,tf,p }_numPhase]排序
  780. // 谢磊:2022 / 4 / 28编写
  781. // 变量声明
  782. int numPhase;
  783. numPhase = setup->numPhase;
  784. /* 分配稀疏信息结构体变量 */
  785. mallocSparseInfo(sparseInfo0, numPhase);
  786. /* 目标函数和事件约束函数的稀疏信息 */
  787. sparseInfoObjEvent(sparseInfo0, refTraj, setup);
  788. /* 动力学和路径约束函数的稀疏信息 */
  789. sparseInfoCont(sparseInfo0, refTraj, setup);
  790. /* 端点函数的稀疏信息 */
  791. sparseInfoEndp(sparseInfo0, refTraj, setup);
  792. /* 衔接函数的稀疏信息 */
  793. sparseInfoLink(sparseInfo0, refTraj, setup);
  794. }