创建一个可以返回对角矩阵的c++ mex函数



我需要创建一个c++ mex函数,该函数输入一个矩阵并在其各自的块中与每个数组对角返回它。交货。

input_matrix = ([1,2,3;4,5,6;7,8,9])
output_matrix = 1 2 3 0 0 0 0 0 0
0 0 0 4 5 6 0 0 0
0 0 0 0 0 0 7 8 9

有谁能帮帮我吗?我现在完全迷路了。

我为你做了这个例子,基本的构建块是std::vector。矩阵可以建模为std::vector的std::vector。std::vector是用于动态分配数组的c++标准库类型

#include <array>
#include <cassert>
#include <vector>
#include <iostream>
// for fixed size arrays use templates, this will also ensure contiguous memory allocation
// to be compatible with other libraries
template<typename type_t, std::size_t rows_v, std::size_t cols_v>
auto create_diagonal_matrix(const type_t(&input)[rows_v][cols_v])
{
// unlike "C" style arrays std::array can be returned from a function
std::array<std::array<type_t,cols_v*rows_v>, rows_v> matrix;
std::size_t prefix_size = 0ul;                         // number of zeros in front of the next row
std::size_t postfix_size = (rows_v - 1ul) * cols_v;    // how many zeros to append at the end of next row;
for (std::size_t row = 0ul; row < rows_v; ++row)
{
std::size_t col = 0ul;
// fill prefix_size indices with 0
for (std::size_t n = 0ul; n < prefix_size; ++n, ++col) matrix[row][col] = 0;
// fill input row size entries with values from the input
for (std::size_t n = 0ul; n < rows_v; ++n, ++col) matrix[row][col] = input[row][n];
// then fill postfix_size indices with 0
for (std::size_t n = 0ul; n < postfix_size; ++n, ++col) matrix[row][col] = 0;
// adjuest the prefix and postfix sizes
prefix_size += rows_v;
postfix_size -= rows_v;
}
return matrix;
}

auto create_diagonal_matrix_dynamic(const std::vector<std::vector<int>>& input)
{
std::vector<std::vector<int>> matrix;
assert(input.size() > 0);
auto row_size = input[0].size();
std::size_t prefix_size = 0ul;                                  // number of zeros in front of the next row
std::size_t postfix_size = (input.size() - 1ul) * row_size;    // how many zeros to append at the end of next row;
for (const auto& row : input)
{
assert(row.size() == row_size);                             // runtime validation, all rows must have same length
std::vector<int> new_row;
// fill prefix_size indices with 0
for (std::size_t n = 0ul; n < prefix_size; ++n) new_row.push_back(0);
// fill input row size entries with values from the input
for (std::size_t n = 0ul; n < row_size; ++n) new_row.push_back(row[n]);
// then fill postfix_size indices with 0
for (std::size_t n = 0ul; n < postfix_size; ++n) new_row.push_back(0);
matrix.push_back(new_row);
// adjuest the prefix and postfix sizes
prefix_size += row_size;
postfix_size -= row_size;
}
return matrix;
}
int main()
{
// use an initializer list to setup the 2D input array
// I think in your code this should be done through parsing an input string
// and then build up a std::vector<std::vector<int>> yourself.
auto matrix = create_diagonal_matrix({ {1,2,3}, {4,5,6}, {7,8,9} });
// output the generated matrix.
for (const auto& row : matrix)
{
bool comma = false;
for (const auto& value : row)
{
if (comma) std::cout << ", ";
std::cout << value;
comma = true;
}
std::cout << "n";
}
std::cout << std::endl;
// to show memory is contiguous in std::array<std::array<int,9>,3>
// this is how to get access to contiguous memory for std::array
auto data_ptr = matrix.data();
for (std::size_t row = 0; row < matrix.size(); row++)   
{
bool comma = false;
for (std::size_t col = 0; col < matrix[0].size(); col++)
{
if (comma) std::cout << ", ";
std::cout << data_ptr[row][col];    
comma = true;
}
std::cout << "n";
}
// creating a mex file is desribed here 
// https://www.mathworks.com/help/matlab/matlab_external/c-mex-source-file.html
return 0;
}