【算法】_016_矩阵乘法_Strassen算法

1、013_matrix_mutiply_strassen.h

/***************************************************************
*版权所有 (C)2014,长沙铁信交通科技有限公司。
*
*文件名称:013_matrix_mutiply_strassen.h
*内容摘要:矩阵乘法Strassen算法(矩阵分解)
*其它说明:难点在于矩阵的具体实现
*当前版本:V1.0
*作   者:伍定湘
*完成日期:2014年9月29日
*
*修改记录1:
*   修改日期:2014年9月29日
*   版本号:V1.0
*   修改人:伍定湘
*   修改内容:创建
***************************************************************/


#ifndef _MATRIX_MUTIPLY_STRASSEN_H_ //防止头文件被重复引用
#define _MATRIX_MUTIPLY_STRASSEN_H_


/**************************************************************
头文件引用
**************************************************************/
#include "typedef.h"//引入内置类型重定义


/**************************************************************
相关宏定义
**************************************************************/


/**************************************************************
相关结构体定义
**************************************************************/
#ifndef _MATRIX_TYPEDEF_2_ //防止头文件被重复引用
#define _MATRIX_TYPEDEF_2_
typedef struct
{
	INT32 iOriginI;
	INT32 iOriginJ;
	INT32 iOriginOrder;
	INT32 *aMtrData;
}MatrixTypedef2;
#endif

/**************************************************************
本程序中出现的函数的声明
**************************************************************/
void matrix_mutiply_strassen(INT32 aMtrDataA[], INT32 aMtrDataB[], const INT32 iOriginOrder);
void mutiply_strassen(MatrixTypedef2 mtrA, MatrixTypedef2 mtrB, MatrixTypedef2 mtrC, INT32 iCurrentOrder, const INT32 iOriginOrder);
void plus_strassen(MatrixTypedef2 mtr1, MatrixTypedef2 mtr2, MatrixTypedef2 mtr3, INT32 iCurrentOrder);
void minus_strassen(MatrixTypedef2 mtr1, MatrixTypedef2 mtr2, MatrixTypedef2 mtr3, INT32 iCurrentOrder);
MatrixTypedef2 child_matrix(MatrixTypedef2 mtrOrigin, INT32 iNewI, INT32 iNewJ, INT32 iCurrentOrder);


#endif


2、013_matrix_mutiply_strassen.c

/***************************************************************
*版权所有 (C)2014,长沙铁信交通科技有限公司。
*
*文件名称:013_matrix_mutiply_strassen.c
*内容摘要:矩阵乘法Strassen算法(矩阵分解)
*其它说明:难点在于矩阵的具体实现
*当前版本:V1.0
*作   者:伍定湘
*完成日期:2014年9月29日
*
*修改记录1:
*   修改日期:2014年9月29日
*   版本号:V1.0
*   修改人:伍定湘
*   修改内容:创建
***************************************************************/


/**************************************************************
头文件引用
**************************************************************/
#include "typedef.h"//引入内置类型重定义
#include "013_matrix_mutiply_strassen.h"

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>


/**************************************************************
全局变量定义
**************************************************************/


/**************************************************************
函数实现
**************************************************************/

