I have written three dimensional integration code which calls a gaussian quadrature routine to do the integration as shown below:
#include <iostream>
#include <cmath>
using namespace std;
float qgaus(float (*func)(float), float a, float b)
{
int j;
float xr,xm,dx,s;
static float x[]={0.0,0.1488743389,0.4333953941,
0.6794095682,0.8650633666,0.9739065285};
static float w[]={0.0,0.2955242247,0.2692667193,
0.2190863625,0.1494513491,0.0666713443};
xm = 0.5*(b+a);
xr = 0.5*(b-a);
s = 0;
for (j=1;j<=5;j++)
{
dx=xr*x[j];
s += w[j]*((*func)(xm+dx)+(*func)(xm-dx));
}
return s *= xr;
}
float func(float x,float y,float z)
{
float f = x*y*z;
return f;
}
float yy1(float x)
{
float y = x;
return y;
}
float yy2(float x)
{
float y = 2*x;
return y;
}
float z1(float x,float y)
{
float z = 5*x*y;
return z;
}
float z2(float x,float y)
{
float z = 10*x*x*y;
return z;
}
static float xsav,ysav;
static float (*nrfunc)(float,float,float);
float quad3d(float (*func)(float, float, float), float x1, float x2)
{
float qgaus(float (*func)(float), float a, float b);
float f1(float x);
nrfunc=func;
return qgaus(f1,x1,x2);
}
float f1(float x)
{
float qgaus(float (*func)(float), float a, float b);
float f2(float y);
float yy1(float),yy2(float);
xsav=x;
return qgaus(f2,yy1(x),yy2(x));
}
float f2(float y)
{
float qgaus(float (*func)(float), float a, float b);
float f3(float z);
float z1(float,float),z2(float,float);
ysav = y;
return qgaus(f3,z1(xsav,y),z2(xsav,y));
}
float f3(float z)
{
return (*nrfunc)(xsav,ysav,z);
}
int main ()
{
float R;
R = quad3d(func, 0, 1);
cout << R << endl;
}
This code works perfectly for any three dimensional function I have tested it with. I have attempted to modify it to compute a four dimensional function by replacing the 3d routine with a 4d one:
static float wsav,xsav,ysav;
static float (*nrfunc)(float,float,float,float);
float quad4d(float (*func)(float, float, float, float), float w1, float w2)
{
float qtrap(float (*func)(float), float a, float b);
float f1(float w);
nrfunc=func;
return qtrap(f1,w1,w2);
}
float f1(float w)
{
float qtrap(float (*func)(float), float a, float b);
float f2(float x);
float x1(float),x2(float);
wsav = w;
return qtrap(f2,x1(w),x2(w));
}
float f2(float x)
{
float qtrap(float (*func)(float), float a, float b);
float f3(float y);
float yy1(float,float),yy2(float,float);
xsav = x;
return qtrap(f2,yy1(wsav,x),yy2(wsav,x));
}
float f3(float y)
{
float qtrap(float (*func)(float), float a, float b);
float f4(float z);
float z1(float,float,float),z2(float,float,float);
ysav = y;
return qtrap(f3,z1(wsav,xsav,y),z2(wsav,xsav,y));
}
float f4(float z)
{
float t = (*nrfunc)(wsav,xsav,ysav,z);
return t;
}
This code compiles correctly, but will output "Segmentation fault: 11" when I run it. From what I understand, this implies that there is either some sort of problem with the arrays or a memory allocation error, but neither seem to make sense since there was no problem with the 3d case. Any help with this would be greatly appreciated.
Related
I'm trying to write a class for the UnitVector, having already written the one for a generic Vector. The UnitVector class diverges from the Vector class only by the fact that the abs variable is set to 1.0f. I'd like to know what the best approach to the problem would be, whether it's better to make another class, UnitVector, that inherits the Vector class (my current idea, that's giving me problems) or to just write a method in the Vector class
Here's my code for the class Vector:
Vector.h
class Vector
{
public:
Vector();
Vector(float x, float y);
void set_by_angle(float abs, float angle);
void set(float x, float y);
void rotate(float angle);
void scale(float scale_factor);
void translate(float x, float y);
void translate(Vector v);
float get_abs();
float get_angle();
static Vector create_by_angle(float abs, float angle);
static Vector create(float x, float y);
static Vector create_from_vectors(Vector v1, Vector v2, float abs);
static float get_distance(Vector v1, Vector v2);
static float get_angle(float x, float y);
static float get_angle(Vector v);
void to_string();
Vector operator=(const Vector &v);
bool operator==(const Vector &v);
bool operator!=(const Vector &v);
Vector operator+=(const Vector &v);
friend Vector operator+(const Vector &v1, const Vector &v2);
friend Vector operator-(const Vector &v1, const Vector &v2);
float x;
float y;
private:
float abs;
float angle;
};
Vector.cpp
#define _USE_MATH_DEFINES
#include <math.h>
#include <iostream>
#include <string>
#include "vector.h"
using namespace std;
Vector::Vector() : Vector(0, 0) {}
Vector::Vector(float x, float y)
{
set(x, y);
}
void Vector::set_by_angle(float abs, float angle)
{
this->abs = abs;
this->angle = angle;
x = abs * cos(angle);
y = abs * sin(angle);
}
void Vector::set(float x, float y)
{
this->x = x;
this->y = y;
abs = get_abs();
angle = get_angle();
}
void Vector::rotate(float angle)
{
set_by_angle(this->abs, this->angle + angle);
}
void Vector::scale(float scale_factor)
{
set(x * scale_factor, y * scale_factor);
}
void Vector::translate(float x, float y)
{
set(this->x + x, this->y + y);
}
void Vector::translate(Vector v)
{
translate(v.x, v.y);
}
float Vector::get_abs()
{
return sqrt(pow(x, 2) + pow(y, 2));
}
float Vector::get_angle()
{
return get_angle(x, y);
}
Vector Vector::create_by_angle(float abs, float angle)
{
Vector v;
v.set_by_angle(abs, angle);
return v;
}
Vector Vector::create(float x, float y)
{
Vector v;
v.set(x, y);
return v;
}
float Vector::get_distance(Vector v1, Vector v2)
{
return sqrt(pow(v1.x - v2.x, 2) + pow(v1.y - v2.y, 2));
}
Vector Vector::create_from_vectors(Vector v1, Vector v2, float abs)
{
float x = v2.x - v1.x;
float y = v2.y - v1.y;
Vector v;
v.set_by_angle(abs, Vector(x, y).get_angle());
return v;
}
float Vector::get_angle(float x, float y)
{
float tan = 0.0f;
float angle = 0.0f;
if (x != 0)
{
tan = y / x;
angle = atan(tan);
// this setting applies to the graphic reference system
if (x > 0 && y < 0) angle = 2 * M_PI + angle;
if (x < 0 && y > 0) angle += M_PI;
if (x < 0 && y < 0) angle += M_PI;
}
if (x == 0)
{
if (y > 0) angle = M_PI_2;
if (y < 0) angle = 3 * M_PI_2;
}
if (y == 0)
{
if (x > 0) angle = 0.0f;
if (x < 0) angle = M_PI;
}
return angle;
}
float Vector::get_angle(Vector v)
{
return get_angle(v.x, v.y);
}
void Vector::to_string()
{
cout << "x: " + std::to_string(x) + " y: " + std::to_string(y) << endl;
}
Vector operator+(const Vector &v1, const Vector &v2)
{
Vector tmp;
tmp.set(v1.x + v2.x, v1.y + v2.y);
return tmp;
}
Vector operator-(const Vector &v1, const Vector &v2)
{
return v1 + Vector(-v2.x, -v2.y);
}
Vector Vector::operator+=(const Vector &v)
{
set(x + v.x, y + v.y);
return *this;
}
Vector Vector::operator=(const Vector &v)
{
set(v.x, v.y);
return *this;
}
bool Vector::operator==(const Vector &v)
{
return
(
(x == v.x)
&&
(y == v.y)
);
}
bool Vector::operator!=(const Vector &v)
{
return !(*this == v);
}
Thanks in advance!
Just add the following two methods:
void normalize()
{
float scalar = 1.0 / this->get_abs();
this->x *= scalar;
this->y *= scalar;
}
And:
static Vector get_unit(const Vector &v)
{
float scalar = 1.0 / v.get_abs();
return Vector(v.x * scalar, v.y * scalar);
}
I am supposed to write a program which has to generate a triangle function, calculate the derivative using forward and backward divided differences and differentiate the triangle function.
So, I wrote some code and have only one problem:
include\MyClass.h|12|note: no known conversion for argument 1 from 'float (MyClass::)(int, float, float)' to 'float ()(int, float, float)'|
My code:
main.cpp
#include <iostream>
#include "MyClass.h"
using namespace std;
int main()
{
MyClass object (3,4,2,0.1);
for (float i=object.x; i<2.5; i+=0.01)
{
cout << object.Triangle(10, 3.14, i) << " ";
}
cout << "////////////////////";
for (float i=object.x; i<2.5; i+=0.01)
{
cout << object.Derivative(&object.Triangle, i, object.con) << " ";
}
}
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
MyClass();
MyClass(int k_max, float omega, float x, float con);
~MyClass();
float Triangle (int k_max, float omega, float x);
float Derivative (float (*w) (int k_max, float omega, float x), float var, float con);
float DerivativeCntr (float (*w) (int k_max, float omega, float x), float var, float con);
int k_max;
float omega, x, result, con;
};
#endif // MYCLASS_H
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass() {}
MyClass::~MyClass() {}
MyClass(int K_max, float Omega, float X, float Con)
{
k_max=K_max;
omega=Omega;
x=X;
con=Con;
}
///////////////////////////////////////////////
float Triangle (int k_max, float omega, float x)
{
result=0;
for int (i=0; i<=k_max; i++)
{
result += ( 8*pow(-1, i)*(sin((2*i+1)*omega*x ) / ( pow(2*i+1, 2) * pow(M_PI, 2) )
}
return result;
}
///////////////////////////////////////////////
float Derivative (float (*w) (int k_max, float omega, float x), float var, float con)
{
float result = (w(10, 3.14, var+con) - w(10, 3.14, var))/var;
return result;
}
///////////////////////////////////////////////
float DerivativeCntr (float (*w) (int k_max, float omega, float x), float var, float con)
{
float result=(w(10, 3.14, var)-w(10, 3.14, var-con))/2*var;
return result;
}
I would really appreciate your help, thanks!
EDIT:
I've got this program working, but it's recommended to use a class and required to use a pointer to the function. That's my non object-oriented code:
https://ideone.com/mtPLAo
You have several errors of syntactical nature in your code.
In MyClass.h, change into
float Derivative (float *w, int k_max, float omega, float x, float var, float con);
float DerivativeCntr (float *w, int k_max, float omega, float x, float var, float con);
In MyClass.cpp, all member functions should be prefixed by MyClass:: and also the same for the constructor that takes arguments.
In order to integrate a two dimensional function of the form
$$\int_{1}^\infty \int_{-\sqrt{x^2-1}}^{\sqrt{x^2-1}} e^{-x} \rm{d}y \rm{d}x,$$
I have been attempting to use the following code (written in C++) taken mostly from the Numerical Recipes book which calls a gaussian quadrature routine for the integration:
static float xsav;
static float (*nrfunc)(float,float);
float quad2d(float (*func)(float, float), float x1, float x2)
{
float qgaus(float (*func)(float), float a, float b);
float f1(float x);
nrfunc=func;
return qgaus(f1,x1,x2);
}
float f1(float x)
{
float qgaus(float (*func)(float), float a, float b);
float f2(float y);
float yy1(float),yy2(float);
xsav=x;
return qgaus(f2,yy1(x),yy2(x));
}
float f2(float y)
{
return (*nrfunc)(xsav,y);
}
This code works fine for two dimensional integrals with finite limits, but fails as the outer limit is taken to infinity. To account for this, I have attempted to use a change of variables:
#define FUNC(x) ((*funk)(-log(x))/(x))
float qgaus(float (*funk)(float), float aa, float bb)
{
int j;
float xr,xm,dx,s,a,b;
b=exp(-aa);
a=0.0;
static float x[]={0.0,0.1488743389,0.4333953941,
0.6794095682,0.8650633666,0.9739065285};
static float w[]={0.0,0.2955242247,0.2692667193,
0.2190863625,0.1494513491,0.0666713443};
xm=0.5*(b+a);
xr=0.5*(b-a);
s=0;
for (j=1;j<=5;j++)
{
dx=xr*x[j];
s += w[j]*(FUNC(xm+dx)+FUNC(xm-dx));
}
return s *= xr;
}
float f(float x, float y)
{
float a = exp(-x);
return a;
}
float yy1(float x)
{
float y = -sqrt(x*x-1);
return y;
}
float yy2(float x)
{
float y = sqrt(x*x-1);
return y;
}
static float xsav;
static float (*nrfunc)(float, float);
float quad2d(float (*func)(float, float), float x1, float x2)
{
float qgaus(float (*func)(float), float aa, float bb);
float f1(float x);
nrfunc=func;
float t = qgaus(f1,x1,x2);
return t;
}
float f1(float x)
{
float qgaus(float (*func)(float), float aa, float bb);
float f2(float y);
float yy1(float);
float yy2(float);
xsav=x;
float r = qgaus(f2,yy1(x),yy2(x));
return r;
}
float f2(float y)
{
float k = (*nrfunc)(xsav,y);
return k;
}
int main ()
{
float z;
z = quad2d(f, 1.0, 20.0);
cout << z << endl;
}
but this still doesn't give the right answer. It should be
$2 \times \rm{BesselK}[1,1] \approx 1.20381$
but instead gives
2.15501
Any suggestions on how I could modify this code to account for the infinite limit would be greatly appreciated!
Ok, so I'd like to input a one-letter character and three numbers into a structure using scanf, and I want to print all four of them by using a function that prints it. But everytime i run it i get errors saying that i can't run it, or sometimes it prints everything right except the character part, where it would just go as blank.. what could be possibly wrong with this??
#include <stdio.h>
struct Score
{
char a;
float x, y, z;
};
void main(void)
{
void avg(char *a, float x, float y, float z);
char a1 = 'b';
float x1 = 0, y1 = 0, z1 = 0;
printf("enter an alphaber\n");
fflush(stdin);
scanf_s("%c", &a1);
printf("enter three numbers (ex:1,2,3)\n");
fflush(stdin);
scanf_s("%f,%f,%f", &x1, &y1, &z1);
struct Score s1 = { a1, x1, y1, z1 };
avg(s1.a, s1.x, s1.y, s1.z);
}
void avg(char *a, float x, float y, float z)
{
printf("%c (%f,%f,%f) \n", a, x, y, z);
}
The signature of avg() is wrong. The first argument should be not char* but char.
Because I hate MSVC-specific code, your code should be like this.
Note that you should check whether readings are successful.
#include <stdio.h>
struct Score
{
char a;
float x, y, z;
};
int main(void)
{
/* declareing function inside function is unusual, but not bad */
void avg(char a, float x, float y, float z);
char a1 = 'b';
float x1 = 0, y1 = 0, z1 = 0;
printf("enter an alphaber\n");
if (scanf("%c", &a1) != 1) {
puts("read error");
return 1;
}
printf("enter three numbers (ex:1,2,3)\n");
if (scanf("%f,%f,%f", &x1, &y1, &z1) != 3) {
puts("read error");
return 1;
}
struct Score s1 = { a1, x1, y1, z1 };
avg(s1.a, s1.x, s1.y, s1.z);
}
void avg(char a, float x, float y, float z)
{
printf("%c (%f,%f,%f) \n", a, x, y, z);
}
I have a vector class with a properly overloaded Vect*float operator and am trying to create the global/non-member float*Vect operator as follows: (Note this is a heavily edited sample)
class Vect
{
public:
Vect::Vect(const float p_x, const float p_y, const float p_z, const float p_w);
Vect operator*(const float p_sclr) const;
private:
float x;
float y;
float z;
float w;
};
Vect::Vect(const float p_x, const float p_y, const float p_z, const float p_w) {
x = p_x;
y = p_y;
z = p_z;
w = p_w;
}
Vect Vect::operator*(const float p_sclr) const {
return Vect( (x * p_sclr), (y * p_sclr), (z * p_sclr), 1); // reset w to 1
}
//Problem Non-MemberOperator
Vect operator*(const float p_sclr, const Vect& p_vect);
Vect operator*(const float p_sclr, const Vect& p_vect) {
return p_vect * p_sclr;
}
But when I go to test the operator with the call:
Vect A(2.0f, 3.0f, 4.0f, 5.0f);
float s = 5.0f;
Vect C, D;
C = A * s; // Fine
D = s * A; // Error as below
I receive the following compile error:
error C2678: binary '*' : no operator found which takes a left-hand operand of type 'float' (or there is no acceptable conversion)
Can anyone provide insight to why this happens? The MS documentation is available at http://msdn.microsoft.com/en-us/library/ys0bw32s(v=VS.90).aspx and isn't very helpful Visual Studio 2008. This is the only compile error or warning I receive.
You still havn't posted a complete example. I can compile the following code without any problems:
class vect
{
float coeffs[4];
public:
vect()
{
for (int k=0; k<4; ++k)
coeffs[k] = 0;
}
vect(float x, float y, float z, float w)
{
coeffs[0] = x;
coeffs[1] = y;
coeffs[2] = z;
coeffs[3] = w;
}
vect operator*(float scalar) const
{
return vect(
scalar*coeffs[0],
scalar*coeffs[1],
scalar*coeffs[2],
scalar*coeffs[3] );
}
};
vect operator*(float scalar, vect const& x)
{
return x*scalar;
}
void test()
{
vect a (2,3,4,5);
float s = 5;
vect c, d;
c = a * s;
d = s * a;
}
So, the problem must lie somewhere else.
I also can compile the code without any problems (like sellibitze, who beat me to it!)
Here's the code I used:
//main.cpp
#include <iostream>
using namespace std;
class Vect
{
public:
float x,y,z,w;
Vect(const float p_x, const float p_y, const float p_z, const float p_w) {
x = p_x;
y = p_y;
z = p_z;
w = p_w;
}
Vect()
{
x=y=z=w=0;
}
Vect operator*(const float p_sclr) const {
return Vect( (x * p_sclr), (y * p_sclr), (z * p_sclr), 1); // reset w to 1
}
};
Vect operator*(const float p_sclr, const Vect& p_vect) {
return p_vect * p_sclr;
}
int main()
{
Vect A(2.0f, 3.0f, 4.0f, 5.0f);
float s = 5.0f;
Vect C, D;
C = A * s; // Fine
D = s * A; // Error as below
cout << D.x << endl;
return 0;
}
Edit: Like sellibitze suggests, the problem may lie elsewhere. Is the error you're listing the ONLY error your compiler is giving you? Also, what version of Visual Studio are you running?
Looks like 2 beat me to it, but it worked for me too - built and ran fine (VS2010, Win32 console project):
class Vect
{
public:
float x,y,z,w;
Vect::Vect(){}
Vect::Vect(const float p_x, const float p_y, const float p_z, const float p_w)
{
x = p_x;
y = p_y;
z = p_z;
w = p_w;
}
Vect Vect::operator*(const float p_sclr) const
{
return Vect( (x * p_sclr), (y * p_sclr), (z * p_sclr), 1); // reset w to 1
}
};
Vect operator*(const float p_sclr, const Vect& p_vect) { return p_vect * p_sclr;}
int _tmain(int argc, _TCHAR* argv[])
{
Vect a (2,3,4,5);
float s = 5;
Vect c, d;
c = a * s;
d = s * a;
}
The final solution was to go with a friend function because the variables were in p_vect were private:
//class definition
friend Vect operator*(const float scale, const Vect& p_vect);
//function
Vect operator*(const float p_sclr, const Vect& p_vect) {
return Vect( (p_vect.x * p_sclr), (p_vect.y * p_sclr), (p_vect.z * p_sclr), 1.0f);
}