C++ MKL 计算矩阵相乘/矩阵转置相乘

/*********************************************************************************************************
1.此子程序主要是用于求解矩阵的相乘
2.参数说明
传入的参数:二维数组Aa,Bb,维数int M, int K, int N
传出的参数:
*********************************************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "mkl.h"

double ** matrix_multiply(double **Aa, double **Bb, int M, int K, int N)
//M为A矩阵的行数;K为矩阵A的列数;N为矩阵B的列数, Aa * Bb
{

	const enum CBLAS_ORDER      Order = CblasRowMajor;
	const enum CBLAS_TRANSPOSE TransA = CblasNoTrans; //A没有转置
	const enum CBLAS_TRANSPOSE TransB = CblasNoTrans; //B没有转置

	int i, j, mm, nn;
	double alpha = 1.0;
	double beta = 0.0;
	double * A;
	double * B;
	double * C;
	double ** end_C;

	int lda = K;     //A的列 
	int ldb = N;     //B的列 
	int ldc = N;     //C的列 

	int A_num = M * K;
	int B_num = K * N;
	int C_num = M * N;

	//动态定义一维数组
	A = (double*)malloc(sizeof(double) * A_num);
	B = (double*)malloc(sizeof(double) * B_num);
	C = (double*)malloc(sizeof(double) * C_num);

	//动态定义二维数组
	end_C = (double**)malloc(sizeof(double*) * M);
	for (i = 0; i < M; i++)
	{
		end_C[i] = (double*)malloc(sizeof(double) * N);
	}

	//矩阵初始化
	for (i = 0; i < M * K; i++)
	{
		A[i] = 0.0;
	}

	for (i = 0; i < N * K; i++)
	{
		B[i] = 0.0;
	}

	for (i = 0; i < M * N; i++)
	{
		C[i] = 0.0;
	}

	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			end_C[i][j] = 0.0;
		}
	}


	//二维矩阵Aa按行内容转为一维矩阵
	mm = 0;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < K; j++)
		{
			mm = i * K + j;
			A[mm] = Aa[i][j]; // Aa:M * K
		}
	}

	//二维矩阵Bb按行内容转为一维矩阵
	nn = 0;
	for (i = 0; i < K; i++)
	{
		for (j = 0; j < N; j++)
		{
			nn = i * N + j;
			B[nn] = Bb[i][j]; // Bb:K * N
		}
	}

	//MKL函数库矩阵相乘
	cblas_dgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);


	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			//end_C[j][i] = C[i*N + j];             //一维矩阵转二维矩阵,并完成转置工作
			end_C[i][j] = C[i*N + j];
		}
	}

	//释放
	free(A); A = NULL; free(B); B = NULL; free(C); C = NULL;

	return end_C;

	for (i = 0; i < N; i++)
	{
		free(end_C[i]); end_C[i] = NULL;  /*释放列*/
	}
	free(end_C); end_C = NULL;            /*释放行*/

}

double ** matrix_multiply_transpose(double **Aa, double **Bb, int M, int K, int N)
//M为A矩阵的行数;K为矩阵A的列数;N为矩阵B的列数, Aa transpose * Bb
{

	const enum CBLAS_ORDER      Order = CblasRowMajor;
	const enum CBLAS_TRANSPOSE TransA = CblasTrans; //转置A
	const enum CBLAS_TRANSPOSE TransB = CblasNoTrans; //B没有转置

	int i, j, mm, nn;
	double alpha = 1.0;
	double beta = 0.0;
	double * A;
	double * B;
	double * C;
	double ** end_C;

	int lda = K;     //A的列 
	int ldb = N;     //B的列 
	int ldc = N;     //C的列 

	int A_num = M * K;
	int B_num = M * N;
	int C_num = K * N;

	//动态定义一维数组
	A = (double*)malloc(sizeof(double) * A_num);
	B = (double*)malloc(sizeof(double) * B_num);
	C = (double*)malloc(sizeof(double) * C_num);

	//动态定义二维数组
	end_C = (double**)malloc(sizeof(double*) * K);
	for (i = 0; i < K; i++)
	{
		end_C[i] = (double*)malloc(sizeof(double) * N);
	}

	//矩阵初始化
	for (i = 0; i < M * K; i++)
	{
		A[i] = 0.0;
	}

	for (i = 0; i < N * M; i++)
	{
		B[i] = 0.0;
	}

	for (i = 0; i < K * N; i++)
	{
		C[i] = 0.0;
	}

	for (i = 0; i < K; i++)
	{
		for (j = 0; j < N; j++)
		{
			end_C[i][j] = 0.0;
		}
	}


	//二维矩阵Aa按行内容转为一维矩阵
	mm = 0;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < K; j++)
		{
			mm = i * K + j;
			A[mm] = Aa[i][j]; // Aa:M * K
		}
	}

	//二维矩阵Bb按行内容转为一维矩阵
	nn = 0;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			nn = i * N + j;
			B[nn] = Bb[i][j]; // Bb:M * N
		}
	}

	//MKL函数库矩阵相乘
	cblas_dgemm(Order, TransA, TransB, K, N, M, alpha, A, lda, B, ldb, beta, C, ldc);


	for (i = 0; i < K; i++)
	{
		for (j = 0; j < N; j++)
		{
			//end_C[j][i] = C[i*N + j];             //一维矩阵转二维矩阵,并完成转置工作
			end_C[i][j] = C[i*N + j];
		}
	}

	//释放
	free(A); A = NULL; free(B); B = NULL; free(C); C = NULL;

	return end_C;

	for (i = 0; i < N; i++)
	{
		free(end_C[i]); end_C[i] = NULL;  /*释放列*/
	}
	free(end_C); end_C = NULL;            /*释放行*/

}