/**********************************************************************
*功能描述:矩阵乘法
*输入参数:aMtrDataA - 存储矩阵A数值的一维数组
*        aMtrDataB - 存储矩阵B数值的一维数组
*        aMtrDataC - 存储矩阵B数值的一维数组
*        iOriginOrder - 矩阵的初始阶数
*输出参数:
*返回值:
*其它说明:
*修改日期           版本号         修改人        修改内容
* ---------------------------------------------------------------------
*2014年9月29日      V1.0          伍定湘        创建
***********************************************************************/
void matrix_mutiply_strassen(INT32 aMtrDataA[], INT32 aMtrDataB[], const INT32 iOriginOrder)
{
	MatrixTypedef2 mtrA = { 0, 0, iOriginOrder, aMtrDataA };
	MatrixTypedef2 mtrB = { 0, 0, iOriginOrder, aMtrDataB };
	INT32 *pMtrDataC = (INT32 *)malloc(iOriginOrder * iOriginOrder * sizeof(INT32));
	memset(pMtrDataC, 0, iOriginOrder * iOriginOrder * sizeof(INT32));
	MatrixTypedef2 mtrC = { 0, 0, iOriginOrder, pMtrDataC };
	INT32 iCurrentOrder = iOriginOrder;
	mutiply_strassen(mtrA, mtrB, mtrC, iOriginOrder, iOriginOrder);
	INT32 x;
	while (iCurrentOrder--)
	{
		x = iOriginOrder;
		while (x--)
		{
			printf("%d\t", pMtrDataC[(iOriginOrder - iCurrentOrder - 1) * iOriginOrder + (iOriginOrder - x - 1)]);
		}
		printf("\n");
	}
	printf("\n");
	printf("\n");
}

