numericalFunctions.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "numericalFunctions.h"
  2. // 生成线性间距向量
  3. void linSpace(double x1, double x2, int n, double* y) {
  4. int i;
  5. double d;
  6. d = (x2 - x1) / (n - 1);
  7. y[0] = x1;
  8. y[n - 1] = x2;
  9. for (i = 1; i < n - 1; i++)
  10. {
  11. y[i] = y[i - 1] + d;
  12. }
  13. }
  14. void ascLinearInterp(double* X, double* Y, int N, int M, double* x, int n, double* y) {
  15. // 升序线性插值
  16. // 函数参数 :
  17. // 为插值节点, 维数 1 * N
  18. // 为插值节点处的函数输出值,维数 M * N
  19. // N 为插值节点数目
  20. // M 为插值函数输出维数
  21. // 函数输入输出:
  22. // x 为函数输入, 维数 1 * n
  23. // n 为函数输入维数
  24. // y 为函数输入的维数,维数 M * n
  25. // 输入要求:
  26. // X 为升序列向量,即X(1) <= X(2) <= ...X(i) <= ... <= X(N)
  27. // x 为升序列向量,即x(1) <= x(2) <= ...x(i) <= ... <= x(n)
  28. int i, j, k, js, yidxs, Yidxs, Y1idxs;
  29. js = 0;
  30. yidxs = 0;
  31. for (i = 0; i < n; i++) {
  32. if (x[i] <= X[0]) {
  33. for (k = 0; k < M; k++) {
  34. y[yidxs + k] = Y[k];
  35. }
  36. }
  37. else if (x[i] > X[N - 1]) {
  38. Yidxs = (N - 1) * M;
  39. for (k = 0; k < M; k++) {
  40. y[yidxs + k] = Y[Yidxs + k];
  41. }
  42. }
  43. else {
  44. for (j = js; j < N - 1; j++) {
  45. if (x[i] > X[j] && x[i] <= X[j + 1]) {
  46. Yidxs = j * M;
  47. Y1idxs = (j + 1) * M;
  48. for (k = 0; k < M; k++) {
  49. y[yidxs + k] = Y[Yidxs + k] + (Y[Y1idxs + k] - Y[Yidxs + k]) / (X[j + 1] - X[j]) * (x[i] - X[j]);
  50. }
  51. js = j;
  52. break;
  53. }
  54. }
  55. }
  56. yidxs += M;
  57. }
  58. }
  59. void computeInteg(double* newState, // 新状态
  60. dynIntegFunc pfun, // 动力学方程
  61. double* oldState, double* control, double* parameter, void* auxdata, // 动力学方程输入
  62. int numState, int numControl, int numParameter, int numPath, // 变量维数
  63. double* tempWork, // 临时空间,避免重复申请和释放空间
  64. double stepSize, int integMode) // 积分步长和积分模式
  65. {
  66. int i;
  67. double* path, * dynRhs1, * dynRhs2, * dynRhs3, * dynRhs4, temp;
  68. /* 积分过程中计算的路径函数和右函数值 */
  69. path = tempWork;
  70. dynRhs1 = path + numPath;
  71. dynRhs2 = dynRhs1 + numState;
  72. dynRhs3 = dynRhs2 + numState;
  73. dynRhs4 = dynRhs3 + numState;
  74. /* 数值积分公式 */
  75. switch (integMode) {
  76. case 1: // 欧拉积分
  77. pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
  78. for (i = 0; i < numState; i++) {
  79. newState[i] = oldState[i] + stepSize * dynRhs1[i];
  80. };
  81. break;
  82. case 2: // 改进型欧拉积分
  83. temp = 0.5 * stepSize;
  84. pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
  85. for (i = 0; i < numState; i++) {
  86. newState[i] = oldState[i] + stepSize * dynRhs1[i];
  87. };
  88. pfun(dynRhs2, NULL, newState, control, parameter, auxdata);
  89. for (i = 0; i < numState; i++) {
  90. newState[i] = oldState[i] + temp * (dynRhs1[i] + dynRhs2[i]);
  91. };
  92. break;
  93. case 3: // 四阶龙哥库塔积分
  94. temp = 0.5 * stepSize;
  95. pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
  96. for (i = 0; i < numState; i++) {
  97. newState[i] = oldState[i] + temp * dynRhs1[i];
  98. };
  99. pfun(dynRhs2, NULL, newState, control, parameter, auxdata);
  100. for (i = 0; i < numState; i++) {
  101. newState[i] = oldState[i] + temp * dynRhs2[i];
  102. };
  103. pfun(dynRhs3, NULL, newState, control, parameter, auxdata);
  104. for (i = 0; i < numState; i++) {
  105. newState[i] = oldState[i] + stepSize * dynRhs3[i];
  106. };
  107. temp = stepSize / 6;
  108. pfun(dynRhs4, NULL, newState, control, parameter, auxdata);
  109. for (i = 0; i < numState; i++) {
  110. newState[i] = oldState[i] + temp * (dynRhs1[i] + 2 * dynRhs2[i] + 2 * dynRhs3[i] + dynRhs4[i]);
  111. };
  112. break;
  113. default:
  114. break;
  115. }
  116. }
  117. void copyIntVec(int* x, int* y, int n, int isNegtive) {
  118. // 函数功能:将n维度向量x复制给y
  119. // 输入:
  120. // x:原向量
  121. // n:向量长度
  122. // isNegtive:是否取负号复制
  123. // 输出:
  124. // y:复制后的向量
  125. // 谢磊:2022 / 6 / 25编写
  126. int i;
  127. if (isNegtive == 0) {
  128. for (i = 0; i < n; i++)
  129. {
  130. y[i] = x[i];
  131. }
  132. }
  133. else
  134. {
  135. for (i = 0; i < n; i++)
  136. {
  137. y[i] = -x[i];
  138. }
  139. }
  140. }
  141. void copyFloatVec(double* x, double* y, int n, int isNegtive) {
  142. int i;
  143. if (isNegtive == 0) {
  144. for (i = 0; i < n; i++)
  145. {
  146. y[i] = x[i];
  147. }
  148. }
  149. else
  150. {
  151. for (i = 0; i < n; i++)
  152. {
  153. y[i] = -x[i];
  154. }
  155. }
  156. }
  157. void floatVecFillin(double* x, int n, double a) {
  158. int i;
  159. for ( i = 0; i < n; i++)
  160. {
  161. x[i] = a;
  162. }
  163. }
  164. void intVecFillin(int* x, int n, int a) {
  165. // 函数功能:将n维度向量全部赋值为a
  166. // 输入:
  167. // x:向量首地址
  168. // n:向量长度
  169. // a:要赋值的向量值
  170. // 输出:
  171. // x:赋值后的向量
  172. // 谢磊:2022 / 6 / 25编写
  173. int i;
  174. for (i = 0; i < n; i++)
  175. {
  176. x[i] = a;
  177. }
  178. }