Structures for dummies - c++

I'm studying structures in C++... I understood the basic concept of it and as far as I know the are meant to list a series of items in a more compact way.... however I came across an example where I don't understand what's going on:
struct cuComplex {
float r; // real part of a complex number
float i; // imaginary part of a complex number
/* !!! I DON'T UNDERSTAND FROM HERE !!! */
cuComplex( float a, float b ) : r(a), i(b) {}
float magnitude2( void ) { return r * r + i * i; }
cuComplex operator*(const cuComplex& a) {
return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
}
cuComplex operator+(const cuComplex& a) {
return cuComplex(r+a.r, i+a.i);
}
/* !!! TO HERE. !!! */
};
It seems to me that some sort of function is defined inside but I don't understand how that is possible and how I should interpret it.
Q. Is there some reference where I can read about this in order to have a better idea of what is going on?

struct in C++ is basically the same as classes with one difference. In class defualt access specifier is private whereas in struct it's public.
So what you're seeing in that code are:-
constructors, overloaded operators +,* for you struct and a method to compute magnitude of a complex number.

This is like a class, with the exception of default member protection, and it has member variables r and i, read here for more: http://www.cplusplus.com/doc/tutorial/classes/
struct cuComplex {
float r;
float i; // imaginary part of a complex number
This is a constructor, read here for more: http://www.cplusplus.com/doc/tutorial/classes/#constructors
cuComplex( float a, float b ) : r(a), i(b) {}
This is a method or member function, if you've made it through the first like you've read about that, but if you want a more concise example read here: http://en.wikipedia.org/wiki/C%2B%2B_classes#Member_functions
float magnitude2( void ) { return r * r + i * i; }
These are overloaded operators read here for more: http://www.cplusplus.com/doc/tutorial/templates/#overloading_operators
cuComplex operator*(const cuComplex& a) {
return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
}
cuComplex operator+(const cuComplex& a) {
return cuComplex(r+a.r, i+a.i);
}
};
If you have a specific question beyond this, you can comment on this post and I'll try to help explain.

Related

How to access to subsequence of a valarray considering it as a 2D matrix in C++

I'm learning C++, so please be patient with me.
I have a std::valarray in which there are double elements and I consider it as a 2D matrix.
class Matrix {
valarray<double> elems;
int r, c;
public:
/* type? operator[](int r) { return ? } */
//...
}
I want to overload the operator[], so that I can get a row of the matrix, and after that, I want have the m[r][c] access operator.
Is there any way to get a row, as a sequence of double using std::slice in the valarray, so that if I change a value, it is changed also in the matrix?
I've read this definition in valarray:
std::slice_array<T> operator[]( std::slice slicearr );
My operator[] must have std::slice_array<double>& as returned type?
Thanks.
I don't think std::slice and std::slice_array is what you're looking for, especially the latter is nothing but a helper type with a very limited public interface. You can instead return an proxy object. Here's a possible example of how to implement that.
class Matrix {
/* ... */
class RowProxy {
public:
RowProxy(std::valarray<double>& elems, int c, int row) :
elems(elems), c(c), row(row) {}
double& operator[](int j)
{
return elems[row*c + j];
}
private:
std::valarray<double>& elems;
int row;
int c;
};
RowProxy operator[](int i)
{
return RowProxy(elems, c, i);
}
};
This way, you can access the data with two operator[].
Matrix m(2, 4); // Assuming the ctor initializes elemens with row*column
m[0][0] = 1.234;
m[1][0] = 2.234;
m[1][3] = -52.023;
Note that both Matrix and RowProxy are missing overloads and proper handling for const-ness, and variable names are poor. Also, you might want to think about an out-of-bounds error handling strategy. But it may serve as a starting point for your implementation.

Adding two complex numbers using classes

