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)
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)
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);
}
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.
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;
}