3

I need to make function in C++ to calculate integrals. I am using the simpsone rule to calculate value of the given integral. I know how to calculate that. I don't have any problem with math. I need to know how can I pass whole expression to make my program flexible.

I have 4 f(x) functions for which I should make calculations. For example:

f(x)=2e^x
f(x)=x^3e
etc.

I have two options to make it.

1)I can do separate function for each f(x) function.

double function1() {
...
calculations 2e^x
...
return resault;
}

double function2() {
...
calculations x^3e
...
return resault;
}

This way is easy and fast to write, but the code is not flexible at all. In this case I need to make new function for every new given f(x) function.

I would like to have one function to which I can pass selected f(x) function.

2) Second case I prefer is to make some kind of interpreter of expressions. I thought about putting the parts of expression into std::vector and then making calculations for each cell of vector.

I've seen already an idea to parse string to the expression, but I think at the end it will be almost the same as idea with vector. I can be wrong.

What is the best way to make my code flexible and easy to use for users(not programmers)?

Iomanip
  • 71
  • 1
  • 4
  • Are you looking for [lambda expressions](http://en.cppreference.com/w/cpp/language/lambda)? – François Andrieux Jun 05 '18 at 18:02
  • 7
    Your question really is: "How to build a parser for mathematical functions?" Isn’t it? – idmean Jun 05 '18 at 18:04
  • I don't think this is the way to go. Write implementations for functions, turn them into objects, and give users a way to look them up by name in a map. I think that will work well enough. A general parser will be a challenge for you to write. – duffymo Jun 05 '18 at 18:07
  • 3
    https://stackoverflow.com/q/114586/1774667 is probably what you want. And yes, this isn't easy. – Yakk - Adam Nevraumont Jun 05 '18 at 18:10
  • 1
    Simpson's rule is the same, and treats the function being integrated as essentially a black box - it doesn't require any ability to change or reinterpret what that function is on the fly. Why do you think that code which implements Simpson's rule needs to be able to change or reinterpret what function it is integrating? As distinct, say, from knowing that it is passed a function that accepts a real argument and returns a real result? – Peter Jun 05 '18 at 18:31
  • Something a bit more primitive you could do is just a `std::unordered_map` where the mathFunctionPtr is a typedefed or aliased (strongly-typed) function pointer and an unordered_map quickly looks up the correct function based on the string. Not sure if that would be sophisticated enough for your needs, but it's certainly easy. You could even look up a class rather than function pointer, and the class could be responsible for parsing the arguments around the function name... – zzxyz Jun 05 '18 at 18:41
  • @Peter No. I just want to type my `f(x)` function while program is running. Then the expression should be passed to function which is used to calculate integral by simpson rule. I've already created the function which is calculating the integral, but the application is useless because every time I want to calculate another one, I need edit the code and compile it again. – Iomanip Jun 05 '18 at 18:44
  • 1
    @Iomanip Then you are asking for an expression parser. There is no standard c++ feature that does this, you have to write your own or use a library that offers that feature. – François Andrieux Jun 05 '18 at 18:46
  • 1
    @Iomanip - then you are asking for an expression parser and the fact of using Simpson's rule is irrelevant. You're mixing requirements that are better kept separate. Simpson's rule (or any approach for numerical integration) has nothing to do with expression parsing. – Peter Jun 05 '18 at 18:50
  • 2
    It could be much easier to do this on interpreter language using eval or embed interpreter into your program (lua or python for example) – Slava Jun 05 '18 at 19:01
  • Thanks for help. I give up this time. Lambda is enough. – Iomanip Jun 05 '18 at 20:24

1 Answers1

1

Suppose you have a function that takes two expressions and returns sum of the results of them. You can pass the expressions to function using lambda expression which is supported since C++11 as follow:

template<typename Func, typename Func2>
int calculate(Func &lambda_expr1, int param1, Func2 &lambda_expr2, int param2)
{
    return lambda_expr1(param1) + lambda_expr2(param2);
}

void main()
{
    // case 1
    auto f1 = [](int p) {return p*p; }; // expression 1
    auto f2 = [](int p) {return p*p*p; }; // expression 2
    int result = calculate(f1, 3, f2, 4);
    // result = 73

    // case 2
    result = calculate([](int p) {return p*p/2; }, 4, [](int p) {return p*p*p/3; }, 3);
    // result = 17
}
Hossein Golshani
  • 1,847
  • 5
  • 16
  • 27