How to integrate when one of the limits is a variable?

In summary, the author is trying to integrate a function using the Romberg method, but has some trouble with the syntax. They also mention a problem with using global variables. The author suggests using a substitution method or a grid of functions.
  • #1
Fabio Kopp
16
0
I'm trying to integrate a simple function (x*y) using the Romberg method.
Question 1:
I want to integrate only x and maintain the argument y present in the rest of calculation, like a global variable. In fortran 77 I would use common.
Question 2:
How to integrate using arguments in the limits. For example:
f(x,y)=x*y
intervals-y->[x,1]
intervals-y->[0,1]

PS: Integration using values in the limits are okay.

Routine obtained from https://people.sc.fsu.edu/~jburkardt/cpp_src/nintlib/nintlib.htmldouble f1(int dim_num,double x[]){
double *a;
double *b;
int dim;
int eval_num;
int ind;
int it_max = 3;
double result;
int *sub_num;
double tol;
//
// Set the integration limits.
//

a = new double[dim_num];
b = new double[dim_num];
sub_num = new int[dim_num];

a[0]=0.0; <- x[0] or x[1]?
b[0]=1.0;
tol = 0.0001;
for ( dim = 0; dim < dim_num; dim++ )
{
sub_num[dim] = 20;
}
result = romberg_nd ( f0, a, b, dim_num, sub_num, it_max, tol,
&ind, &eval_num );

delete [] a;
delete [] b;
delete [] sub_num;
// cout << result << endl;
return result;
}

double f0(int dim_num,double x[]){
double value;
value=x[0]*x[1];
return value;
}
 
Technology news on Phys.org
  • #2
Fabio Kopp said:
I'm trying to integrate a simple function (x*y) using the Romberg method.
Question 1:
I want to integrate only x and maintain the argument y present in the rest of calculation, like a global variable. In fortran 77 I would use common.
I don't see how you can do this. Your function isn't really that "simple" as it involves two variables. Romberg is a numerical method for integration -- you seem to be wanting to to symbolic integration. For example, it's easy enough to find approximate values for the derivative of f(x) = sin(x) at a variety of points, but it's a completely different problem to have a program tell you that the derivative of sin(x) is cos(x).

Having global variables or a common block is not a solution. In all of the numerical methods, numbers go in, numbers, not symbols, come out.

Fabio Kopp said:
Question 2:
How to integrate using arguments in the limits. For example:
f(x,y)=x*y
intervals-y->[x,1]
intervals-y->[0,1]
Is there a typo here? You have intervals-y twice. In any case, the routine you're using wants the function to be one with just one variable, not two.
 
  • Like
Likes Fabio Kopp
  • #4
What stops you from using a grid of f(x,y)?
 
  • #5
ChrisVer said:
What stops you from using a grid of f(x,y)?
He was interested in using Romberg integration, which works for functions of a single variable.
 
  • #6
ChrisVer said:
What stops you from using a grid of f(x,y)?
I was looking on the the internet about this method of integration, but it is unclear to me how to apply it through a simple example.
I have already solved my problem using the change of variable.
Do you have a simple example in fortran, python or c++ for I study it?

Now, I'm still trying to find how pass a variable (common in fortran) in c++. I guess that is possible to do this using struct or static, but my attempts had no effects. For example, in this code, I used the numerical recipes with Romberg integration.
I'm newbie in C++, that is why I have some basic doubts on how to pass variables between functions.

#include <iostream>
#include <iomanip>
#include <cmath>
#include "nr.h"
#include <cstdlib>
using namespace std;

DP func0(const double x)
{
return x*y; <- y variable to be integrated after integration in x
}DP func1(const double y1){
r=NR::qromb(func0,0.0,3.0);
return r;
}int main(void)
{ double s;
s=NR::qromb(func1,0.0,1.0);
cout << "Result from routine QROMB is " << setw(12) << s << endl;
return 0;
}
 
Last edited:
  • #7
Ehmm you can't have an undefined variable in a function (if it's not global)... in func0 you will get an error... That's why I initially asked if you could make a chart of f(x,y) (like a table)...
I don't know this method of integration though and it's tough for me to look into it now (on mobile). Also I don't know what qcomb/DP/NP are :( ... For passing functions as arguments in C++ you may look at pointer returning functions...
 
  • Like
Likes Fabio Kopp
  • #8
