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).
Related
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;
I've created a class Complex for a complex number and the get/set methods to extract and change the real and imaginary part of the number. Now I want to sum and multiplicate two complex numbers, so I've created the following functions:
Complex somma(Complex a, Complex b) {
Complex c;
c.set_Rez(a.get_Rez()+b.get_Rez());
c.set_Imz(a.get_Imz()+b.get_Imz());
return c;
}
Complex prodotto(Complex a, Complex b) {
Complex c;
c.set_ro(a.get_ro()*b.get_ro());
c.set_fi(a.get_fi()+b.get_fi());
return c;
}
My question is if there is a way to have as an output of the functions a simple double if the inputs are doubles. Is it possible to give to the functions doubles and getting a double as a result?
My question is if there is a way to have as an output of the functions a simple double if the inputs are doubles. Is it possible to give to the functions doubles and getting a double as a result?
It sounds like you want the following overloads:
Complex somma(Complex a, Complex b);
Complex somma(Complex a, double b);
Complex somma(double a, Complex b);
double somma(double a, double b);
If there is converting constructor from a double to a Complex, you can simply use:
Complex somma(Complex a, Complex b);
double somma(double a, double b);
to get what you need. You need similar functions for prodotto
Complex prodotto(Complex a, Complex b);
double prodotto(double a, double b);
Overloading the functions somma and prodotto for Complex and double makes your code look more uniform. However, it will more idiomatic to overload operator+ and operator* for Complex.
Complex operator+(Complex const& lhs, Complex const& rhs) { ... }
Complex operator*(Complex const& lhs, Complex const& rhs) { ... }
Then you can use
Complex c1 = { ... };
Complex c2 = { ... };
Complex c3 = c1 + c2;
Complex c4 = c1 * c2;
Then, you don't have to worry about overloading somma and prodotto for double. You can just use + and * for objects of type Complex as well as type double.
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.
I have two classes a 3D vector class(Vector3) with an array of 3 floats as its member(float[3]), and a 3 by 3 matrix class that stores 3 of these vectors in another array(Vector3[3]). My vector class requires the matrix class to rotate about an axis, and my matrix class requires vectors for everything. I was using forward declarations and pointers to deal with it, like in this question: What is the best way to deal with co-dependent classes in C++?, but there must be a better way to design this to avoid that altogether. At the moment I declare a pointer to Vector3 on my matrix header file, and then initialize it with new in my implementation file, yet this feels clumsy. Any pointers(no pun) on how to solve this issue?
Edit: I use the vector class to represent a 3D point which I intend to rotate about an arbitrary axis.
The code as I would like it to work:
//Vector3.h
#include "Matrix3.h"
class Matrix3;
class Vector3 {
float xyz[3];
};
//Vector3.cpp
Vector3 Vector3::rotatePoint(Vector3 o, Vector3 a, float theta) {
Vector3 point = (*this);
Vector3 x = Vector3(1,0,0);
Vector3 y = Vector3(0,1,0);
Vector3 z = Vector3(0,0,1);
// Create new coordinate system
Vector3 new_coord[4];
new_coord[0] = o;
new_coord[1] = a.normalize();
unsigned closer_to;
if (a*x < a*y) {
new_coord[2] = (a % x).normalize();
closer_to = 0; // x
}
else {
new_coord[2] = (a % y).normalize();
closer_to = 1; // y
}
new_coord[3] = (a % new_coord[2]).normalize();
// Transform point to new coord system
Matrix3 trans_matrix = Matrix3(new_coord[0], new_coord[1], new_coord[2]);
point = trans_matrix*(point - o);
// Rotate about a by theta degrees
Matrix3 r_m(closer_to, theta);
point = r_m*point;
//Transform back to original coord system
point = (trans_matrix.inverse()*point) + o;
return point;
}
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 rows[3];
}
The code that I use to make it work:
//Vector3.h
class Matrix3;
class Vector3 {
float xyz[3];
};
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 *rows;
}
//Matrix3.cpp
Matrix3::Matrix3() {
rows = new V3[3];
}
I took the advice given by #n.m. and #Chris Dodd's and just removed the Matrix3 include from my Vector header, and into my Vector implementation file, like this:
//Vector3.h
class Vector3 {
float xyz[3];
}
//Vector.cpp
#include "Vector3.h"
#include "Matrix3.h"
//Matrix3.h
#include "Vector3.h"
class Vector3;
class Matrix3 {
Vector3 rows[3];
}
//Matrix3.cpp
#include "Matrix3.h"
Since you're dealing with vectors and matrices, you could define a single matrix class with templates for the dimensions (and maybe the element type) -- the vector class would then (depending on the type of vector) be a matrix with one of the dimension = 1. If you do this, you only end up with one class, one set of code and all the functionality required to do everything you want. You avoid any inter-class dependencies since you only have one class!
The class itself would look something like this:
template<unsigned m, unsigned n, typename T = float>
class matrix {
T e[m * n];
public:
T* operator [](unsigned i) { return e + i; }
T * const operator [](unsigned i) const { return e + i; }
/* repeat for -, *, / -- same pattern */
matrix<m,n>& operator += (matrix<m,n> const& a) {
for (unsigned i = 0; i < m * n; ++i) e[i] += a.e[i];
return *this;
}
};
You should then define any functions which does not take equal sized matrices outside the class (this is why we have the [] operator). Note that the * and / operators work on all elements and do not calculate the usual matrix-matrix multiplication or matrix-matrix division. Instead, you will want to have a invert function and a multiply function.
template<unsigned m, unsigned n, unsigned k>
matrix<m,k> const multiply(matrix<m,n> const& a, matrix<n,k> const& b);
template<unsigned m>
matrix<m,m> const invert(matrix<m,m> const&);
template<unsigned m, unsigned n>
matrix<n,m> const transpose(matrix<m,n> const&);
Note that, if you have a method for inverting a generic non-square matrix, of which I know none, the above template will only work for a square matrix. Filling in the code for the functions I leave to you as an exercise.
To get a 3 vector and a 3x3 matrix, you could typedef them as so:
typedef matrix<3,1,float> vector3f;
typedef matrix<3,3,float> matrix3x3f;
Remember to add comparison operators as well as anything else you need.
If you wish, you could add matrix-scalar and scalar-matrix operators and functions as well (to ease, say, adding a scalar to all the elements in a matrix).
If you want better control over the elements in the [] operators, you could use vectors as the base class and then define matrices as a vector of vectors. This will give you the same advantages but may suit your mindset more easily (a lot of people think of vectors and matrices as being distinct types).
I am doing an addition of matrices using classes.I have declared a class 'Matrix'.now i need to pass an object of Matrix to a function.how do i do that?
Actually, the best way (IMHO) is to overload operator+(). Thus in your code, you'll need to use only +:
class Matrix {
private:
// Your code
public:
// Your code
friend Matrix operator+(const Matrix &c1, const Matrix &c2);
}
friend Matrix operator+(const Matrix &c1, const Matrix &c2) { <--- passing by reference
// Your code to add matrices
}
int main() {
Matrix A, B;
Matrix C = A + B;
}
In the case of the passing by value Matrix sum(Matrix a, Matrix b), you will need to write a copy constructor if memory for matrix is allocated dynamically.
Passing by pointer Matrix sum(Matrix *a, Matrix *b) is a C style coding, so it is still correct, but not preferable for C++.
Matrix object;
// ...
f(object);
You have quite a few ways to do it.
By Value:
void func (Matrix m);
By Reference:
void func (Matrix& m);
Or By Pointer:
void func (Matrix* m);
Which one you use depends on your needs and semantics of the operation.