如何使用此C代码使用Strassen';s算法?

如何使用此C代码使用Strassen';s算法?,c,matrix,matrix-multiplication,strassen,C,Matrix,Matrix Multiplication,Strassen,我一直在寻找C语言中的实现,最后我找到了这段代码 要使用乘法功能: void multiply(int n, matrix a, matrix b, matrix c, matrix d); 它将两个矩阵相乘,a,b,并将结果放入c(d是一个中间矩阵)。矩阵a和b应具有以下类型: typedef union _matrix { double **d; union _matrix **p; } *matrix; 我已动态分配了四个矩阵a,b,c,d(二维双精度数组),并已将其

我一直在寻找C语言中的实现,最后我找到了这段代码

要使用
乘法
功能:

void multiply(int n, matrix a, matrix b, matrix c, matrix d);
它将两个矩阵相乘,
a
b
,并将结果放入
c
d
是一个中间矩阵)。矩阵
a
b
应具有以下类型:

typedef union _matrix 
{
    double **d;
    union _matrix **p;
} *matrix;
我已动态分配了四个矩阵
a
b
c
d
(二维双精度数组),并已将其地址分配给字段
\u matrix.d

#include "strassen.h"

#define SIZE 50 

int main(int argc, char *argv[])
{
    double ** matA, ** matB, ** matC, ** matD;
    union _matrix ma, mb, mc, md; 
    int i = 0, j = 0, n;

    matA = (double **) malloc(sizeof(double *) * SIZE);
    for (i = 0; i < SIZE; i++)
        matA[i] = (double *) malloc(sizeof(double) * SIZE); 
    // Do the same for matB, matC, matD.

    ma.d = matA;
    mb.d = matB;
    mc.d = matC;
    md.d = matD;

    // Initialize matC and matD to 0.

    // Read n.

    // Read matA and matB.

    multiply(n, &ma, &mb, &mc, &md);
    return 0;
}
斯特拉森h:

#define BREAK 8   

typedef union _matrix {
    double **d;
    union _matrix **p;
} *matrix;

/* Notational shorthand to access submatrices for matrices named a, b, c, d */

#define a11 a->p[0]
#define a12 a->p[1]
#define a21 a->p[2]
#define a22 a->p[3]
#define b11 b->p[0]
#define b12 b->p[1]
#define b21 b->p[2]
#define b22 b->p[3]
#define c11 c->p[0]
#define c12 c->p[1]
#define c21 c->p[2]
#define c22 c->p[3]
#define d11 d->p[0]
#define d12 d->p[1]
#define d21 d->p[2]
#define d22 d->p[3]
我的问题是如何使用函数
乘法
(如何实现矩阵)


当n>中断时,矩阵乘法算法使用分层矩阵表示法(联合矩阵的
p
字段,而不是
d

在分配内存和初始化矩阵
a
b
时,您需要调整代码的层次表示形式。同样,您需要为这两个矩阵正确初始化
matrix.p

1) 首先,你的
矩阵
是一个如此
p
本质上变成了
d
被解释为
\u矩阵**
,这在这里没有意义-这就是它崩溃的原因。您可能需要将
matrix
改为
struct

最后,
p
根据定义是一个子矩阵数组,因此它应该是一个
struct\u矩阵*
(需要时需要
malloc
实际数组)或
struct\u矩阵[4]
(这是不可能的:)

2) 现在,让我们看看
p
应该是什么

                           │
A.d ->  d1 -> a[1,1] a[1,2]│a[1,3] a[1,4]
        d2 -> a[2,1] a[2,2]│a[2,3] a[2,4]
             ─────────────────────────────
        d3 -> a[3,1] a[3,2]│a[3,3] a[3,4]
        d4 -> a[4,1] a[4,2]│a[4,3] a[4,4]
                           │
p
指向一组
矩阵
结构!其特点是使这些结构的
d
指向 以这样的方式,
(p[k].d[i][j]
是相应子矩阵的元素:

p[0].d -> p01 -> a[1,1]    p[1].d -> p11 -> a[1,3]
          p02 -> a[2,1]              p12 -> a[2,3]

p[2].d -> p21 -> a[3,1]    p[3].d -> p31 -> a[3,3]
          p22 -> a[4,1]              p32 -> a[4,3]
您现在可以推导出对任意偶数大小的正方形A初始化
p
的算法吗


什么时候开始初始化它?;)

不要将
malloc()
中的返回值强制转换为C。不要丢弃如此大的代码块,请将问题集中起来,并清楚地解释它是什么!还告诉我你尝试了什么,怀疑了什么?您当前版本的问题可能会让人发痒
n
在您的
main
中不熟悉
检查这篇关于实现strassen算法的伟大文档,以及@Tudor发布的代码:问题是我不知道如何做到这一点,我对二维数组使用了标准的动态分配,但是当涉及到n>break时,代码崩溃了,谢谢。你是说“2”而不是“tow”?我认为,根据上面的定义,作者希望为矩阵引入一种分层存储。假设你有一个8乘8的矩阵,BREAK的值是2,你首先分配p来表示4个子矩阵,然后这个p将表示d的4个矩阵。所以你给p分配了1+4倍,给d分配了16倍。或者,为什么有人想分治矩阵的加法?
                           │
A.d ->  d1 -> a[1,1] a[1,2]│a[1,3] a[1,4]
        d2 -> a[2,1] a[2,2]│a[2,3] a[2,4]
             ─────────────────────────────
        d3 -> a[3,1] a[3,2]│a[3,3] a[3,4]
        d4 -> a[4,1] a[4,2]│a[4,3] a[4,4]
                           │
p[0].d -> p01 -> a[1,1]    p[1].d -> p11 -> a[1,3]
          p02 -> a[2,1]              p12 -> a[2,3]

p[2].d -> p21 -> a[3,1]    p[3].d -> p31 -> a[3,3]
          p22 -> a[4,1]              p32 -> a[4,3]