gradInfoFunctions.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. #include "gradInfoFunctions.h"
  2. void copyObjEventInput(cmscp_objEventInput*x, cmscp_objEventInput* y, cmscp_setup* setup)
  3. {
  4. // 函数功能:复制copyObjEventInput形变量
  5. // 输入:
  6. // x:原本
  7. // setup:问题设置参数
  8. // 输出:
  9. // y:复本
  10. // 谢磊:2022 / 6 / 28编写
  11. int iphase, numPhase, numState, numParameter;
  12. cmscp_dimension* dimension;
  13. numPhase = setup->numPhase; // 阶段数
  14. dimension = setup->dimension;
  15. for ( iphase = 0; iphase < numPhase; iphase++)
  16. {
  17. numState = dimension->phase[iphase]->state;
  18. numParameter = dimension->phase[iphase]->parameter;
  19. y->phase[iphase]->initialtime = x->phase[iphase]->initialtime;
  20. y->phase[iphase]->finaltime = x->phase[iphase]->finaltime;
  21. copyFloatVec(x->phase[iphase]->initialstate, y->phase[iphase]->initialstate, numState, 0);
  22. copyFloatVec(x->phase[iphase]->finalstate, y->phase[iphase]->finalstate, numState, 0);
  23. copyFloatVec(x->phase[iphase]->parameter, y->phase[iphase]->parameter, numParameter, 0);
  24. }
  25. }
  26. void copyEndpInput(cmscp_endpInput* x, cmscp_endpInput* y, int iphase, cmscp_setup* setup)
  27. {
  28. // 函数功能:复制cmscp_endpInput形变量
  29. // 输入:
  30. // x:原本
  31. // setup:问题设置参数
  32. // 输出:
  33. // y:复本
  34. // 谢磊:2022 / 6 / 28编写
  35. int numPhase;
  36. cmscp_dimension* dimension;
  37. numPhase = setup->numPhase; // 阶段数
  38. dimension = setup->dimension;
  39. copyFloatVec(x->initialstate, y->initialstate, dimension->phase[iphase]->state, 0);
  40. copyFloatVec(x->finalstate, y->finalstate, dimension->phase[iphase]->state, 0);
  41. copyFloatVec(x->parameter, y->parameter, dimension->phase[iphase]->parameter, 0);
  42. y->initialtime = x->initialtime;
  43. y->finaltime = x->finaltime;
  44. }
  45. void copyContInput(cmscp_contInput* x, cmscp_contInput* y, int numState, int numControl, int numParameter, cmscp_setup* setup)
  46. {
  47. // 函数功能:复制cmscp_endpInput形变量
  48. // 输入:
  49. // x:原本
  50. // setup:问题设置参数
  51. // 输出:
  52. // y:复本
  53. // 谢磊:2022 / 6 / 28编写
  54. cmscp_dimension* dimension;
  55. dimension = setup->dimension;
  56. copyFloatVec(x->state, y->state, numState, 0);
  57. copyFloatVec(x->control, y->control, numControl, 0);
  58. copyFloatVec(x->parameter, y->parameter, numParameter, 0);
  59. }
  60. void copyLinkInput(cmscp_linkInput* x, cmscp_linkInput* y, int iphase, cmscp_setup* setup)
  61. {
  62. // 函数功能:复制cmscp_endpInput形变量
  63. // 输入:
  64. // x:原本
  65. // setup:问题设置参数
  66. // 输出:
  67. // y:复本
  68. // 谢磊:2022 / 6 / 28编写
  69. cmscp_dimension* dimension;
  70. dimension = setup->dimension;
  71. y->leftFinTime = x->leftFinTime;
  72. y->rightIniTime = x->rightIniTime;
  73. copyFloatVec(x->leftFinState, y->leftFinState, dimension->phase[iphase]->state, 0);
  74. copyFloatVec(x->leftParameter, y->leftParameter, dimension->phase[iphase]->parameter, 0);
  75. copyFloatVec(x->rightIniState, y->rightIniState, dimension->phase[iphase+1]->state, 0);
  76. copyFloatVec(x->rightParameter, y->rightParameter, dimension->phase[iphase+1]->parameter, 0);
  77. }
  78. void gradInfoSparseObjEvent(cmscp_derInfo** objDerInfo0, cmscp_derInfo** eventDerInfo0, cmscp_sparseInfo* sparseInfo, cmscp_trajInfo** refTraj, cmscp_setup* setup)
  79. {
  80. // 函数功能:获取二阶锥规划问题的参数的维数以及分配相应的空间
  81. // 输入:
  82. // refTraj:参考轨迹
  83. // sparseInfo:稀疏(非零元位置)信息
  84. // setup:问题设置参数
  85. // 输出:
  86. // objDerInfo:目标函数的一阶导数信息
  87. // eventDerInfo:事件函数的一阶导数信息
  88. // Tri表示软信赖域边界
  89. // 谢磊:2022 / 6 / 27编写
  90. // 变量声明
  91. int numPhase, numObjEventInput, numEventOutput, iphase, numState, numControl, numParameter, numMesh, cntObjEventInput, *iniStateNzIdxRow, * finStateNzIdxRow, * iniTimeNzIdxRow, * finTimeNzIdxRow, * parameterNzIdxRow, *iniStateNzPtrCol, * finStateNzPtrCol, * iniTimeNzPtrCol, * finTimeNzPtrCol, * parameterNzPtrCol, j, p, i, idxRowEventGrd;
  92. double derStep, derStepInv, refObjOutput, pertObjOutput, *refEventOutput, *pertEventOutput, *objGrd, * eventGrd;
  93. cmscp_dimension* dimension;
  94. cmscp_mesh** mesh;
  95. cmscp_nzPos_endp** objEventNzPos;
  96. cmscp_objEventInput* objEventInput, *pertObjEventInput;
  97. cmscp_objEvent objEventFunc;
  98. // 1. 基本参数
  99. dimension = setup->dimension; // 问题维数信息
  100. mesh = setup->mesh; // 网格信息
  101. numPhase = setup->numPhase; // 阶段数
  102. derStep = setup->derStep; // 求导步长
  103. derStepInv = 1 / derStep;
  104. objEventFunc = setup->functions->objEvent;
  105. numObjEventInput = 0; // 端点函数的输入变量个数
  106. objEventNzPos = sparseInfo->objEventNzPos; // 稀疏信息
  107. // 事件函数的输出维数
  108. if (dimension->event->soc->n)
  109. {
  110. numEventOutput = dimension->event->nl + cmscp_sum(dimension->event->soc->q, dimension->event->soc->n);
  111. }
  112. else
  113. {
  114. numEventOutput = dimension->event->nl;
  115. }
  116. // 函数的输入
  117. objEventInput = (cmscp_objEventInput*)malloc(sizeof(cmscp_objEventInput));
  118. objEventInput->phase = (cmscp_objEventInputPhase**)malloc(setup->numPhase * sizeof(cmscp_objEventInputPhase*));
  119. objEventInput->auxdata = setup->auxdata;
  120. for ( iphase = 0; iphase < numPhase; iphase++)
  121. {
  122. numMesh = mesh[iphase]->num;
  123. numState = dimension->phase[iphase]->state;
  124. numControl = dimension->phase[iphase]->control;
  125. numParameter = dimension->phase[iphase]->parameter;
  126. objEventInput->phase[iphase] = (cmscp_objEventInputPhase*)malloc(sizeof(cmscp_objEventInputPhase));
  127. objEventInput->phase[iphase]->initialtime = refTraj[iphase]->initialtime;
  128. objEventInput->phase[iphase]->finaltime = refTraj[iphase]->finaltime;
  129. objEventInput->phase[iphase]->initialstate = refTraj[iphase]->state->v;
  130. objEventInput->phase[iphase]->finalstate = refTraj[iphase]->state->v + (numMesh - 1) * numState;
  131. objEventInput->phase[iphase]->parameter = refTraj[iphase]->parameter;
  132. numObjEventInput = numObjEventInput + 2 * dimension->phase[iphase]->state + 2 + dimension->phase[iphase]->parameter;
  133. }
  134. cntObjEventInput = 0; // 端点函数输入变量计数
  135. refEventOutput = (double*)malloc(numEventOutput * sizeof(double));
  136. objEventFunc(&refObjOutput, refEventOutput, objEventInput); // 参考输出值
  137. objGrd = (double*)malloc(numObjEventInput * sizeof(double)); // 目标函数梯度空间分配
  138. eventGrd = (double*)malloc(numEventOutput * numObjEventInput * sizeof(double));
  139. //if (numEventOutput)
  140. //{
  141. // eventGrd = (double*)malloc(numEventOutput * numObjEventInput * sizeof(double));
  142. //}
  143. // 扰动空间分配
  144. pertEventOutput = (double*)malloc(numEventOutput * sizeof(double));
  145. pertObjEventInput = (cmscp_objEventInput*)malloc(sizeof(cmscp_objEventInput));
  146. pertObjEventInput->phase = (cmscp_objEventInputPhase**)malloc(setup->numPhase * sizeof(cmscp_objEventInputPhase*));
  147. for ( iphase = 0; iphase < numPhase; iphase++)
  148. {
  149. pertObjEventInput->phase[iphase] = (cmscp_objEventInputPhase*)malloc(sizeof(cmscp_objEventInputPhase));
  150. pertObjEventInput->phase[iphase]->initialstate = (double*)malloc(numState * sizeof(double));
  151. pertObjEventInput->phase[iphase]->finalstate = (double*)malloc(numState * sizeof(double));
  152. pertObjEventInput->phase[iphase]->parameter = (double*)malloc(numParameter * sizeof(double));
  153. }
  154. for (iphase = 0; iphase < numPhase; iphase++)
  155. {
  156. // 离散点个数和各种变量的维数
  157. numState = dimension->phase[iphase]->state;
  158. numParameter = dimension->phase[iphase]->parameter;
  159. // 稀疏信息
  160. iniStateNzIdxRow = objEventNzPos[iphase]->iniState->idxRow;
  161. finStateNzIdxRow = objEventNzPos[iphase]->finState->idxRow;
  162. iniTimeNzIdxRow = objEventNzPos[iphase]->iniTime->idxRow;
  163. finTimeNzIdxRow = objEventNzPos[iphase]->finTime->idxRow;
  164. parameterNzIdxRow = objEventNzPos[iphase]->parameter->idxRow;
  165. iniStateNzPtrCol = objEventNzPos[iphase]->iniState->ptrCol;
  166. finStateNzPtrCol = objEventNzPos[iphase]->finState->ptrCol;
  167. iniTimeNzPtrCol = objEventNzPos[iphase]->iniTime->ptrCol;
  168. finTimeNzPtrCol = objEventNzPos[iphase]->finTime->ptrCol;
  169. parameterNzPtrCol = objEventNzPos[iphase]->parameter->ptrCol;
  170. pertObjEventInput->auxdata = setup->auxdata;
  171. numMesh = mesh[iphase]->num;
  172. numState = dimension->phase[iphase]->state;
  173. numControl = dimension->phase[iphase]->control;
  174. numParameter = dimension->phase[iphase]->parameter;
  175. // 初始状态
  176. for (j = 0; j < numState; j++)
  177. {
  178. // 复制扰动输入
  179. copyObjEventInput(objEventInput, pertObjEventInput, setup);
  180. pertObjEventInput->phase[iphase]->initialstate[j] = pertObjEventInput->phase[iphase]->initialstate[j] + derStep;
  181. // 施加扰动
  182. objEventFunc(&pertObjOutput, pertEventOutput, pertObjEventInput);// 扰动输出
  183. for (p = iniStateNzPtrCol[j]; p < iniStateNzPtrCol[j + 1]; p++)
  184. {
  185. i = iniStateNzIdxRow[p]; //行
  186. if (i == 0)
  187. {
  188. objGrd[cntObjEventInput] = (pertObjOutput - refObjOutput) * derStepInv;
  189. }
  190. else
  191. {
  192. idxRowEventGrd = (i - 1);
  193. eventGrd[idxRowEventGrd + numEventOutput * cntObjEventInput] = (pertEventOutput[idxRowEventGrd] - refEventOutput[idxRowEventGrd]) * derStepInv;
  194. }
  195. }
  196. cntObjEventInput++;
  197. }
  198. // 终端状态
  199. for (j = 0; j < numState; j++)
  200. {
  201. // 复制扰动输入
  202. copyObjEventInput(objEventInput, pertObjEventInput, setup);
  203. pertObjEventInput->phase[iphase]->finalstate[j] = pertObjEventInput->phase[iphase]->finalstate[j] + derStep;
  204. // 施加扰动
  205. objEventFunc(&pertObjOutput, pertEventOutput, pertObjEventInput);// 扰动输出
  206. for (p = finStateNzPtrCol[j]; p < finStateNzPtrCol[j + 1]; p++)
  207. {
  208. i = finStateNzIdxRow[p]; //行
  209. if (i == 0)
  210. {
  211. objGrd[cntObjEventInput] = (pertObjOutput - refObjOutput) * derStepInv;
  212. }
  213. else
  214. {
  215. idxRowEventGrd = (i - 1);
  216. eventGrd[idxRowEventGrd + numEventOutput * cntObjEventInput] = (pertEventOutput[idxRowEventGrd] - refEventOutput[idxRowEventGrd]) * derStepInv;
  217. }
  218. }
  219. cntObjEventInput++;
  220. }
  221. // 初始时刻
  222. // 复制扰动输入
  223. copyObjEventInput(objEventInput, pertObjEventInput, setup);
  224. pertObjEventInput->phase[iphase]->initialtime = pertObjEventInput->phase[iphase]->initialtime + derStep;
  225. // 施加扰动
  226. objEventFunc(&pertObjOutput, pertEventOutput, pertObjEventInput);// 扰动输出
  227. for (p = iniTimeNzPtrCol[0]; p < iniTimeNzPtrCol[1]; p++)
  228. {
  229. i = iniTimeNzIdxRow[p]; //行
  230. if (i == 0)
  231. {
  232. objGrd[cntObjEventInput] = (pertObjOutput - refObjOutput) * derStepInv;
  233. }
  234. else
  235. {
  236. idxRowEventGrd = (i - 1);
  237. eventGrd[idxRowEventGrd + numEventOutput * cntObjEventInput] = (pertEventOutput[idxRowEventGrd] - refEventOutput[idxRowEventGrd]) * derStepInv;
  238. }
  239. }
  240. cntObjEventInput++;
  241. // 终端时刻
  242. // 复制扰动输入
  243. copyObjEventInput(objEventInput, pertObjEventInput, setup);
  244. pertObjEventInput->phase[iphase]->finaltime = pertObjEventInput->phase[iphase]->finaltime + derStep;
  245. // 施加扰动
  246. objEventFunc(&pertObjOutput, pertEventOutput, pertObjEventInput);// 扰动输出
  247. for (p = finTimeNzPtrCol[0]; p < finTimeNzPtrCol[1]; p++)
  248. {
  249. i = finTimeNzIdxRow[p]; //行
  250. if (i == 0)
  251. {
  252. objGrd[cntObjEventInput] = (pertObjOutput - refObjOutput) * derStepInv;
  253. }
  254. else
  255. {
  256. idxRowEventGrd = (i - 1);
  257. eventGrd[idxRowEventGrd + numEventOutput * cntObjEventInput] = (pertEventOutput[idxRowEventGrd] - refEventOutput[idxRowEventGrd]) * derStepInv;
  258. }
  259. }
  260. cntObjEventInput++;
  261. // 终端状态
  262. for (j = 0; j < numParameter; j++)
  263. {
  264. // 复制扰动输入
  265. copyObjEventInput(objEventInput, pertObjEventInput, setup);
  266. pertObjEventInput->phase[iphase]->parameter[j] = pertObjEventInput->phase[iphase]->parameter[j] + derStep;
  267. // 施加扰动
  268. objEventFunc(&pertObjOutput, pertEventOutput, pertObjEventInput);// 扰动输出
  269. for (p = parameterNzPtrCol[j]; p < parameterNzPtrCol[j + 1]; p++)
  270. {
  271. i = parameterNzIdxRow[p]; //行
  272. if (i == 0)
  273. {
  274. objGrd[cntObjEventInput] = (pertObjOutput - refObjOutput) * derStepInv;
  275. }
  276. else
  277. {
  278. idxRowEventGrd = (i - 1);
  279. eventGrd[idxRowEventGrd + numEventOutput * cntObjEventInput] = (pertEventOutput[idxRowEventGrd] - refEventOutput[idxRowEventGrd]) * derStepInv;
  280. }
  281. }
  282. cntObjEventInput++;
  283. }
  284. }
  285. // 输出
  286. // 内存分配
  287. (*objDerInfo0) = (cmscp_derInfo*)malloc(sizeof(cmscp_derInfo));
  288. (*objDerInfo0)->ref = (double*)malloc(sizeof(double));
  289. (*objDerInfo0)->ref[0] = refObjOutput;
  290. (*objDerInfo0)->der = objGrd;
  291. (*eventDerInfo0) = (cmscp_derInfo*)malloc(sizeof(cmscp_derInfo));
  292. (*eventDerInfo0)->ref = refEventOutput;
  293. (*eventDerInfo0)->der = eventGrd;
  294. // free
  295. free(pertEventOutput);
  296. for (iphase = 0; iphase < numPhase; iphase++)
  297. {
  298. free(pertObjEventInput->phase[iphase]->initialstate);
  299. free(pertObjEventInput->phase[iphase]->finalstate);
  300. free(pertObjEventInput->phase[iphase]->parameter);
  301. free(pertObjEventInput->phase[iphase]);
  302. free(objEventInput->phase[iphase]);
  303. }
  304. free(pertObjEventInput->phase);
  305. free(pertObjEventInput);
  306. free(objEventInput->phase);
  307. free(objEventInput);
  308. }
  309. void gradInfoSparseEndp(cmscp_derInfo** gradInfo, cmscp_sparseInfo* sparseInfo, cmscp_trajInfo** refTraj, cmscp_setup* setup) {
  310. // 变量声明
  311. int numPhase, iphase, numState, numParameter, * iniStateNzIdxRow, * finStateNzIdxRow, * iniTimeNzIdxRow, * finTimeNzIdxRow, * parameterNzIdxRow, * iniStateNzPtrCol, * finStateNzPtrCol, * iniTimeNzPtrCol, * finTimeNzPtrCol, * parameterNzPtrCol, j, p, i, numEndpInput, numEndpOutput, cntCol;
  312. double derStep, derStepInv, *refOutput, *pertOutput, * endpGrd;
  313. cmscp_dimension* dimension;
  314. cmscp_mesh** mesh;
  315. cmscp_nzPos_endp** endpNzPos;
  316. cmscp_endpInput* endpInput, * pertEndpInput;
  317. cmscp_endpoint endpFunc;
  318. // 1. 基本参数
  319. dimension = setup->dimension; // 问题维数信息
  320. mesh = setup->mesh; // 网格信息
  321. numPhase = setup->numPhase; // 阶段数
  322. derStep = setup->derStep; // 求导步长
  323. derStepInv = 1 / derStep;
  324. endpNzPos = sparseInfo->endpNzPos;
  325. // 参考输入
  326. endpInput = (cmscp_endpInput*)malloc(sizeof(cmscp_endpInput));
  327. for ( iphase = 0; iphase < numPhase; iphase++)
  328. {
  329. numState = dimension->phase[iphase]->state;
  330. numParameter = dimension->phase[iphase]->parameter;
  331. numEndpInput = 2 * numState + numParameter + 2;
  332. if (dimension->phase[iphase]->endpoint->soc->n)
  333. {
  334. numEndpOutput = dimension->phase[iphase]->endpoint->nl + cmscp_sum(dimension->phase[iphase]->endpoint->soc->q, dimension->phase[iphase]->endpoint->soc->n);
  335. }
  336. else
  337. {
  338. numEndpOutput = dimension->phase[iphase]->endpoint->nl;
  339. }
  340. // 各段稀疏信息
  341. iniStateNzIdxRow = endpNzPos[iphase]->iniState->idxRow;
  342. iniStateNzPtrCol = endpNzPos[iphase]->iniState->ptrCol;
  343. finStateNzIdxRow = endpNzPos[iphase]->finState->idxRow;
  344. finStateNzPtrCol = endpNzPos[iphase]->finState->ptrCol;
  345. iniTimeNzIdxRow = endpNzPos[iphase]->iniTime->idxRow;
  346. iniTimeNzPtrCol = endpNzPos[iphase]->iniTime->ptrCol;
  347. finTimeNzIdxRow = endpNzPos[iphase]->finTime->idxRow;
  348. finTimeNzPtrCol = endpNzPos[iphase]->finTime->ptrCol;
  349. parameterNzIdxRow = endpNzPos[iphase]->parameter->idxRow;
  350. parameterNzPtrCol = endpNzPos[iphase]->parameter->ptrCol;
  351. // 参考输入
  352. endpInput->auxdata = setup->auxdata;
  353. endpInput->initialstate = refTraj[iphase]->state->v;
  354. endpInput->finalstate = refTraj[iphase]->state->v + refTraj[iphase]->state->m* (refTraj[iphase]->state->n-1);
  355. endpInput->initialtime = refTraj[iphase]->initialtime;
  356. endpInput->finaltime = refTraj[iphase]->finaltime;
  357. endpInput->parameter = refTraj[iphase]->parameter;
  358. endpFunc = setup->functions->phase[iphase]->endpoint;
  359. // 扰动输入空间分配
  360. pertEndpInput = (cmscp_endpInput*)malloc(sizeof(cmscp_endpInput));
  361. pertEndpInput->initialstate = (double*)malloc(numState * sizeof(double));
  362. pertEndpInput->finalstate = (double*)malloc(numState * sizeof(double));
  363. pertEndpInput->parameter = (double*)malloc(numParameter * sizeof(double));
  364. pertEndpInput->auxdata = setup->auxdata;
  365. // 参考输出空间分配
  366. refOutput = (double*)malloc(numEndpOutput * sizeof(double));
  367. // 扰动输出
  368. pertOutput = (double*)malloc(numEndpOutput * sizeof(double));
  369. // 雅可比矩阵的输入
  370. endpGrd = (double*)malloc(numEndpOutput * numEndpInput * sizeof(double));
  371. // 计算参考输出
  372. endpFunc(refOutput, endpInput);
  373. // 初始状态
  374. cntCol = 0;
  375. for ( j = 0; j < numState; j++)
  376. {
  377. copyEndpInput(endpInput, pertEndpInput, iphase, setup);
  378. pertEndpInput->initialstate[j] = pertEndpInput->initialstate[j] + derStep;
  379. endpFunc(pertOutput, pertEndpInput);
  380. for ( p = iniStateNzPtrCol[j]; p < iniStateNzPtrCol[j+1]; p++)
  381. {
  382. i = iniStateNzIdxRow[p];
  383. endpGrd[i + cntCol * numEndpOutput] = (pertOutput[i]- refOutput[i])*derStepInv;
  384. }
  385. cntCol++;
  386. }
  387. // 终端状态
  388. for (j = 0; j < numState; j++)
  389. {
  390. copyEndpInput(endpInput, pertEndpInput, iphase, setup);
  391. pertEndpInput->finalstate[j] = pertEndpInput->finalstate[j] + derStep;
  392. endpFunc(pertOutput, pertEndpInput);
  393. for (p = finStateNzPtrCol[j]; p < finStateNzPtrCol[j + 1]; p++)
  394. {
  395. i = finStateNzIdxRow[p];
  396. endpGrd[i + cntCol * numEndpOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  397. }
  398. cntCol++;
  399. }
  400. // 初始时刻
  401. for (j = 0; j < 1; j++)
  402. {
  403. copyEndpInput(endpInput, pertEndpInput, iphase, setup);
  404. pertEndpInput->initialtime = pertEndpInput->initialtime + derStep;
  405. endpFunc(pertOutput, pertEndpInput);
  406. for (p = iniTimeNzPtrCol[j]; p < iniTimeNzPtrCol[j + 1]; p++)
  407. {
  408. i = iniTimeNzIdxRow[p];
  409. endpGrd[i + cntCol * numEndpOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  410. }
  411. cntCol++;
  412. }
  413. // 终端时刻
  414. for (j = 0; j < 1; j++)
  415. {
  416. copyEndpInput(endpInput, pertEndpInput, iphase, setup);
  417. pertEndpInput->finaltime = pertEndpInput->finaltime + derStep;
  418. endpFunc(pertOutput, pertEndpInput);
  419. for (p = finTimeNzPtrCol[j]; p < finTimeNzPtrCol[j + 1]; p++)
  420. {
  421. i = finTimeNzIdxRow[p];
  422. endpGrd[i + cntCol * numEndpOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  423. }
  424. cntCol++;
  425. }
  426. // 静态参数
  427. for (j = 0; j < numParameter; j++)
  428. {
  429. copyEndpInput(endpInput, pertEndpInput, iphase, setup);
  430. pertEndpInput->parameter[j] = pertEndpInput->parameter[j] + derStep;
  431. endpFunc(pertOutput, pertEndpInput);
  432. for (p = parameterNzPtrCol[j]; p < parameterNzPtrCol[j + 1]; p++)
  433. {
  434. i = parameterNzIdxRow[p];
  435. endpGrd[i + cntCol * numEndpOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  436. }
  437. cntCol++;
  438. }
  439. gradInfo[iphase] = (cmscp_derInfo*)malloc(sizeof(cmscp_derInfo));
  440. gradInfo[iphase]->ref = refOutput;
  441. gradInfo[iphase]->der = endpGrd;
  442. // free空间
  443. free(pertEndpInput->initialstate);
  444. free(pertEndpInput->finalstate);
  445. free(pertEndpInput->parameter);
  446. free(pertEndpInput);
  447. free(pertOutput);
  448. }
  449. free(endpInput);
  450. }
  451. void gradInfoSparseCont(cmscp_derInfo** dynGradInfo0, cmscp_derInfo** pathGradInfo0, double* refState, double* refControl, double* refParameter,
  452. int* stateNzIdxRow, int* controlNzIdxRow, int* parameterNzIdxRow, int* stateNzPtrCol, int* controlNzPtrCol, int* parameterNzPtrCol,
  453. int numState, int numControl, int numParameter, int numPathOutput, int iphase, cmscp_setup* setup) {
  454. int numPhase, j, p, i,numContInput, cntContInput, idxRowPathGrd;
  455. double derStep, derStepInv, * refDynOutput, * refPathOutput, *refOutput, * pertOutput, * dynGrd, * pathGrd, * pertDynOutput, * pertPathOutput;
  456. cmscp_dimension* dimension;
  457. cmscp_mesh** mesh;
  458. cmscp_contInput* contInput, * pertContInput;
  459. cmscp_continuous contFunc;
  460. // 1. 基本参数
  461. dimension = setup->dimension; // 问题维数信息
  462. mesh = setup->mesh; // 网格信息
  463. numPhase = setup->numPhase; // 阶段数
  464. derStep = setup->derStep; // 求导步长
  465. derStepInv = 1 / derStep;
  466. // 假设函数的自变量按照[x, u, p]排序
  467. // 函数的参考输入和扰动输入
  468. contInput = (cmscp_contInput*)malloc(sizeof(cmscp_contInput));// 参考输入
  469. contInput->auxdata = setup->auxdata;
  470. contInput->state = refState;
  471. contInput->control = refControl;
  472. contInput->parameter = refParameter;
  473. pertContInput = (cmscp_contInput*)malloc(sizeof(cmscp_contInput));
  474. pertContInput->auxdata = setup->auxdata; // 扰动输入
  475. pertContInput->state = (double*)malloc(numState * sizeof(double));
  476. pertContInput->control = (double*)malloc(numControl * sizeof(double));
  477. pertContInput->parameter = (double*)malloc(numParameter * sizeof(double));
  478. // 连续函数
  479. contFunc = setup->functions->phase[iphase]->continuous;
  480. // 函数的参考输出和扰动输出
  481. refDynOutput = dynGradInfo0[0]->ref; // (double*)malloc(numState * sizeof(double));
  482. refPathOutput = pathGradInfo0[0]->ref; // (double*)malloc(numPathOutput * sizeof(double));
  483. contFunc(refDynOutput, refPathOutput, contInput); // 参考输出值
  484. pertDynOutput = (double*)malloc(numState * sizeof(double));
  485. pertPathOutput = (double*)malloc(numPathOutput * sizeof(double));
  486. // 雅可比矩阵
  487. numContInput = numState + numControl + numParameter;
  488. dynGrd = dynGradInfo0[0]->der;// (double*)malloc(numState * numContInput * sizeof(double));
  489. pathGrd = pathGradInfo0[0]->der; // (double*)malloc(numPathOutput * numContInput * sizeof(double));
  490. cntContInput = 0;
  491. for ( j = 0; j < numState; j++)
  492. {
  493. copyContInput(contInput, pertContInput, numState, numControl, numParameter, setup);
  494. pertContInput->state[j] = pertContInput->state[j] + derStep;
  495. contFunc(pertDynOutput, pertPathOutput, pertContInput);
  496. for ( p = stateNzPtrCol[j]; p < stateNzPtrCol[j+1]; p++)
  497. {
  498. i = stateNzIdxRow[p]; // 行
  499. if (i < numState)
  500. {
  501. dynGrd[i+cntContInput*numState] = (pertDynOutput[i] - refDynOutput[i]) * derStepInv;
  502. }
  503. else
  504. {
  505. idxRowPathGrd = i - numState;
  506. pathGrd[idxRowPathGrd + numPathOutput * cntContInput] = (pertPathOutput[idxRowPathGrd] - refPathOutput[idxRowPathGrd]) * derStepInv;;
  507. }
  508. }
  509. cntContInput++;
  510. }
  511. // 控制变量
  512. for (j = 0; j < numControl; j++)
  513. {
  514. copyContInput(contInput, pertContInput, numState, numControl, numParameter, setup);
  515. pertContInput->control[j] = pertContInput->control[j] + derStep;
  516. contFunc(pertDynOutput, pertPathOutput, pertContInput);
  517. for (p = controlNzPtrCol[j]; p < controlNzPtrCol[j + 1]; p++)
  518. {
  519. i = controlNzIdxRow[p]; // 行
  520. if (i < numState)
  521. {
  522. dynGrd[i+cntContInput * numState] = (pertDynOutput[i] - refDynOutput[i]) * derStepInv;
  523. }
  524. else
  525. {
  526. idxRowPathGrd = i - numState;
  527. pathGrd[idxRowPathGrd + numPathOutput * cntContInput] = (pertPathOutput[idxRowPathGrd] - refPathOutput[idxRowPathGrd]) * derStepInv;;
  528. }
  529. }
  530. cntContInput++;
  531. }
  532. // 静态参数变量
  533. for (j = 0; j < numParameter; j++)
  534. {
  535. copyContInput(contInput, pertContInput, numState, numControl, numParameter, setup);
  536. pertContInput->parameter[j] = pertContInput->parameter[j] + derStep;
  537. contFunc(pertDynOutput, pertPathOutput, pertContInput);
  538. for (p = parameterNzPtrCol[j]; p < parameterNzPtrCol[j + 1]; p++)
  539. {
  540. i = parameterNzIdxRow[p]; // 行
  541. if (i < numState)
  542. {
  543. dynGrd[i+cntContInput * numState] = (pertDynOutput[i] - refDynOutput[i]) * derStepInv;
  544. }
  545. else
  546. {
  547. idxRowPathGrd = i - numState;
  548. pathGrd[idxRowPathGrd + numPathOutput * cntContInput] = (pertPathOutput[idxRowPathGrd] - refPathOutput[idxRowPathGrd]) * derStepInv;;
  549. }
  550. }
  551. cntContInput++;
  552. }
  553. free(pertDynOutput);
  554. free(pertPathOutput);
  555. free(pertContInput->state);
  556. free(pertContInput->control);
  557. free(pertContInput->parameter);
  558. free(pertContInput);
  559. free(contInput);
  560. }
  561. void gradInfoSparseLink(cmscp_derInfo** gradInfo, cmscp_sparseInfo* sparseInfo, cmscp_trajInfo** refTraj, cmscp_setup* setup) {
  562. // 变量声明
  563. int numPhase, numObjEventInput, numEventOutput, iphase, numState, numControl, numParameter, numMesh, cntObjEventInput, * iniStateNzIdxRow, * finStateNzIdxRow, * iniTimeNzIdxRow, * finTimeNzIdxRow, * parameterNzIdxRow, * iniStateNzPtrCol, * finStateNzPtrCol, * iniTimeNzPtrCol, * finTimeNzPtrCol, * parameterNzPtrCol, j, p, i, idxRowEventGrd, numLinkInput, numLinkOutput, cntCol, * leftStatefIdxRow, * leftStatefPtrCol, * leftTfIdxRow, * leftTfPtrCol, * leftParameterIdxRow, * leftParameterPtrCol, * rightState0IdxRow, * rightState0PtrCol, * rightT0IdxRow, * rightT0PtrCol, * rightParameterIdxRow, * rightParameterPtrCol, numStateK, numStateKp1, numParameterK, numParameterKp1;;
  564. double derStep, derStepInv, * refOutput, * pertOutput, * linkGrd;
  565. cmscp_dimension* dimension;
  566. cmscp_mesh** mesh;
  567. cmscp_nzPos_link** linkNzPos;
  568. cmscp_linkInput* linkInput, * pertLinkInput;
  569. cmscp_linkage linkFunc;
  570. // 1. 基本参数
  571. dimension = setup->dimension; // 问题维数信息
  572. mesh = setup->mesh; // 网格信息
  573. numPhase = setup->numPhase; // 阶段数
  574. derStep = setup->derStep; // 求导步长
  575. derStepInv = 1 / derStep;
  576. linkNzPos = sparseInfo->linkNzPos;
  577. // 参考输入
  578. linkInput = (cmscp_linkInput*)malloc(sizeof(cmscp_linkInput));
  579. pertLinkInput = (cmscp_linkInput*)malloc(sizeof(cmscp_linkInput));
  580. for (iphase = 0; iphase < numPhase-1; iphase++)
  581. {
  582. numStateK = dimension->phase[iphase]->state;
  583. numStateKp1 = dimension->phase[iphase + 1]->state;
  584. numParameterK = dimension->phase[iphase]->parameter;
  585. numParameterKp1 = dimension->phase[iphase + 1]->parameter;
  586. numLinkInput = numStateK + numStateKp1 + numParameterK + numParameterKp1 + 2;
  587. if (dimension->phase[iphase]->linkage->soc->n)
  588. {
  589. numLinkOutput = dimension->phase[iphase]->linkage->nl + cmscp_sum(dimension->phase[iphase]->linkage->soc->q, dimension->phase[iphase]->linkage->soc->n);
  590. }
  591. else
  592. {
  593. numLinkOutput = dimension->phase[iphase]->linkage->nl;
  594. }
  595. // 各段稀疏信息
  596. leftStatefIdxRow = linkNzPos[iphase]->leftStatef->idxRow;
  597. leftStatefPtrCol = linkNzPos[iphase]->leftStatef->ptrCol;
  598. leftTfIdxRow = linkNzPos[iphase]->leftTf->idxRow;
  599. leftTfPtrCol = linkNzPos[iphase]->leftTf->ptrCol;
  600. leftParameterIdxRow = linkNzPos[iphase]->leftParameter->idxRow;
  601. leftParameterPtrCol = linkNzPos[iphase]->leftParameter->ptrCol;
  602. rightState0IdxRow = linkNzPos[iphase]->rightState0->idxRow;
  603. rightState0PtrCol = linkNzPos[iphase]->rightState0->ptrCol;
  604. rightT0IdxRow = linkNzPos[iphase]->rightT0->idxRow;
  605. rightT0PtrCol = linkNzPos[iphase]->rightT0->ptrCol;
  606. rightParameterIdxRow = linkNzPos[iphase]->rightParameter->idxRow;
  607. rightParameterPtrCol = linkNzPos[iphase]->rightParameter->ptrCol;
  608. // 参考输入
  609. linkInput->auxdata = setup->auxdata;
  610. linkInput->leftFinState = refTraj[iphase]->state->v + refTraj[iphase]->state->m * (refTraj[iphase]->state->n - 1);
  611. linkInput->leftFinTime = refTraj[iphase]->finaltime;
  612. linkInput->leftParameter = refTraj[iphase]->parameter;
  613. linkInput->rightIniState = refTraj[iphase + 1]->state->v;
  614. linkInput->rightIniTime = refTraj[iphase + 1]->initialtime;
  615. linkInput->rightParameter = refTraj[iphase + 1]->parameter;
  616. // 衔接点函数
  617. linkFunc = setup->functions->phase[iphase]->linkage;
  618. // 扰动输入空间分配
  619. pertLinkInput->auxdata = setup->auxdata;
  620. pertLinkInput->leftFinState = (double*)malloc(dimension->phase[iphase]->state * sizeof(double));
  621. pertLinkInput->leftParameter = (double*)malloc(dimension->phase[iphase]->parameter * sizeof(double));
  622. pertLinkInput->rightIniState = (double*)malloc(dimension->phase[iphase+1]->state * sizeof(double));
  623. pertLinkInput->rightParameter = (double*)malloc(dimension->phase[iphase + 1]->parameter * sizeof(double));
  624. // 参考输出空间分配
  625. refOutput = (double*)malloc(numLinkOutput * sizeof(double));
  626. // 扰动输出
  627. pertOutput = (double*)malloc(numLinkOutput * sizeof(double));
  628. // 雅可比矩阵的输入
  629. linkGrd = (double*)malloc(numLinkOutput * numLinkInput * sizeof(double));
  630. // 计算参考输出
  631. linkFunc(refOutput, linkInput);
  632. // 左侧终端状态
  633. cntCol = 0;
  634. for (j = 0; j < numStateK; j++)
  635. {
  636. copyLinkInput(linkInput, pertLinkInput, iphase, setup);
  637. pertLinkInput->leftFinState[j] = pertLinkInput->leftFinState[j] + derStep;
  638. linkFunc(pertOutput, pertLinkInput);
  639. for (p = leftStatefPtrCol[j]; p < leftStatefPtrCol[j + 1]; p++)
  640. {
  641. i = leftStatefIdxRow[p];
  642. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  643. }
  644. cntCol++;
  645. }
  646. // 左侧终端时刻
  647. copyLinkInput(linkInput, pertLinkInput, iphase, setup); // 扰动输入
  648. pertLinkInput->leftFinTime = pertLinkInput->leftFinTime + derStep;
  649. linkFunc(pertOutput, pertLinkInput);
  650. for ( p = leftTfPtrCol[0]; p < leftTfPtrCol[1]; p++)
  651. {
  652. i = leftTfIdxRow[p]; // 行
  653. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  654. }
  655. cntCol = cntCol + 1;
  656. // 左侧静态参数
  657. for ( j = 0; j < numParameterK; j++)
  658. {
  659. copyLinkInput(linkInput, pertLinkInput, iphase, setup); // 扰动输入
  660. pertLinkInput->leftParameter[j] = pertLinkInput->leftParameter[j] + derStep;
  661. linkFunc(pertOutput, pertLinkInput);
  662. for ( p = leftParameterPtrCol[j]; p < leftParameterPtrCol[j + 1]; p++)
  663. {
  664. i = leftParameterIdxRow[p]; // 行
  665. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  666. }
  667. cntCol = cntCol + 1;
  668. }
  669. // 右侧初始状态
  670. for (j = 0; j < numStateKp1; j++)
  671. {
  672. copyLinkInput(linkInput, pertLinkInput, iphase, setup); // 扰动输入
  673. pertLinkInput->rightIniState[j] = pertLinkInput->rightIniState[j] + derStep;
  674. linkFunc(pertOutput, pertLinkInput);
  675. for (p = rightState0PtrCol[j]; p < rightState0PtrCol[j + 1]; p++)
  676. {
  677. i = rightState0IdxRow[p]; // 行
  678. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  679. }
  680. cntCol = cntCol + 1;
  681. }
  682. // 右侧终端时刻
  683. copyLinkInput(linkInput, pertLinkInput, iphase, setup); // 扰动输入
  684. pertLinkInput->rightIniTime = pertLinkInput->rightIniTime + derStep;
  685. linkFunc(pertOutput, pertLinkInput);
  686. for (p = rightT0PtrCol[0]; p < rightT0PtrCol[1]; p++)
  687. {
  688. i = rightT0IdxRow[p]; // 行
  689. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  690. }
  691. cntCol = cntCol + 1;
  692. // 右侧静态参数
  693. for ( j = 0; j < numParameterKp1; j++)
  694. {
  695. copyLinkInput(linkInput, pertLinkInput, iphase, setup); // 扰动输入
  696. pertLinkInput->rightParameter[j] = pertLinkInput->rightParameter[j] + derStep;
  697. linkFunc(pertOutput, pertLinkInput);
  698. for ( p = rightParameterPtrCol[j]; p < rightParameterPtrCol[j+1]; p++)
  699. {
  700. i = rightParameterIdxRow[p]; // 行
  701. linkGrd[i + cntCol * numLinkOutput] = (pertOutput[i] - refOutput[i]) * derStepInv;
  702. }
  703. cntCol = cntCol + 1;
  704. }
  705. gradInfo[iphase] = (cmscp_derInfo*)malloc(sizeof(cmscp_derInfo));
  706. gradInfo[iphase]->ref = refOutput;
  707. gradInfo[iphase]->der = linkGrd;
  708. // free空间
  709. free(pertLinkInput->leftFinState);
  710. free(pertLinkInput->leftParameter);
  711. free(pertLinkInput->rightIniState);
  712. free(pertLinkInput->rightParameter);
  713. free(pertOutput);
  714. }
  715. free(pertLinkInput);
  716. free(linkInput);
  717. }