123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #include "numericalFunctions.h"
- // 生成线性间距向量
- void linSpace(double x1, double x2, int n, double* y) {
- int i;
- double d;
- d = (x2 - x1) / (n - 1);
- y[0] = x1;
- y[n - 1] = x2;
- for (i = 1; i < n - 1; i++)
- {
- y[i] = y[i - 1] + d;
- }
- }
- void ascLinearInterp(double* X, double* Y, int N, int M, double* x, int n, double* y) {
- // 升序线性插值
- // 函数参数 :
- // 为插值节点, 维数 1 * N
- // 为插值节点处的函数输出值,维数 M * N
- // N 为插值节点数目
- // M 为插值函数输出维数
- // 函数输入输出:
- // x 为函数输入, 维数 1 * n
- // n 为函数输入维数
- // y 为函数输入的维数,维数 M * n
- // 输入要求:
- // X 为升序列向量,即X(1) <= X(2) <= ...X(i) <= ... <= X(N)
- // x 为升序列向量,即x(1) <= x(2) <= ...x(i) <= ... <= x(n)
- int i, j, k, js, yidxs, Yidxs, Y1idxs;
- js = 0;
- yidxs = 0;
- for (i = 0; i < n; i++) {
- if (x[i] <= X[0]) {
- for (k = 0; k < M; k++) {
- y[yidxs + k] = Y[k];
- }
- }
- else if (x[i] > X[N - 1]) {
- Yidxs = (N - 1) * M;
- for (k = 0; k < M; k++) {
- y[yidxs + k] = Y[Yidxs + k];
- }
- }
- else {
- for (j = js; j < N - 1; j++) {
- if (x[i] > X[j] && x[i] <= X[j + 1]) {
- Yidxs = j * M;
- Y1idxs = (j + 1) * M;
- for (k = 0; k < M; k++) {
- y[yidxs + k] = Y[Yidxs + k] + (Y[Y1idxs + k] - Y[Yidxs + k]) / (X[j + 1] - X[j]) * (x[i] - X[j]);
- }
- js = j;
- break;
- }
- }
- }
- yidxs += M;
- }
- }
- void computeInteg(double* newState, // 新状态
- dynIntegFunc pfun, // 动力学方程
- double* oldState, double* control, double* parameter, void* auxdata, // 动力学方程输入
- int numState, int numControl, int numParameter, int numPath, // 变量维数
- double* tempWork, // 临时空间,避免重复申请和释放空间
- double stepSize, int integMode) // 积分步长和积分模式
- {
- int i;
- double* path, * dynRhs1, * dynRhs2, * dynRhs3, * dynRhs4, temp;
- /* 积分过程中计算的路径函数和右函数值 */
- path = tempWork;
- dynRhs1 = path + numPath;
- dynRhs2 = dynRhs1 + numState;
- dynRhs3 = dynRhs2 + numState;
- dynRhs4 = dynRhs3 + numState;
- /* 数值积分公式 */
- switch (integMode) {
- case 1: // 欧拉积分
- pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + stepSize * dynRhs1[i];
- };
- break;
- case 2: // 改进型欧拉积分
- temp = 0.5 * stepSize;
- pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + stepSize * dynRhs1[i];
- };
- pfun(dynRhs2, NULL, newState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + temp * (dynRhs1[i] + dynRhs2[i]);
- };
- break;
- case 3: // 四阶龙哥库塔积分
- temp = 0.5 * stepSize;
- pfun(dynRhs1, NULL, oldState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + temp * dynRhs1[i];
- };
- pfun(dynRhs2, NULL, newState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + temp * dynRhs2[i];
- };
- pfun(dynRhs3, NULL, newState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + stepSize * dynRhs3[i];
- };
- temp = stepSize / 6;
- pfun(dynRhs4, NULL, newState, control, parameter, auxdata);
- for (i = 0; i < numState; i++) {
- newState[i] = oldState[i] + temp * (dynRhs1[i] + 2 * dynRhs2[i] + 2 * dynRhs3[i] + dynRhs4[i]);
- };
- break;
- default:
- break;
- }
- }
- void copyIntVec(int* x, int* y, int n, int isNegtive) {
- // 函数功能:将n维度向量x复制给y
- // 输入:
- // x:原向量
- // n:向量长度
- // isNegtive:是否取负号复制
- // 输出:
- // y:复制后的向量
- // 谢磊:2022 / 6 / 25编写
- int i;
- if (isNegtive == 0) {
- for (i = 0; i < n; i++)
- {
- y[i] = x[i];
- }
- }
- else
- {
- for (i = 0; i < n; i++)
- {
- y[i] = -x[i];
- }
- }
- }
- void copyFloatVec(double* x, double* y, int n, int isNegtive) {
- int i;
- if (isNegtive == 0) {
- for (i = 0; i < n; i++)
- {
- y[i] = x[i];
- }
- }
- else
- {
- for (i = 0; i < n; i++)
- {
- y[i] = -x[i];
- }
- }
- }
- void floatVecFillin(double* x, int n, double a) {
- int i;
- for ( i = 0; i < n; i++)
- {
- x[i] = a;
- }
- }
- void intVecFillin(int* x, int n, int a) {
- // 函数功能:将n维度向量全部赋值为a
- // 输入:
- // x:向量首地址
- // n:向量长度
- // a:要赋值的向量值
- // 输出:
- // x:赋值后的向量
- // 谢磊:2022 / 6 / 25编写
- int i;
- for (i = 0; i < n; i++)
- {
- x[i] = a;
- }
- }
|