You can use it as you like. The only thing I ask you is to be recognized myself and inform me to any issue.
/*
* File: Matrix.h
* Author: Aikon
*
* http://surprising-code.blogspot.com
* Created on 20 de febrero de 2012, 22:43
* updated at: 26/02/2012
* last update at: 27/02/2012
*/
#ifndef MATRIX_H
#define MATRIX_H
#include <vector>
#include <iostream>
#include <stdexcept>
template<typename T, int ROWS, int COLS>
class Matrix {
private:
std::vector<T> _elements;
public:
T& operator()(unsigned i, unsigned j) {
return _elements[i * COLS + j];
}
const T& operator()(unsigned i, unsigned j) const {
return _elements[i * COLS + j];
}
T& operator()(unsigned i) {
return _elements[i];
}
const T& operator()(unsigned i) const {
return _elements[i];
}
public:
// constructors
Matrix();
Matrix(T element);
template<typename Function>
Matrix(Function f);
Matrix(const Matrix<T, ROWS, COLS>&);
// destructor
~Matrix();
// comparison
bool operator==(const Matrix<T, ROWS, COLS>&) const;
bool operator!=(const Matrix<T, ROWS, COLS>& cmp) const {
return !((*this) == (cmp));
}
// scalar multiplication
Matrix<T, ROWS, COLS>& operator*=(const T& a);
Matrix<T, ROWS, COLS> operator*(const T& a) const {
return Matrix<T, ROWS, COLS > (*this).operator*=(a);
}
Matrix<T, ROWS, COLS> operator-() const {
return Matrix<T, ROWS, COLS > (*this)*(-1);
}
// addition/subtraction
Matrix<T, ROWS, COLS>& operator+=(const Matrix<T, ROWS, COLS>&);
Matrix<T, ROWS, COLS>& operator-=(const Matrix<T, ROWS, COLS>&);
Matrix<T, ROWS, COLS> operator+(const Matrix<T, ROWS, COLS>& M) const {
return Matrix<T, ROWS, COLS > (*this).operator+=(M);
}
Matrix<T, ROWS, COLS> operator-(const Matrix<T, ROWS, COLS>& M) const {
return Matrix<T, ROWS, COLS > (*this).operator-=(M);
}
// Matrix multiplication
template<int InCOLS>
Matrix<T, ROWS, InCOLS> operator*(const Matrix<T, COLS, InCOLS>& in) const;
template<int InCOLS>
Matrix<T, ROWS, InCOLS>& operator*=(const Matrix<T, COLS, InCOLS>& M) {
return *this = *this * M;
}
Matrix<T, COLS, ROWS> operator~();
/*
Matrix<T, ROWS, COLS> getcol( unsigned i ) const;
Matrix<T, ROWS, COLS> getrow( unsigned j ) const;
Matrix<T, ROWS, COLS>& setcol( unsigned j, const Matrix<T, ROWS, COLS>& C );
Matrix<T, ROWS, COLS>& setrow( unsigned i, const Matrix<T, ROWS, COLS>& R );
Matrix<T, ROWS, COLS> delrow( unsigned i ) const;
Matrix<T, ROWS, COLS> delcol( unsigned j ) const;
Matrix<T, ROWS, COLS> transpose() const;
*/
void set(unsigned i, unsigned j, T in) {
_elements[i * COLS + j] = in;
}
};
#endif /* MATRIX_H */
//constructors
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>::Matrix()
: _elements(ROWS*COLS, T(0.0)) {
if (ROWS == 0 || COLS == 0)
throw std::range_error("attempt to create a degenerate matrix");
};
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>::Matrix(T element)
: _elements(ROWS*COLS, T(element)) {
if (ROWS == 0 || COLS == 0)
throw std::range_error("attempt to create a degenerate matrix");
};
template<typename T, int ROWS, int COLS>
template<typename Function>
Matrix<T, ROWS, COLS>::Matrix(Function f){
if (ROWS == 0 || COLS == 0)
throw std::range_error("attempt to create a degenerate matrix");
for (int i = 0; i < ROWS * COLS; i++) _elements.push_back(f());
}
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>::Matrix(const Matrix<T, ROWS, COLS>& M){
if (ROWS == 0 || COLS == 0)
throw std::range_error("attempt to create a degenerate matrix");
(*this) = M;
}
// destructor
//Erases all the elements. Note that this function only erases
//the elements, and that if the elements themselves are pointers,
//the pointed-to memory is not touched in any way. Managing
//the pointer is the user's responsibility.
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>::~Matrix() {
}
template<typename T, int ROWS, int COLS>
bool Matrix<T, ROWS, COLS>::operator==(const Matrix<T, ROWS, COLS>& cmp) const {
for (unsigned i = 0; i < ROWS * COLS; i++)
if (_elements[i] != cmp._elements[i])
return false;
return true;
}
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>& Matrix<T, ROWS, COLS>::operator*=(const T& a) {
for (int i = 0; i < ROWS * COLS; i++)
_elements[i] *= a;
return *this;
}
// Matrix multiplication
//(this)*B = C sizeX(files de this), sizeY = columnes de B sizeY
template<typename T, int ROWS, int COLS>
template<int InCOLS>
Matrix<T, ROWS, InCOLS> Matrix<T, ROWS, COLS>::operator*(const Matrix<T, COLS, InCOLS>& in) const {
Matrix<T, ROWS, InCOLS> aux(0.0);
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < InCOLS; j++)
for (int k = 0; k < COLS; k++)
(aux)(i, j) += (*this)(i, k) * in(k, j);
return aux;
}
// addition/subtraction
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>& Matrix<T, ROWS, COLS>::operator+=(const Matrix<T, ROWS, COLS>& in) {
for (unsigned i = 0; i < ROWS * COLS; i++)
_elements[i] += in._elements[i];
return *this;
}
template<typename T, int ROWS, int COLS>
Matrix<T, ROWS, COLS>& Matrix<T, ROWS, COLS>::operator-=(const Matrix<T, ROWS, COLS>& in) {
for (unsigned i = 0; i < ROWS * COLS; i++)
_elements[i] -= in._elements[i];
return *this;
}
template<typename T, int ROWS, int COLS>
Matrix<T, COLS, ROWS> Matrix<T, ROWS, COLS>::operator~() {
Matrix<T, COLS, ROWS> aux;
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
aux(j, i) = (*this)(i, j);
return aux;
}
template<class T, int ROWS, int COLS>
std::ostream& operator<<(std::ostream& out, const Matrix<T, ROWS, COLS>& M) {
out << std::endl;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++)
out << " " << M(i, j) << " ";
out << std::endl;
}
return out;
}
#include <cstdlib>
#include <ctime>
double myfunction() {
return (rand() % 10) + 1;
}
std::string randomStrGen() {
int length = 5;
std::string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
std::string result;
result.resize(length);
for (int i = 0; i < length; i++)
result[i] = charset[rand() % charset.length()];
return result;
}
int main() {
try {
srand(time(0));
Matrix<double, 4, 2 > m(1.1);
Matrix<double, 2, 4 > m2(myfunction);
Matrix<double, 4, 4 > m3(myfunction);
Matrix<std::string, 2, 2 > m4(randomStrGen);
std::cout << "isEqual: " << (m == m) << std::endl;
std::cout << m << m2 << m3;
m3 = m*m2;
m * 2;
std::cout << "new m3" << m3 << m;
m3 = -m3;
std::cout << m3 << m4;
Matrix<double, 4, 2 > aux;
aux = ~m2;
std::cout << aux;
Matrix<int, 2, 2> intMatrix;
Matrix<int, 2, 2> intMatrix2(2);
intMatrix = intMatrix - intMatrix2;
std::cout << intMatrix - intMatrix2;//again -2 so is -4
} catch (const std::exception& in) {
std::cout << in.what() << std::endl;
}
}
output:
isEqual: 1
1.1 1.1
1.1 1.1
1.1 1.1
1.1 1.1
1 1 8 6
1 9 2 10
3 1 7 1
4 6 10 4
5 7 4 1
3 1 10 1
new m3
2.2 11 11 17.6
2.2 11 11 17.6
2.2 11 11 17.6
2.2 11 11 17.6
1.1 1.1
1.1 1.1
1.1 1.1
1.1 1.1
-2.2 -11 -11 -17.6
-2.2 -11 -11 -17.6
-2.2 -11 -11 -17.6
-2.2 -11 -11 -17.6
L019l vpUG9
F77UO mpQK8
1 1
1 9
8 2
6 10
-4 -4
-4 -4
RUN SUCCESSFUL (total time: 72ms)
Uau!
ReplyDeleteQuina feinada, noi.
Impressionant que facis tot això simplement pel plaer de programar. :)
^^
ReplyDeleteTot i que realment és una classe interesant la qual possiblement necesitaré en algun moment, per això li estic dedicant temps extra.
Merci ^^