hey there i'm a student in computer science ,
we are asked to build a generic matrix using the vector class and we are not allowed to use "new" and "delete" at all.
I don't know how to start it properly we can use these libraries:
cassert
vector
cstdlib
cmath
I searched all over the Internet but didn't found a class that uses the vector as the matrix (index of matrix is mat[i*cols+j]) and doesn't use new and delete function or allocate memory:
examples of what we are supposed to check:(int google test)
"Matrix.hpp"
template < class T ><class T> class Matrix {
private:
int rows;
int cols;
vector< T > mat;
public:
Matrix(int row, int col,const T& mat2):rows(row),cols(col) {
mat.resize(rows*cols);
//?
};
Matrix(int row, int col);
virtual ~Matrix();
Matrix(const Matrix< T >& rhs);
Matrix< T > transpose();
Matrix< T >& operator=(const Matrix< T >& rhs);
bool operator==(const Matrix< T >& rhs)const;
const int getRowNum() const;
const int getColNum() const;
Matrix< T >& operator+(const Matrix< T >& rhs);
};
"gtest/gtest.h"
Matrix<int> mat1(1, 1, std::vector<int>(1,2));
EXPECT_EQ(1, mat1.getRowNum());
EXPECT_EQ(1, mat1.getColNum());
int t= 0;
EXPECT_TRUE(mat1.hasTrace(t));
EXPECT_TRUE(mat1.isSquareMatrix());
Matrix<int> transpose_mat= mat1;
EXPECT_EQ(transpose_mat, mat1.transpose());
Matrix<int> mat2(1, 1, std::vector<int>(1,3));
Matrix<int> add_mat(1, 1, std::vector<int> (1,5));
EXPECT_EQ(add_mat, mat1+mat2);
Matrix<int> multi_mat(1, 1, std::vector<int>(1,6));
EXPECT_EQ(multi_mat, mat1*mat2);
Matrix<int> scalar_multi_mat(1, 1, std::vector<int>(1,4));
EXPECT_EQ(scalar_multi_mat, mat1*2);
This is what we are supposed to do:
Matrix interface: You must define and implement the generic class file Matrix.hpp Matrix. The matrix will be generic and limbs will not necessarily integers but generic type numbers. For the purpose of due diligence, you Squirrels are entitled to assume that operators will have the necessary exercise as being above. Also you can assume the Squirrels be used in relation to the rest of the matrix are such that the order of the atomic steps of connecting or twice) a long chain of calculations (does not matter. For example (a + b) + c == a + (b + c) the exercise or functions that you can use the default language is given), all generically, of course (:
Constructor without parameters. The builder builds a matrix of 1x1 With organ is conducted T where T is the type that is stored in the matrix.
The constructor gets the number of rows, number of columns and the vector with the values of the matrix filling) saw the driver call this constructor does not realize, the department should be structured so that default is good enough
(Constructor Copy) copy constructor (a different matrix receiver) does not realize, the department should be structured so that default is good enough
(The assignment operator) do not realize, the department must be built so that default is good enough
Plus (+) operator to connect matrices.
Multiplication (*) operator matrix multiplication. Matrix of the object it does the function is left matrix multiplication.
(Swap function matrix) transpose
(Aqaba function) HasTrace (reference to the organ recipient generic type and a task which the value of the trace (if any) of the matrix and returns a Boolean value: true if a square matrix, and another false case put the value additive identity organ received about .reference
The four functions above) connection, transpose and HasTrace double (not from the object it was applied function. In addition, you can add more public functions or Privacy desired, according to what you think is useful to the department.
If someone can help me, I will be grateful!
You can start by considering that an NxM matrix can be represented as a vector with M*N elements. Operations such as addition and subtraction become simply equivalent to vector addition and subtraction.
More general operations, though will require a simple transformation to convert a matrix index [a, b] into a vector index [c].
Given a matrix index [a, b] you can find the corresponding vector element by using:
c = a*N + b
Similarly, converting from a vector index [c] to the matrix index [a, b] by:
a = c / N
b = c % N
Here the / and % are integer division and modulus.
template < class T ><class T> class Matrix {
private:
int rows;
int cols;
vector< T > mat;
public:
Matrix(int row, int col,const T& mat2):rows(row),cols(col) {
mat.resize(rows*cols);
//?
};
Matrix(int row, int col);
virtual ~Matrix();
Matrix(const Matrix< T >& rhs);
Matrix< T > transpose();
Matrix< T >& operator=(const Matrix< T >& rhs);
bool operator==(const Matrix< T >& rhs)const;
const int getRowNum() const;
const int getColNum() const;
Matrix< T >& operator+(const Matrix< T >& rhs);
};
Related
Given a vector of reals c and a vector of integers rw, I want to create a vector z with elements z_i=c_i^rw_i. I tried to do this using the component-wise function pow, but I get a compiler error.
#include <Eigen/Core>
typedef Eigen::VectorXd RealVector;
typedef Eigen::VectorXi IntVector; // dynamically-sized vector of integers
RealVector c; c << 2, 3, 4, 5;
IntVector rw; rw << 6, 7, 8, 9;
RealVector z = c.pow(rw); **compile error**
The compiler error is
error C2664: 'const Eigen::MatrixComplexPowerReturnValue<Derived> Eigen::MatrixBase<Derived>::pow(const std::complex<double> &) const': cannot convert argument 1 from 'IntVector' to 'const double &'
with
[
Derived=Eigen::Matrix<double,-1,1,0,-1,1>
]
c:\auc\sedanal\LammSolve.h(117): note: Reason: cannot convert from 'IntVector' to 'const double'
c:\auc\sedanal\LammSolve.h(117): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
What is wrong with this code? And, assuming it can be fixed, how would I do the same operation when c is a real matrix instead of a vector, to compute c_ij^b_i for all elements of c?
Compiler is Visual Studio 2015, running under 64-bit Windows 7.
First of all, MatrixBase::pow is a function that computes the matrix power of a square matrix (if the matrix has an eigenvalue decomposition, it is the same matrix, but with the eigenvalues raised to the given power).
What you want is an element-wise power, which since there is no cwisePow function in MatrixBase, requires switching to the Array-domain. Furthermore, there is no integer-specialization for the powers (this could be efficient, but only up to a certain threshold -- and checking for that threshold for every element would waste computation time), so you need to cast the exponents to the type of your matrix.
To also answer your bonus-question:
#include <iostream>
#include <Eigen/Core>
int main(int argc, char **argv) {
Eigen::MatrixXd A; A.setRandom(3,4);
Eigen::VectorXi b = (Eigen::VectorXd::Random(3)*16).cast<int>();
Eigen::MatrixXd C = A.array() // go to array domain
.pow( // element-wise power
b.cast<double>() // cast exponents to double
.replicate(1, A.cols()).array() // repeat exponents to match size of A
);
std::cout << A << '\n' << b << '\n' << C << '\n';
}
Essentially, this will call C(i,j) = std::pow(A(i,j), b(i)) for each i, j. If all your exponents are small, you might actually be faster than that with a
simple nested loop that calls a specialized pow(double, int) implementation (like gcc's __builtin_powi), but you should benchmark that with actual data.
I want to write a function that take n int as a coordinate of array with the max value for each coordinate. This function linearizes these parameters to target a specific index.
int my_func(int x, int y, int XMAX, int YMAX){
return x + y*XMAX;
}
Here is a 2D example, but I can make something generic thanks to variadic template quite easily.
However, I am stucked when I want to make the same function that does not take the max value for each coordinate in parameters.
Something like that :
template<int XMAX, int YMAX>
int my_func(int x, int y){
return x + y*XMAX;
}
Here it works in 2D, but I want to generalize that from 1 to N dimensions and I don't know how I could achieve that.
I was thinking to pass an int N which is the number of dimension and an std::array<N, int>::iterator which is an iterator on the std::array containing the actual max value, but it does not compile.
Here is the code:
template <int N, std::array<size_t, N>::iterator it>
void foo(){...}
It says ’std::array<long unsigned int, N>::iterator’ is not a type.
If i just pass the std::array, I get the following error : ’struct std::array<long unsigned int, N>’ is not a valid type for a template non-type parameter
Does someone have an idea on how to solve such a problem ? I am using C++ 11 (G++ 5.4.0).
First of all, I suppose you did a little mistake in your function, because if you need to linearize the accessing of array you need to multuply y by XMAX
int my_func(int x, int y, int XMAX, int YMAX){
return x + y*XMAX;
}
because each row is composed of XMAX items. For answer to your question I used a template parameter pack
template <int N>
int my_func(int x)
{
assert(x < N);
return x;
}
template <int N, int... Ns, typename ARG, typename... ARGS>
ARG my_func (ARG x, ARGS... args)
{
assert(x < N);
return x + N*my_func<Ns...>(args...);
}
int main()
{
int a = 1;
int b = 2;
int c = my_func<10, 3>(a, b);
}
The fist function is the base for the recursion, the second function use two parameter packs but also 2 explicit template parameter to make the recursion possible.
I am writing simple classes that implement vectors and matrices as part of trying to learn OpenGL. I have matrix and vector classes that look like this :
// Forward declarations
template <typename T, size_t N/*len*/> struct vec;
template<typename T, size_t N /*rows*/, size_t M /*cols*/> struct mat;
// Forward declare *operator for matrix
// (NxM) matrix multiplied by (MxP) matrix yields (NxP) matrix
mat<T, N, P> operator* (const mat<T, N, M>& A, const mat<T, M, P>& B);
template <typename T, size_t N>
struct vec {
public:
vec() {}
virtual ~vec() {}
private:
T[N] m_data;
};
template <typename T, size_t N, size_t M>
struct mat {
public:
mat() {}
virtual ~mat() {}
// This is where it gets interesting. By my reading of the rules
// of C++11, this counts as a partial specialization of the
// operator template, and should not work.
// However, it compiles just fine!
template <size_t n, size_t m, size_t p>
friend mat<T, n, p> operator* (const mat<T, n, m>& A,
const mat<T, m, p> &B);
// Implementation appears later in the same header file.
private:
T[N*M] m_data;
};
I declare the * operator as a friend because I want it to have access to the internal m_data member, but I don't want the users of 'mat' and 'vec' to know the internals.
This compiles and runs just fine. I have a unit test for that matrix multiplication, and it works just fine. However, I don't know why it even compiles, let alone runs. By my reading of the rules of C++ templates, the declaration of the * operator counts as a partial specialization of function template, and is illegal.
What am I missing here?
Turns out this does *NOT* compile. I thought it was compiling because I wasn't invoking the template stream operator in my unit test when I thought I was.
Sorry for the stupid question!
I have the following basic class structure:
class Distance : public Base {
public:
using Base::Base;
void run(int u, int v); // indices for nodes in graph
void runAll();
};
and
class Base {
protected:
const Graph& G;
Matrix& results;
public:
explicit Base(const Graph& G, Matrix& results);
virtual ~Base() = default;
virtual void run(int u, int v) = 0;
virtual void runAll() = 0;
double getResult(int u, int v) const;
const Matrix& getResults() const;
};
where Distance basically calculates either for a node-pair (u, v) or for all possible node-pairs a distance-score which gets stored in the results Matrix.
The problem right now is the separation of the algorithm and the data structure. If I want to reuse the run-method of Distance in a second class AnotherDistance derived from Base I have to allocated the matrix 2 times (1 in Distance and 1 in AnotherDistance) which is not feasible in my case as the matrix could amount to multiple GB.
What would be the best approach to solve this? I could take the results-Matrix as an argument in the constructor (probably bad design) or maybe use move-semantics in another separate getter which would empty the matrix in the class.
Hello. I write matrix class but i have some problem with matrices multiplication which have different dimensions.
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template< typename MulT >
auto operator * (const MulT& other) -> Matrix<T, Row, other.getColNum()>
{
if (other.getRowNum() != getColNum())
throw std::logic_error("Multiplication are not possible");
Matrix<T, Row, other.getColNum()> temp;
// Some operations.
return temp; // Must return matrix with this type Matrix<T, Row, other.getColNum()>
// but it dont work.
}
.....................................
}; // class Matrix
This code don't work. It is possible to resolve this problem?
other.getColNum() is probably not a constexpr function and can therefore not be used as a template non-type argument.
Read up on constexpr here: http://en.cppreference.com/w/cpp/language/constexpr
You don't want to check the if if (other.getRowNum() != getColNum()) at runtime, this should be done at compile time. One way to do this is to define the operator only for when the multiplication is valid. In this case:
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template<size_t _RHSWIDTH>
Matrix<_T, _RHSWIDTH, Row> operator * (const Matrix<T, _RHSWIDTH, Col> &rhs) const
{
Matrix<_T, _RHSWIDTH, Row> temp;
// Some operations.
return temp;
}
.....................................
}; // class Matrix
As a result, any attempt to multiply matrices which cannot be multiplied will fail at compile time. For a complete example, I wrote a complete matrix template a long time ago which uses very similar syntax: https://github.com/Enseed/GenericGeometry/blob/master/Matrix.h