/**********************************************************************
*功能描述:矩阵乘法Strassen算法(矩阵分解)
*输入参数:mtrA - 矩阵A的参数结构体
*        mtrB - 矩阵B的参数结构体
*        mtrC - 矩阵C的参数结构体
*        iCurrentOrder - 当前阶数
*        iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
*        2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
*        3 - 指针修改C矩阵数值,无返回值
*        4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期           版本号         修改人        修改内容
* ---------------------------------------------------------------------
*2014年9月29日      V1.0          伍定湘        创建
***********************************************************************/
void mutiply_strassen(MatrixTypedef2 mtrA, MatrixTypedef2 mtrB, MatrixTypedef2 mtrC, INT32 iCurrentOrder, const INT32 iOriginOrder)
{
	/* 递归至最基本情况,递归结束 */
	if (iCurrentOrder == 1)
	{
		INT32 x = mtrA.aMtrData[mtrA.iOriginI *  mtrA.iOriginOrder + mtrA.iOriginJ] *
			mtrB.aMtrData[mtrB.iOriginI *  mtrB.iOriginOrder + mtrB.iOriginJ];
		mtrC.aMtrData[mtrC.iOriginI *  mtrC.iOriginOrder + mtrC.iOriginJ] = x;
		return;
	}

	iCurrentOrder >>= 1;//阶数减半

	/* 分解矩阵 */
	MatrixTypedef2 mtrA00 = child_matrix(mtrA, 0, 0, iCurrentOrder);
	MatrixTypedef2 mtrA01 = child_matrix(mtrA, 0, 1, iCurrentOrder);
	MatrixTypedef2 mtrA10 = child_matrix(mtrA, 1, 0, iCurrentOrder);
	MatrixTypedef2 mtrA11 = child_matrix(mtrA, 1, 1, iCurrentOrder);

	MatrixTypedef2 mtrB00 = child_matrix(mtrB, 0, 0, iCurrentOrder);
	MatrixTypedef2 mtrB01 = child_matrix(mtrB, 0, 1, iCurrentOrder);
	MatrixTypedef2 mtrB10 = child_matrix(mtrB, 1, 0, iCurrentOrder);
	MatrixTypedef2 mtrB11 = child_matrix(mtrB, 1, 1, iCurrentOrder);

	MatrixTypedef2 mtrC00 = child_matrix(mtrC, 0, 0, iCurrentOrder);
	MatrixTypedef2 mtrC01 = child_matrix(mtrC, 0, 1, iCurrentOrder);
	MatrixTypedef2 mtrC10 = child_matrix(mtrC, 1, 0, iCurrentOrder);
	MatrixTypedef2 mtrC11 = child_matrix(mtrC, 1, 1, iCurrentOrder);

	INT32 *pMtrS[10];
	MatrixTypedef2 mtrS[10] = { { 0, 0, 0, NULL } };
	for (size_t i = 0; i < 10; i++)
	{
		pMtrS[i]= (INT32 *)malloc(iCurrentOrder * iCurrentOrder * sizeof(INT32));
		memset(pMtrS[i], 0, iCurrentOrder * iCurrentOrder * sizeof(INT32));
		mtrS[i].iOriginOrder = iCurrentOrder;
		mtrS[i].aMtrData = pMtrS[i];
	}

	/* 根据矩阵A、B获取十个矩阵 */
	minus_strassen(mtrB01, mtrB11, mtrS[0], iCurrentOrder);//S0 = B01 - B11
	plus_strassen(mtrA00, mtrA01, mtrS[1], iCurrentOrder);//S1 = A00 + A01
	plus_strassen(mtrA10, mtrA11, mtrS[2], iCurrentOrder);//S2 = A10 + A11
	minus_strassen(mtrB10, mtrB00, mtrS[3], iCurrentOrder);//S3 = B10 - B00
	plus_strassen(mtrA00, mtrA11, mtrS[4], iCurrentOrder);//S4 = A00 + A11
	plus_strassen(mtrB00, mtrB11, mtrS[5], iCurrentOrder);//S5 = B00 + B11
	minus_strassen(mtrA01, mtrA11, mtrS[6], iCurrentOrder);//S6 = A01 - A11
	plus_strassen(mtrB10, mtrB11, mtrS[7], iCurrentOrder);//S7 = B10 + B11
	minus_strassen(mtrA00, mtrA10, mtrS[8], iCurrentOrder);//S8 = A00 - A10
	plus_strassen(mtrB00, mtrB01, mtrS[9], iCurrentOrder);//S9 = B00 + B01

	INT32 *pMtrP[7];
	MatrixTypedef2 mtrP[7] = { { 0, 0, 0, NULL } };//不要带变量初始化数组
	for (size_t i = 0; i < 7; i++)
	{
		pMtrP[i] = (INT32 *)malloc(iCurrentOrder * iCurrentOrder * sizeof(INT32));
		memset(pMtrP[i], 0, iCurrentOrder * iCurrentOrder * sizeof(INT32));
		mtrP[i].iOriginOrder = iCurrentOrder;
		mtrP[i].aMtrData = pMtrP[i];
	}

	/* 递归地计算7次子矩阵乘法 */
	mutiply_strassen(mtrA00, mtrS[0], mtrP[0], iCurrentOrder, iOriginOrder);//P0 = A00 * S0
	mutiply_strassen(mtrS[1], mtrB11, mtrP[1], iCurrentOrder, iOriginOrder);//P1 = S1 * B11
	mutiply_strassen(mtrS[2], mtrB00, mtrP[2], iCurrentOrder, iOriginOrder);//P2 = S2 * B00
	mutiply_strassen(mtrA11, mtrS[3], mtrP[3], iCurrentOrder, iOriginOrder);//P3 = A11 * S3
	mutiply_strassen(mtrS[4], mtrS[5], mtrP[4], iCurrentOrder, iOriginOrder);//P4 = S4 * S5
	if (iCurrentOrder == 2)
	{
		int a = 5;
	}
	mutiply_strassen(mtrS[6], mtrS[7], mtrP[5], iCurrentOrder, iOriginOrder);//P5 = S6 * S7
	mutiply_strassen(mtrS[8], mtrS[9], mtrP[6], iCurrentOrder, iOriginOrder);//P6 = S8 * S9

	/* 释放S */
	for (size_t i = 0; i < 10; i++)
	{
		free(pMtrS[i]);
	}

	/* C00 = P4 + P3 - P1 + P5 */
	plus_strassen(mtrP[4], mtrP[3], mtrC00, iCurrentOrder);
	minus_strassen(mtrC00, mtrP[1], mtrC00, iCurrentOrder);
	plus_strassen(mtrC00, mtrP[5], mtrC00, iCurrentOrder);

	/* C01 = P0 + P1 */
	plus_strassen(mtrP[0], mtrP[1], mtrC01, iCurrentOrder);

	/* C10 = P2 + P3 */
	plus_strassen(mtrP[2], mtrP[3], mtrC10, iCurrentOrder);

	/* C11 = P4 + P0 - P2 - P6 */
	plus_strassen(mtrP[4], mtrP[0], mtrC11, iCurrentOrder);
	minus_strassen(mtrC11, mtrP[2], mtrC11, iCurrentOrder);
	minus_strassen(mtrC11, mtrP[6], mtrC11, iCurrentOrder);

	/* 释放P */
	for (size_t i = 0; i < 7; i++)
	{
		free(pMtrP[i]);
	}
}

