4

The pseudo-code below depicts a computation I want to do. The idea is designing a C/C++ function that takes any mathematical function of x and evaluates the sum of the first N terms. function(x) could be any function e.g. 2x-1 , 2x , 1/x , etc . x varies from zero to N . I think challenge is how to design the function(x) datastructure , am not sure if this is achievable without any datastructure(this would be better) .

   function(x) = 2*x - 1 ;              

   sum_expression_to_N(  function(x)  , N ){

      float sum = 0.0;

      for ( int x =0; x<=N; x++){
           sum = sum +  function(x)       
      }
      return sum ;
  }
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Walker
  • 323
  • 1
  • 12
  • Take a look at function pointers – qrdl Aug 21 '15 at 08:38
  • Is the function given at compile time? If yes, use a template or a simple function pointer. If you have to read it from the user, use a good math parsing library (or write one yourself, but I would not recommend that for any reason but "for fun". The existing tools are quite good already). – Baum mit Augen Aug 21 '15 at 08:40
  • Thanks, @qrdl can you recommend any web-resource? – Walker Aug 21 '15 at 08:41
  • I'm not sure where the complexity arises. Just define your functions which take a value `x` and returns a value. Then define a templated function which takes any of those functions and computes the sum of `x = 0, -> x = N` – smac89 Aug 21 '15 at 08:42
  • @BaummitAugen , the Math function could be harded-coded . Before compiling the code . – Walker Aug 21 '15 at 08:44
  • @Smac89 , what am not used to is providing the flexibility in the kind of Math function to be given e.g. `1/x` , `2x-1` , `2*Pi*x- 2` . I havent done any generic function to consume any of these before . Let me try read on the suggested function pointers. – Walker Aug 21 '15 at 08:51
  • Pick a language. C doesn't have `std::function `, C++ does. – MSalters Aug 21 '15 at 08:56
  • 1
    @Walker, I put my comment as an answer. See below – smac89 Aug 21 '15 at 08:56

5 Answers5

2

You're reinventing std::accumulate. (your usage with x=0...N can be handled by boost's counting iterator, and accumulate would want the binary operator sum += f(x) instead of the default sum+=x.

In C++, functions that take other functions avoid making assumptions about what exactly they're calling. You see this in std::accumulate: it is a template so it can accept any kind of function (as well as any type of input iterator).

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

For your usecase, you can use the very easy and generic template feature C++ has:

template <class MathFunction> 
double foo (MathFunction function) {
    return function(1);
}

This handles anything that can be used as a 1-D math function, including lambdas, plain functions, std::functions, functors etc. (Live)

As this is also tagged C and the above is C++, you can also use function pointers:

double fun (double (*function)(double)) {
    return function(1);
}

This works for normal functions, which is all you have in C anyways. (Live)

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
1

This is trivial in modern C++. For example, you can write

#include <iostream>

template <typename F>
float sum_expr_to_n(F f, int n) {
    float sum = 0;
    for (int i = 0; i <= n; ++i) sum += f(i);
    return sum;
}

int main() {
    auto f = [](int x) { return 2 * x - 1; };
    std::cout << sum_expr_to_n(f, 3) << std::endl;
}
Lingxi
  • 14,579
  • 2
  • 37
  • 93
0

Is that function supposed to be input by the user at runtime or can you just have it at compile time? In the second case it is trivial. If you need to evaluate at runtime you need to parse the string and create a representation of the expression (usually a tree). Google "Parsing Trees" and look also at parsing math expression in c/c++

Community
  • 1
  • 1
Chris Cinelli
  • 4,679
  • 4
  • 28
  • 40
0

This is my crack at it (C++ answer):

#include <iostream>
#include <vector>

using func = int (*)(int);

// define your functions here -> f1, f2, f3,...

int main() {
    std::vector<func> functions = {f1, f2, f3,...};

    for (func f : functions) {
        int sum = 0;
        for (int x = 0; x <= N; x++) {
           sum = sum + f(x)       
        }
        std::cout << sum << '\n';
    }
    return 0;
}

Note that the functions you define should follow the pattern given by the func pointer.

So the function for this 2x-1, has to look like:

int f1(int x) {
    return 2 * x - 1;
}

And the same thing goes for the other ones. So only the logic changes, but not the function parameters or return type

smac89
  • 39,374
  • 15
  • 132
  • 179