ChrisVer said:
Ehmm you can't have an undefined variable in a function (if it's not global)... in func0 you will get an error... That's why I initially asked if you could make a chart of f(x,y) (like a table)...
I don't know this method of integration though and it's tough for me to look into it now (on mobile).
You are right about the declaration of global variable. As I told before, in fortran 77 I use common/v/y inside the func0 and func1 and the both integrations are done properly. And in python we could use args=(y) that is used to pass the arguments.
 
Last edited:
  • #9
ChrisVer said:
Ehmm you can't have an undefined variable in a function (if it's not global)... in func0 you will get an error... That's why I initially asked if you could make a chart of f(x,y) (like a table)...
I don't know this method of integration though and it's tough for me to look into it now (on mobile). Also I don't know what qcomb/DP/NP are :( ... For passing functions as arguments in C++ you may look at pointer returning functions...
result = qromb(func, a, b) -> rotine to integration where a is the inferior limit and b the superior.
DP -> is double in the numerical recipes library.
Could you show me a simple example of the use of pointers for this case?
 
  • #10
Fabio Kopp said:
I was looking on the the internet about this method of integration, but it is unclear to me how to apply it through a simple example.
I have already solved my problem using the change of variable.
Do you have a simple example in fortran, python or c++ for I study it?

Now, I'm still trying to find how pass a variable (common in fortran) in c++. I guess that is possible to do this using struct or static, but my attempts had no effects.
Writing a function that has parameters in C or C++ isn't difficult, but this is something you need to work on. Using global variables or common blocks is really not the best way to go. If you do a web search for "C++ function parameters" there should be lots of hits with examples.
Fabio Kopp said:
For example, in this code, I used the numerical recipes with Romberg integration.
I'm newbie in C++, that is why I have some basic doubts on how to pass variables between functions.

#include <iostream>
#include <iomanip>
#include <cmath>
#include "nr.h"
#include <cstdlib>
using namespace std;

DP func0(const double x)
{
return x*y; <- y variable to be integrated after integration in x
}
This isn't going to work since y isn't declared anywhere. If a function needs two inputs (x and y), they should be passed as parameters.

Also, what do you mean y is "to be integrated after integration in x"?
Fabio Kopp said:
DP func1(const double y1){
r=NR::qromb(func0,0.0,3.0);
return r;
}
Similar problem here as r isn't declared, and, as well, y1 is declared but not used. What is the purpose of having y1 if you don't use it?
Fabio Kopp said:
int main(void)
{ double s;
s=NR::qromb(func1,0.0,1.0);
cout << "Result from routine QROMB is " << setw(12) << s << endl;
return 0;
}
The line where s gets a value doesn't make sense to me. In this assignment you call the library function gromb(), passing func1 as a parameter. In your code for func1(), you call gromb.

It would be helpful if you gave us the exact, verbatim problem description.
 
  • #11
Fabio Kopp said:
Could you show me a simple example of the use of pointers for this case?
I don't think this would be productive. If you don't understand basic parameter passing in functions, you definitely won't understand parameters passed as addresses.
 
  • Like
Likes Fabio Kopp
  • #12
Mark44 said:
Writing a function that has parameters in C or C++ isn't difficult, but this is something you need to work on. Using global variables or common blocks is really not the best way to go. If you do a web search for "C++ function parameters" there should be lots of hits with examples.
This isn't going to work since y isn't declared anywhere. If a function needs two inputs (x and y), they should be passed as parameters.

Also, what do you mean y is "to be integrated after integration in x"?
Similar problem here as r isn't declared, and, as well, y1 is declared but not used. What is the purpose of having y1 if you don't use it?

The line where s gets a value doesn't make sense to me. In this assignment you call the library function gromb(), passing func1 as a parameter. In your code for func1(), you call gromb.

It would be helpful if you gave us the exact, verbatim problem description.

When I compile this code(for a function with only one variable x), it's works properly. Mark44, you are looking for the "mistakes" on my code example and you are not giving me a clear answer, even it seems ugly to a professional programmer like you, I'm newbie. If the ugly way works, the next step is to learn the details of language.

#include <iostream>
#include <iomanip>
#include <cmath>
#include "nr.h"
#include <cstdlib>
using namespace std;DP func(const double y){
double r;
r=pow(y,2);
return r;
}

int main(void)
{ double s;
s=NR::qromb(func,0.0,1.0);
cout << "Result from routine QROMB is " << setw(12) << s << endl;
return 0;
}