void matrix_multiply_transpose_test() {

	printf("enter matrix_mult_transpose_test\n");

	int M = 2, K = 3, N = 1;
	double **Aa = (double**)malloc(sizeof(double*) * M);
	for (int i = 0; i < M; i++)
	{
		Aa[i] = (double*)malloc(sizeof(double) * K);
	}
	printf("Aa:\n");
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < K; j++)
		{
			Aa[i][j] = i + j;
			printf("%.0f,", Aa[i][j]);
		}
		printf("\n");
	}
	double **Bb = (double**)malloc(sizeof(double*) * M);
	for (int i = 0; i < M; i++)
	{
		Bb[i] = (double*)malloc(sizeof(double) * N);
	}
	printf("Bb:\n");
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N; j++)
		{
			Bb[i][j] = i + j + 2;
			printf("%.0f,", Bb[i][j]);
		}
		printf("\n");
	}
	double ** Cc = matrix_multiply_transpose(Aa, Bb, M, K, N);
	printf("Aa transpose * Bb:\n");
	for (int i = 0; i < K; i++)
	{
		for (int j = 0; j < N; j++)
		{

			printf("%.0f,", Cc[i][j]);
		}
		printf("\n");
	}

	for (int i = 0; i < M; i++)
	{
		free(Aa[i]);  /*释放列*/
	}
	free(Aa);         /*释放行*/

	for (int i = 0; i < M; i++)
	{
		free(Bb[i]);   /*释放列*/

	}
	free(Bb);            /*释放行*/

	for (int i = 0; i < K; i++)
	{
		free(Cc[i]);  /*释放列*/
	}
	free(Cc);           /*释放行*/

	printf("leave matrix_mult_transpose_test\n");

}

void matrix_multiply_test() {

	printf("enter matrix_mult_test\n");

	int M = 3, K = 2, N = 1;
	double **Aa = (double**)malloc(sizeof(double*) * M);
	for (int i = 0; i < M; i++)
	{
		Aa[i] = (double*)malloc(sizeof(double) * K);
	}
	printf("Aa:\n");
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < K; j++)
		{
			Aa[i][j] = i + j;
			printf("%.0f,", Aa[i][j]);
		}
		printf("\n");
	}
	double **Bb = (double**)malloc(sizeof(double*) * K);
	for (int i = 0; i < K; i++)
	{
		Bb[i] = (double*)malloc(sizeof(double) * N);
	}
	printf("Bb:\n");
	for (int i = 0; i < K; i++)
	{
		for (int j = 0; j < N; j++)
		{
			Bb[i][j] = i + j + 2;
			printf("%.0f,", Bb[i][j]);
		}
		printf("\n");
	}
	double ** Cc = matrix_multiply(Aa, Bb, M, K, N);
	printf("Aa*Bb:\n");
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N; j++)
		{

			printf("%.0f,", Cc[i][j]);
		}
		printf("\n");
	}

	for (int i = 0; i < M; i++)
	{
		free(Aa[i]);  /*释放列*/
	}
	free(Aa);         /*释放行*/

	for (int i = 0; i < K; i++)
	{
		free(Bb[i]);   /*释放列*/

	}
	free(Bb);            /*释放行*/

	for (int i = 0; i < M; i++)
	{
		free(Cc[i]);  /*释放列*/
	}
	free(Cc);           /*释放行*/

	printf("leave matrix_mult_test\n");

}



void main() {

	matrix_multiply_transpose_test();
	printf("\n");
	matrix_multiply_test();
	printf("\n");

	getchar();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值