C数组函数

时间:2012-03-04 22:53:22

标签: c arrays function return

我遇到一系列功能问题。我有一个'返回值'数组(我通过矩阵计算它)来自单个函数 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; 
    }

3 个答案:

答案 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中你可以有一个指向函数的数组;您可以使用数字索引从数组中选择一个函数,但您也可以将指向函数的指针传递给另一个将调用它的函数。

那说:从你的代码来看,你应该保持简单。如果您想使用数字来控制执行哪些代码,只需使用ifswitch语句。

switch (c) {
case 0:
  /* Algorithm 0 */
  break;
case 1:
  /* Algorithm 1 */
  etc.