Making an AbstractOdeSolver class library to solve differential equations numerically (c++) - c++

I am trying to make and ode solver using c++ and numerical methods (euler, heun and runge kutta). first i made and abstract class for ode solving requirements then i made a separate class for each solver inheriting from the ABClass. there is no problem with the code excpet it works only with first order differential equations as dydt = y
however i need to expand it to be able to solve a system of first order differential equations as dydt = x-y & dxdt = y together
here is the header file
#ifndef ABSTRACTODESOLVER_H_INCLUDED
#define ABSTRACTODESOLVER_H_INCLUDED
#include <iostream>
using namespace std;
class AbstractOdeSolver
{
private:
double stepsize;
double initialTime;
double finalTime;
double initialValue;
public:
double (*RHS)(double, double); //pointer to function
void SetStepSize(double h);
void SetIntervalTime(double t0, double t1);
void SetInitialValue(double y0);
void setRHS(double (*pRHS)(double, double)); //set pointer function
double getStepSize(){return stepsize;}
double getInitialTime(){return initialTime;}
double getFinalTime(){return finalTime;}
double getInitialValue(){return initialValue;}
virtual void SolveEquation() = 0;
};
class EulerSolver : public AbstractOdeSolver
{
public:
virtual void SolveEquation();
};
class HeunSolver : public AbstractOdeSolver
{
public:
virtual void SolveEquation();
};
class RungeKuttaSolver : public AbstractOdeSolver
{
public:
virtual void SolveEquation();
};
#endif // ABSTRACTODESOLVER_H_INCLUDED
and this is the source code for one solver:
void EulerSolver::SolveEquation(){
double yNew = 0.0;
double yOld = getInitialValue(); // y0 initial value of Y
double tInit = getInitialTime(); // t0 initial value of T
double tFinal = getFinalTime();
double h = getStepSize();
for (double i = tInit; i <= tFinal; i += h){
yNew = yOld + (h * RHS(tInit,yOld));
yOld = yNew;
tInit += h;
cout << left << setw(5) << tInit << " " << setw(5) << yNew << endl;
}
}
and this is a program:
double Func(double t, double y){
return y;
}
EulerSolver euler1;
euler1.SetIntervalTime(0,0.6);
euler1.SetInitialValue(1);
euler1.SetStepSize(0.1);
euler1.setRHS(Func);
euler1.SolveEquation();
here i am using a function pointer RHS to allow the solver to use the function every time in the iteration, however i need to have more than one function in order to solve higher degree equations and the problem i dont know a way of making two separate functions with related variables (dydt = x-y & dxdt = y) and then having a pointer on each and returning the answer in an array!.
Any ideas will be great.

Related

conflicting declaration 'printPolarForm c'

