-
Notifications
You must be signed in to change notification settings - Fork 1
Documentation
C++ template class that provides an interface for matrix-based computing.
This documentation layout is strongly inspired from the Qt documentation. HTML export by StackEdit.
Type | Name | Access |
---|---|---|
std::vector<T> |
_data | protected |
size_t |
_rows | protected |
size_t |
_columns | protected |
ste::EXE |
_device | protected |
enum class |
Orientation{ ROW , LINE , RW , R , COLUMN , COL , CL , C }
|
Matrix(const size_t &rows , const size_t& columns , const T &value = T(0) , const EXE &device = EXE::CPU)
|
|
Matrix(const size_t &size = 0 , const T &value = T(0) , const EXE &device = EXE::CPU)
|
|
Matrix(const std::vector<T> &data , const size_t &rows , const size_t&columns , const EXE &device = EXE::CPU)
|
|
Matrix(const std::vector<std::vector<T>> &data , const EXE &device = EXE::CPU)
|
|
Matrix& |
add(const std::vector<T> &data , const Orientation &orientation)
|
Matrix& |
add_row(const std::vector<T> &data)
|
Matrix& |
add_line(const std::vector<T> &data)
|
Matrix& |
add_column(const std::vector<T> &data)
|
T |
average() const
|
T& |
at(const size_t &row , const size_t &column)
|
T& |
at(const size_t &linear_index)
|
const T& |
at(const size_t &row , const size_t &column) const
|
const T& |
at(const size_t &linear_index) const
|
auto |
begin() const
|
auto |
begin()
|
virtual size_t |
begin_row() const
|
size_t |
begin_line() const
|
virtual size_t |
begin_column() const
|
Matrix& |
clear()
|
T |
cofactor(const size_t &row , const size_t &column) const
|
T |
cofactor(const size_t &index) const
|
Matrix |
cofactormatrix() const
|
Matrix |
comatrix() const
|
std::vector<T> |
columnAt(const size_t &index) const
|
const size_t& |
columns() const
|
Matrix& |
cut(std::vector<size_t> indexes , const Orientation &orientation)
|
Matrix& |
cut(const size_t &begin , const size_t &end , const Orientation &orientation)
|
Matrix& |
cut_columns(const std::vector<size_t> &indexes)
|
Matrix& |
cut_columns(const size_t &begin , const size_t &end)
|
Matrix& |
cut_lines(const std::vector<size_t> &indexes)
|
Matrix& |
cut_lines(const size_t &begin , const size_t &end)
|
Matrix& |
cut_rows(const std::vector<size_t> &indexes)
|
Matrix& |
cut_rows(const size_t &begin , const size_t &end)
|
Matrix& |
deleteAll()
|
virtual T |
det() const
|
const EXE& |
device() const
|
EXE& |
device()
|
size_t |
elements() const
|
Matrix |
element_wise(const Matrix &arg) const
|
bool |
empty() const
|
auto |
end()
|
auto |
end() const
|
virtual size_t |
end_column() const
|
size_t |
end_line() const
|
virtual size_t |
end_row() const
|
Matrix& |
fill(const size_t &size , const T &value)
|
Matrix& |
fill(const size_t &rows , const size_t &columns , const T &value)
|
Matrix& |
template<class Function> for_each(Function function)
|
const Matrix& |
template<class Function> for_each(Function function) const
|
Matrix |
hadamard(const Matrix &arg) const
|
Matrix& |
insert(const size_t &element_index , const Orientation &orientation , const std::vector<T> &data)
|
Matrix& |
insert_column(const size_t &index , const std::vector<T> &data)
|
Matrix& |
insert_line(const size_t &index , const std::vector<T> &data)
|
Matrix& |
insert_row(const size_t &index , const std::vector<T> &data)
|
Matrix |
inv() const
|
Matrix& |
invert()
|
bool |
isColumn() const
|
bool |
isInvertible() const
|
bool |
isLine() const
|
bool |
isRow() const
|
bool |
isSquare() const
|
std::vector<T> |
lineAt(const size_t &index) const
|
const size_t& |
lines() const
|
T |
max(std::function<T (const std::vector<T>&)> criterium = [](const std::vector<T> &data){return *std::max_element(data.begin() , data.end());}) const
|
virtual T |
mean() const
|
T |
min(std::function<T (const std::vector<T>&)> criterium = [](const std::vector<T> &data){return *std::min_element(data.begin() , data.end());}) const
|
Matrix& |
operator=(const Matrix &arg)
|
Matrix& |
operator=(const std::vector<std::vector<T>> &arg)
|
Matrix& |
operator=(const std::vector<T> &arg)
|
virtual Matrix |
operator*(const Matrix &arg) const
|
Matrix |
operator* (const T &arg) const
|
virtual Matrix& |
operator*=(const Matrix &arg)
|
Matrix& |
operator*=(const T &arg)
|
Matrix |
operator+(const Matrix &arg) const
|
Matrix |
operator+(const T &arg) const
|
Matrix& |
operator+=(const Matrix &arg)
|
Matrix& |
operator+=(const T &arg)
|
Matrix |
operator-(const Matrix &arg) const
|
Matrix |
operator-(const T &arg) const
|
Matrix |
operator-() const
|
Matrix& |
operator-=(const Matrix &arg)
|
Matrix& |
operator-=(const T &arg)
|
virtual Matrix |
operator!()const
|
virtual Matrix |
operator^(const long long int &arg) const
|
virtual Matrix& |
operator^=(const long long int &arg)
|
virtual bool |
operator==(const Matrix &arg) const
|
virtual bool |
operator!=(const Matrix &arg) const
|
virtual std::ostream& |
print(std::ostream &outstream = std::cout) const
|
virtual std::ostream& |
print_size(std::ostream &outstream = std::cout) const
|
Matrix& |
push_back(const std::vector<T> &data , const Orientation &orientation)
|
Matrix& |
push_back_column(const std::vector<T> &data)
|
Matrix& |
push_back_line(const std::vector<T> &data)
|
Matrix& |
push_back_row(const std::vector<T> &data)
|
Matrix& |
remove(const size_t &element_index , const Orientation &orientation)
|
Matrix& |
remove_column(const size_t &index)
|
Matrix& |
remove_line(const size_t &index)
|
Matrix& |
remove_row(const size_t &index)
|
Matrix& |
replace(const size_t &row , const unsigned &column , const T &value)
|
Matrix& |
replace(const size_t &index, const T &value)
|
Matrix& |
replace(const size_t &value_index ,const Orientation &orientation , const std::vector<T> &value)
|
Matrix& |
replace(const size_t &row_begin, const size_t &row_end ,const size_t &column_begin, const size_t &column_end,const T &value)
|
Matrix& |
replace_column(const size_t &value_index , const std::vector<T> &value)
|
Matrix& |
replace_line(const size_t &value_index , const std::vector<T> &value)
|
Matrix& |
replace_row(const size_t &value_index , const std::vector<T> &value)
|
Matrix& |
reshape(const size_t &rows , const size_t &columns)
|
std::vector<T> |
rowAt(const size_t &index) const
|
const size_t& |
rows() const
|
Matrix& |
self_transpose()
|
Matrix& |
setDevice(const EXE &device)
|
const std::vector<size_t> |
size() const
|
virtual T |
sum() const
|
Matrix& |
swap(const size_t &element_1 , const size_t &element_2 ,const Orientation &orientation)
|
Matrix& |
swap_columns(const size_t &element_1 , const size_t &element_2)
|
Matrix& |
swap_lines(const size_t &element_1 , const size_t &element_2)
|
Matrix& |
swap_rows(const size_t &element_1 , const size_t &element_2)
|
const std::vector<T>& |
toVector1D() const
|
std::vector<T>& |
toVector1D()
|
virtual std::vector<std::vector<T>> |
toVector2D() const
|
T |
trace() const
|
Matrix& |
template<class Function> transform(Function function)
|
Matrix |
transpose() const
|
Matrix& |
transpose_in_place()
|
Matrix |
eye (const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
ones(const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
ones(const size_t &rows , const size_t &columns , const EXE &device = EXE::CPU)
|
Matrix |
uniform(const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
uniform(const size_t &rows , const size_t &columns , const EXE &device = EXE::CPU)
|
Matrix |
uniform_int(const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
uniform_int(const size_t &rows , const size_t &columns , const EXE &device = EXE::CPU)
|
Matrix |
rand(const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
rand(const size_t &rows , const size_t &columns , const EXE &device = EXE::CPU)
|
Matrix |
randn(const size_t &size , const T &mean = T(0) , const T &standard_deviation = T(1.) const EXE &device = EXE::CPU)
|
Matrix |
randn(const size_t &rows , const size_t &columns , const T &mean = T(0) , const T &standard_deviation = T(1) , const EXE &device = EXE::CPU)
|
Matrix |
zeroes(const size_t &size , const EXE &device = EXE::CPU)
|
Matrix |
zeroes(const size_t &rows , const size_t &columns , const EXE &device = EXE::CPU)
|
Matrix |
template<class T> element_wise(const Matrix<T> &arg1 , const Matrix<T> &arg2)
|
Matrix& |
template<class T , class Function> for_each(Matrix<T> &matrix , Function function)
|
const Matrix& |
template<class T , class Function> for_each(const Matrix<T> &matrix , Function function)
|
Matrix |
template<class T> hadamard(const Matrix<T> &arg1 , const Matrix<T> &arg2)
|
Matrix& |
template<class T> invert(Matrix<T> &arg)
|
std::ostream& |
template<class T> operator<<(std::ostream &outstream , const Matrix<T> &arg)
|
std::ostream& |
operator<<(std::ostream &outstream , const EXE &a)
|
EXE |
operator|(const EXE &a , const EXE &b)
|
bool |
operator||(const EXE &a , const EXE &b)
|
EXE |
operator&(const EXE &a , const EXE &b)
|
bool |
operator&&(const EXE &a , const EXE &b)
|
Matrix& |
template<class T , class Function> transform(Matrix<T> &matrix , Function function)
|
enum class |
EXE{CPU = 0, C = CPU, HOST = CPU, GPU = 1, G = GPU, DEVICE = GPU}
|
typedef Matrix<float> |
FMatrix |
typedef Matrix<double> |
DMatrix |
typedef Matrix<long double> |
LDMatrix |
typedef Matrix<int> |
IMatrix |
typedef Matrix<long int> |
LIMatrix |
typedef Matrix<long long int> |
LLIMatrix |
typedef Matrix<unsigned int> |
UIMatrix |
typedef Matrix<unsigned long> |
ULMatrix |
typedef Matrix<unsigned long long> |
ULLMatrix |
typedef Matrix<char> |
CMatrix |
typedef Matrix<unsigned char> |
UCMatrix |
No value | STE_MATRIX_ALLOW_GPU |
The ste::Matrix
template class offers an interface for any matrix computation-related applications.
Simple to use and highly customizable through inheritance, this class provides high level functions to fasten the developpment. Among its main features:
• CUDA-compatible. Refer to the paragraph Using a GPU for more information. • Dynamic reshaping and resizing. • Determinant, trace, sum, average, min, max... • Cofactors, cofactor matrix, inverse, transpose, Hadamard (element-wise) product. • Multiplication, sum, difference operators.
This class offers four different constructors for convenience purposes.
The following code snippets creates a 2*4
float matrix filled with 0, with CPU as default execution policy.
ste::Matrix<float> mat(2 , 4 , 0 , ste::EXE::CPU); //2*4 float matrix filled with 0.
/*
mat is :
0 0 0 0
0 0 0 0
*/
To create a square matrix, proceed this way :
ste::Matrix<int> mat_square(2 , 99 , ste::EXE::CPU); //2*2 int square matrix filled with 99.
/*
mat_square is :
99 99
99 99
*/
It is possible to speficy the data when creating the matrix, as long as
ste::Matrix<unsigned> mat_from_vector({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3); //3*3 unsigned matrix with CPU as default execution policy.
/*
mat_from_vector is :
1 2 3
4 5 6
7 8 9
*/
Finally, if your data is stored in a std::vector<std::vector<T>>
, simply proceed this way ;
To use this constructor, all std::vector<T>
must be of the same size.
ste::Matrix<double> mat_from_vector2D({{1 , 2 , 3} , {4 , 5 , 6}} , ste::EXE::GPU); //2*3 double matrix that will use the GPU (refere to the dedicated paragraph for more details).
/*
mat_from_vector2D is :
1 2 3
4 5 6
*/
Element access is made possible using at
. It always returns a reference to the element, meaning that you can modify it this way.
Both linear indexes and (row, column)
coordinates are acceptable arguments.
The two methods performances are identical.
ste::Matrix<unsigned> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
std::cout << mat.at(3) << std::endl; //Prints 4
std::cout << mat.at(2 , 2) << std::endl; //Prints 5
To access a row or a column, simply use rowAt
, lineAt
or columnAt
.
ste::Matrix<unsigned> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.rowAt(2); //Returns std::vector<unsigned>({6 , 7 , 8})
mat.columnAt(1): //Returns std::vector<unsigned>({2,5,8})
ste::Matrix
provides O(1)
reshaping as long as data is not appended or removed.
reshape
changes the size of the matrix, and throws an exception if the total number of element do not match.
ste::Matrix<unsigned> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.reshape(1,9); //mat is now 1*9 matrix.
mat.reshape(9,1); //mat is now 9*1 matrix.
To add column or row, using add
or push_back
as follow :
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.add({10 , 11 , 12} , ste::FMatrix::Orientation::ROW); //Adds a row at the end of the matrix.
///This syntaxe being heavy, it is recommended to use either 'push_back_row' or 'add_row'.
/*
mat is now :
1 2 3
4 5 6
7 8 9
10 11 12
*/
mat.push_back_column({100 , 101 , 102 , 103});
/*
mat is now :
1 2 3 100
4 5 6 101
7 8 9 102
10 11 12 103
*/
You can insert a row or a column using the insert
functions.
The sizes must match when appending to a matrix.
ste::Matrix<double> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.insert_row(0 , {10 , 11 , 12}); //Inserts a row at position '0'
/*
mat is now :
10 11 12
1 2 3
4 5 6
7 8 9
*/
mat.insert_column(1 , {100 , 101 , 102 , 103}); //Inserts a column at position '1'
/*
mat is now :
10 100 11 12
1 101 2 3
4 102 5 6
7 103 8 9
*/
You can remove a single row or a single column using the remove
functions.
ste::Matrix<double> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.remove_row(0); //Removes the first row
/*
mat is now :
4 5 6
7 8 9
*/
mat.remove_column(0); //Removes the first column
/*
mat is now :
5 6
8 9
*/
To remove several rows or columns at one, use cut
as follows :
ste::Matrix<double> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.cut_rows({2 , 0}); //Removes rows 0 and 2.
/*
mat is now :
4 5 6
*/
mat.cut_columns(0 , 1); //Removes columns 0 to 1 (included).
/*
mat is now :
6
*/
You can swap two rows or columns using the swap
functions.
ste::Matrix<double> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.swap_rows(2 , 0); //Swaps rows 0 and 2.
/*
mat is now :
7 8 9
4 5 6
1 2 3
*/
mat.swap_columns(1 , 2); //Swaps columns 1 and 2.
/*
mat is now :
7 9 8
4 6 5
1 3 2
*/
Should you need to replace an entire column or entire row, use the replace
functions.
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.replace_row(0 , {99 , 98 , 97});
/*
mat is now :
99 98 97
4 5 6
7 8 9
*/
mat.replace_column(2 , {100 , 101 , 102});
/*
mat is now :
99 98 100
4 5 101
7 8 102
*/
You can completely override a matrix content and change its size using fill
.
WARNING! When the contents are dynamically allocated (pointers), memory IS NOT FREED.
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.fill(8 , 22); //mat is now a 8*8 float matrix holding 22 in each element.
mat.fill(3,2, 1.6); //mat is now a 3*2 float matrix holding 1.6 in each element.
The ste
namespace provides the analogs functions to std::for_each
and std::transform
for any instantiation of a ste::Matrix
.
For convenience purposes, ste::Matrix
also has member functions named for_each
and transform
, that behave the same.
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
ste::for_each(mat , [](const float &value){std::cout << value << " ";});
/*
Identical to :
mat.for_each([](const float &value){std::cout << value << " ";});
Prints '1 2 3 4 5 6 7 8 9'.
*/
ste::transform(mat , [](const float &value){return 2*value;});
/*
Identical to :
mat.transform([](const float &value){return 2*value;});
mat is now :
2 4 6
8 10 12
14 16 18
*/
You can print a ste::Matrix
to any std::ostream
by using either print() const
or operator<<
.
Note that print() const
is virtual
.
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.print() << std::endl; //Prints "[ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ]" to std::cout.
std::cout << mat << std::endl; //Same as above.
mat.print(std::clog); //Prints the matrix contents to std::clog.
std::clog << mat; //Same as above.
To print a matrix size without having to write anything yourself, use print_size() const
.
ste::Matrix<float> mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3);
mat.print_size() << std::endl; //Prints "[3 ; 3]" to std::cout.
mat.print_size(std::cerr) << std::endl; //Prints "[3 ; 3]" to std::cerr.
ste::Matrix
provides several convenience maths functions.
You can for example compute the numerical value of the determinant of any square matrix by calling det
:
const ste::FMatrix square_mat({1 , 2 , 3 , 4 , 52 , 6 , 7 , 141 , 9} , 3 , 3); //3*3 float matrix
std::cout << square_mat.det() << std::endl; //Prints the determinant (here 234) to std::cout
Should you need the explicit expression of the inverse of a matrix, you can use operator!
, inv
or invert
.
Explicitely computing a matrix inverse is HEAVY. You should not try to compute inverses of matrices bigger than 10 x 10.
ste::FMatrix square_mat({1 , 2 , 3 , 4 , 52 , 6 , 7 , 141 , 9} , 3 , 3); //3*3 float matrix
/*
This matrix inverse is:
-1.61538 1.73077 -0.615385
0.025641 -0.0512821 0.025641
0.854701 -0.542735 0.188034
*/
std::cout << !square_mat << std::endl; //Computes and prints the inverse of square_mat to std::cout
std::cout << square_mat.inv() << std::endl; //Equivalent to above
std::cout << square_mat.invert() << std::endl; //square_mat is now !square_mat.
You can also compute any cofactor and the cofactor matrix explicitely :
Computing the cofactor matrix is the same complexity as computing the inverse.
const ste::FMatrix square_mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3); //3*3 float matrix
std::cout << square_mat.cofactor(0) << std::endl; //Cofactor using linear indexes
std::cout << square_mat.cofactor(0,1) << std::endl; //Cofactor using (x,y) indexes
std::cout << square_mat.cofactormatrix() << std::endl; //Prints the cofactor matrix
Among the other features : trace
, max
/ min
, sum
and average
:
const ste::FMatrix square_mat({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3); //3*3 float matrix
std::cout << square_mat.trace() << std::endl; //Prints the trace of a matrix (the sum of the diagonal terms)
std::cout << square_mat.max() << std::endl; //Prints the maximum of the matrix. Default uses 'std::max_element'
std::cout << square_mat.min() << std::endl; //Prints the minimum of the matrix. Default uses 'std::min_element'
std::cout << square_mat.sum() << std::endl; //Prints the sum of all the elements of the matrix.
std::cout << square_mat.average() << std::endl; //Prints the average of the matrix.
If your matrix does not contain a POD type, you can add a criterium to min
and max
. See their documentation for more details.
Especially using CUDA, it is often necessary to be able to obtain a std::vector
holding the data.
ste::Matrix
provides such a function :
const ste::FMatrix mat_1({1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9} , 3 , 3); //3*3 float matrix
ste::ULLMatrix mat_2({10 , 11 , 12 ,13 ,14 , 15 , 16 , 17 , 18} , 3 , 3); //3*3 uint64_t matrix
mat_1.toVector1D(); //Returns a const std::vector<float>& holding {1 , 2 , 3 ,4 ,5 , 6 , 7 , 8 , 9}
mat_2.toVector1D(); //Returns a std::vector<uint64_t>& holding {10 , 11 , 12 ,13 ,14 , 15 , 16 , 17 , 18}
As the data is passed by reference, it is possible to modify it using toVector1D()
when the matrix is not const
.
ste::FMatrix a({1 , 2 , 3 ,
4 , 52 , 6 ,
7 , 141 , 9} ,
3 , 3); //3*3 float matrix
std::vector<float> &vect = a.toVector1D();
vect.at(0) = 999;
std::cout << a << std::endl; //Prints [ [ 999 2 3 ] [ 4 52 6 ] [ 7 141 9 ] ]
Should you need a std::vector<std::vector<T>>
, simply use toVector2D
:
ste::FMatrix a({1 , 2 , 3 ,
4 , 52 , 6 ,
7 , 141 , 9} ,
3 , 3); //3*3 float matrix
std::vector<std::vector<float>> two_dimensional_vector = a.toVector2D();
/*
two_dimensional_vector is :
{ {1 , 2 , 3} , //First vector
{4 , 52 , 6} , //Second vector
{7 , 141 , 9} //Third vector
}
*/
toVector2D
orders the data by row . This method is virtual
, allowing you to change the format should you need it.
Configuring Qt on Windows for using CUDA librairies requires you to use MSVC.
Requirements: 1. Make sure your computer is equipped with a CUDA-compatible GPU. 2. Download the CUDA Toolkit. 3. Download Visual Studio and a version of MSVC compatible with the CUDA Toolkit version.
ste::Matrix specific requirements:
Add STE_MATRIX_ALLOW_GPU
to the DEFINES
of your .pro file
:
DEFINES += STE_MATRIX_ALLOW_GPU
Writing the .pro
file:
This tutorial is based on this GitHub repository by mihaits.
- CUDA and MSVC have conflicting names in some of their functions. Adding these lines to the
.pro
file solves the problem:
# Avoid conflicts between CUDA and MSVC
QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:msvcrtd.lib
QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:libcmt.lib
# Avoid conflicts between CUDA and MSVC
QMAKE_CFLAGS_DEBUG += /MTd
QMAKE_CFLAGS_RELEASE += /MT
QMAKE_CXXFLAGS_DEBUG += /MTd
QMAKE_CXXFLAGS_RELEASE += /MT
- Create a list of the CUDA source files for your project:
CUDA_SOURCES += ../someDistantFolder/some_CUDA_code.cu \
someFolder/other_CUDA_code.cu
- Specify the CUDA installation path, the system architecture, the system type (32 bits or 64 bits), the architecture of your GPU, and the CUDA compiler options:
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.1" #Path to your CUDA installation
SYSTEM_NAME = x64 #NB: SYSTEM DEPENDENT
SYSTEM_TYPE = 64 #SAME HERE
CUDA_ARCH = sm_61 #Compute capability of the GPU (here GTX Geforce 1050 - Compute capability 6.1 so sm_61)
NVCC_OPTIONS = --use_fast_math #CUDA compiler options
- Include CUDA headers and CUDA libraires (such as CUBLAs) headers:
#CUDA Headers
INCLUDEPATH += $$CUDA_DIR/include
#CUDA librairies headers
QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME
#Required libraires added here
LIBS += -lcuda -lcudart -lcublas
# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
- Configure the CUDA compiler:
#Configuration of the CUDA compiler
CONFIG(debug, debug|release) {
# Debug mode
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release mode
cuda.input = CUDA_SOURCES
cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
- Known troubles:
- Debug build sometimes fails with some CUDA librairies.
ste::Matrix specific parts:
- Add the CUDA-related headers to the list of the headers:
HEADERS += ../Matrix/CUDA_src/CUDA_global.h \
../Matrix/CUDA_src/CUDA_matrix_operators.h \
- Add the CUDA-related source files to the list of the CUDA files:
CUDA_SOURCES += ../Matrix/CUDA_src/CUDA_global.cu \
../Matrix/CUDA_src/CUDA_matrix_operators.cu \
../Matrix/CUDA_src/CUDA_setup.cu \
For a sample .pro
file, see /qmake.
TO BE ADDED
TO BE ADDED
Using your GPU for all computations is not recommended. As its RAM and the CPU one are not shared, it is required to copy data two times, meaning that bottleneck effects occur. Small matrix-related computations run faster on a CPU than on a GPU.
For further information, you may look at the following sites:
- When should I be offloading work to a GPU instead of the CPU?
- CPU vs. GPU: Making the Most of Both
- What’s the Difference Between a CPU and a GPU?
Constant | Value | Description |
---|---|---|
Orientation::ROW |
0 | Specifier for functions that apply either on rows or on columns, such as replace , swap or remove . |
Orientation::LINE |
Orientation::ROW |
Alias for Orientation::ROW
|
Orientation::RW |
Orientation::ROW |
Alias for Orientation::ROW
|
Orientation::R |
Orientation::ROW |
Alias for Orientation::ROW
|
Orientation::COLUMN |
1 | Specifier for functions that apply either on rows or on columns, such as replace , swap or remove . |
Orientation::COL |
Orientation::COLUMN |
Alias for Orientation::COLUMN
|
Orientation::CL |
Orientation::COLUMN |
Alias for Orientation::COLUMN
|
Orientation::C |
Orientation::COLUMN |
Alias for Orientation::COLUMN
|
Matrix(const size_t &rows , const size_t&columns , const T &value = T(0) , const EXE &device = EXE::CPU)
Constructs a matrix of size rows * columns
filled with value
and with execution policy device
.
Default fill value is T(0)
.
Default execution policy is EXE::CPU
.
Constructs a square matrix of size size
filled with value
and with execution policy device
.
Default fill value is T(0)
.
Default execution policy is EXE::CPU
.
This is the default constructor called by Matrix()
, which constructs an empty matrix (0 by 0).
Matrix(const std::vector<T> &data , const size_t &rows , const size_t&columns , const EXE &device = EXE::CPU)
Constructs a matrix from the elements of data
.
Throws an exception if rows * columns != data.size()
.
Constructs a matrix from a two dimensional vector.
Throws an exception if the size of all the vectors is not identical.
Adds data
as a row or a column at the end of the matrix according to orientation
.
Throws an exception if the number of elements in data
do not match the matrix dimensions.
Adds data
as a column at the end of the matrix.
Throws an exception if the number of elements in data
do not match the matrix dimensions.
mat.add(data , ste::Matrix<T>::Orientation::COLUMN);
Alias for add_row.
Adds data
as a row at the end of the matrix.
Throws an exception if the number of elements in data
do not match the matrix dimensions.
This function is identical to:
mat.add(data , ste::Matrix<T>::Orientation::ROW);
Computes the average of the matrix.
Implementation gives :
mat.average() == mat.sum() * (1./(mat.elements()));
Returns a reference to the element at the (x,y)
position specified in argument.
Throws an exception if the position is outside the matrix.
This is identical to calling :
mat.at(row *_columns + column).
Returns a reference to the element at the linear index specified in argument.
Throws an exception if the position is outside the matrix.
Returns a reference to the element at the (x,y)
position specified in argument.
Throws an exception if the position is outside the matrix.
Returns a reference to the element at the linear index specified in argument.
Throws an exception if the position is outside the matrix.
Returns an iterator to the beginning of the data of the matrix.
Returns an iterator to the beginning of the data of the matrix.
Non-const equivalent of begin.
Provided for specifying were the rows begin in the data.
Default implementation returns 0
.
Alias for begin_row
Provided for specifying were the columns begin in the data.
Default implementation returns 0
.
Resizes the matrix to (0 ; 0)
and removes all the elements from the data it holds.
WARNING : MEMORY IS NOT FREED WHEN T IS DYNAMICALLY ALLOCATED.
Computes the cofactor of the element speficied in argument.
Throws an exception if the position is outside the matrix.
Computes the cofactor of the element speficied in argument.
Throws an exception if the position is outside the matrix.
This is equivalent to calling:
mat.cofactor(index / _columns , index % _columns);
Computes the cofactor matrix.
Alias for cofactormatrix.
Extracts a column of the matrix and returns it as a std::vector<T>
.
Throws an exception if the position is outside the matrix.
Returns the number of columns of the matrix.
Removes all the rows or columns according to the indexes speficied in indexes
.
Throws an exception if one the positions is outside the matrix.
Removes all the rows or columns from begin
to end
(included).
Throws an exception if one the positions is outside the matrix.
Removes all the columns specified in indexes
.
Throws an exception if one the positions is outside the matrix.
This is identical to calling:
mat.cut(indexes , ste::Matrix<T>::Orientation::COLUMN);
Removes all the columns between begin
and end
(included).
Throws an exception if one the positions is outside the matrix.
This is identical to calling:
mat.cut(begin , end , ste::Matrix<T>::Orientation::COLUMN);
Alias for cut_rows.
Alias for cut_rows.
Removes all the rows specified in indexes
.
Throws an exception if one the positions is outside the matrix.
This is identical to calling:
mat.cut(indexes , ste::Matrix<T>::Orientation::ROW);
Removes all the rows between begin
and end
(included).
Throws an exception if one the positions is outside the matrix.
This is identical to calling:
mat.cut(begin , end , ste::Matrix<T>::Orientation::ROW);
Frees the memory of all elements contained by the matrix, which is resized to (0 ; 0)
.
This member function is only available when T is dynamically allocated.
Computes the determinant of the matrix.
Throws an exception if the matrix is not squared.
If your matrix has specific properties that simplify the computation of the determinant, it is recommended to override this function in a subclass.
Returns a reference to the execution policy of the matrix.
Returns a reference to the execution policy of the matrix.
Returns the total of elements stored in a matrix.
As a ste::Matrix
is always contiguous, elements
returns _rows * columns
.
Alias for hadamard.
Computes the Hadamard product (element-wise product) of the matrix and the argument.
Returns true
if the matrix is empty, false
otherwise.
Returns an iterator to the end of the data in the matrix.
Returns an iterator to the end of the data in the matrix.
Provided for specifying were the columns end in the data.
Default implementation returns _columns
.
Alias for end_row.
Provided for specifying were the rows end in the data.
Default implementation returns _rows
.
Resizes the matrix to (size ; size)
and fills it with value
.
WARNING: when T is dynamically allocated, MEMORY IS NOT FREED.
Resizes the matrix to (rows ; columns)
and fills it with value
.
WARNING: when T is dynamically allocated, MEMORY IS NOT FREED.
Applies function
according to std::for_each
to all the elements of the matrix.
Applies function
according to std::for_each
to all the elements of the matrix.
This member function is the const
equivalent of for_each.
Computes the Hadamard product (element-wise product) of the matrix and the argument.
Matrix&
insert(const size_t &element_index , const Orientation &orientation , const std::vector<T> &data)
Inserts data
as either a row or a column (according to orientation
) at the position element_index
.
Inserts data
as a column at the position element_index
.
Calling this function is equivalent to:
mat.insert(index , ste::Matrix<T>::Orientation::COLUMN , data);
Alias for insert_row.
Inserts data
as a row at the position element_index
.
Calling this function is equivalent to:
mat.insert(index , ste::Matrix<T>::Orientation::ROW , data);
Returns the inverse of the matrix, as computed by operator!.
Inverts the matrix using operator!.
Returns true
if the matrix is a column, false
otherwise.
Returns true
if the matrix is invertible, false
otherwise.
Alias for isRow
Returns true
if the matrix is a row, false
otherwise.
Returns true
if the matrix is square, false
otherwise.
Alias for rowAt.
Alias for rows.
T
max(std::function<T (const std::vector<T>&)> criterium = [](const std::vector<T> &data){return *std::max_element(data.begin() , data.end());}) const
Returns the maximum of the matrix according to the argument.
Default uses std::max_element
.
Alias for average.
T
min(std::function<T (const std::vector<T>&)> criterium = [](const std::vector<T> &data){return *std::max_element(data.begin() , data.end());}) const
Returns the minimum of the matrix according to the argument.
Default uses `std::min_element
Assignement operator. Copies the contents of the argument in the matrix.
Assignement operator. Copies the contents of the argument in the matrix.
Throws an exception if the size of all the vectors is not identical.
Assignement operator. Copies the contents of the argument in the matrix.
Throws an exception if arg.size() != _data.size()
, meaning you cannot resize a matrix with this operator.
Computes the usual matrix product of the object and the argument.
Throws an exception if the sizes do not match.
A new object is created, meaning that a deep-copy occurs.
Computes the product of the matrix and a constant.
A new object is created, meaning that a deep-copy occurs.
Computes the usual matrix product of the object and the argument, and returns a reference to it.
Computes the product of the matrix and a constant, and returns a reference to it.
Computes the usual matrix sum of the object and the argument.
A new object is created, meaning that a deep-copy occurs.
Throws an exception if the sizes do not match.
Adds the argument to all the elements of the matrix.
A new object is created, meaning that a deep-copy occurs.
Computes the usual matrix sum of the object and the argument, and returns a reference to it.
Throws an exception if the sizes do not match.
Adds the argument to all the elements of the matrix, and returns a reference to it.
Computes the usual matrix difference of the object and the argument.
A new object is created, meaning that a deep-copy occurs.
Throws an exception if the sizes do not match.
Substracts the argument to all the elements of the matrix.
A new object is created, meaning that a deep-copy occurs.
Returns the opposite of the matrix.
A new object is created, meaning that a deep-copy occurs.
Computes the usual matrix sum of the object and the argument, and returns a reference to it.
Throws an exception if the sizes do not match.
Substracts the argument to all the elements of the matrix, and returns a reference to it.
Computes the inverse of the matrix and returns it as a new object.
To fasten calculations, pre-computed formulas are used for matrices up to (4 ; 4)
.
If your matrices have specific properties that simplify the determination of the inverse, it is recommended to override this function in a subclass.
Explicitely computing an inverse is HEAVY. It is recommended to avoid such computations for matrices bigger than (10 ; 10)
.
Power operator. Returns the matrix to the specified power.
A new object is created, meaning that a deep-copy occurs.
Throws an exception if the matrix is not square. Throws an exception if the matrix is not invertible and the power is negative.
Power operator. Returns the matrix to the specified power.
Throws an exception if the matrix is not square. Throws an exception if the matrix is not invertible and the power is negative.
Equality operator.
Returns true
if the argument and the matrix are of the same size and hold the same elements at the same positions.
You may override this function if you need comparison by adresses.
Difference operator.
Returns the opposite of the result obtained by operator==.
Prints the matrix to the speficied std::outstream
, and returns a reference to the stream.
You may override this function, should you prefer another format.
Prints the size of matrix to the speficied std::outstream
, and returns a reference to the stream.
You may override this function, should you prefer another format.
Alias for add.
Alias for add_column.
Alias for add_line.
Alias for add_row.
Removes the row or column specified in argument, and returns a reference to the matrix.
Throws an exception if the index is outside the matrix.
Removes the column specified in argument, and returns a reference to the matrix.
Throws an exception if the index is outside the matrix.
Alias for remove_row.
Removes the row specified in argument, and returns a reference to the matrix.
Throws an exception if the index is outside the matrix.
Replaces the element at (row ; column)
by value
and returns a reference to the matrix.
Throws an exception if the position is outside the matrix.
Replaces the element at the linear index in argument by value
and returns a reference to the matrix.
Throws an exception if the position is outside the matrix.
Matrix&
replace(const size_t &value_index ,const Orientation &orientation , const std::vector<T> &value)
Replaces the row or column at value_index
by value
, and returns a reference to the matrix.
Throws an exception if the position is outside the matrix.
Throws an exception if the size of value
does not match the matrix' one.
Matrix&
replace(const size_t &row_begin, const size_t &row_end ,const size_t &column_begin, const size_t &column_end,const T &value)
Replaces the contents in the range specified by value
and returns a reference to the matrix.
Throws an exception if one of the positions is outside the matrix.
Replaces the column at value_index
by value
and returns a reference to the matrix.
Throws an exception if the position is outside the matrix.
Throws an exception if the size of value
does not match the matrix' one.
Alias for replace_row.
Replaces the row at value_index
by value
and returns a reference to the matrix.
Throws an exception if the position is outside the matrix.
Throws an exception if the size of value
does not match the matrix' one.
Changes the shape of the matrix to (rows ; columns)
.
Throws an exception if the number of elements is different.
Extracts a row of the matrix and returns it as a std::vector<T>
.
Throws an exception if the position is outside the matrix.
Returns a reference to the total number of rows in the matrix.
This function is still under developpment.
Transposes the matrix in place and returns a reference to it.
Changes the execution policy for the computations involving the matrix to device
.
Returns a std::vector<size_t>
holding {_rows , _columns}
.
Computes the sum of all the elements of the matrix.
Swaps two rows or two columns at the specified indexes.
Throws an exception if one of the positions is outside the matrix.
Swaps the two columns at the positions in argument.
Throws an exception if one of the positions is outside the matrix.
Alias for swap_rows.
Swaps the two rows at the positions in argument.
Throws an exception if one of the positions is outside the matrix.
Returns a reference to the vector holding the data of the matrix.
Returns a reference to the vector holding the data of the matrix.
It is possible to modify the matrix through this method.
Constructs a std::vector<std::vector<T>>
from the matrix data.
Data is ordered row by row.
This member is virtual, allowing you to change the export format.
Computes the trace of the matrix.
Applies function
according to std::transform
to all the elements of the matrix.
Returns the transpose of the matrix.
Alias for self_transpose.
Returns the identity matrix of dimensions (size ; size)
.
Elements of the diagonal are T(1)
.
Returns a square matrix of dimensions (size ; size)
filled with T(1)
.
Returns a matrix of dimensions (rows ; columns)
filled with T(1)
.
Returns a square matrix of dimensions (size ; size)
filled with uniformly distributed numbers (according to std::uniform_real_distribution<T>
).
Returns a matrix of dimensions (rows ; columns)
filled with uniformly distributed numbers (according to std::uniform_real_distribution<T>
).
Returns a square matrix of dimensions (size ; size)
filled with uniformly distributed numbers (according to std::uniform_int<T>
).
Returns a matrix of dimensions (rows ; columns)
filled with uniformly distributed numbers (according to std::uniform_int<T>
).
Alias for uniform.
Alias for uniform.
Matrix
randn (const size_t &size , const T &mean = T(0) , const T &standard_deviation = T(1.), const EXE &device = EXE::CPU)
Returns a square matrix of dimensions (size ; size)
filled with normally distributed numbers (according to std::normal_distribution<T>
) with the parameters in argument.
Matrix
randn (const size_t &rows , const size_t &columns , const T &mean = T(0) , const T &standard_deviation = T(1) const EXE &device = EXE::CPU)
Returns a matrix of dimensions (rows ; columns)
filled with normally distributed numbers (according to std::normal_distribution<T>
) with the parameters in argument.
Returns a square matrix of dimensions (size ; size)
filled with T(0)
.
Returns a matrix of dimensions (rows ; columns)
filled with T(0)
.
Alias for hadamard.
Computes the Hadamard product (element-wise product) of the two matrices.
Applies function
according to std::for_each
to all the elements of the matrix in argument.
const Matrix&
template<class T , class Function>
for_each(const Matrix<T> &matrix , Function function)
const
equivalent of for_each.
Computes the Hadamard product (element-wise product) of the two matrices.
Inverts the matrix in argument and returns a reference to it.
Prints a matrix to a std::ostream
, and returns a reference to the stream.
Prints a ste::EXE
to a std::ostream
, and returns a reference to the stream.
Binary OR for ste::EXE
.
Returns EXE::GPU
if a == EXE::GPU
or b == EXE::GPU
, or EXE::CPU
otherwise.
Logical OR for ste::EXE
.
Returns true
if a == EXE::GPU
or b == EXE::GPU
.
Binary AND for ste::EXE
.
Returns EXE::GPU
if a == EXE::GPU
and b == EXE::GPU
, or EXE::CPU
otherwise.
Logical AND for ste::EXE
.
Returns true
if a == EXE::GPU
and b == EXE::GPU
, or false
otherwise.
Applies function
to all the elements of matrix
, according to std::transform
.
enum class
used to specify the execution policy for the calculations involving a ste::Matrix.
Constant | Value | Description |
---|---|---|
EXE::CPU |
0 | All calculations involving this matrix will use the CPU, except the ones involving GPU matrices with EXE::GPU for _device . |
EXE::C |
EXE::CPU | Alias for EXE::CPU. |
EXE::HOST |
EXE::CPU | Alias for EXE::CPU. |
EXE::GPU |
1 | All calculations involving this matrix will use the GPU. This member only exists if STE_MATRIX_ALLOW_GPU has been #define d.
|
EXE::G |
EXE::GPU | Alias for EXE::GPU. |
EXE::DEVICE |
EXE::GPU | Alias for EXE::GPU. |
Shortcut for ste::Matrix<float>
.
Shortcut for ste::Matrix<double>
.
Shortcut for ste::Matrix<long double>
.
Shortcut for ste::Matrix<int>
.
Shortcut for ste::Matrix<long int>
.
Shortcut for ste::Matrix<long long int>
.
Shortcut for ste::Matrix<unsigned int>
.
Shortcut for ste::Matrix<unsigned long>
.
Shortcut for ste::Matrix<unsigned long long>
.
Shortcut for ste::Matrix<char>
.
Shortcut for ste::Matrix<unsigned char>
.
Enables the possibility to use the GPU for calculations.
When STE_MATRIX_ALLOW_GPU
is defined, ste::EXE
gains the member ste::EXE::GPU
and its aliases, allowing you to choose a device for the calculations.
See paragraph Using a GPU for more information.
This class is provided with the GNU General Public License v3.0.
See ste-Matrix/LICENSE for more information.
Developer / Tester: DUHAMEL Erwan (erwanduhamel@outlook.com)
Tester: SOUDIER Jean (jean.soudier@insa-strasbourg.fr)