Matrix and permutation precomputation. More...
Functions | |
void | prepare_permutation (std::span< std::size_t > perm) |
template<typename E > | |
void | apply_permutation (std::span< const std::size_t > perm, std::span< E > data, std::size_t offset=0, std::size_t block_size=1) |
template<typename E > | |
void | apply_permutation_mapped (std::span< const std::size_t > perm, std::span< E > data, std::span< const int > emap, std::size_t block_size=1) |
Permutation of mapped data. | |
template<typename E > | |
void | apply_permutation_to_transpose (std::span< const std::size_t > perm, std::span< E > data, std::size_t offset=0, std::size_t block_size=1) |
template<std::floating_point T> | |
std::vector< std::size_t > | prepare_matrix (std::pair< std::vector< T >, std::array< std::size_t, 2 >> &A) |
template<typename T , typename E > | |
void | apply_matrix (std::span< const std::size_t > v_size_t, MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 >> M, std::span< E > data, std::size_t offset=0, std::size_t block_size=1) |
Apply a (precomputed) matrix. More... | |
template<typename T , typename E > | |
void | apply_matrix_to_transpose (std::span< const std::size_t > v_size_t, MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 >> M, std::span< E > data, std::size_t offset=0, std::size_t block_size=1) |
Apply a (precomputed) matrix to some transposed data. More... | |
Matrix and permutation precomputation.
void basix::precompute::apply_matrix | ( | std::span< const std::size_t > | v_size_t, |
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 >> | M, | ||
std::span< E > | data, | ||
std::size_t | offset = 0 , |
||
std::size_t | block_size = 1 |
||
) |
Apply a (precomputed) matrix.
This uses the representation returned by prepare_matrix()
to apply a matrix without needing any temporary memory.
In pseudo code, this function does the following:
If block_size
is set, this will apply the permutation to every block. The offset
is set, this will start applying the permutation at the offset
th block.
[in] | v_size_t | A permutation, as computed by precompute::prepare_matrix |
[in] | M | The vector created by precompute::prepare_matrix |
[in,out] | data | The data to apply the permutation to |
[in] | offset | The position in the data to start applying the permutation |
[in] | block_size | The block size of the data |
void basix::precompute::apply_matrix_to_transpose | ( | std::span< const std::size_t > | v_size_t, |
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 >> | M, | ||
std::span< E > | data, | ||
std::size_t | offset = 0 , |
||
std::size_t | block_size = 1 |
||
) |
Apply a (precomputed) matrix to some transposed data.
See apply_matrix()
.
void basix::precompute::apply_permutation | ( | std::span< const std::size_t > | perm, |
std::span< E > | data, | ||
std::size_t | offset = 0 , |
||
std::size_t | block_size = 1 |
||
) |
Apply a (precomputed) permutation
This uses the representation returned by prepare_permutation()
to apply a permutation without needing any temporary memory.
In pseudo code, this function does the following:
If block_size
is set, this will apply the permutation to every block. The offset
is set, this will start applying the permutation at the offset
th block.
As an example, consider the permutation P = [1, 4, 0, 5, 2, 3]
. In the documentation of prepare_permutation()
, we saw that the precomputed representation of this permutation is P2 = [1, 4, 4, 5, 4, 5]
. In this example, we look at how this representation can be used to apply this permutation to the array A = [a, b, c, d, e, f]
.
P2[0]
is 1, so we swap A[0]
and A[1]
. After this, A = [b, a, c, d, e, f]
.
P2[1]
is 4, so we swap A[1]
and A[4]
. After this, A = [b, e, c, d, a, f]
.
P2[2]
is 4, so we swap A[2]
and A[4]
. After this, A = [b, e, a, d, c, f]
.
P2[3]
is 5, so we swap A[3]
and A[5]
. After this, A = [b, e, a, f, c, d]
.
P2[4]
is 4, so we swap A[4]
and A[4]
. This changes nothing.
P2[5]
is 5, so we swap A[5]
and A[5]
. This changes nothing.
Therefore the result of applying this permutation is [b, e, a, f, c, d]
(which is what we get if we apply the permutation directly).
[in] | perm | A permutation in precomputed form (as returned by prepare_permutation() ) |
[in,out] | data | The data to apply the permutation to |
[in] | offset | The position in the data to start applying the permutation |
[in] | block_size | The block size of the data |
void basix::precompute::apply_permutation_to_transpose | ( | std::span< const std::size_t > | perm, |
std::span< E > | data, | ||
std::size_t | offset = 0 , |
||
std::size_t | block_size = 1 |
||
) |
Apply a (precomputed) permutation to some transposed data
see apply_permutation()
.
std::vector<std::size_t> basix::precompute::prepare_matrix | ( | std::pair< std::vector< T >, std::array< std::size_t, 2 >> & | A | ) |
Prepare a square matrix
This computes the LU decomposition of the transpose of the matrix
This function returns the permutation \(P\)P in the representation \(PA^t=LU\) (precomputed as in prepare_permutation()
). The LU decomposition of \(A^t\) is computed in-place
For an example of how the permutation in this form is applied, see apply_matrix()
.
[in,out] | A | The matrix's data |
prepare_permutation()
);void basix::precompute::prepare_permutation | ( | std::span< std::size_t > | perm | ) |
Prepare a permutation
This computes a representation of the permutation that allows the permutation to be applied without any temporary memory assignment.
In pseudo code, this function does the following:
As an example, consider the permutation P = [1, 4, 0, 5, 2, 3]
.
First, we look at the 0th entry. P[0]
is 1. This is greater than 0, so the 0th entry of the output is 1.
Next, we look at the 1st entry. P[1]
is 4. This is greater than 1, so the 1st entry of the output is 4.
Next, we look at the 2nd entry. P[2]
is 0. This is less than 2, so we look at P[0].
P[0]is 1. This is less than 2, so we look at
P[1].
P[1]` is 4. This is greater than 2, so the 2nd entry of the output is 4.
Next, we look at the 3rd entry. P[3]
is 5. This is greater than 3, so the 3rd entry of the output is 5.
Next, we look at the 4th entry. P[4]
is 2. This is less than 4, so we look at P[2]
. P[2]
is 0. This is less than 4, so we look at P[0]
. P[0]
is 1. This is less than 4, so we look at P[1]
. P[1]
is 4. This is greater than (or equal to) 4, so the 4th entry of the output is 4.
Next, we look at the 5th entry. P[5]
is 3. This is less than 5, so we look at P[3]
. P[3]
is 5. This is greater than (or equal to) 5, so the 5th entry of the output is 5.
Hence, the output of this function in this case is [1, 4, 4, 5, 4, 5]
.
For an example of how the permutation in this form is applied, see apply_permutation()
.
[in,out] | perm | A permutation |