1、012_matrix_mutiply_recursive.h
/***************************************************************
*版权所有 (C)2014,长沙铁信交通科技有限公司。
*
*文件名称:012_matrix_mutiply_recursive.h
*内容摘要:矩阵乘法Strassen算法(矩阵分解)
*其它说明:难点在于矩阵的具体实现
*当前版本:V1.0
*作 者:伍定湘
*完成日期:2014年9月28日
*
*修改记录1:
* 修改日期:2014年9月28日
* 版本号:V1.0
* 修改人:伍定湘
* 修改内容:创建
***************************************************************/
#ifndef _MATRIX_MUTIPLY_RECURSIVE_H_ //防止头文件被重复引用
#define _MATRIX_MUTIPLY_RECURSIVE_H_
/**************************************************************
头文件引用
**************************************************************/
#include "typedef.h"//引入内置类型重定义
/**************************************************************
相关宏定义
**************************************************************/
/**************************************************************
相关结构体定义
**************************************************************/
#ifndef _MATRIX_TYPEDEF_ //防止头文件被重复引用
#define _MATRIX_TYPEDEF_
typedef struct
{
INT32 iOriginI;
INT32 iOriginJ;
INT32 iOriginOrder;
INT32 *aMtrData;
}MatrixTypedef;
#endif
/**************************************************************
本程序中出现的函数的声明
**************************************************************/
void matrix_mutiply_recursive(INT32 aMtrDataA[], INT32 aMtrDataB[], const INT32 iOriginOrder);
void mutiply(MatrixTypedef mtrA, MatrixTypedef mtrB, MatrixTypedef mtrC, INT32 iCurrentOrder, const INT32 iOriginOrder);
MatrixTypedef child_matrix2(MatrixTypedef mtrOrigin, INT32 iNewI, INT32 iNewJ, INT32 iCurrentOrder);
void plus(MatrixTypedef mtr1, MatrixTypedef mtr2, MatrixTypedef mtr3, INT32 iCurrentOrder);
#endif
2、012_matrix_mutiply_recursive.c
/***************************************************************
*版权所有 (C)2014,长沙铁信交通科技有限公司。
*
*文件名称:012_matrix_mutiply_recursive.c
*内容摘要:矩阵乘法Strassen算法(矩阵分解)
*其它说明:难点在于矩阵的具体实现
*当前版本:V1.0
*作 者:伍定湘
*完成日期:2014年9月28日
*
*修改记录1:
* 修改日期:2014年9月28日
* 版本号:V1.0
* 修改人:伍定湘
* 修改内容:创建
***************************************************************/
/**************************************************************
头文件引用
**************************************************************/
#include "typedef.h"//引入内置类型重定义
#include "012_matrix_mutiply_recursive.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**************************************************************
全局变量定义
**************************************************************/
/**************************************************************
函数实现
**************************************************************/
/**********************************************************************
*功能描述:矩阵乘法
*输入参数:aMtrDataA - 存储矩阵A数值的一维数组
* aMtrDataB - 存储矩阵B数值的一维数组
* aMtrDataC - 存储矩阵B数值的一维数组
* iOriginOrder - 矩阵的初始阶数
*输出参数:
*返回值:
*其它说明:
*修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
*2014年9月28日 V1.0 伍定湘 创建
***********************************************************************/
void matrix_mutiply_recursive(INT32 aMtrDataA[], INT32 aMtrDataB[], const INT32 iOriginOrder)
{
<span style="white-space:pre"> </span>INT32 *pMtrDataC = (INT32 *)malloc(iOriginOrder * iOriginOrder * sizeof(INT32));
<span style="white-space:pre"> </span>memset(pMtrDataC, 0, iOriginOrder * iOriginOrder * sizeof(INT32));
<span style="white-space:pre"> </span>MatrixTypedef mtrA = { 0, 0, iOriginOrder, aMtrDataA };
<span style="white-space:pre"> </span>MatrixTypedef mtrB = { 0, 0, iOriginOrder, aMtrDataB };
<span style="white-space:pre"> </span>MatrixTypedef mtrC = { 0, 0, iOriginOrder, pMtrDataC };
<span style="white-space:pre"> </span>INT32 iCurrentOrder = iOriginOrder;
<span style="white-space:pre"> </span>mutiply(mtrA, mtrB, mtrC, iOriginOrder, iOriginOrder);
<span style="white-space:pre"> </span>INT32 x;
<span style="white-space:pre"> </span>while (iCurrentOrder--)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>x = iOriginOrder;
<span style="white-space:pre"> </span>while (x--)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>printf("%d\t", pMtrDataC[(iOriginOrder - iCurrentOrder - 1) * iOriginOrder + (iOriginOrder - x - 1)]);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>printf("\n");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>printf("\n");
<span style="white-space:pre"> </span>printf("\n");
}
/**********************************************************************
*功能描述:矩阵乘法Strassen算法(矩阵分解)
*输入参数:mtrA - 矩阵A的参数结构体
* mtrB - 矩阵B的参数结构体
* iCurrentOrder - 当前阶数
* iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
* 2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
* 3 - 指针修改C矩阵数值,无返回值
* 4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
*2014年9月28日 V1.0 伍定湘 创建
***********************************************************************/
void mutiply(MatrixTypedef mtrA, MatrixTypedef mtrB, MatrixTypedef mtrC, INT32 iCurrentOrder, const INT32 iOriginOrder)
{
<span style="white-space:pre"> </span>/* 递归至最基本情况,递归结束 */
<span style="white-space:pre"> </span>if (iCurrentOrder == 1)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>INT32 x = mtrA.aMtrData[mtrA.iOriginI * iOriginOrder + mtrA.iOriginJ] *
<span style="white-space:pre"> </span>mtrB.aMtrData[mtrB.iOriginI * iOriginOrder + mtrB.iOriginJ];
<span style="white-space:pre"> </span>x += mtrC.aMtrData[mtrC.iOriginI * iOriginOrder + mtrC.iOriginJ] ;
<span style="white-space:pre"> </span>mtrC.aMtrData[mtrC.iOriginI * iOriginOrder + mtrC.iOriginJ] = x;
<span style="white-space:pre"> </span>return;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>//INT32 *pMtrTmp = (INT32 *)malloc(iCurrentOrder * iCurrentOrder * sizeof(INT32));
<span style="white-space:pre"> </span>//MatrixTypedef mtrTmp = { 0, 0, iCurrentOrder, pMtrTmp };//问题:8阶矩阵部分数值溢出;16阶矩阵堆溢出
<span style="white-space:pre"> </span>/* 分解矩阵 */
<span style="white-space:pre"> </span>iCurrentOrder >>= 1;//阶数减半
<span style="white-space:pre"> </span>MatrixTypedef mtrA00 = child_matrix2(mtrA, 0, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrA01 = child_matrix2(mtrA, 0, 1, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrA10 = child_matrix2(mtrA, 1, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrA11 = child_matrix2(mtrA, 1, 1, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrB00 = child_matrix2(mtrB, 0, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrB01 = child_matrix2(mtrB, 0, 1, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrB10 = child_matrix2(mtrB, 1, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrB11 = child_matrix2(mtrB, 1, 1, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrC00 = child_matrix2(mtrC, 0, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrC01 = child_matrix2(mtrC, 0, 1, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrC10 = child_matrix2(mtrC, 1, 0, iCurrentOrder);
<span style="white-space:pre"> </span>MatrixTypedef mtrC11 = child_matrix2(mtrC, 1, 1, iCurrentOrder);
<span style="white-space:pre"> </span>/* C00 = A00 * B00 + A01 * B10 */
<span style="white-space:pre"> </span>mutiply(mtrA00, mtrB00, mtrC00, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>mutiply(mtrA01, mtrB10, mtrC00, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>//plus(mtrTmp, mtrC00, mtrC00, iCurrentOrder);
<span style="white-space:pre"> </span>/* C01 = A00 * B01 + A01 * B11 */
<span style="white-space:pre"> </span>mutiply(mtrA00, mtrB01, mtrC01, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>mutiply(mtrA01, mtrB11, mtrC01, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>//plus(mtrTmp, mtrC01, mtrC01, iCurrentOrder);
<span style="white-space:pre"> </span>/* C10 = A10 * B00 + A11 * B10 */
<span style="white-space:pre"> </span>mutiply(mtrA10, mtrB00, mtrC10, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>mutiply(mtrA11, mtrB10, mtrC10, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>//plus(mtrTmp, mtrC10, mtrC10, iCurrentOrder);
<span style="white-space:pre"> </span>/* C11 = A10 * B01 + A11 * B11 */
<span style="white-space:pre"> </span>mutiply(mtrA10, mtrB01, mtrC11, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>mutiply(mtrA11, mtrB11, mtrC11, iCurrentOrder, iOriginOrder);
<span style="white-space:pre"> </span>//plus(mtrTmp, mtrC11, mtrC11, iCurrentOrder);
<span style="white-space:pre"> </span>//free(pMtrTmp);
}
/**********************************************************************
*功能描述:矩阵加法
*输入参数:mtr1 - 矩阵1的参数结构体
* mtr2 - 矩阵2的参数结构体
* mtr3 - 矩阵3的参数结构体
* iCurrentOrder - 当前阶数
* iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
* 2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
* 3 - 指针修改C矩阵数值,无返回值
* 4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
*2014年9月29日 V1.0 伍定湘 创建
***********************************************************************/
MatrixTypedef child_matrix2(MatrixTypedef mtrOrigin, INT32 iNewI, INT32 iNewJ, INT32 iCurrentOrder)
{
<span style="white-space:pre"> </span>if (iNewI)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>mtrOrigin.iOriginI += iCurrentOrder;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (iNewJ)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>mtrOrigin.iOriginJ += iCurrentOrder;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return(mtrOrigin);
}
/**********************************************************************
*功能描述:矩阵加法
*输入参数:mtr1 - 矩阵1的参数结构体
* mtr2 - 矩阵2的参数结构体
* mtr3 - 矩阵3的参数结构体
* iCurrentOrder - 当前阶数
* iOriginOrder - 初始阶数
*输出参数:
*返回值:
*其它说明:1 - 递归函数
* 2 - 通过向下级传递新的首元素位置以及减半的阶数实现分解矩阵
* 3 - 指针修改C矩阵数值,无返回值
* 4 - 不要返回下一级矩阵的参数,以免返回值修改了上级矩阵C的首元素参数
*修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
*2014年9月29日 V1.0 伍定湘 创建
***********************************************************************/
void plus(MatrixTypedef mtr1, MatrixTypedef mtr2, MatrixTypedef mtr3, INT32 iCurrentOrder)
{
<span style="white-space:pre"> </span>INT32 x;
<span style="white-space:pre"> </span>for (INT32 i = 0; i < iCurrentOrder; i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for (INT32 j = 0; j < iCurrentOrder; j++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>x = mtr1.aMtrData[(i + mtr1.iOriginI) * mtr1.iOriginOrder + mtr1.iOriginJ + j] +
<span style="white-space:pre"> </span>mtr2.aMtrData[(i + mtr2.iOriginI) * mtr2.iOriginOrder + mtr2.iOriginJ + j];
<span style="white-space:pre"> </span>mtr3.aMtrData[(i + mtr3.iOriginI) * mtr3.iOriginOrder + mtr3.iOriginJ + j] = x;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
}