program.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include "program.hpp"
  2. #include <cassert>
  3. #include <iostream>
  4. #include <armadillo>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "GPM.h"
  8. using namespace Ipopt;
  9. using namespace std;
  10. using namespace arma;
  11. /* Constructor. */
  12. Program::Program()
  13. {}
  14. Program::~Program()
  15. {}
  16. ////////////////////////////*赋值函数(自编)*/////////////////////////////////
  17. Index var_num, constraint_num, nnz_jac, nnz_h;
  18. vec Fmin, Fmax, Zmin, Zmax, z0, z_ans0, zl_temp0, zu_temp0, lambda_temp0;
  19. uvec first_col, N_Col;
  20. auxdata1 auxdata;
  21. Grad_struct_info0 Grad_struct_info;
  22. Jacb_struct_info0 Jacb_struct_info;
  23. sp_mat Jacb_struct0, I_Z_struct0;
  24. field<mat> D_phasei;
  25. mat D_phase, W_phase, deta_t_in_col;
  26. int Col_total, length_state, length_control, length_integral, length_parameter, length_path, length_event, interval_num, length_Z0;
  27. char *deri_supplier;
  28. double eps0;
  29. double* Objective_ans0;
  30. int length_F0;
  31. int(*Dynamics_ptr)(mat*, mat*, auxdata1, mat*, mat*, mat*);
  32. int(*Objective_ptr)(input0*, double*, mat*);
  33. void get_var_num(int varnum0) {
  34. var_num = varnum0;
  35. z_ans0 = zeros<vec>(var_num);
  36. zl_temp0 = zeros<vec>(var_num);
  37. zu_temp0 = zeros<vec>(var_num);
  38. }
  39. void get_constraint_num(int constraint_num0) {
  40. constraint_num = constraint_num0;
  41. lambda_temp0 = zeros<vec>(constraint_num);
  42. }
  43. void get_nnz_jac(int nnz_jac0) {
  44. nnz_jac = nnz_jac0;
  45. }
  46. void get_nnz_h(int nnz_h0) {
  47. nnz_h = nnz_h0;
  48. }
  49. void get_x0(vec x00) {
  50. z0 = x00;
  51. }
  52. void get_bounds(vec Fmin0, vec Fmax0, vec Zmin0, vec Zmax0) {
  53. Fmin = Fmin0;
  54. Fmax = Fmax0;
  55. Zmin = Zmin0;
  56. Zmax = Zmax0;
  57. }
  58. void get_data(auxdata1 auxdata00, mat W_phase00, mat deta_t_in_col00, int Col_total00, int length_state00, int length_control00,
  59. Grad_struct_info0 Grad_struct_info00, int length_integral00, double eps00, mat D_phase00, uvec first_col00, int length_path00,
  60. int length_event00, sp_mat Jacb_struct00, field<mat> D_phasei0, uvec N_Col00, sp_mat I_Z_struct00, int interval_num00,
  61. int length_Z00, int length_parameter00, Jacb_struct_info0 Jacb_struct_info00, char *deri_supplier00, int length_F000,
  62. int(*Dynamics_ptr00)(mat* StateVar, mat* ControlVar, auxdata1 auxdata, mat* dState, mat* integrand, mat* path),
  63. int(*Objective_ptr00)(input0* input, double* output, mat* event)) {
  64. auxdata = auxdata00;
  65. W_phase = W_phase00;
  66. deta_t_in_col = deta_t_in_col00;
  67. Col_total = Col_total00;
  68. length_state = length_state00;
  69. length_control = length_control00;
  70. Grad_struct_info = Grad_struct_info00;
  71. length_integral = length_integral00;
  72. eps0 = eps00;
  73. D_phase = D_phase00;
  74. first_col = first_col00;
  75. length_path = length_path00;
  76. length_event = length_event00;
  77. Jacb_struct0 = Jacb_struct00;
  78. D_phasei = D_phasei0;
  79. N_Col = N_Col00;
  80. I_Z_struct0 = I_Z_struct00;
  81. interval_num = interval_num00;
  82. length_Z0 = length_Z00;
  83. length_parameter = length_parameter00;
  84. Jacb_struct_info = Jacb_struct_info00;
  85. deri_supplier = deri_supplier00;
  86. length_F0 = length_F000;
  87. Dynamics_ptr = Dynamics_ptr00;
  88. Objective_ptr = Objective_ptr00;
  89. }
  90. //初始化静态成员变量
  91. vec Program::x = zeros<vec>(var_num);
  92. vec Program::z_L = zeros<vec>(var_num);
  93. vec Program::z_U = zeros<vec>(var_num);
  94. vec Program::lambda = zeros<vec>(constraint_num);
  95. ///////////////////////////*重载函数部分*///////////////////////////////////////////
  96. bool Program::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
  97. Index& nnz_h_lag, IndexStyleEnum& index_style)
  98. {
  99. // MyNLP.hpp 中描述的问题有2个变量,x1,&x2。
  100. n = var_num;
  101. // 一个等式约束
  102. m = constraint_num;
  103. // 雅可比矩阵的非零值数目
  104. nnz_jac_g = nnz_jac;
  105. // 海森矩阵的非零值数目
  106. nnz_h_lag = nnz_h;
  107. // 我们对行/列条目使用标准的fortran索引样式。
  108. index_style = TNLP::C_STYLE;
  109. return true;
  110. }
  111. bool Program::get_bounds_info(Index n, Number* x_l, Number* x_u,
  112. Index m, Number* g_l, Number* g_u)
  113. {
  114. // 在这里,我们在 get_nlp_info 中给 IPOPT 的 n 和 m 被传回给我们。
  115. // 如果需要的话,我们可以通过assert来确保它们是我们认为的那样。
  116. assert(n == var_num);
  117. assert(m == constraint_num);
  118. // 变量的上下界
  119. vector_ARM2NLP(Zmin, x_l, var_num);
  120. vector_ARM2NLP(Zmax, x_u, var_num);
  121. // 约束的上下界
  122. vector_ARM2NLP(Fmin, g_l, constraint_num);
  123. vector_ARM2NLP(Fmax, g_u, constraint_num);
  124. return true;
  125. }
  126. bool Program::get_starting_point(Index n, bool init_x, Number* x,
  127. bool init_z, Number* z_L, Number* z_U,
  128. Index m, bool init_lambda,
  129. Number* lambda)
  130. {
  131. // 这里,我们假设我们只有x的起始值。
  132. // 如果你对自己的NLP进行编码,如果你愿意的话,你可以为其他数值提供起始值。
  133. assert(init_x == true);
  134. assert(init_z == false);
  135. assert(init_lambda == false);
  136. // 自变量的起点值
  137. vector_ARM2NLP(z0, x, n);
  138. // 协态变量的起点值
  139. // 约束乘子的起点值
  140. return true;
  141. }
  142. bool Program::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
  143. {
  144. // 返回目标函数的值
  145. vec Z1 = zeros(n, 1);;
  146. vector_NLP2ARM(x, &Z1, n);
  147. double J = 0;
  148. Objective_ipopt(Z1, deta_t_in_col, Col_total, auxdata, W_phase, length_state, length_control, length_parameter, Dynamics_ptr, Objective_ptr, &J);
  149. // cout << J << endl;////////////
  150. obj_value = J;
  151. return true;
  152. }
  153. bool Program::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
  154. {
  155. // 返回目标函数grad_{x} f(x)的梯度。
  156. assert(n == var_num);
  157. sp_mat Grad;
  158. vec Z1 = zeros(n, 1);;
  159. vector_NLP2ARM(x, &Z1, n);
  160. Grad_pro(Z1, Grad_struct_info, deta_t_in_col, Col_total, auxdata, W_phase, length_state, length_control, length_integral,
  161. length_parameter, eps0, deri_supplier, Dynamics_ptr, Objective_ptr, &Grad);
  162. // Grad.print();////////////
  163. vec Grad_vec = mat(Grad).col(0);
  164. vector_ARM2NLP(Grad_vec, grad_f, n);
  165. return true;
  166. }
  167. bool Program::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
  168. {
  169. // 返回约束条件的值:g(x)
  170. vec Z1 = zeros(var_num, 1);;
  171. vector_NLP2ARM(x, &Z1, var_num);
  172. vec F1;
  173. F_pro(Z1, D_phase, first_col, deta_t_in_col, length_path, Col_total, auxdata, W_phase, var_num,
  174. length_event, length_state, length_control, length_integral, length_parameter, Dynamics_ptr, Objective_ptr, &F1);
  175. //F1.print("F1");/////////////////
  176. vector_ARM2NLP(F1, g, constraint_num);
  177. return true;
  178. }
  179. bool Program::eval_jac_g(Index n, const Number* x, bool new_x,
  180. Index m, Index nele_jac, Index* iRow, Index *jCol,
  181. Number* values)
  182. {
  183. if (values == NULL) {
  184. // 返回约束条件的雅各布结构。
  185. sp_ARM2NLP(Jacb_struct0, iRow, jCol, nnz_jac);
  186. }
  187. else {
  188. // 返回约束条件的jacobian值。
  189. // 赋值
  190. vec Z1 = zeros(n, 1);;
  191. vector_NLP2ARM(x, &Z1, n);
  192. sp_mat Jacb;
  193. Jacb_pro(Z1, D_phasei, N_Col, deta_t_in_col, I_Z_struct0, Jacb_struct_info, length_F0, length_path, Col_total, auxdata, W_phase, length_event,
  194. length_state, length_control, length_integral, length_parameter, interval_num, eps0, deri_supplier, length_Z0, Dynamics_ptr, Objective_ptr, &Jacb);
  195. // Jacb.print("Jacb");////////////////////////
  196. values_set(Jacb, Jacb_struct0, values, nnz_jac);
  197. }
  198. return true;
  199. }
  200. bool Program::eval_h(Index n, const Number* x, bool new_x,
  201. Number obj_factor, Index m, const Number* lambda,
  202. bool new_lambda, Index nele_hess, Index* iRow,
  203. Index* jCol, Number* values)
  204. {
  205. if (values == NULL) {
  206. // 返回该结构。这是一个对称矩阵,只填写左下角的三角形。
  207. iRow[0] = 0;
  208. jCol[0] = 0;
  209. }
  210. else {
  211. // 返还值
  212. values = 0;
  213. }
  214. return true;
  215. }
  216. void Program::finalize_solution(SolverReturn status,
  217. Index n, const Number* x, const Number* z_L, const Number* z_U,
  218. Index m, const Number* g, const Number* lambda,
  219. Number obj_value,
  220. const IpoptData* ip_data,
  221. IpoptCalculatedQuantities* ip_cq)
  222. {
  223. Status_Display(status);
  224. vector_NLP2ARM(x, &z_ans0, var_num);
  225. vector_NLP2ARM(z_L, &zl_temp0, var_num);
  226. vector_NLP2ARM(z_U, &zu_temp0, var_num);
  227. vector_NLP2ARM(lambda, &lambda_temp0, constraint_num);
  228. Program::x = z_ans0;
  229. Program::z_L = zl_temp0;
  230. Program::z_U = zu_temp0;
  231. Program::lambda = lambda_temp0;
  232. // 这里是我们将解决方案存储到变量,或写入文件等,以便我们可以使用解决方案。
  233. // 由于解决方案是显示在控制台的,所以我们目前在这里什么也不做。
  234. }