The code in the previous post was only to ilustrate my problem. I'm will never post a code without the proper variable declaration. As I'm using a routine for integration, even if it is a ugly way to pass a variable, I think that is more practical to do this than change the routine for each function to be integrated.
 
  • #13
Mark44 said:
I don't think this would be productive. If you don't understand basic parameter passing in functions, you definitely won't understand parameters passed as addresses.
Mark44, this is a forum. If you don't know, it is used to make question and get answers. If you don't want to answer the questions, ok. Or if it is more agreeable to you, imagine that all humans are stupids (except you) and you are the next Alan Turin to save the world.
And as a see in a previous post here in the forum, that you sometimes used the argument of authority to make your point. It does not seem to me a good behavior of a university teacher or a retired teacher.
I'm so sorry to offend your intelligence with my stupid questions.
 
Last edited:
  • #14
Fabio Kopp said:
When I compile this code(for a function with only one variable x), it's works properly. Mark44, you are looking for the "mistakes" on my code example and you are not giving me a clear answer, even it seems ugly to a professional programmer like you, I'm newbie. If the ugly way works, the next step is to learn the details of language.

#include <iostream>
#include <iomanip>
#include <cmath>
#include "nr.h"
#include <cstdlib>
using namespace std;DP func(const double y){
double r;
r=pow(y,2);
return r;
}

int main(void)
{ double s;
s=NR::qromb(func,0.0,1.0);
cout << "Result from routine QROMB is " << setw(12) << s << endl;
return 0;
}

The code in the previous post was only to ilustrate my problem. I'm will never post a code without the proper variable declaration. As I'm using a routine for integration, even if it is a ugly way to pass a variable, I think that is more practical to do this than change the routine for each function to be integrated.
Your code here looks fine. I don't see any problems with it.
 
  • #15
Fabio Kopp said:
Mark44, this is a forum. If you don't know, it is used to make question and get answers. If you don't want to answer the questions, ok.
When people ask well-defined questions, it's possible to provide meaningful answers. On the other hand, people sometimes ask questions that aren't at all clear, and it can take several additional questions from the people responding to get to the heart of the question.

In post #6, you said this:
Now, I'm still trying to find how pass a variable (common in fortran) in c++. I guess that is possible to do this using struct or static, but my attempts had no effects.

If it's not clear to you how the parameter passing mechanism works in C or C++, then that's something you need to look into. I suggested a search string you could use to find more information. If you have a specific question, we're happy to answer it, but you shouldn't expect this forum to provide all the details and examples on parameter passing, a topic that can fill a full chapter (or more) in a C++ programming textbook.
Fabio Kopp said:
Or if it is more agreeable to you, imagine that all humans are stupids (except you) and you are the next Alan Turin to save the world.
You are being overly sensitive. I don't think you are stupid, and nothing I wrote implies this. However, by your own admission, you don't have much knowledge in C++. The solution to this lack of knowledge is to expend some time on research, either on the web as I suggested earlier or by looking in a book on C++.
Fabio Kopp said:
And as a see in a previous post here in the forum, that you sometimes used the argument of authority to make your point.
Which post of mine are you referring to?
Fabio Kopp said:
It does not seem to me a good behavior of a university teacher or a retired teacher.
I'm so sorry to offend your intelligence with my stupid questions.
 
Last edited:
  • #16
OK, let me make a clear statement. Try answering the following:

Q1: What is it you are trying to do? Are you trying to integrate: [itex]f(x,y)=xy[/itex]? What's the integral like? Is it:
[itex]\int_0^1 dx \int_0^x dy~f(x,y)[/itex]
?

Q2: What's your ("complete") code? Where does it fail (what errors do you get)? What do you want to do? In fact I don't understand the "I'm still trying to find how pass a variable (common in fortran) in c++" either. A variable is passed as a variable in C++.

Q3: Have you tried solving an "easier" integration to make sure the functions of the libraries you are using work properly with your own code? Like one that doesn't have [itex]x[/itex] on the integral limits.
 
  • Like
Likes Fabio Kopp
  • #17
ChrisVer said:
OK, let me make a clear statement. Try answering the following:

Q1: What is it you are trying to do? Are you trying to integrate: [itex]f(x,y)=xy[/itex]? What's the integral like? Is it:
[itex]\int_0^1 dx \int_0^x dy~f(x,y)[/itex]
?