So, I have found this code in a book:
class complex
{
public:
float x,y;
complex(float a, float b) // CONSTRUCTOR
{
x=a; y=b;
}
complex sum (complex z)
{
***complex c;*** // i get the error here
c.x=x+z.x;
c.y=y+z.y;
return c;
}
};
This code is supposed to help me sum 2 complex numbers, like this:
int main ()
{
complex a(1,2),b(1,1),c; // first number in paranthesis is the real part, the
// second one is the imaginary part
c=a.sum(b) ; // c should get the value of a+b (c.x=2, c.y=3)
return 0;
}
But everytime I try to compile it I get this error:
"no matching function for call to complex::complex()"
Why? What should I do ?
You defined your own constructor, therefore the default constructor is defined as complex() = delete;. You either need your own constructor or force the default one to be created
class complex
{
public:
float x = 0;
float y = 0;
complex() = default; // Compiler will generate the default constructor
complex(float a, float b): x(a), y(b) {}
complex sum (complex z)
{
complex c;
c.x=x+z.x;
c.y=y+z.y;
return c;
}
};
Instead of creating sum member function, I would create non-member operator+
// No need to make it friend because you declared x and y as public
complex operator+(complex const& a, complex const& b) {
return complex(a.x + b.x, a.y + b.y);
}
and use it like this
complex a(3, 4), b(5, 6);
complex c = a + b;

Easily convert between different geometry classes in c++?

I work in robotics, which means I use a large number of open-source projects dealing with 3D geometry. Since the classes and math tend to be fairly simple, everyone seems to implement their own version of Vector3D, Quaternion, etc., each with slight variations, e.g. vec.x, vec.X, vec.x(). So within one project, one might need to convert between Eigen, ROS, Assimp, Bullet, and other versions of the same basic classes. Is there an easy or elegant way to do this in C++ that doesn't require an n^2 mapping from every library to every other library?
Similar to: This SO question, but I can't edit any of the source libraries.
Example:
namespace a
{
class Vector
{
public:
double x, y, z;
};
} // namespace a
namespace b
{
class Vector
{
public:
double X, Y, Z;
};
} // namespace b
namespace c
{
class Vector
{
public:
double& x() { return mx; }
double& y() { return my; }
double& z() { return mz; }
private:
double mx, my, mz;
};
} // namespace c
int main()
{
a::Vector va;
b::Vector vb;
c::Vector vc = va + vb; // Ideal, but probably unrealistic goal
return 0;
}
EDIT:
If there are ~10 different geometry libraries, a particular project may only use 2-4 of them, so I'd like to avoid introducing a dependency on all the unused libraries. I was hoping for something like static_cast<b::Vec>(a::Vec), or maybe
c::Vec vc = my_cvt<c::Vec>(vb + my_cvt<b::Vec>(va));
but my understanding of templates and type_traits is pretty weak.
If you write three helper functions for each vector type to access X, Y and Z:
double X(const a::Vector& v) { return v.x; }
double Y(const a::Vector& v) { return v.y; }
double Z(const a::Vector& v) { return v.z; }
double X(const c::Vector& v) { return v.x(); }
double Y(const c::Vector& v) { return v.y(); }
//...
then you can easily write template functions that work with any type. e.g:
template<typename V1, typename V2>
V1 operator+(const V1& v1, const V2& v2) {
return {X(v1)+X(v2), Y(v1)+Y(v2), Z(v1)+Z(v2)};
}
template<typename V1, typename V2>
V1 convert(const V2& v) {
return {X(v), Y(v), Z(v)};
}
int main() {
a::Vector va;
b::Vector vb;
auto vc = convert<c::Vector>(va + vb);
}
Live demo.
Well, just define a operator+ function and your 'unrealistic goals' would be achieved:
c::Vector operator+(const a::Vector& a, const b::Vector& b) {
return {a.x+b.X, a.y+b.Y, a.z+b.Z};
}
And your small code snippet will work.
EDIT
If you do not want to define a hell lot of function, and assuming you can't change the Vector version from a and b, modifiy your vector class by adding these constructors:
Vector(a::Vector a) : mx(a.x), my(a.y), mz(a.z) {}
Vector(b::Vector b) : mx(b.X), my(b.Y), mz(b.Z) {}
And then define only one operator dealing only with the c class:
c::Vector operator+(c::Vector a, c::Vector b) {
return {a.x()+b.x(), a.y()+b.y(), a.z()+b.z()};
}
And your code snippet will work with declaring thousands of operator
EDIT 2
If you want your type to be compatible with your library's types you may add conversion operator to your struct, example, if you want your type to be convertible with Vector a, add this function inside your class:
operator a::Vector() const {
// return a a::Vector from our c::Vector
return a::Vector{mx, my, mz};
}
I see that this is an old question but check out Boost QVM.

