song.yz@foxmail.com wechat: math-box

计算数学



C语言矩阵与向量运算

C语言对矩阵与向量运算比较简洁的方式是动态数组。由于矩阵与向量在数值计算中较为频繁,也可以单独定义为结构体。 以下为C语言实现矩阵与向量相乘范例,分别给出范例。
至于矩阵的其他运算可以参考前面的算法。


   /*------------------------------------------------------
   Created  :  Song Yezhi   2024-2-8 14:40

   include  需包含  stdio.h 与  stdlib.h  因显示问题,使用时注意

--------------------------------------------------------
   Email        : song.yz@foxmail.com
   Copyrigt (C) : Chinese Academy of Sciences
                  All rights reserved,  2024
-------------------------------------------------------*/

#include 
#include 

// Function to allocate a matrix
double** matrix(int rows, int cols)
{
	double **matrix = (double**) malloc(rows * sizeof(double*));
	for (int i = 0; i < rows; i++)
	{
		matrix[i] = (double*) malloc(cols * sizeof(double));
	}
	return matrix;
}

double* vector(int cols)
{
	double *vec = (double*) malloc(cols * sizeof(double));
	return vec;
}

// Function to free a matrix
void freeMatrix(int rows, double **matrix)
{
	for (int i = 0; i < rows; i++)
	{
		free(matrix[i]);
	}
	free(matrix);
}

// Function to multiply a matrix by a vector
void matmul(int rows, int cols, double **matrix, double *vector, double *result)
{
	for (int i = 0; i < rows; i++)
	{
		result[i] = 0.0;
		for (int j = 0; j < cols; j++)
		{
			result[i] = result[i] + matrix[i][j] * vector[j];
		}
	}
}

// Function to print a vector
void printVector(int size, double *vector)
{
	for (int i = 0; i < size; i++)
	{
		printf("%.4f\t", vector[i]);
	}
	printf("\n");
}

void printMatrix(int rows, int cols, double **matrix)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			printf("%.4f\t", matrix[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	// Define matrix dimensions
	int rows = 8;
	int cols = 3;

	// Allocate matrix
	double **A = matrix(rows, cols);

	// Initialize matrix
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			A[i][j] = (i + j) * 1.0;
		}
	}

	double *b = vector(cols);

	for (int i = 0; i < cols; i++)
	{
		b[i] = i * 1.0;
	}

	double *result = vector(rows);

	// Multiply matrix by vector
	matmul(rows, cols, A, b, result);

	// Print the results
	printf("Matrix:\n");
	printMatrix(rows, cols, A);

	printf("\nVector:\n");
	printVector(cols, b);

	printf("\nResulting Vector:\n");
	printVector(rows, result);

	// Free allocated memory
	freeMatrix(rows, A);
	free(b);
	free(result);

	return 0;
}




或者定义为结构体形式,这样在矩阵与向量运算时,维数可以包含在结构体的元素中,而不必作为参数输入输出。

  #include 
    #include 
    
    // 定义向量结构体
    typedef struct
    {
      int size;        // 向量的大小
      double *data;    // 指向向量数据的指针
    } Vector;
    
    // 初始化向量
    Vector createVector(int size)
    {
      Vector vector;
      vector.size = size;
      vector.data = (double*) malloc(size * sizeof(double));
      return vector;
    }
    
    // 释放向量内存
    void freeVector(Vector *vector)
    {
      free(vector->data);
      vector->data = NULL;
      vector->size = 0;
    }
    
    // 定义矩阵结构体
    typedef struct
    {
      int rows;        // 矩阵的行数
      int cols;        // 矩阵的列数
      double **data;   // 指向矩阵数据的二维指针
    } Matrix;
    
    // 初始化矩阵
    Matrix createMatrix(int rows, int cols)
    {
      Matrix matrix;
      matrix.rows = rows;
      matrix.cols = cols;
    
      // 分配指向行指针的内存
      matrix.data = (double**) malloc(rows * sizeof(double*));
      if (matrix.data == NULL)
      {
        perror("Error allocating memory for matrix rows");
        exit(EXIT_FAILURE);
      }
    
      // 分配每行元素的内存
      for (int i = 0; i < rows; i++)
      {
        matrix.data[i] = (double*) malloc(cols * sizeof(double));
        if (matrix.data[i] == NULL)
        {
          perror("Error allocating memory for matrix elements");
          // 释放之前已分配的内存
          for (int j = 0; j < i; j++)
          {
            free(matrix.data[j]);
          }
          free(matrix.data);
          exit(EXIT_FAILURE);
        }
      }
    
      return matrix;
    }
    
    // 释放矩阵内存
    void freeMatrix(Matrix *matrix)
    {
      for (int i = 0; i < matrix->rows; i++)
      {
        free(matrix->data[i]);
      }
      free(matrix->data);
      matrix->data = NULL;
      matrix->rows = 0;
      matrix->cols = 0;
    }
    
    // 矩阵与向量相乘
    Vector matmul(Matrix matrix, Vector vector)
    {
      if (matrix.cols != vector.size)
      {
        printf("Error: Matrix columns must match vector size.\n");
        exit(1);
      }
    
      Vector result = createVector(matrix.rows);
      for (int i = 0; i < matrix.rows; i++)
      {
        result.data[i] = 0;
        for (int j = 0; j < matrix.cols; j++)
        {
          result.data[i] += matrix.data[i][j] * vector.data[j];
        }
      }
      return result;
    }
    
    int main()
    {
      // 创建一个3x2的矩阵
      Matrix matrix;
      matrix = createMatrix(3, 2);
    
      // 初始化矩阵数据
      for (int i = 0; i < matrix.rows; i++)
      {
        for (int j = 0; j < matrix.cols; j++)
        {
          matrix.data[i][j] = i + j + 1; // 填充矩阵为1, 2, 3, 4, 5, 6
        }
      }
    
      // 创建一个2维的向量
      Vector vector = createVector(2);
    
      // 初始化向量数据
      vector.data[0] = 1;
      vector.data[1] = 2;
    
      // 执行矩阵乘以向量的操作
      Vector result = matmul(matrix, vector);
    
      // 打印结果
      for (int i = 0; i < result.size; i++)
      {
        printf("%f\n", result.data[i]);
      }
    
      // 释放内存
      freeVector(&vector);
      freeMatrix(&matrix);
      freeVector(&result);
    
      return 0;
    }