-2

If i have a composition of functions f(f(f(f(x)))) how can i write it as function in C ? Is it possible to write it with recursive algorithm?

For example what happens if we have the following function:

f(x)=cosa*X1+cosb*X2 where x=(X1,X2)
Barmar
  • 741,623
  • 53
  • 500
  • 612
Otinane
  • 29
  • 9
  • 1
    Your function expects a structure as input, but returns a number. So the return value can't be used as the argument to another call on that function. – Barmar Jun 05 '14 at 09:32
  • I wrote a wrong example... The function returns two values. It is like this: F[0] = cosa*X0 + cosa*X1 F[1] = sina*X0 - cosa*X1 This is the first step. For all the other steps we use F[0] instead of X0 and F[1] instead of X1. And in every iteration F[0],F[1] gets new values. – Otinane Jun 05 '14 at 09:52
  • Hacked an iteration/recursion exercise program I had handy as a demo, though your explanation of actual function is still unclear. The initial values, are element 0, first output element 1 – Rob11311 Jun 05 '14 at 17:08

3 Answers3

1

Here's an example toy program I have, an exercise comparing iteration to head & tail recursion.

With a little hacking for this question, it reapplys a function "wibble" N times, and aggregates X0,X1 by struct array, builds series by reapply_f iterative and recursive functions. Refactoring the tail call optimised version, mutates code back to look like the iteration. ( Just using a typedef'd array, has problem you can't return it from a function, and don't have call by value semantics when passed to function calls. )

The output :

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)

And the C, showing the similarity of iteration and recursive code :

#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);
}
Rob11311
  • 1,396
  • 8
  • 10
0

If I get what you mean correctly, you can always set a counter to be the number of times you want the function to be called and pass it as one additional parameter for the function. Then reduce the counter by one each time you call the function once and stop the iteration as long as the counter gets zero.

theflyingwolves
  • 191
  • 1
  • 3
  • 10
0
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;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Barmar
  • 741,623
  • 53
  • 500
  • 612