Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
GRASLAND Hadrien
Fast5x5
Commits
b843b601
Commit
b843b601
authored
May 18, 2017
by
Lucas Serrano
Browse files
Matrix inversion
parent
bfd54bf3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
56 additions
and
13 deletions
+56
-13
fast_matrix.hpp
fast_matrix.hpp
+56
-13
No files found.
fast_matrix.hpp
View file @
b843b601
...
...
@@ -6,7 +6,8 @@
#include<boost/simd/constant/one.hpp>
#include<boost/simd/function/aligned_store.hpp>
#include<boost/simd/function/dot.hpp>
#include <boost/simd/function/shuffle.hpp>
#include<boost/simd/function/shuffle.hpp>
#include<boost/simd/function/none.hpp>
namespace
bs
=
boost
::
simd
;
...
...
@@ -19,6 +20,9 @@ constexpr int nearest_power_of_two(int min_value, int current_value) {
template
<
typename
T
,
int
MatrixSize
,
int
MaxVecSize
>
class
BaseMatrix
;
template
<
typename
T
,
int
MatrixSize
,
int
MaxVecSize
>
class
IdentityMatrix
;
template
<
typename
T
,
int
MatrixSize
,
int
MaxVecSize
>
class
Matrix
:
public
BaseMatrix
<
T
,
MatrixSize
,
MaxVecSize
>
{
};
...
...
@@ -100,7 +104,7 @@ static inline void matrix_mul_m_m(M &a, M &b, M &c) {
}
template
<
typename
M
>
static
inline
void
matrix_mul_
t
m_m
(
M
&
a
,
M
&
b
,
M
&
c
)
{
static
inline
void
matrix_mul_m
t
_m
(
M
&
a
,
M
&
b
,
M
&
c
)
{
/*
* Computes the following matrix product C = t(A)*B
* where A, B and C are BaseMatrix objects.
...
...
@@ -174,27 +178,58 @@ static constexpr int blend_for_size(int i, int c) {
}
template
<
typename
pack_t
,
int
Size
>
void
protect_for_division
(
pack_t
&
vector
)
{
pack_t
&
protect_for_division
(
pack_t
&
vector
)
{
vector
=
bs
::
shuffle
<
bs
::
pattern
<
blend_for_size
<
Size
>>>
(
vector
,
bs
::
One
<
pack_t
>
());
return
vector
;
}
template
<
typename
M
,
int
N
>
void
matrix_inv
(
M
&
matrix
,
M
&
inverse
)
{
void
matrix_inv
(
M
&
A
,
M
&
X
)
{
using
pack_t
=
bs
::
pack
<
typename
M
::
ElementType
,
M
::
VecSize
>
;
static
BaseMatrix
<
typename
M
::
ElementType
,
M
::
MatSize
,
M
::
MaxVecSize
>
Id
(
1
);
M
R
,
P
,
AP
,
AlphaP
,
AlphaAP
;
pack_t
alpha
,
rs_old
,
rs_new
,
tmp
;
X
=
Id
;
matrix_sub
(
Id
,
A
,
R
);
P
=
R
;
rs_old
=
column_dot_product
(
R
,
R
);
for
(
int
i
=
0
;
i
<
N
&&
!
bs
::
none
(
rs_old
);
i
++
)
{
matrix_mul_m_m
(
A
,
P
,
AP
);
tmp
=
column_dot_product
(
P
,
AP
);
alpha
=
rs_old
/
protect_for_division
<
pack_t
,
M
::
MatSize
>
(
tmp
);
column_scalar_product
(
alpha
,
P
,
AlphaP
);
matrix_add
(
X
,
AlphaP
,
X
);
column_scalar_product
(
alpha
,
AP
,
AlphaAP
);
matrix_sub
(
R
,
AlphaAP
,
R
);
rs_new
=
column_dot_product
(
R
,
R
);
tmp
=
rs_new
/
protect_for_division
<
pack_t
,
M
::
MatSize
>
(
rs_old
);
column_scalar_product
(
tmp
,
P
,
P
);
matrix_add
(
R
,
P
,
P
);
rs_old
=
rs_new
;
}
/*
matrix_mul_m_m(A, P, AP);
tmp = column_dot_product(P, AP);
alpha = rs_old / protect_for_division<pack_t, M::MatSize>(tmp);
column_scalar_product(alpha, P, AlphaP);
matrix_add(X, AlphaP, X);
*/
}
template
<
typename
T
,
int
MatrixSize
,
int
Max
Vec
Size
>
template
<
typename
T
,
int
MatrixSize
,
int
Max
imumVector
Size
>
class
BaseMatrix
{
/* Class for matrix object
* Matrix object are linearized 2D array with padded line to fit vector size
*/
static_assert
(
MatrixSize
<=
Max
Vec
Size
,
"Matrix size must be less than maximum vector size"
);
static_assert
((
Max
Vec
Size
>=
4
)
&
!
(
Max
Vec
Size
&
(
Max
Vec
Size
-
1
)),
"Maximum vector size must be a power of two."
);
static_assert
(
MatrixSize
<=
Max
imumVector
Size
,
"Matrix size must be less than maximum vector size"
);
static_assert
((
Max
imumVector
Size
>=
4
)
&
!
(
Max
imumVector
Size
&
(
Max
imumVector
Size
-
1
)),
"Maximum vector size must be a power of two."
);
protected:
static
constexpr
int
MatSize
=
MatrixSize
;
static
constexpr
int
MaxVecSize
=
MaximumVectorSize
;
// We use the smallest vector size possible
static
constexpr
int
VecSize
=
nearest_power_of_two
(
MatrixSize
,
Max
Vec
Size
);
static
constexpr
int
VecSize
=
nearest_power_of_two
(
MatrixSize
,
Max
imumVector
Size
);
using
matrix_t
=
BaseMatrix
<
T
,
MatrixSize
,
MaxVecSize
>
;
using
pack_t
=
bs
::
pack
<
T
,
VecSize
>
;
...
...
@@ -202,7 +237,7 @@ class BaseMatrix {
public:
BaseMatrix
()
=
default
;
BaseMatrix
(
float
const
a
[])
{
BaseMatrix
(
T
const
a
[])
{
if
(
MatSize
==
VecSize
)
{
// In this case there is no padding, we can copy directly the array
std
::
memcpy
(
this
->
array
,
a
,
sizeof
(
T
)
*
MatSize
*
VecSize
);
}
...
...
@@ -213,7 +248,13 @@ class BaseMatrix {
}
}
matrix_t
operator
=
(
float
const
a
[])
{
BaseMatrix
(
T
const
a
)
{
for
(
int
i
=
0
;
i
<
MatrixSize
;
i
++
)
{
array
[
VecSize
*
i
+
i
]
=
a
;
}
}
matrix_t
operator
=
(
T
const
a
[])
{
if
(
MatSize
==
VecSize
)
{
std
::
memcpy
(
this
->
array
,
a
,
sizeof
(
T
)
*
MatSize
*
VecSize
);
}
...
...
@@ -243,20 +284,22 @@ class BaseMatrix {
}
private:
friend
void
matrix_add
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
void
matrix_sub
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
void
matrix_mul_m_m
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
void
matrix_mul_
t
m_m
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
void
matrix_mul_m
t
_m
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
void
matrix_mul_m_mt
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
,
matrix_t
&
c
);
friend
bs
::
pack
<
ElementType
,
VecSize
>
column_dot_product
<
matrix_t
>
(
matrix_t
&
a
,
matrix_t
&
b
);
friend
void
column_scalar_product
<
matrix_t
,
pack_t
>
(
pack_t
&
scalar
,
matrix_t
&
b
,
matrix_t
&
c
);
template
<
typename
M
,
int
N
>
friend
void
matrix_inv
(
M
&
a
,
M
&
b
);
friend
std
::
ostream
&
operator
<<<
T
,
MatrixSize
,
MaxVecSize
>
(
std
::
ostream
&
os
,
matrix_t
&
mat
);
protected:
alignas
(
sizeof
(
T
)
*
VecSize
)
float
array
[
MatSize
*
VecSize
]
=
{
0
};
};
/*
template<typename T, int MatrixSize, int MaxVecSize>
class IdentityMatrix: public BaseMatrix<T, MatrixSize, MaxVecSize> {
using BaseMatrix<T, MatrixSize, MaxVecSize>::VecSize;
...
...
@@ -267,4 +310,4 @@ class IdentityMatrix: public BaseMatrix<T, MatrixSize, MaxVecSize> {
this->array[VecSize*i+i] = 1;
}
}
};
};
*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment