我遇到一系列功能问题。我有一个'返回值'数组(我通过矩阵计算它)来自单个函数 sys ,它依赖于一个整数变量,比方说, j ,我想要根据这个 j 返回它们,我的意思是,如果我想要方程式数字 j ,例如,我只写 sys(j) 为此,我使用 for 循环,但我不知道它是否定义良好,因为当我运行我的代码时,我没有得到正确的值。 是否有更好的方法来获得一系列函数并以简单的方式调用它们?这样可以更容易地使用Runge Kutta方法中的函数来求解diff方程。
我在这里放了这部分代码:( c 只是我之前用来解释的 j 整数)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int N=3;
double s=10.;
//float r=28.;
double b=8.0/3.0;
/ * Define functions * /
double sys(int c,double r,double y[])
{
int l,m,n,p=0;
double tmp;
double t[3][3]={0};
double j[3][3]={{-s,s,0},{r-y[2],-1,-y[0]},{y[1],y[0],-b}}; //Jacobiano
double id[3][3] = { {y[3],y[6],y[9]} , {y[4],y[7],y[10]} , {y[5],y[8],y[11]} };
double flat[N*(N+1)];
// Multiplication of matrices J * Y
for(l=0;l<N;l++)
{
for(m=0;m<N;m++)
{
for(n=0;n<N;n++)
{
t[l][m] += j[l][n] * id[n][m];
}
}
}
// Transpose the matrix (J * Y) -> () t
for(l=0;l<N;l++)
{
for(m=l+1;m<N;m++)
{
tmp = t[l][m];
t[l][m] = t[m][l];
t[m][l] = tmp;
}
}
// We flatten the array to be left in one array
for(l=0;l<N;l++)
{
for(m=0;m<N;m++)
{
flat[p+N] = t[l][m];
}
}
flat[0] = s*(y[1]-y[0]);
flat[1] = y[0]*(r-y[2])-y[1];
flat[2] = y[0]*y[1]-b*y[2];
for(l=0;l<(N*(N+1));l++)
{
if(c==l)
{
return flat[c];
}
}
}
EDIT ---------------------------------------------- ------------------
好的,这是我使用函数
的代码的一部分int main(){
output = fopen("lyapcoef.dat","w");
int j,k;
int N2 = N*N;
int NN = N*(N+1);
double r;
double rmax = 29;
double t = 0;
double dt = 0.05;
double tf = 50;
double z[NN]; // Temporary matrix for RK4
double k1[N2],k2[N2],k3[N2],k4[N2];
double y[NN]; // Matrix for all variables
/* Initial conditions */
double u[N];
double phi[N][N];
double phiu[N];
double norm;
double lyap;
//Here we integrate the system using Runge-Kutta of fourth order
for(r=28;r<rmax;r++){
y[0]=19;
y[1]=20;
y[2]=50;
for(j=N;j<NN;j++) y[j]=0;
for(j=N;j<NN;j=j+3) y[j]=1; // Identity matrix for y from 3 to 11
while(t<tf){
/* RK4 step 1 */
for(j=0;j<NN;j++){
k1[j] = sys(j,r,y)*dt;
z[j] = y[j] + k1[j]*0.5;
}
/* RK4 step 2 */
for(j=0;j<NN;j++){
k2[j] = sys(j,r,z)*dt;
z[j] = y[j] + k2[j]*0.5;
}
/* RK4 step 3 */
for(j=0;j<NN;j++){
k3[j] = sys(j,r,z)*dt;
z[j] = y[j] + k3[j];
}
/* RK4 step 4 */
for(j=0;j<NN;j++){
k4[j] = sys(j,r,z)*dt;
}
/* Updating y matrix with new values */
for(j=0;j<NN;j++){
y[j] += (k1[j]/6.0 + k2[j]/3.0 + k3[j]/3.0 + k4[j]/6.0);
}
printf("%lf %lf %lf \n",y[0],y[1],y[2]);
t += dt;
}
答案 0 :(得分:1)
由于您实际上是在同时计算所有这些值,因此您真正需要的是函数将它们全部返回。最简单的方法是传入一个指向数组的指针,函数将在其中写入值。或者也许是两个阵列;它看起来好像你的函数的输出(概念上)是一个3x3矩阵和一个长度为3的向量。
所以sys
的声明看起来像这样:
void sys(double v[3], double JYt[3][3], double r, const double y[12]);
其中v
最终会包含flat
的前三个元素,JYt
将包含其余元素。 (可能有更多信息的名称。)
顺便提一下,代码末尾的for
循环完全等同于只说return flat[c];
,除非c
恰好不是&gt; = 0
并且&lt; N*(N+1)
然后控制将从函数的末尾开始,这实际上意味着它将返回一些几乎肯定不是你想要的随机数。
答案 1 :(得分:1)
你的函数sys()
进行O(N 3 )计算以乘以两个矩阵,然后执行一些O(N 2 )运算,并且最后选择一个要返回的号码。然后在下次调用它并经历大部分相同的处理。除非(即使?)矩阵非常小,否则感觉有点浪费。
函数中的最后一个循环也有点奇怪:
for(l=0;l<(N*(N+1));l++)
{
if(c==l)
{
return flat[c];
}
}
这不是简单地写成:
return flat[c];
或者,或许:
if (c < N * (N+1))
return flat[c];
else
...do something on disastrous error other than fall off the end of the
...function without returning a value as the code currently does...
答案 2 :(得分:0)
我看不到你在哪里用j的值选择算法。如果那是你想要描述的内容,在C中你可以有一个指向函数的数组;您可以使用数字索引从数组中选择一个函数,但您也可以将指向函数的指针传递给另一个将调用它的函数。
那说:从你的代码来看,你应该保持简单。如果您想使用数字来控制执行哪些代码,只需使用if
或switch
语句。
switch (c) {
case 0:
/* Algorithm 0 */
break;
case 1:
/* Algorithm 1 */
etc.