/**********************************************************************
*功能描述:矩阵加法
*输入参数:mtr1 - 矩阵1的参数结构体
*        mtr2 - 矩阵2的参数结构体
*        mtr3 - 矩阵3的参数结构体
*        iCurrentOrder - 当前阶数
*        iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
*        2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
*        3 - 指针修改C矩阵数值,无返回值
*        4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期           版本号         修改人        修改内容
* ---------------------------------------------------------------------
*2014年9月29日      V1.0          伍定湘        创建
***********************************************************************/
void plus_strassen(MatrixTypedef2 mtr1, MatrixTypedef2 mtr2, MatrixTypedef2 mtr3, INT32 iCurrentOrder)
{
	INT32 x;
	for (INT32 i = 0; i < iCurrentOrder; i++)
	{
		for (INT32 j = 0; j < iCurrentOrder; j++)
		{
			x = mtr1.aMtrData[(i + mtr1.iOriginI) *  mtr1.iOriginOrder + mtr1.iOriginJ + j] +
				mtr2.aMtrData[(i + mtr2.iOriginI) *  mtr2.iOriginOrder + mtr2.iOriginJ + j];
			mtr3.aMtrData[(i + mtr3.iOriginI) *  mtr3.iOriginOrder + mtr3.iOriginJ + j] = x;
		}
	}
}

/**********************************************************************
*功能描述:矩阵加法
*输入参数:mtr1 - 矩阵1的参数结构体
*        mtr2 - 矩阵2的参数结构体
*        mtr3 - 矩阵3的参数结构体
*        iCurrentOrder - 当前阶数
*        iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
*        2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
*        3 - 指针修改C矩阵数值,无返回值
*        4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期           版本号         修改人        修改内容
* ---------------------------------------------------------------------
*2014年9月29日      V1.0          伍定湘        创建
***********************************************************************/
void minus_strassen(MatrixTypedef2 mtr1, MatrixTypedef2 mtr2, MatrixTypedef2 mtr3, INT32 iCurrentOrder)
{
	INT32 x;
	for (INT32 i = 0; i < iCurrentOrder; i++)
	{
		for (INT32 j = 0; j < iCurrentOrder; j++)
		{
			x = mtr1.aMtrData[(i + mtr1.iOriginI) *  mtr1.iOriginOrder + mtr1.iOriginJ + j] -
				mtr2.aMtrData[(i + mtr2.iOriginI) *  mtr2.iOriginOrder + mtr2.iOriginJ + j];
			mtr3.aMtrData[(i + mtr3.iOriginI) *  mtr3.iOriginOrder + mtr3.iOriginJ + j] = x;
		}
	}
}

/**********************************************************************
*功能描述:矩阵加法
*输入参数:mtr1 - 矩阵1的参数结构体
*        mtr2 - 矩阵2的参数结构体
*        mtr3 - 矩阵3的参数结构体
*        iCurrentOrder - 当前阶数
*        iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
*        2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
*        3 - 指针修改C矩阵数值,无返回值
*        4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期           版本号         修改人        修改内容
* ---------------------------------------------------------------------
*2014年9月29日      V1.0          伍定湘        创建
***********************************************************************/
MatrixTypedef2 child_matrix(MatrixTypedef2 mtrOrigin, INT32 iNewI, INT32 iNewJ, INT32 iCurrentOrder)
{
	if (iNewI)
	{
		mtrOrigin.iOriginI += iCurrentOrder;
	}
	if (iNewJ)
	{
		mtrOrigin.iOriginJ += iCurrentOrder;
	}
	return(mtrOrigin);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值