overloading operator for linear algebra

I want to implement the Euler method in two dimensions and I don´t want to use any library (for practice).
Therefore I want to use my own linear algebra with overloaded functions.
The two first overloads seem to work but there´s still a problem with the multiplication matrix * vector i.e a (2x2)*(2x1).
class vector{
public:
double a;
double b;
vector::vector();
vector::vector(double a, double b){
this->a = a;
this->b = b;
};
vector operator+(vector &a);
vector operator*(double factor);
vector operator*(matrix &B);
};
class matrix{
public:
double a1;
double a2;
double b1;
double b2;
matrix::matrix();
matrix::matrix(double a1, double a2, double b1, double b2) {
this->a1 = a1;
this->a2 = a2;
this->b1 = b1;
this->b2 = b2;
};
};
vector vector::operator+(vector& v){
return vector(this->a+v.a,this->b+v.b);
};
vector vector::operator*(double factor){
return vector(this->a*factor, this->b*factor);
};
vector vector::operator*(matrix& B){
vector newv(this->a*B.a1 + B.a2*b, this->a*B.a1 + B.b2*b);
return newv;
};
Errors when I compile it:
'vector vector::operator *(matrix &)' : overloaded member function not found in 'vector'
unable to resolve function overload
Since you're a bit short on details, I must fill in the gap with guesses. My guess is that you try to support something like the following:
matrix m;
vector v, w;
// fill m and v with values
w = m*v;
I'm also guessing that your matrix has the following form:
( a1 a2 )
( b1 b2 )
You now have two options: Either implement matrix-vector multiplication in the class matrix, or implement it as a free function.
If you want to put if in the matrix class, you'd change the code as follows (note that there are many more things for the code that should be changed, but those are unrelated to the question):
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// all that's already in the class
vector operator*(vector const& v) const;
};
vector matrix::operator*(vector const& v) const
{
return vector(a1*v.a + a2*v.b, b1*v.a + b2*v.b);
}
// the rest of your code
If you want to make it a free function (I personally would do it that way, but I'm sure that opinion is not universally held), you'd write
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// completely unchanged
};
vector operator*(matrix const& m, vector const& v)
{
return vector(m.a1*v.a + m.a2*v.b, m.b1*v.a + m.b2*v.b);
}
// the rest of your code
I would prefer a BLAS library as an implementation in long term against reinvent the wheel again for basic matrix operations. Additionally some of the BLAS libraries are multithreaded and/or GPU based; they are widely used and tested.
In terms of design I would introduce functions what could be easily implemented by BLAS against operators:
C = α * A + β * B
C = α * A * B + β *C
So as a header:
...
bool blasAdd(const double alfa_, const Matrix& A_, const double beta_, const Matrix& B_, Matrix& C_);
bool blasMultiply(const double alfa_, const Matrix& A_, const Matrix& B_, const double beta_, Matrix& C_);
...
In this way your code automatically could be optimized for BLAS.
My favorite BLAS implementation is Intel MKL, but there are also many free BLAS implementations in the market (e.g.: boost BLAS).

How to evaluate a function directly?

Title may not make any sense but I dont really know how to explain this.
I have a class called polynomial and lets say I defined a polynome called p1 which is 2x+4. What I want to do is calculate p1(5) directly. I dont want anything like double calculate (polynomial) etc I want to be able to calculate my polynom with p1(x).
I hope my question is clear
Overload the function-call operator:
struct polynomial
{
double a, b;
polynomial(double m, double n) : a(m), b(n) { } // represents "a * x + b"
double operator()(double x) const
{
return a * x + b;
}
};
Usage:
polynomial p(2.5, 3.8);
double val = p(1.0);
By overloading operator() you can "call" an object just like you would call a function:
struct polynomial {
int operator()(int x)
{
/* calculate */
}
};
int main()
{
polynomial p;
int x = p(5);
}