MKL函数库矩阵相乘在C语言中的运用

总结了MKL函数库中矩阵相乘在C语言中的运用子函数。注意:mkl函数库得将二维矩阵转为一维矩阵(按行排序)进行计算。
1、官方给的原理
矩阵与矩阵的乘法,分为双精度的cblas_sgemm和单精度的cblas_sgemm,两个函数的参数意义一样,只是类型不一样

运算式:C=alpha*A*B+beta*C 

一般取alpha=1.0,beta=0.0 即计算式:C=A*B

cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,M,N,K,alpha,A,A的列数,B,B的列数,beta,C,C的列数)

CblasRowMajor表示数组时行为主,相应矩阵大小为(MK)乘以(KN),可以得到M,K,N的值

前面的CblasNoTrans表示A是否转置,后面表示B是否转置,即可以表示A(T)B=C或者AB(T)=C或者A(T)*B(T)=C,如果是A的转置乘以B,M,N是A的转置的行数和列数

cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,M,N,K,alpha,A,A的列数,B,B的列数,beta,C,C的列数)

矩阵与向量的乘法,同样有两个cblas_sgemv和cblas_dgemv

运算式:C=alphaAb+beta*C

一般取alpha=1.0,beta=0.0 即计算式:C=A*b

cblas_sgemv(CblasRowMajor, CblasNoTrans,A的行数,A的列数,alpha,A,A的列数,b,1,beta,C,1)

如果是A的转置*b,用

cblas_sgemv(CblasRowMajor, CblasTrans,A的行数,A的列数,alpha,A,A的列数,b,1,beta,C,1)

2、自己代码
完成普通两个二维矩阵的相乘运算:Aa*Bb=Cc
matrix_mult.c

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

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

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

	const enum CBLAS_ORDER      Order = CblasRowMajor;
	const enum CBLAS_TRANSPOSE TransA = CblasNoTrans;
	const enum CBLAS_TRANSPOSE TransB = CblasNoTrans;

	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*) * N);
	for (i = 0; i < N; i++)
	{
		end_C[i] = (double*)malloc(sizeof(double) * M);
	}

	//矩阵初始化
	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 < N; i++)
	{
		for (j = 0; j < M; 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];
		}
	}

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

	//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];             //一维矩阵转二维矩阵,并完成转置工作
		}
	}

	//释放
	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;            /*释放行*/

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值