I wanted to declare a constructor but I face this error. As it's obvious , I wanted to create a program to show the polar form of a complex number. I know it's kind of ridiculous and it's easier to do this , with functions . BUT this is a project and it is mentioned not to change the body of main function.
How can this be fixed?
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
class Complex
{
public:
double real , img;
Complex()
{
real = 0;
img = 0;
}
};
class constructComplex : public Complex
{
public:
constructComplex(double a , double b)
{
real = a;
img = b;
}
};
class printPolarForm : public Complex
{
public:
printPolarForm(Complex z)
{
cout << fixed << setprecision(2);
double r = sqrt( z.real * z.real + z.img * z.img );
double argument = atan2(z.img , z.real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
};
int main()
{
cout << fixed << setprecision(2);
double x1, y1;
cin >> x1 >> y1;
Complex c = constructComplex(x1, y1);
printPolarForm(c);
return 0;
}
You have a serious misunderstanding of what classes are for. Generally speaking classes encapsulate some state, i.e. member variables, and some operations on that state. None of your last two classes above have any state beyond the Complex class that they inherit from, so they should not exist as classes.
Let's see how this code should be written
constructComplex is an attempt to construct a complex number from parameters, so it should be an alternate constructor within the Complex class. i.e.
class Complex
{
public:
double real , img;
Complex()
{
real = 0;
img = 0;
}
Complex(double a, double b)
{
real = a;
img = b;
}
};
With this new constructor your main code changes from
Complex c = constructComplex(x1, y1);
to
Complex c(x1, y1);
printPolarForm is an operation on an existing complex number. It could be defined as a member function or a free function. I'll show that as a free function first
void printPolarForm(Complex z)
{
cout << fixed << setprecision(2);
double r = sqrt( z.real * z.real + z.img * z.img );
double argument = atan2(z.img , z.real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
the alternative is to make is a member function of the Complex class
class Complex
{
...
void printPolarForm() const
{
cout << fixed << setprecision(2);
double r = sqrt( real * real + img * img );
double argument = atan2(img , real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
};
The rest of the Complex class is as before. With the member function method you have to change how the function is called in main. Instead of
printPolarForm(c);
you would write
c.printPolarForm();
Either of these two options (free function or member function) are perfectly acceptable in this case. In both cases the class printPolarForm has been removed.

Errors in implementing an integral function from x to infinity from scratch in CPP with substitution

So I am trying to implement an integration function from scratch in CPP. I have been stuck on this for 2 days.
I am not sure how to do an integration computation from x to +inf. My plan was to use the sigmoid function as a substitution for the integration which should mathematically work but it didn't work computationally. Formula reference: https://en.wikipedia.org/wiki/Integration_by_substitution#Definite_integrals
My questions are 1). why my method didn't work? 2). Is there a better method/function to be used for the substitution?
Reproducible Code
which can be accessed via https://onlinegdb.com/F3rzIEReA with explanations as comments
#include <iostream>
#include <cmath>
const double PI = 3.14159265358979323846;
using namespace std;
// I have an interface for a real function named RealFunction which
// is used to be fed into the integral function
class RealFunction {
public:
virtual ~RealFunction() {};
virtual double evaluate( double x ) = 0;
};
// integral function that utilises the rectangular rule
double integral( RealFunction& f,
double a,
double b,
int nPoints ) {
double h = (b-a)/nPoints;
double x = a + 0.5*h;
double totalHeight = 0.0;
for (int i=0; i<nPoints; i++) {
double height = f.evaluate(x);
totalHeight+=height;
x+=h;
}
return h*totalHeight;
}
// a probability normal distribution function
class NormPDF : public RealFunction {
public:
NormPDF(double mu, double sigma) :
mu(mu), sigma(sigma){}
NormPDF() :
mu(0.0), sigma(1.0){}
double mu;
double sigma;
double evaluate(double x){
return exp(-0.5*pow((x-mu)/sigma,2.0))/(sigma*sqrt(2*PI));
}
};
// my chosen substitution function - sigmoid function
double sigmoidFunction(double x) {
return 1/(1+exp(-x));
}
// implementing the integral to infinity function with
// the sigmoid function
double integralToInfinity( RealFunction& f,
double x,
int nPoints) {
class SigmoidInfusedFunction : public RealFunction {
public:
SigmoidInfusedFunction(RealFunction& f) :
f(f) {
}
RealFunction &f;
double evaluate(double x) {
// d(sig)/dx = exp(-x) / pow(1+exp(-x),2)
return f.evaluate(sigmoidFunction(x)) * exp(-x) / pow(1+exp(-x),2);
}
};
SigmoidInfusedFunction sigmoidInfusedFunc(f);
return integral(sigmoidInfusedFunc, sigmoidFunction(x), 1, 1000);
}
int main() {
// Test for integrate - result: 0.95004 expected: 0.95 (CORRECT)
NormPDF normPDF;
cout << integral(normPDF, -1.96, 1.96, 1000) << endl;
// Test for infinity - result: 0.0688965 expected: 0.5 (INCORRECT)
cout << integralToInfinity(normPDF, 0, 1000) << endl;
return 0;
}

How do I call a function from a given class in a different class

I want to declare a function in one class and run it in a different one.Below is the implementation of my class
#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int myNo = 1 + rand () % 10;
class Point {
protected: int x; int y;
Point() {
x = myNo;
y = myNo;
}
float distanceBetweenMeAndAnotherPoint (Point anotherPoint){
float xyz = sqrt(pow((x-x),2) + pow((y-y),2));
return xyz;
}
};
class Circle : public Point {
private:
int radius;
Circle(int x, int y){
radius=myNo;
}
public:
printCircleInfo(){
cout << x << " " << y << " " << radius << " ";
return 1;
}Point Obj;
bool doIBumpIntoAnotherCircle (Circle anotherCircle){
if (radius + radius >=Obj.distanceBetweenMeAndAnotherPoint)
return true;
else
return false;
}
};
What should I replace Obj.distanceBetweenMeAndAnotherPoint with in order to call the function in this class?
Please provide an example in your answer. Thank you for your time.
You should use the parameter that you get, like this:
float distanceBetweenMeAndAnotherPoint (Point anotherPoint){
float dist = sqrt(pow((x-anotherPoint.x),2) + pow((y-anotherPoint.y),2));
return dist;
}
Also for the bump method, use the parameter that you get. And additionally simplify boolean return value, no need for the if-else. Resulting with something like:
bool doIBumpIntoAnotherCircle (Circle anotherCircle) {
return distanceBetweenMeAndAnotherPoint(anotherCircle)
<= (radius + anotherCircle.radius);
}
Note also that constructors should usually (though not necessarily) be public. In your case, the ctor of both classes, Point and Circle, should most likely be public and not private or protected to allow creation of objects of these types in your main.

Point, square, and cube program help on C++

I've been writing a program for CS class that's supposed to get the X and Y coordinates from the user, as well as the length of a square and the height of the cube, and it should then calculate the area of the square and the surface area and volume of the cube (plus some coordinates stuff but that's not a pressing issue right now)
I've written the test file and it compiled successfully, but I've been getting very long answers for the square and cube properties that are obviously wrong. Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?
Point.h
class Point
{
protected:
double Xint, Yint;
public:
Point();
void setX(double);
void setY(double);
double getX() const;
double getY() const;
};
Point.ccp
Point::Point()
{
Xint = 0;
Yint = 0;
}
void Point::setX(double x)
{ Xint = x; }
void Point::setY(double y)
{ Yint = y; }
double Point::getX() const
{ return Xint; }
double Point::getY() const
{ return Yint; }
Square.h
#include "Point.h"
class Square : public Point
{
protected:
Point lowerLeft;
double sideLength;
public:
Square(double sideLength, double x, double y) : Point()
{
sideLength = 0.0;
x = 0.0;
y = 0.0;
}
void setLowerLeft(double, double);
void setSideLength(double);
double getSideLength() const;
double getSquareArea() const;
};
Square.ccp
#include "Square.h"
void Square::setLowerLeft(double x, double y)
{
lowerLeft.setX(x);
lowerLeft.setY(y);
}
void Square::setSideLength(double SL)
{ sideLength = SL; }
double Square::getSideLength() const
{ return sideLength; }
// Calculate the area of square
double Square::getSquareArea() const
{ return sideLength * sideLength; }
Cube.h
#include "Square.h"
class Cube : public Square
{
protected:
double height;
double volume;
public:
Cube(double height, double volume) : Square(sideLength, Xint, Yint)
{
height = 0.0;
volume = 0.0;
}
double getSurfaceArea() const;
double getVolume() const;
};
Cube.ccp
#include "Cube.h"
// Redefine GetSquareArea to calculate the cube's surface area
double Cube::getSurfaceArea() const
{ return Square::getSquareArea() * 6; }
// Calculate the volume
double Cube::getVolume() const
{ return getSquareArea() * height; }
"Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?"
Well, from our well known 3-dimensional geometry a cube is made up from exactly 6 squares.
So how do you think inheriting a Cube class from a Square actually should work well?
You can easily define a Cube class by means of a fixed Point (e.g. the upper, left, front corner) and a fixed size of the edge length.
If you really want and need to, you can add a convenience function for your Cube class, that returns all of the 6 Squares it consist of in 3 dimensional space:
class Cube {
public:
Cube(const Point& upperLeftFrontCorner, double edgeLength);
std::array<Square,6> getSides() const;
};

C++ inheritance (overriding constructors)

I am learning OpenGL w/ C++. I am building the asteroids game as an exercise. I'm not quite sure how to override the constructors:
projectile.h
class projectile
{
protected:
float x;
float y;
public:
projectile();
projectile(float, float);
float get_x() const;
float get_y() const;
void move();
};
projectile.cpp
projectile::projectile()
{
x = 0.0f;
y = 0.0f;
}
projectile::projectile(float X, float Y)
{
x = X;
y = Y;
}
float projectile::get_x() const
{
return x;
}
float projectile::get_y() const
{
return y;
}
void projectile::move()
{
x += 0.5f;
y += 0.5f;
}
asteroid.h
#include "projectile.h"
class asteroid : public projectile
{
float radius;
public:
asteroid();
asteroid(float X, float Y);
float get_radius();
};
main.cpp
#include <iostream>
#include "asteroid.h"
using namespace std;
int main()
{
asteroid a(1.0f, 2.0f);
cout << a.get_x() << endl;
cout << a.get_y() << endl;
}
error I'm getting:
main.cpp:(.text+0x20): undefined reference to `asteroid::asteroid(float, float)'
You can use the : syntax to call the parent's constructor:
asteroid(float X, float Y) : projectile (x ,y);
Ok, just figured it out.
I actually don't have asteroid constructors defined because I thought they would inherit. But I think I have to do the following in asteroid.h:
asteroid(float X, float Y) : projectile(X, Y){];
You need a asteroid.cpp.
Even though inheriting from projectile, for non-default constructors (i.e., asteroid(float,float)), you still need to define the child class constructor.
You'll also need to define get_radius, as it's not defined in your base class.
Here's how that might look (I've taken the liberty of passing values for radius into both ctors):
#include "asteroid.h"
asteroid::asteroid(float r)
: projectile()
{
radius = r;
}
asteroid::asteroid(float x, float y, float r)
: projectile(x, y)
{
radius = r;
}
float asteroid::get_radius()
{
return radius;
}