【问题标题】:Outer product using CBLAS使用 CBLAS 的外部产品
【发布时间】:2013-11-08 19:34:27
【问题描述】:

我在使用 CBLAS 执行外部产品时遇到问题。我的代码如下:

//===SET UP===//
double x1[] = {1,2,3,4};
double x2[] = {1,2,3};
int dx1 = 4;
int dx2 = 3;
double X[dx1 * dx2];
for (int i = 0; i < (dx1*dx2); i++) {X[i] = 0.0;}

//===DO THE OUTER PRODUCT===//
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, dx1, dx2, 1, 1.0, x1, dx1, x2, 1, 0.0, X, dx1);

//===PRINT THE RESULTS===//
printf("\nMatrix X (%d x %d) = x1 (*) x2 is:\n", dx1, dx2);
for (i=0; i<4; i++) {
    for (j=0; j<3; j++) {
        printf ("%lf ", X[j+i*3]);
    }
    printf ("\n");
}

我明白了:

Matrix X (4 x 3) = x1 (*) x2 is:
1.000000 2.000000 3.000000 
0.000000 -1.000000 -2.000000 
-3.000000 0.000000 7.000000 
14.000000 21.000000 0.000000 

但正确答案在这里找到: https://www.sharcnet.ca/help/index.php/BLAS_and_CBLAS_Usage_and_Examples

我见过:Efficient computation of kronecker products in C

但是,这对我没有帮助,因为他们实际上并没有说明如何使用 dgemm 来实际执行此操作...

有什么帮助吗?我在这里做错了什么?

【问题讨论】:

    标签: c linear-algebra scientific-computing numerical


    【解决方案1】:

    您可以使用 dgemm 来做到这一点,但使用 dger 会在风格上更正确,这是一个专用的外部产品实现。因此,它更容易正确使用:

    cblas_dger(CblasRowMajor, /* you’re using row-major storage */
               dx1,           /* the matrix X has dx1 rows ...  */
               dx2,           /*  ... and dx2 columns.          */
               1.0,           /* scale factor to apply to x1x2' */
               x1,
               1,             /* stride between elements of x1. */
               x2,
               1,             /* stride between elements of x2. */
               X,
               dx2);          /* leading dimension of matrix X. */
    

    dgemm 确实 有一个很好的功能,即传递\beta = 0 会为您初始化结果矩阵,这样您就无需在调用之前自行将其显式归零。 @Artem Shinkarov 的回答很好地描述了如何使用 dgemm。

    【讨论】:

    • 你确定最后一个参数 (LDA) 必须是 dx2,而不是 dx1?
    • @Christoph90:是的,因为函数调用使用的是行主要存储。如果您改用 column-major,则为 dx1
    【解决方案2】:

    BLAS中的接口不是很方便,不过,让我们试着弄清楚。首先,假设我们所有的矩阵都在 RowMajor 中。现在我们有以下设置

         row  col
    x1:  dx1   1   (A)
    x2:   1   dx2  (B)
     X:  dx1  dx2  (C)
    

    现在,我们只需要根据文档来填写调用,文档中指定了

    C = \alpha A*B + \beta C
    

    所以我们得到:

    cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans,
                 (int)dx1, /* rows in A         */
                 (int)dx2, /* columns in B      */
                 (int)1,   /* columns in A      */
                 1.0, x1,  /* \alpha, A itself  */
                 (int)1,   /* Colums in A       */
                 x2,       /* B itself          */
                 (int)dx2, /* Columns in B      */
                 0.0, X,   /* \beta, C itself   */
                 (int)dx2  /* Columns in C  */);
    

    所以这应该可以完成我希望的工作。 下面是dgemm的参数说明:Link

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      相关资源
      最近更新 更多