C语言中的复合函数

C语言中的复合函数,c,recursion,function-composition,C,Recursion,Function Composition,如果我有一个函数的组合f(f(f(f(x)))我怎么能把它写成C中的函数呢?可以用递归算法来写吗 例如,如果我们有以下函数,会发生什么情况: f(x)=cosa*X1+cosb*X2 where x=(X1,X2) 如果我理解正确,您可以将计数器设置为希望调用函数的次数,并将其作为函数的一个附加参数传递。然后,每次调用函数一次时,将计数器减少一个,只要计数器为零,就停止迭代。下面是我的一个示例玩具程序,一个将迭代与头尾递归进行比较的练习 typedef struct composite {

如果我有一个函数的组合
f(f(f(f(x)))
我怎么能把它写成C中的函数呢?可以用递归算法来写吗

例如,如果我们有以下函数,会发生什么情况:

f(x)=cosa*X1+cosb*X2 where x=(X1,X2)

如果我理解正确,您可以将计数器设置为希望调用函数的次数,并将其作为函数的一个附加参数传递。然后,每次调用函数一次时,将计数器减少一个,只要计数器为零,就停止迭代。

下面是我的一个示例玩具程序,一个将迭代与头尾递归进行比较的练习

typedef struct composite {
    float X1,
    float X2
} composite;

composite f(composite x) {
    composite result;
    result.X1 = cosa*x.X1 + xosa*x.X2;
    result.X2 = sina*x.X0 - cosa*x.X2;
    return result;
}
对这个问题稍加修改,它重新分析函数“wibble”N次,并通过结构数组聚合X0、X1,通过重新应用迭代函数和递归函数构建序列。重构尾部调用优化版本,使代码变回迭代的样子。 (仅使用typedef'd数组就有问题,您无法从函数返回它,并且在传递到函数调用时没有按值调用语义。)

输出:

Iterative Series Technique
    f0 = f(0.100000,0.900000)
    f1 = f(1.000000,-0.800000)
    f2 = f(0.200000,1.800000)
    f3 = f(2.000000,-1.600000)

Head Recursive Series Technique
    f0 = f(0.100000,0.900000)
    f1 = f(1.000000,-0.800000)
    f2 = f(0.200000,1.800000)
    f3 = f(2.000000,-1.600000)

Tail Recursive Series Technique
    f0 = f(0.100000,0.900000)
    f1 = f(1.000000,-0.800000)
    f2 = f(0.200000,1.800000)
    f3 = f(2.000000,-1.600000)

Optimised Tail Recursive Series Technique
    f0 = f(0.100000,0.900000)
    f1 = f(1.000000,-0.800000)
    f2 = f(0.200000,1.800000)
    f3 = f(2.000000,-1.600000)

Tidied Optimised Tail Recursive Series Technique
    f0 = f(0.100000,0.900000)
    f1 = f(1.000000,-0.800000)
    f2 = f(0.200000,1.800000)
    f3 = f(2.000000,-1.600000)
和C,表示迭代和递归代码的相似性:

#include <stdio.h>
#include <stdlib.h>

typedef struct aggregate {
    double X[2];
} aggregate;

void display_series(int n, aggregate series[]) {
    for (int i=0; i<=n; i++) {
        printf( "    f%d = f(%f,%f)\n", i, series[i].X[0], series[i].X[1]);
    }
    putchar( '\n');
}

void init_series(int n, aggregate series[]) {
    series[0].X[0] = 0.1; series[0].X[1] = 0.9;
    for (int i=1; i <= n; i++) {
        series[ i].X[0] = 0.0; series[ i].X[1] = 0.0;
    }
}

aggregate wibble( const aggregate in) {
    aggregate out;
    out.X[0] = in.X[0] + in.X[1];
    out.X[1] = in.X[0] - in.X[1];
    return out;
}

aggregate reapply_f_iterative(int n, aggregate (*f)(), aggregate series[]) {
    for (int i=1; i <= n; i++) {
        series[ i] = (*f)( series[ i-1]);
    }
    return series[n];
}

aggregate reapply_f_head_recursive(int n, aggregate (*f)(), aggregate series[]) {
    if (n>0) {
        reapply_f_head_recursive( n-1, f, series);
    series[n] = (*f)( series[n-1]);
    }
    return series[n];
}

aggregate reapply_f_tail_recursive( int applied, int limit, aggregate (*f)(), aggregate series[]) {
    if (applied >= limit) {
        return series[ applied];
    }
    series[applied+1] = (*f)( series[ applied]);
    return reapply_f_tail_recursive( ++applied, limit, f, series);
}

aggregate reapply_f_optimised_tail_recursive( int applied, int limit, aggregate (*f)(), aggregate series[]) {
RESTART:
    if (applied >= limit) {
        return series[ applied];
    }
    series[applied+1] = (*f)( series[ applied]);
    ++applied;
    goto RESTART;
}

aggregate reapply_f_tidied_optimised_tail_recursive( int applied, int limit, aggregate (*f)(), aggregate series[]) {
    for( ; applied < limit; ++applied) {
        series[ applied+1] = (*f)( series[ applied]);
    };
    return series[ applied];
}



int main (int argc, char **argv) {

    /* series 0..N */
    size_t N = 3;
    if (argc == 2) {
        N = strtol( argv[ 1], NULL, 0);
    }
    aggregate *series = calloc( N+1, sizeof( aggregate));

    printf( "Iterative Series Technique\n");
    init_series( N, series);
    (void) reapply_f_iterative( N, &wibble, series);
    display_series( N, series);

    printf( "Head Recursive Series Technique\n");
    init_series( N, series);
    (void) reapply_f_head_recursive( N, &wibble, series);
    display_series( N, series);

    printf( "Tail Recursive Series Technique\n");
    init_series( N, series);
    (void) reapply_f_tail_recursive( 0, N, &wibble, series);
    display_series( N, series);

    printf( "Optimised Tail Recursive Series Technique\n");
    init_series( N, series);
    (void) reapply_f_optimised_tail_recursive( 0, N, &wibble, series);
    display_series( N, series);

    printf( "Tidied Optimised Tail Recursive Series Technique\n");
    init_series( N, series);
    (void) reapply_f_tidied_optimised_tail_recursive( 0, N, &wibble, series);
    display_series( N, series);
}
#包括
#包括
typedef结构聚合{
双X[2];
}骨料;
无效显示_系列(整数n,聚合系列[]){
for(int i=0;i=limit){
返回序列[应用];
}
系列[applied+1]=(*f)(系列[applied]);
++应用;
转到重新启动;
}
聚合重新应用\u f\u整理\u优化\u尾部\u递归(应用整数,整数限制,聚合(*f)(),聚合系列[]){
对于(;应用<限制;++应用){
系列[applied+1]=(*f)(系列[applied]);
};
返回序列[应用];
}
int main(int argc,字符**argv){
/*系列0..N*/
尺寸N=3;
如果(argc==2){
N=strtol(argv[1],NULL,0);
}
聚合*系列=calloc(N+1,sizeof(聚合));
printf(“迭代系列技术”);
init_系列(N,系列);
(无效)重新应用_f_迭代(N,&wibble,级数);
显示_系列(N,系列);
printf(“头递归系列技术”);
init_系列(N,系列);
(无效)重新应用头递归(N,&wibble,级数);
显示_系列(N,系列);
printf(“尾部递归系列技术”);
init_系列(N,系列);
(无效)重新应用\u f\u tail\u recursive(0,N和wibble,series);
显示_系列(N,系列);
printf(“优化的尾部递归序列技术”);
init_系列(N,系列);
(无效)重新应用优化的尾部递归(0,N和wibble,级数);
显示_系列(N,系列);
printf(“整理优化尾部递归序列技术”\n);
init_系列(N,系列);
(无效)重新应用\u f\u整理的\u优化的\u尾部\u递归(0,N和wibble,系列);
显示_系列(N,系列);
}

函数需要一个结构作为输入,但返回一个数字。所以返回值不能用作该函数的另一个调用的参数。我写了一个错误的示例。。。该函数返回两个值。它是这样的:F[0]=cosaX0+cosaX1 F[1]=sinaX0-cosaX1这是第一步。对于所有其他步骤,我们使用F[0]代替X0,使用F[1]代替X1。在每次迭代F[0]中,F[1]都会得到新的值。黑客攻击了一个我手边的迭代/递归练习程序作为演示,尽管你对实际函数的解释还不清楚。初始值是元素0,第一个输出元素1