Q2: What's your ("complete") code? Where does it fail (what errors do you get)? What do you want to do? In fact I don't understand the "I'm still trying to find how pass a variable (common in fortran) in c++" either. A variable is passed as a variable in C++.

Q3: Have you tried solving an "easier" integration to make sure the functions of the libraries you are using work properly with your own code? Like one that doesn't have [itex]x[/itex] on the integral limits.
Chris, now I found the right solution and what is the meaning of a grid in your answer. By the way, the 3 questions I have already solved. The question 1 I solved using the trick https://en.wikipedia.org/wiki/Integration_by_substitution like in example 1, but for a different parameterization. Here is my simple code (slow convergence) tested for 1D and 2D integration. The way to pass the variable between the functions is ugly, but it's works. :D
Thanks for your readiness to help me.

#include<iostream>
#include<cmath>
using namespace std;
// to compile this code, use g++ -O3 filename.cpp
// https://en.wikipedia.org/wiki/Trapezoidal_rule - trapezoidal method of integration in 1 dimension (slow method)
// http://mathinsight.org/double_integral_examples - function used in this example

static double yy;
double trap(double f(double x), double a, double b, double n);
double f1(double x);
double f2(double y);
int main(){
double res,exactsol,error;
res=trap( f2, 0.0,1.0, 1.E4);
exactsol=2.0/3.0;
cout << " The numeracally result is " << res << endl;
cout << " The exact result is " << exactsol << endl;
cout << " The error is " << res - exactsol << endl;

return 0;

}double trap(double f(double x), double a, double b, double n0){
double sum, h,sol,err0,err;
sum=0.0;
h=(b-a)/(2.0*n0);
for(double x1=a; x1<=b; x1+=h){
sum+=f(x1);
}
sol=h*(sum+ f(a));

err0=0.0;
for(double n=1.0;n<=(n0-1.0);n+=1.0){
err0+=f(a+((n*(b-a))/n0));
}
err=sol - ((b-a)/n0)*( (f(a)+f(b))/2.0 + err0 );
// cout<<"the error in the integration is"<< err << endl; to reduce it, increase the n0.
return sol;

}

double f2(double y){
double res;
yy=y;
res=trap( f1, 0.0, 2.0, 1.E4);
return res;
}

double f1(double x){
double res;
res=x*pow(yy,2);
return res;
}
 
Last edited:
  • #18
Fabio Kopp said:
Chris, now I found the right solution and what is the meaning of a grid in your answer. By the way, the 3 questions I have already solved. The question 1 I solved using the trick https://en.wikipedia.org/wiki/Integration_by_substitution like in example 1, but for a different parameterization. Here is my simple code (slow convergence) tested for 1D and 2D integration. The way to pass the variable between the functions is ugly, but it's works. :D
Thanks for you readiness to help me.

#include<iostream>
#include<cmath>
using namespace std;
// to compile this code, use g++ -O3 filename.cpp
// https://en.wikipedia.org/wiki/Trapezoidal_rule - trapezoidal method of integration in 1 dimension (slow method)
// http://mathinsight.org/double_integral_examples - function used in this example

static double yy;
double trap(double f(double x), double a, double b, double n);
double f1(double x);
double f2(double y);
int main(){
double res,exactsol,error;
res=trap( f2, 0.0,1.0, 1.E4);
exactsol=2.0/3.0;
cout << " The numeracally result is " << res << endl;
cout << " The exact result is " << exactsol << endl;
cout << " The error is " << res - exactsol << endl;

return 0;

}double trap(double f(double x), double a, double b, double n0){
double sum, h,sol,err0,err;
sum=0.0;
h=(b-a)/(2.0*n0);
for(double x1=a; x1<=b; x1+=h){
sum+=f(x1);
}
sol=h*(sum+ f(a));

err0=0.0;
for(double n=1.0;n<=(n0-1.0);n+=1.0){
err0+=f(a+((n*(b-a))/n0));
}
err=sol - ((b-a)/n0)*( (f(a)+f(b))/2.0 + err0 );
// cout<<"the error in the integration is"<< err << endl; to reduce it, increase the n0.
return sol;

}

double f2(double y){
double res;
yy=y;
res=trap( f1, 0.0, 2.0, 1.E4);
return res;
}

double f1(double x){
double res;
res=x*pow(yy,2);
return res;
}

