Какие изменения следует внести при выполнении cblas_cgemm();

Я попытался выполнить умножение матрицы на матрицу с помощью функции cblas_cgemm(); Но ответ, который я получаю, неверен по сравнению с ручным расчетом. Я пытался упростить свой код, не используя при вводе воображаемые термины, но проблема остается. Какие изменения я должен сделать, чтобы получить правильный вывод. Это мой код.

#include<stdio.h>
#include<math.h>
#include<complex.h>
#include "cblas.h"

void main()
{
 int i,j;
 double complex A[2][2]={1,2,
                         3,4};
 double complex B[2][2]={4,5,
                         6,7};
 double complex W[2][2]={0,0,
                         0,0};

 const int m1=2;
 const int n1=2;
 const int k1=2;

 const int lda1=2;
 const int ldb1=2;
 const int ldc1=2;
 const double alpha=1.0;
 const double beta=0.0;

 cblas_cgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,m1,n1,k1,&alpha,A,lda1,B, ldb1 ,&beta,W, ldc1);

 for(i=0;i<m1;++i)
  {
  for(j=0;j<n1;++j)
    printf("%lf %lf\n" ,creal(W[i][j]),cimag(W[i][j]));
  printf("\n");
   }
 }

Я получил вывод как

-119296,000000 0,000000
-188416,000000 0,000000 0,000000 0,000000
0,000000 0,000000
Я ссылался на этот сайт lapack:cblas_cgemm Пожалуйста, помогите Мой код, использующий cblas_dgemm(), приведен ниже

//Y := alpha*A*X + beta*Y, or   y := alpha*A**T*x + beta*y,
#include<stdio.h>
#include "cblas.h"
const double A[3][1]={
                      1,
                      2,
                      3
                       };
const double X[1][4]={
1,2,3,4,
};
double Y[3][4]={
0,0,0,0,
0,0,0,0,
0,0,0,0
};
int main()
{
 const int m=3;
const int k=1;const int n=4;
const int lda=1;
const int ldb=4;
const int ldc=4;
int incX,incY;
const double alpha=1.0;
const double beta=0.0;
incX=1;incY=1;
int i,j;
for(i=0;i<m;++i)
   {for(j=0;j<k;++j)
    printf("%lf \t" ,A[i][j]);
putchar('\n');
}
cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,m,n,k,alpha,A, lda,X, ldb ,beta,Y, ldc);
for(i=0;i<m;++i)
{
for(j=0;j<n;++j)
printf("%lf\t" ,Y[i][j]);
printf("\n");
}
return 0;
}

Я получил вывод как

hp@hp-hp-notebook: ~/forming/programs/studentProjectDetails $ ./dgemm_trial 1.000000
2.000000
3.000000
1.000000 2.000000 3,000000 4.000000
2.000000 4.000000.000000 8.000000 a 3,000000000000000000000000000000000000000000.000000> 3,000000000000000000000000000000000000000000.


person ANAGHA S GOURI    schedule 12.01.2018    source источник


Ответы (2)


Первая проблема: ваши комплексные числа должны быть объявлены и использованы в соответствии с определенной компоновкой комплексных чисел, указанной в cblas.h. Ваш код указывает, что вы ожидаете матрицу 2x2, а матрица комплексных значений 2x2 должна быть указана с восемью общими значениями (четыре действительных и четыре мнимых).

*
 * A note on complex data layouts:
 *
 * In order to allow straightforward interoperation with other libraries and
 * complex types in C and C++, complex data in BLAS is passed through an opaque
 * pointer (void *).  The layout requirements on this complex data are that
 * the real and imaginary parts are stored consecutively in memory, and have
 * the alignment of the corresponding real type (float or double).  The BLAS
 * complex interfaces are compatible with the following types:
 *
 *     - The C complex types, defined in <complex.h>.
 *     - The C++ std::complex types, defined in <complex>.
 *     - The LAPACK complex types, defined in <Accelerate/vecLib/clapack.h>.
 *     - The vDSP types DSPComplex and DSPDoubleComplex, defined in <Accelerate/vecLib/vDSP.h>.
 *     - An array of size two of the corresponding real type.
 *     - A structure containing two elements, each of the corresponding real type.
 * 

Вторая проблема: подпрограммы BLAS не предназначены для работы с двумерными массивами. Вместо этого вы должны объявить длинный одномерный массив. Это цель параметров LDA. Правильная передача двумерного массива основана на предположении, что компилятор собирается разместить ваш двумерный массив в определенном порядке, который может быть верным или нет, и приводит к неопределенному поведению.

person David    schedule 12.01.2018
comment
Спасибо за объяснение. Я сделал тот же код, используя cblas_dgemm(), но он работал отлично. Я хотел бы знать, почему cblas_cgemm() столкнулся с этой проблемой. Может ли кто-нибудь внести изменения в мой код, поскольку я не знаком с объявлением сложных переменных, чтобы развеять мои сомнения. - person ANAGHA S GOURI; 13.01.2018

См. соглашения об именах BLAS и Lapack. Поскольку тип матриц double complex, cblas_zgemm() должен использоваться вместо cblas_cgemm(). Действительно, z для комплекса с двойной точностью и c для комплекса с одинарной точностью.

Кроме того, скаляры alpha и beta также должны иметь тип double complex. См. источник подпрограммы Фортран zgemm(), чтобы проверить такие вещи: COMPLEX*16 соответствует double complex.

person francis    schedule 14.01.2018