Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 62 additions & 54 deletions python_numpy/python_numpy_base_simplification.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,108 +608,116 @@ struct ConcatenateArgsType {
};

template <std::size_t M, std::size_t N, typename Tuple, typename... Args>
using ConcatenateArgsType_t =
typename ConcatenateArgsType<M, N, Tuple, Args...>::type;
using ArgsType_t = typename ConcatenateArgsType<M, N, Tuple, Args...>::type;

template <std::size_t M, std::size_t N, typename Tuple, typename Last>
inline auto concatenate_args(const Tuple &previousArgs, Last last) ->
typename ConcatenateBlock<
M, N,
decltype(std::tuple_cat(previousArgs, std::make_tuple(last)))>::type {
template <std::size_t M, std::size_t N, typename Concatenate_Type,
typename Tuple, typename Last>
inline void concatenate_args(Concatenate_Type &Concatenated,
const Tuple &previousArgs, Last last) {

auto all_args = std::tuple_cat(previousArgs, std::make_tuple(last));

using UpdatedArgsType = decltype(all_args);

constexpr std::size_t TUPLE_SIZE = std::tuple_size<decltype(all_args)>::value;
constexpr std::size_t TUPLE_SIZE = std::tuple_size<UpdatedArgsType>::value;

static_assert(TUPLE_SIZE == (M * N),
"Number of arguments must be equal to M * N.");

typename ConcatenateBlock<M, N, UpdatedArgsType>::type result;
using ConcatenateMatrix_Type =
typename ConcatenateBlock<M, N, UpdatedArgsType>::type;

PartMatrixOperation::TupleRow<M, N, decltype(result), decltype(all_args), 0,
M>::substitute(result, all_args);

return result;
PartMatrixOperation::TupleRow<M, N, ConcatenateMatrix_Type, UpdatedArgsType,
0, M>::substitute(Concatenated, all_args);
}

template <std::size_t M, std::size_t N, typename Tuple, typename First,
typename... Rest>
inline auto concatenate_args(const Tuple &previousArgs, First first,
Rest... rest)
-> ConcatenateArgsType_t<
M, N, decltype(std::tuple_cat(previousArgs, std::make_tuple(first))),
Rest...> {
template <std::size_t M, std::size_t N, typename Concatenate_Type,
typename Tuple, typename First, typename... Rest>
inline void concatenate_args(Concatenate_Type &Concatenated,
const Tuple &previousArgs, First first,
Rest... rest) {

auto updatedArgs = std::tuple_cat(previousArgs, std::make_tuple(first));

return concatenate_args<M, N>(updatedArgs, rest...);
return concatenate_args<M, N>(Concatenated, updatedArgs, rest...);
}

template <std::size_t M, std::size_t N, typename... Args>
inline auto calculate(Args... args)
-> ConcatenateArgsType_t<M, N, std::tuple<>, Args...> {
inline void calculate(ArgsType_t<M, N, std::tuple<>, Args...> &Concatenated,
Args... args) {
static_assert(M > 0, "M must be greater than 0.");
static_assert(N > 0, "N must be greater than 0.");

return concatenate_args<M, N>(std::make_tuple(), args...);
return concatenate_args<M, N>(Concatenated, std::make_tuple(), args...);
}

} // namespace ConcatenateBlockOperation

template <std::size_t M, std::size_t N, typename Concatenate_Type,
typename... Args>
inline void update_block_concatenated_matrix(Concatenate_Type &Concatenated,
Args... args) {

static_assert(M > 0, "M must be greater than 0.");
static_assert(N > 0, "N must be greater than 0.");

ConcatenateBlockOperation::calculate<M, N>(Concatenated, args...);
}

template <std::size_t M, std::size_t N, typename... Args>
inline auto concatenate_block(Args... args)
-> ConcatenateBlockOperation::ConcatenateArgsType_t<M, N, std::tuple<>,
Args...> {
-> ConcatenateBlockOperation::ArgsType_t<M, N, std::tuple<>, Args...> {

ConcatenateBlockOperation::ArgsType_t<M, N, std::tuple<>, Args...>
Concatenated;

ConcatenateBlockOperation::calculate<M, N>(Concatenated, args...);

return ConcatenateBlockOperation::calculate<M, N>(args...);
return Concatenated;
}

/* Concatenate block Type */
template <std::size_t M, std::size_t N, typename... Args>
using ConcatenateBlock_Type =
typename ConcatenateBlockOperation::ConcatenateArgsType_t<
M, N, std::tuple<>, Args...>;
typename ConcatenateBlockOperation::ArgsType_t<M, N, std::tuple<>, Args...>;

/* repmat */
namespace ReatmatOperation {
/* tile */
namespace TileOperation {

template <std::size_t M, std::size_t N, std::size_t Count, typename MATRIX_Type,
typename... Args>
struct GenerateRepmatTypes {
using type = typename GenerateRepmatTypes<M, N, (Count - 1), MATRIX_Type,
MATRIX_Type, Args...>::type;
struct GenerateTileTypes {
using type = typename GenerateTileTypes<M, N, (Count - 1), MATRIX_Type,
MATRIX_Type, Args...>::type;
};

template <std::size_t M, std::size_t N, typename MATRIX_Type, typename... Args>
struct GenerateRepmatTypes<M, N, 0, MATRIX_Type, Args...> {
struct GenerateTileTypes<M, N, 0, MATRIX_Type, Args...> {
using type = ConcatenateBlock_Type<M, N, Args...>;
};

} // namespace ReatmatOperation
} // namespace TileOperation

template <std::size_t M, std::size_t N, typename MATRIX_Type>
using Repmat_Type =
typename ReatmatOperation::GenerateRepmatTypes<M, N, M * N,
MATRIX_Type>::type;
using Tile_Type =
typename TileOperation::GenerateTileTypes<M, N, M * N, MATRIX_Type>::type;

namespace ReatmatOperation {
namespace TileOperation {

template <std::size_t... Indices> struct index_sequence_for_repmat {};
template <std::size_t... Indices> struct index_sequence_for_tile {};

template <std::size_t N, std::size_t... Indices>
struct make_index_sequence_for_repmat_impl
: make_index_sequence_for_repmat_impl<N - 1, N - 1, Indices...> {};
struct make_index_sequence_for_tile_impl
: make_index_sequence_for_tile_impl<N - 1, N - 1, Indices...> {};

template <std::size_t... Indices>
struct make_index_sequence_for_repmat_impl<0, Indices...> {
using type = index_sequence_for_repmat<Indices...>;
struct make_index_sequence_for_tile_impl<0, Indices...> {
using type = index_sequence_for_tile<Indices...>;
};

template <std::size_t N>
using make_index_sequence_for_repmat =
typename make_index_sequence_for_repmat_impl<N>::type;
using make_index_sequence_for_tile =
typename make_index_sequence_for_tile_impl<N>::type;

template <std::size_t Count, typename MATRIX_Type, typename... Args>
struct RepeatMatrix {
Expand All @@ -725,25 +733,25 @@ struct RepeatMatrix<0, MATRIX_Type, Args...> {
template <std::size_t M, std::size_t N, typename MATRIX_Type,
std::size_t... Indices>
inline auto implement(const MATRIX_Type &matrix,
index_sequence_for_repmat<Indices...>)
-> Repmat_Type<M, N, MATRIX_Type> {
index_sequence_for_tile<Indices...>)
-> Tile_Type<M, N, MATRIX_Type> {

return concatenate_block<M, N>((static_cast<void>(Indices), matrix)...);
}

} // namespace ReatmatOperation
} // namespace TileOperation

template <std::size_t M, std::size_t N, typename MATRIX_Type>
inline auto repmat(const MATRIX_Type &matrix)
-> Repmat_Type<M, N, MATRIX_Type> {
inline auto concatenate_tile(const MATRIX_Type &matrix)
-> Tile_Type<M, N, MATRIX_Type> {

static_assert(M > 0, "M must be greater than 0.");
static_assert(N > 0, "N must be greater than 0.");

constexpr std::size_t TotalCount = M * N;

return ReatmatOperation::implement<M, N>(
matrix, ReatmatOperation::make_index_sequence_for_repmat<TotalCount>{});
return TileOperation::implement<M, N>(
matrix, TileOperation::make_index_sequence_for_tile<TotalCount>{});
}

} // namespace PythonNumpy
Expand Down
30 changes: 27 additions & 3 deletions sample/concatenation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,15 @@ int main() {
std::cout << std::endl;

/* Concatenate Block */
constexpr std::size_t BLOCK_COLUMN_SIZE = 2;
constexpr std::size_t BLOCK_ROW_SIZE = 2;

using ABCE_Type =
ConcatenateBlock_Type<decltype(A), decltype(B), decltype(C), decltype(E)>;
ConcatenateBlock_Type<BLOCK_COLUMN_SIZE, BLOCK_ROW_SIZE, decltype(A),
decltype(B), decltype(C), decltype(E)>;

ABCE_Type ABCE = concatenate_block(A, B, C, E);
ABCE_Type ABCE =
concatenate_block<BLOCK_COLUMN_SIZE, BLOCK_ROW_SIZE>(A, B, C, E);
auto ABCE_dense = ABCE.create_dense();

std::cout << "ABCE = " << std::endl;
Expand All @@ -101,7 +106,8 @@ int main() {
std::cout << std::endl;

/* Update Block */
update_block_concatenated_matrix(ABCE, A, 2.0 * B, C, E);
update_block_concatenated_matrix<BLOCK_COLUMN_SIZE, BLOCK_ROW_SIZE>(
ABCE, A, 2.0 * B, C, E);
ABCE_dense = ABCE.create_dense();

std::cout << "ABCE = " << std::endl;
Expand All @@ -113,5 +119,23 @@ int main() {
}
std::cout << std::endl;

/* Concatenate Tile */
constexpr std::size_t TILE_COLUMN_SIZE = 2;
constexpr std::size_t TILE_ROW_SIZE = 3;

using C_Tile_Type = Tile_Type<TILE_COLUMN_SIZE, TILE_ROW_SIZE, decltype(C)>;

C_Tile_Type C_Tile = concatenate_tile<TILE_COLUMN_SIZE, TILE_ROW_SIZE>(C);
auto C_Tile_dense = C_Tile.create_dense();

std::cout << "C_Tile = " << std::endl;
for (size_t j = 0; j < C_Tile_dense.cols(); ++j) {
for (size_t i = 0; i < C_Tile_dense.rows(); ++i) {
std::cout << C_Tile_dense(j, i) << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;

return 0;
}
10 changes: 10 additions & 0 deletions sample/concatenation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,23 @@

print("vertical =")
print(vertical)
print("\n")

horizontal = np.concatenate([A, B], 1)

print("horizontal =")
print(horizontal)
print("\n")


block = np.block([[A, B], [C, E]])

print("block =")
print(block)
print("\n")


tiled_matrix = np.tile(C, (2, 3))
print("tiled_matrix =")
print(tiled_matrix)
print("\n")
21 changes: 19 additions & 2 deletions test_vs/check_python_numpy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2077,8 +2077,25 @@ void CheckPythonNumpy<T>::check_python_numpy_concatenate(void) {
tester.expect_near(ABCE_block_t_dense_2.matrix.data, ABCE_block_answer.matrix.data, NEAR_LIMIT_STRICT,
"check concatenate block Dense, Diag, Sparse and Empty.");

/* repmat */
Repmat_Type<2, 3, decltype(C)> R = repmat<2, 3>(C);
update_block_concatenated_matrix<2, 2>(ABCE_block_2, A, static_cast<T>(2)* B, C, Empty);

auto ABCE_block_dense_2 = ABCE_block_2.create_dense();

Matrix<DefDense, T, 6, 6> ABCE_block_answer_2_2({
{1, 2, 3, 2, 0, 0},
{5, 4, 6, 0, 4, 0},
{9, 8, 7, 0, 0, 6},
{1, 0, 0, 0, 0, 0},
{3, 0, 8, 0, 0, 0},
{0, 2, 4, 0, 0, 0}
});

tester.expect_near(ABCE_block_dense_2.matrix.data, ABCE_block_answer_2_2.matrix.data, NEAR_LIMIT_STRICT,
"check update block concatenated matrix Dense, Diag, Sparse and Empty.");


/* tile */
Tile_Type<2, 3, decltype(C)> R = concatenate_tile<2, 3>(C);
auto R_dense = R.create_dense();

Matrix<DefDense, T, 6, 9> R_answer({
Expand Down