【发布时间】:2017-10-23 23:10:00
【问题描述】:
我正在尝试使用 Runge Kutta 解决二阶 ODE。我有 RK 方法的大纲,并且 ODE 本身已建立,但我无法继续。我在一个数组中有 ODE-s,我尝试将这个数组传递给 RK,但是在 f(dy[i]) 部分它给出了“预期的 double* 但键入 double”错误。当我尝试将两个 ODE-s 分成两个函数并将它们传递给 RK 时,它只适用于第一个函数。传递 dy 的元素而不是函数指针不是一种选择,因为 RK 本身应该能够求解包含任意数量变量的 ODE。
如何正确添加数组并使用它? 这是我对应的一段代码:
double* harmOsc(double* p, double t, double* y, double* dy, int n)
{
double k = p[0];
double m = p[1];
double x = y[0];
double v = y[1];
dy[0] = v;
dy[1] = -k/m*x;
return(dy);
}
double* HarmOsc1(double* dy, double t)
{
return(dy);
}
void RK4(
double t, //independent variable
double dt, //stepsize
double *y, //variables
double *dy, //derivatives
int n, //number of equations
double* (*f)(double*, double))
{
int j;
double* l = (double*)calloc(4*n,sizeof(double));
for(j=0;j<n;j++)
{
l[0*n+j] = dt*f(dy[j],t);
l[1*n+j] = dt*f(dy[j]+0.5*l[0*n+j],t+0.5*dt);
l[2*n+j] = dt*f(dy[j]+0.5*l[1*n+j],t+0.5*dt);
l[3*n+j] = dt*f(dy[j]+0.5*l[2*n+j],t+0.5*dt);
y[j] = y[j] + (l[0*n+j] + 2*l[1*n+j] + 2*l[2*n+j] + l[3*n+j])/6;
}
}
int main(int argc, char *argv[])
{
double* p = (double*)calloc(2,sizeof(double));
p[0] = 15; p[1] = 140;
double* y = (double*)calloc(2,sizeof(double));
y[0] = 12.4; y[1] = 1.1;
double t=0;
double* dy = (double*)calloc(2,sizeof(double));
dy = harmOsc(p,t,y,dy,2);
dy = HarmOsc1(dy,t);
RK4(t,0.05,p,y,dy,2,&HarmOsc1);
printf("%f, %f\n",dy[1],dy[0]);
}
HarmOsc1 是我调用的函数,因此它具有所需数量的参数。
当然还有我收到的警告:
RK3.c:55:13: 错误:‘f’的参数 1 的类型不兼容
RK3.c:55:13:注意:预期为“double *”,但参数类型为“double”
RK3.c:56:6: 错误:‘f’的参数 1 的类型不兼容
RK3.c:56:6:注意:预期为“双 *”,但参数的类型为“双”
RK3.c:57:6: 错误:‘f’的参数 1 的类型不兼容
RK3.c:57:6:注意:预期为“双 *”,但参数的类型为“双”
RK3.c:58:6:错误:‘f’的参数 1 的类型不兼容
RK3.c:58:6:注意:预期为“double *”,但参数类型为“double”
【问题讨论】:
-
如果您澄清编译器拒绝的函数调用会有所帮助。
-
没有直接关系,但是
(1/6)是整数除法,结果被截断为0。 -
@HolyBlackCat 解决了这个问题。此外,编辑以显示正在发生的事情
-
你的 f 需要一个 double*,你给一个 double。这就是编译器所抱怨的,这就是你的代码所做的。请解释什么让您感到困惑。
-
当你解决了 f() 参数的类型问题后,接下来你会遇到返回值类型的问题。
dt*f(...)将 doube "dt" 乘以 f 的返回值,f 是指向 double 的指针。
标签: c function-pointers numerical-methods numerical-integration runge-kutta