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);
}