如何用C语言中的一个函数操作不同大小的矩阵?
我有一个来自Mathlab的代码,所有的矩阵运算都是由几个符号完成的。通过将其转换为C,我面临一个问题,即对于每种大小的矩阵,我都必须创建一个特殊的函数。这是一个很大的代码,我不会把它全部放在这里,但会尝试解释它是如何工作的 我还有一个大循环,其中有很多矩阵运算。使用矩阵操作的函数应将矩阵作为收入,并将结果存储在临时矩阵中以备后续操作。事实上,我知道矩阵的大小,但我也想使函数尽可能通用。为了减少代码大小和节省时间 例如,2x4和4x4矩阵的矩阵换位操作:如何用C语言中的一个函数操作不同大小的矩阵?,c,arrays,pointers,matrix,C,Arrays,Pointers,Matrix,我有一个来自Mathlab的代码,所有的矩阵运算都是由几个符号完成的。通过将其转换为C,我面临一个问题,即对于每种大小的矩阵,我都必须创建一个特殊的函数。这是一个很大的代码,我不会把它全部放在这里,但会尝试解释它是如何工作的 我还有一个大循环,其中有很多矩阵运算。使用矩阵操作的函数应将矩阵作为收入,并将结果存储在临时矩阵中以备后续操作。事实上,我知道矩阵的大小,但我也想使函数尽可能通用。为了减少代码大小和节省时间 例如,2x4和4x4矩阵的矩阵换位操作: void A_matrix_transp
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix);
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix);
int main() {
float transposed_matrix_A[4][2]; //temporary matrices
float transposed_matrix_B[4][4];
float input_matrix_A[2][4], input_matrix_B[4][4]; //input matrices with numbers
A_matrix_transposition (transposed_matrix_A, input_matrix_A, 2, 4);
B_matrix_transposition (transposed_matrix_B, input_matrix_B, 4, 4);
// after calling the functions i want to use temporary matrices again. How do I pass them to other functions if i dont know their size, in general?
}
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
void A_matrix_transposition(float transposed_matrix[4][2]、float matrix[2][4]、int rows_in_matrix、int columns_in_matrix);
无效B_矩阵_变换(浮点变换_矩阵[4][4],浮点矩阵[4][4],矩阵中的int行_,矩阵中的int列_);
int main(){
浮点转置_矩阵_A[4][2];//临时矩阵
浮点转置_矩阵_B[4][4];
浮点输入矩阵A[2][4],输入矩阵B[4][4];//带数字的输入矩阵
A_矩阵_变换(变换矩阵_A,输入矩阵_A,2,4);
B_矩阵_变换(变换矩阵_B,输入矩阵_B,4,4);
//调用函数后,我想再次使用临时矩阵。如果我不知道它们的大小,通常如何将它们传递给其他函数?
}
无效A_矩阵_转置(浮点转置_矩阵[4][2],浮点矩阵[2][4],矩阵中的int行_,矩阵中的int列_)
{静态int i,j;
对于(i=0;i<矩阵中的行数;++i){
对于(j=0;j<矩阵中的列;++j)
{转置_矩阵[j][i]=矩阵[i][j];
}
}
}
无效B_矩阵_变换(浮点变换_矩阵[4][4],浮点矩阵[4][4],矩阵中的int行_,矩阵中的int列_)
{静态int i,j;
对于(i=0;i<矩阵中的行数;++i){
对于(j=0;j<矩阵中的列;++j)
{转置_矩阵[j][i]=矩阵[i][j];
}
}
}
操作很简单,但是由于有两个不同的函数,代码已经很庞大了,但是如果我继续这样做的话,这将是一个缓慢的灾难
我如何创建一个函数进行转置以操作不同大小的矩阵
我想可以用指针来做,但我不知道怎么做
我正在寻找一个真实的一般的答案,以了解如何调整函数和临时矩阵之间的“通信”,最好用一个例子。提前感谢所有人提供的信息和帮助。从不太好的解决方案到很好的解决方案,您可以通过不同的方式实现这一点 如果您知道矩阵的最大大小,您可以创建一个足够大的矩阵来容纳该大小,并对其进行处理。如果小于该值,则可以编写自定义操作,只考虑小的子矩阵,而不是整个子矩阵 另一种解决方案是创建一个数据结构来保存矩阵,这可能不同于使用存储在结构本身中的属性创建交错数组。例如:行数和列数信息将存储在结构本身中。锯齿数组的好处是,现在可以分配取消分配的内存,从而更好地控制矩阵的形式顺序。更好的是,现在你可以传递两个不同大小的矩阵,函数都可以看到包含实际矩阵的结构,并对其进行处理。(我会说)。 我所说的结构是指
struct matrix{
int ** mat;
int row;
int col;
}
如果您的C实现支持可变长度数组,则可以通过以下方式实现:
void matrix_transposition(size_t M, size_t N,
float Destination[M][N], const float Source[N][M])
{
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m][n] = Source[n][m];
}
(不幸的是,这会阻止编译器检查参数类型是否与预期类型匹配,但这是C的一个缺点。)
如果您需要一个严格使用标准C且没有可变长度数组的解决方案,那么从技术上讲,正确的方法是复制对象的字节:
void matrix_transposition(size_t M, size_t N,
void *DestinationPointer, const void *SourcePointer)
{
char *Destination = DestinationPointer;
const char *Source = SourcePointer;
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
{
// Calculate locations of elements in memory.
char *D = Destination + (m*N+n) * sizeof(float);
const char *S = Source + (n*M+m) * sizeof(float);
memcpy(D, S, sizeof(float));
}
}
void matrix\u transposition(大小\u t M,大小\u t N,
void*DestinationPointer,const void*SourcePointer)
{
char*Destination=DestinationPointer;
const char*Source=SourcePointer;
用于(尺寸m=0;m
笔记:
包含
以声明大小
,如果使用上一个解决方案,则包含
以声明memcpy
可变长度数组在C 1999中是必需的,但在C 2011中是可选的。通用系统的高质量编译器将支持它们。如果您使用的是C99编译器,则可以使用可变长度数组(VLA)(在C11编译器中是可选的)。您可以编写如下函数:
void matrix_transposition (int rows_in_matrix, int columnes_in_matrix, float transposed_matrix[columnes_in_matrix][rows_in_matrix], float matrix[rows_in_matrix][columnes_in_matrix])
{
int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{
transposed_matrix[j][i] = matrix[i][j];
}
}
}
matrix_transposition (2, 4, transposed_matrix_A, input_matrix_A);
matrix_transposition (4, 4, transposed_matrix_B, input_matrix_B);
您可能不想在程序中硬编码数组大小。我建议使用一个包含单个平面阵列的结构,然后可以在二维中对其进行解释:
typedef struct {
size_t width;
size_t height;
float *elements;
} Matrix;
将其初始化为
int matrix_init(Matrix *m, size_t w, size_t h)
{
m.elements = malloc((sizeof *m.elements) * w * h);
if (!m.elements) {
m.width = m.height = 0;
return 0; /* failed */
}
m.width = w;
m.height = h;
return 1; /* success */
}
然后,为了找到位置(x,y)处的元素,我们可以使用一个简单的函数:
float *matrix_element(Matrix *m, size_t x, size_t y)
{
/* optional: range checking here */
return m.elements + x + m.width * y;
}
这比指针数组具有更好的局部性(并且更容易、更快地正确分配和取消分配),并且比数组数组更灵活(如您所发现的,内部数组需要编译时常量大小)
您可能能够使用一个包装在
矩阵
结构中的数组数组-如果数组数组在您的平台上有填充,您可能需要一个跨步
,它不一定与宽度
相同。在C中正确的方法是创建一个结构矩阵
,元素的2D数组指针和两个等于数字o的整数值
int matrix_init(Matrix *m, size_t w, size_t h)
{
m.elements = malloc((sizeof *m.elements) * w * h);
if (!m.elements) {
m.width = m.height = 0;
return 0; /* failed */
}
m.width = w;
m.height = h;
return 1; /* success */
}
float *matrix_element(Matrix *m, size_t x, size_t y)
{
/* optional: range checking here */
return m.elements + x + m.width * y;
}