I've got such a piece of code:
#include <gsl/gsl_integration.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
double func1(double x, void* params) {
return 1/(x-1);
}
int main() {
int num = 100;
gsl_integration_workspace *workspace = gsl_integration_workspace_alloc(num);
double result, error;
double alpha;
alpha = 1;
gsl_function F;
F.function = &func1;
F.params = α
double a, b;
a=0;
b=2;
double err1= 0;
double err2 = 1e-7;
gsl_integration_qawc (&F, a, b, 1.0, err1, err2, num, workspace,&result, &error);
printf("Function QAWC - Cauchy Principal value\n");
printf("Result: %f\n", result);
printf("Error: %f\n", error);
result = 0;
gsl_integration_workspace_free(workspace); //zwolnienie pamięci dla całkowania
return 0;
}
I thought that it'll deal with such a kind of function, but I get the "could not integrate function" error. Why?
It's not that hard. Simply the function which will be calculated has a form F(x)=g(x)*w(x), where g(x) is a function which user has to define. w(x) is made using c parameter and has form: w(x)=1/(x-c). So if we want to compute principal value for function f(x)=1/(x-1) func1 should be:
double func1(double x, void* params) {
return 1;
}
And parameter c (4. parameter of function gsl_integration_qawc) sholud be 1.
Related
I find a solution to the equation using the bisection method.
And I need to find the value of a and b on some iterations. Therefore, I made two arrays for these points, respectively.
in order to "pull out" the number of iterations from the function, I had no problems. They are displayed on the screen. But how do I "pull out" these two arrays?Please tell me how to do it. Thank you in advance!
double f1(double x){
return x*x-5*sin(x);
}
double f2(double x){
return exp(x)-pow(10,x);
}
double f3(double x){
return sin(x)-x+0.15;
}
double f4(double x){
return x-pow(9+x,0.5)+x*x-4;
}
double dihotom (double a , double b , double e , double(*fp)(double),int &iter,double &points_a[],double &points_b[]){
double c , fc , fa = fp(a);
iter=(log10((b-a)/e))/log10(2);
int step = iter/3;
int step_current = step;
int it=0;
int k=0;
do{
c=(a+b)/2;
fc=fp(c);
if (fa*fc<=0) b = c ; else a = c;
it++;
if(it==step_current){
points_a[k]=a;
points_b[k]=b;
k++;
step_current=step_current+step;
}
fa=fp(a);
printf ("it %d: a = %lf,b = %lf\n",iter,a,b);
}while (fabs(a-b)>=e);
return c;
}
int main(int argc, char *argv[]) {
int int_s=0;
double points_a[3];
double points_b[3];
double k3= dihotom (0.5,1,0.0001,f3,int_s,points_a[3],points_b[3]);
printf("For F3 - root = %lf, F3(%.2lf)=%lf ;iter =%d\n", k3, k3 ,f3(k3),int_s);
int i=0;
for(i=0;i<3;i++){
printf("step : %d , a: %lf, b: %lf ", i,points_a[i],points_b[i]);
}
return 0;
}
In your case, you should take the arrays by reference:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double (&points_a)[3], double (&points_b)[3]) {
// ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
You could also let the arrays decay into pointers:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double points_a[], double points_b[]) {
or
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double* points_a, double* points_b) {
But by taking them by reference, you make sure that you only accept arrays of the correct size.
In either case, the call to the function will simply be:
double k3 = dihotom(0.5, 1, 0.0001, f3, int_s, points_a, points_b);
Demo
If you want to return two arrays from a function then make a struct with two vectors. Something like this. The way you are doing it is harder to maintain, who will allocate the arrays and delete them for example?
// todo for you : create better names then points_a and points_b
struct my_result_t
{
std::vector<double> points_a;
std::vector<double> points_b;
};
my_result_t function();
{
my_result_t result;
result.points_a.push_back(1.0);
result.points_b.push_back(2.0);
return result;
}
int main()
{
auto result = function();
std::cout << result.points_a[0];
}
In the following code:
#include "Simple_window.h"
#include "Graph.h"
int fac(int n) // factorial(n); n!
{
int r = 1;
while(n>1) {
r *= n;
--n;
}
return r;
}
double term(double x,int n) { return pow(x,n)/fac(n); }
double expe(double x,int n) // sum of n terms for x
{
double sum = 0;
for(int i = 0; i<n; ++i) sum += term(x,i);
return sum;
}
int main() {
Simple_window win {Point{100,100},xmax,ymax,""};
for(int n = 0; n<50; ++n) {
ostringstream ss;
ss << "exp approximation; n==" << n;
win.set_label(ss.str());
// get next approximation:
Function e {[n](double x) { return expe(x,n); },
-10,10,Point{300,300},200,30,30; // ***this line doesn't compile***
win.attach(e);
win.wait_for_button();
win.detach(e);
}
}
From the book "Principles and Practice using C++" by Stroustrup, the local variable n isn't taken when I try to compile it, and gives the error message:
No instance of the constructor Graph_lib::Function::Function coincides with the argument list
What is the problem?
By the way, the support code used for the books is https://web.archive.org/web/20191217104940/http://www.stroustrup.com/Programming/PPP2code
Your post is not close to a Minimal Reproducible Example
Here is an example for Minimal Reproducible Example.
In Graph.h Function takes a variable of Fct.
Where Fct is typedef double Fct(double);.
According to this post, lambda expression doesn't translate to function automatically, unless it doesn't create closure object by capturing nothing.
Check this example
typedef double Fct ( double );
typedef double bct ( double, int );
struct Foo{
Foo( Fct f ){};
};
struct bar{
bar( bct f){};
};
int main(){
int n(1);
Foo f{ [](double x){ return x; } };
//Foo f{ [n](double x){ return x*n; } }; // <=== this won't compile
bar b{[](double x, int n){return x*n;}};
}
To pass the n into function f without closure, you may
Change signature from typedef double Fct ( double ); to typedef double Fct ( double, int ); Like my example of bar
Write a function with a constant n.
(Strongly not suggested, unless you never maintain the code ) Global variable to make it possible to change n outside the function.
I'm wrapping GSL's ODE functions is a class I'm defining. When written with no class involved, the functions are working perfectly. However, when using the class I get an error after the second gsl_odeiv2_evolve_apply_fixed_step, getting the error gsl: evolve.c:317: ERROR: step dimension must match evolution size. I'm confused why the first step should work but the second shouldn't. In printing out the dimension of the step and evolve functions I get the same thing. Here's what I have for my class and what I'm calling inside the main() function.
class DynSys {
public:
DynSys(const size_t size, double startTime, double endTime, double stepSize,
double* iState,
int (*func)(double, const double*, double*, void*),
int (*jac)(double, const double*, double*, double*, void*),
const gsl_odeiv2_step_type* T = gsl_odeiv2_step_rk8pd)
: T(T), size(size), t(startTime), t1(endTime), h(stepSize) {
y = new double[size];
y = iState;
yPrev = new double[size];
s = gsl_odeiv2_step_alloc(T, size);
c = gsl_odeiv2_control_y_new(1e-6, 0.0);
e = gsl_odeiv2_evolve_alloc(size);
sys = { func, jac, size, 0 };
}
~DynSys() {
delete [] y;
delete [] yPrev;
gsl_odeiv2_evolve_free(e);
gsl_odeiv2_control_free(c);
gsl_odeiv2_step_free(s);
}
void step() {
printf("e dim: %ld\n", e->dimension);
printf("s dim: %ld\n", s->dimension);
printf("y: %.5f %.5f %.5f %.5f %.5f %.5f\n", y[0], y[1],
y[2], y[3], y[4], y[5]);
tPrev = t;
yPrev = std::copy(y, y+size, yPrev);
int status = gsl_odeiv2_evolve_apply_fixed_step(e, c, s, &sys,
&t, h, y);
if (status != GSL_SUCCESS) {
printf("Error: %s\n", gsl_strerror(status));
throw std::logic_error(gsl_strerror(status));
}
}
double getT() {
return t;
}
void setY(double* y) {
y = y;
}
private:
const gsl_odeiv2_step_type* T;
gsl_odeiv2_step* s;
gsl_odeiv2_control* c;
gsl_odeiv2_evolve* e;
gsl_odeiv2_system sys;
const size_t size;
double t;
double t1;
double h;
double* y;
double tPrev;
double* yPrev;
};
and then
int main() {
double state[] = { 1.0, 0.0, 0.0, 0.796975, 0.11637, 0.0185312};
const size_t size = 6;
DynSys system(size, 0.0, 40.0, 1e-3, state, func, jac);
system.step();
printf("t: %.5f\n", system.getT());
system.step();
printf("t: %.5f\n", system.getT());
return 0;
}
edit: Here's a link to the GSL functions GSL ODE
I am having trouble using a set function in a class file. So far I have the following. I am trying to write a quadratic class that has three private data members and can calculate both the value of a quadratic and the number of real roots in the quadratic. I'm not stuck on the math part as much as I am getting the set methods to not give me weird values. When I test using main, the values for a, b, and c are numbers that I didn't input when I created the object.
Quadratic.hpp
#ifndef QUADRATIC_HPP
#define QUADRATIC_HPP
class Quadratic
{
private:
double a;
double b;
double c;
public:
Quadratic();
Quadratic(double, double, double);
void setA(double);
void setB(double);
void setC(double);
double getA();
double getB();
double getC();
double valueFor(double);
int numRealRoots();
};
#endif
Quadratic.cpp
#include <cmath>
#include <iostream>
Quadratic::Quadratic()
{
setA(1.0);
setB(1.0);
setC(1.0);
}
Quadratic::Quadratic(double A, double B, double C)
{
a = A;
b = B;
c = C;
}
void Quadratic::setA(double A)
{
a = A;
}
void Quadratic::setB(double B)
{
a = B;
}
void Quadratic::setC(double C)
{
c = C;
}
double Quadratic::getA()
{
return a;
}
double Quadratic::getB()
{
return b;
}
double Quadratic::getC()
{
return c;
}
double Quadratic::valueFor(double x)
{
return (a*(pow(x,2)) + b*x + c);
}
int Quadratic:: numRealRoots()
{
double discriminant = pow(b,2) - (4*a*c);
double epsilon = 0.00001;
int realRoots;
if (discriminant <= epsilon && discriminant > 0)
realRoots = 1;
else if (discriminant > epsilon)
realRoots = 2;
else
realRoots = 0;
return realRoots;
}
Your setB method is wrong - it updates a instead of b:
void Quadratic::setB(double B)
{
b = B; // Was "a = B;" in the original code
}
I'm trying to create a program to numerically integrate a function between two limits. I've created a minimal example (where the "integral" is always 1.0) to illustrate an error I get. The code below tries to use a function whose arguments are two doubles and a function from doubles to doubles:
#include <iostream>
#include <math.h>
double cons(double a, double b, double c(double d))
{
return 1.0;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f(x));
std::cout << I << "";
}
This results in an error on cpp.sh:
14:31: error: cannot convert 'double' to 'double ()(double)' for argument '3' to 'double cons(double, double, double ()(double))'
Obviously, the difference between doubles and double-valued functions is causing a problem here. How can I get this working?
You need to pass the function, not call it.
#include <iostream>
#include <math.h>
double cons(double a, double b, double c(double d))
{
return 1.0;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f);
std::cout << I << "";
}
You didn't pass a function but the result of a function, a double. Second, you didn't correctly declared a function pointer as argument.
If you want to pass a double then declare a double as argument:
double cons(double a, double b, double c)
{
return 1.0*a*b*c;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f(x));
std::cout << I << "";
}
If you want to pass a function (aka function pointer as C++ is not a functional language):
double cons(double a, double b, double (*c)(double d))
{
return 1.0*c(a);
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f);
std::cout << I << "";
}
Your problem in this case is that you are calling the function with:
double I = cons(0, 1, f(x));
so you actually give cons the return value of f() instead of the actual function. So you need to write this insteed:
double I = cons(0, 1, f);
As an alternativ you could also use lambda expressions for your problem. For example something like this:
#include <iostream>
#include <math.h>
#include <functional>
double cons(double a, double b, const std::function<double(double)>& callback)
{
// do something
}
int main()
{
double x;
double I = cons(0, 1, [](double x){ return x*x});
std::cout << I << "";
}