By the way, I was disregarding one big thing. The routines of integration were in different files(the definition in .cpp and the declaration in .hpp), so in this way, the approach that I was using would never work indeed. I've tried this simple case rekcha (7) (for constants) from this site [http://www.cplusplus.com/forum/general/21368/ ]
and it works. But when I considered an argument inside a function it does not work. And in all routines bentioned before, the arguments were passed as an array. That is different from my trapezoidal routine that argument is explicit and allowed me to use static to turn yy visible at next integration.
My argument is right, Chris?
 
  • #19
Fabio, please use code tags when you post code. These tags preserve your indentation, which helps make your code a lot more readable.
They look like this:
[code=c]
int main()
{
int size = 5
int count = 10;
// etc.
return 0;
}[/code]

I have added them to your code below.
Fabio Kopp said:
C:
#include<iostream>
#include<cmath>
using namespace std;
// to compile this code, use g++ -O3 filename.cpp
// [URL]https://en.wikipedia.org/wiki/Trapezoidal_rule[/URL]   - trapezoidal method of integration in 1 dimension (slow method)
// [URL]http://mathinsight.org/double_integral_examples[/URL]  - function used in this example

static double yy;
double trap(double f(double x), double a, double b, double n);
double f1(double x);
double f2(double y);
int main(){
    double res,exactsol,error;
    res=trap( f2, 0.0,1.0, 1.E4);
    exactsol=2.0/3.0;  
    cout << " The numeracally result is " << res << endl;
    cout << " The exact result is " << exactsol << endl;
    cout << " The error   is " << res - exactsol << endl;
      
return 0;

}double trap(double f(double x), double a, double b, double n0){
    double sum, h,sol,err0,err;
    sum=0.0;
    h=(b-a)/(2.0*n0);
    for(double x1=a; x1<=b; x1+=h){
    sum+=f(x1);
    }
    sol=h*(sum+ f(a));

    err0=0.0;      
    for(double n=1.0;n<=(n0-1.0);n+=1.0){
    err0+=f(a+((n*(b-a))/n0));
}
    err=sol - ((b-a)/n0)*( (f(a)+f(b))/2.0 + err0 );
//      cout<<"the error in the integration is"<< err << endl; to reduce it, increase the n0.
    return sol;

}

double f2(double y){
    double res;
    yy=y;  
    res=trap( f1, 0.0, 2.0, 1.E4);
    return res;
}

double f1(double x){
    double res;
    res=x*pow(yy,2);
    return res;
}
 
  • Like
Likes Fabio Kopp
  • #20
Mark44 said:
Fabio, please use code tags when you post code. These tags preserve your indentation, which helps make your code a lot more readable.
They look like this:
[code=c]
int main()
{
int size = 5
int count = 10;
// etc.
return 0;
}[/code]

I have added them to your code below.
Perfect, Mark44. Thanks!
 

What is integration?

Integration is a mathematical technique used to find the area under a curve. It involves finding the antiderivative of a function and evaluating it at different limits.

Why is it challenging to integrate when one of the limits is a variable?

Integration becomes challenging when one of the limits is a variable because it adds an extra layer of complexity to the problem. It requires the use of advanced techniques and strategies to solve the integration.

What are some techniques to integrate when one of the limits is a variable?

Some techniques to integrate when one of the limits is a variable include substitution, integration by parts, and partial fractions. These techniques help in simplifying the problem and solving it.

Can we always integrate when one of the limits is a variable?

It is not always possible to integrate when one of the limits is a variable. In some cases, the integral may not have a closed form solution, and it may require the use of numerical methods to approximate the value.

How can we check if the integration with a variable limit is done correctly?

We can check the integration with a variable limit by differentiating the result and verifying if it matches the original function. Additionally, we can also use online calculators or graphing software to plot the original function and the integral to visually confirm the correctness.

Similar threads

  • Programming and Computer Science
Replies
1
Views
598
  • Programming and Computer Science
Replies
1
Views
628
  • Programming and Computer Science
Replies
7
Views
1K
  • Programming and Computer Science
Replies
11
Views
926
  • Programming and Computer Science
Replies
5
Views
2K
Replies
63
Views
3K
  • Programming and Computer Science
Replies
15
Views
2K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
9
Views
1K
  • Programming and Computer Science
2
Replies
35
Views
2K
Back
Top