Вопрос

У меня проблемы с использованием CBLS для выполнения внешнего продукта. Мой код заключается в следующем:

//===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

Я видел: Эффективное вычисление продуктов кронекера в C

Но это не помогает мне, потому что они на самом деле не говорят, как использовать DGEMM, чтобы сделать это ...

Любая помощь? Что я здесь делаю не так?

Это было полезно?

Решение

Вы можете сделать это с помощью 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.

Другие советы

Интерфейсы не очень удобны в BLA, однако давайте попробуем выяснить это. Прежде всего, скажем, что все наши матрицы в Роумаджоре. Теперь у нас есть следующая настройка

     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: Ссылка на сайт

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top