矩阵相乘的三种实现
2013-02-13 18:30
471 查看
对于两个N阶矩阵的乘法,可以使用蛮力法,三层循环即可实现,也可以使用分治法实现。
原数据结构:
三层循环:
分治法:
Strassen
主方法:
实现界面:
本次实现使用花费时间和空间较多的数组内容拷贝,并没有实现索引计算。
原数据结构:
public class Matrix { public Matrix(int N) { this.n = N; m = new int[n, n]; sx = 0; sy = 0; ex = N - 1; ey = N - 1; } public int[,] m; public int n; //position.start and end coordinate public int sx; public int sy; public int ex; public int ey; public void init() { Random r = new Random(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { m[i, j] = r.Next(n); } } } }
三层循环:
public static Matrix SquareMatrixMultiply(Matrix a, Matrix b) { int tmp = 0, n; n = a.n; Matrix c = new Matrix(n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { tmp += a.m[i,k] * b.m[k,j]; } c.m[i,j] = tmp; tmp = 0; } } return c; }
分治法:
public static Matrix SquareMatrixMultiplyRecursive(Matrix a, Matrix b) { int n = a.n; Matrix c = new Matrix(n); if (n == 1) { //c.m[a.sx, b.sy] += a.m[a.sx, a.sy] * b.m[b.sx, b.sy]; c.m[0, 0] = a.m[0, 0] * b.m[0, 0]; } else { Matrix suba,subb; int[] ta1 = new int[4] { 0, 0, 2, 2 }; int[] ta2 = new int[4] { 1, 1, 3, 3 }; int[] tb1 = new int[4] { 0, 1, 0, 1 }; int[] tb2 = new int[4] { 2, 3, 2, 3 }; for (int i = 0; i < 4; i++) { suba = partitionArray(ta1[i], a); subb = partitionArray(tb1[i], b); Matrix c1 = SquareMatrixMultiplyRecursive(suba, subb); suba = partitionArray(ta2[i], a); subb = partitionArray(tb2[i], b); Matrix c2 = SquareMatrixMultiplyRecursive(suba, subb); Plus(c, c1, c2, i); } } return c; }
Strassen
public static Matrix SquareMatrixMultiplyStrassen(Matrix a, Matrix b) { int N = a.n; Matrix c = new Matrix(N); if (N <= 1) { c.m[a.sx, b.sy] = a.m[a.sx, a.sy] * b.m[b.sx, b.sy]; //c.m[0, 0] = a.m[0, 0] * b.m[0, 0]; } else { Dictionary<string, Matrix> ms = new Dictionary<string, Matrix>(); //s1~s10 string[] sa = { "S2", "S3", "S5", "S7", "S9" }; string[] sb = { "S1", "S4", "S6", "S8", "S10" }; int[] sa1 = { 0, 2, 0, 1, 0 }; int[] sa2 = { 1, 3, 3, 3, 2 }; bool[] sa3 = { true, true, true, false, false }; int[] sb1 = { 1, 2, 0, 2, 0 }; int[] sb2 = { 3, 0, 3, 3, 2 }; bool[] sb3 = { false, false, true, true, true }; Matrix tmp = null, sub1 = null, sub2 = null; for (int i = 0; i < 5; i++) { sub1 = PartitionArrayByCalcuIndex(sa1[i], a); sub2 = PartitionArrayByCalcuIndex(sa2[i], a); tmp = AddMinus(sub1, sub2, sa3[i]); ms.Add(sa[i], tmp); sub1 = PartitionArrayByCalcuIndex(sb1[i], b); sub2 = PartitionArrayByCalcuIndex(sb2[i], b); tmp = AddMinus(sub1, sub2, sb3[i]); ms.Add(sb[i], tmp); } string[] sp1 = { "A0", "S2", "S3", "A3", "S5", "S7", "S9" }; string[] sp2 = { "S1", "B3", "B0", "S4", "S6", "S8", "S10" }; for (int i = 0; i < sp1.Length; i++) { string name = "P" + (i+1); sub1 = getMBy(sp1[i], a, b, ms); sub2 = getMBy(sp2[i], a, b, ms); ms.Add(name, SquareMatrixMultiplyStrassen(sub1, sub2)); } sub1 = ms["P5"].Add(ms["P4"]).Minus(ms["P2"]).Add(ms["P6"]); c.Add(sub1); sub1 = ms["P1"].Minus(ms["P2"]); c.Add(sub1); sub1 = ms["P3"].Add(ms["P4"]); c.Add(sub1); sub1 = ms["P5"].Add(ms["P1"]).Minus(ms["P3"]).Minus(ms["P7"]); c.Add(sub1); } return c;
主方法:
class Program { static void Main(string[] args) { const int N = 8; //a Matrix a = new Matrix(N); a.init(); Operation.ShowMatrix(a,"a"); //b Matrix b = new Matrix(N); b.init(); Operation.ShowMatrix(b, "b"); //c Matrix c = Operation.SquareMatrixMultiply(a, b); Operation.ShowMatrix(c,"c brute-force method"); //d Matrix d = Operation.SquareMatrixMultiplyRecursive(a, b); Operation.ShowMatrix(d,"d divide and conquer"); //e Matrix e = Operation.SquareMatrixMultiplyStrassen(a, b); Operation.ShowMatrix(e, "e Strassen"); } }
实现界面:
本次实现使用花费时间和空间较多的数组内容拷贝,并没有实现索引计算。
相关文章推荐
- Python实现矩阵相乘的三种方法小结
- 矩阵相乘的三种方法(java实现)
- Python实现矩阵相乘的三种方法
- C++实现两个矩阵相乘
- 实现稀疏矩阵相乘C/C++
- Hadoop 实现矩阵相乘
- opencv 矩阵与一个常数相乘的 两种实现方法
- 将对称矩阵压缩存储,实现矩阵相乘,输出相乘后结果(用二维数组)
- MIT18.06线性代数课程笔记1:矩阵和向量相乘的三种解释
- MapReduce实现矩阵相乘
- 矩阵相乘strassen-c++代码实现及运行实例结果
- CUDA编程接口:共享存储器实现矩阵相乘
- mapreduce实现矩阵相乘
- java实现矩阵相乘
- opencv 矩阵与一个常数相乘的 两种实现方法
- 矩阵相加、相乘,Java实现
- tensorflow 实现 前一个tensor 的最后一维 矩阵相乘 后一个tensor 的第一维
- 《算法设计与分析基础》三种求最大公约数的方法C++实现--欧几里德辗转相除、连续整数检测、质因数相乘
- 矩阵相乘strassen-c++代码实现及运行实例结果
- 矩阵相乘的C代码实现