Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

## How to use complex data type in MKL C program?

Beginner
3,105 Views

Dear all:

I am facing a problem on how to use lapack_complex_double data type, Including multiply, divide,conjugate(I can do this using z_imag=-z_imag, is this the best way?), and print the results(actually I can print the result, but every time I need a cast (double)z.real, (double)z.imag, which is not convenient).I have tried cast the variable (double complex) z the multiply, but it failed. I will give my sample program. Anyone please kindly show me how I can handle this data type. Please modify on my program so that I can see clear how this is done. I am a novice in both C and MKL programming. I have searched this site and found some similar thread, but I still cannot work it out.

Below is my program, you can do the matrix element operations using matrix m in it.

```#include    <complex.h>
#include    <math.h>
#include    <stdlib.h>
#include    <stdint.h>
#include    <stdio.h>
#include    <mkl.h>
lapack_int LAPACKE_zheev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w );
//hermitian matrix, each row in output is an eigenvector
void    diag(lapack_complex_double *mat, double *e, lapack_int n)
{
char    jobz='V';   //also eigenvectors
char    uplo='U';   //upper triangle
lapack_int  info;

info=LAPACKE_zheev(LAPACK_ROW_MAJOR,jobz,uplo,n,mat,n,e);

if(info!=0){
printf("matrix diag fail,the %d argument is wrong\n",info);
exit(1);
}
}

int main()
{
lapack_complex_double *mat;
lapack_complex_double *m;
double  *e;

mat=(lapack_complex_double *)malloc(sizeof(lapack_complex_double)*4);
m=(lapack_complex_double *)malloc(sizeof(lapack_complex_double)*4);
e=(double *)malloc(sizeof(double)*2);
mat[0].real=1.0;    mat[0].imag=0.0;
mat[1].real=1.0;    mat[1].imag=-1.0;
mat[2].real=1.0;    mat[2].imag=1.0;
mat[3].real=2.0;    mat[3].imag=0.0;
*m=*mat;
*(m+1)=*(mat+1);
*(m+2)=*(mat+2);
*(m+3)=*(mat+3);
diag(mat,e,2);

printf("{(%f,+%fI),(%f,+%fI)}\n",(double)m[0].real,(double)m[0].imag,(double)m[1].real,(double)m[1].imag);
printf("{(%f,+%fI),(%f,+%fI)}\n",(double)m[2].real,(double)m[2].imag,(double)m[3].real,(double)m[3].imag);
printf("the eigenvalue is %f,%f\n",e[0],e[1]);

printf("{(%f,+%fI),(%f,+%fI)}\n",(double)mat[0].real,(double)mat[0].imag,(double)mat[1].real,(double)mat[1].imag);
printf("{(%f,+%fI),(%f,+%fI)}\n",(double)mat[2].real,(double)mat[2].imag,(double)mat[3].real,(double)mat[3].imag);

printf("{(%f,+%fI),(%f,+%fI)}\n",(double)mat[0].real,(double)mat[0].imag,(double)mat[1].real,(double)mat[1].imag);
printf("{(%f,+%fI),(%f,+%fI)}\n",(double)mat[2].real,(double)mat[2].imag,(double)mat[3].real,(double)mat[3].imag);
free(mat);
free(m);
free(e);
return 0;
}
```

By the way, I am using gcc, below is my Makefile so that you may need when you compile the above program.

```NAME=upload
OBJECTS = \$(NAME).c
cc = gcc
MKLPATH=/opt/intel/composer_xe_2013.5.192/mkl/lib/intel64
MKLINCLUDE=/opt/intel/composer_xe_2013.5.192/mkl/include
MODPATH=/opt/intel/composer_xe_2013.5.192/mkl/include/intel64/lp64

OUTNAME=\$(NAME).out

\$(NAME): \$(OBJECTS)
\$(cc) -o \$(OUTNAME) \$(OBJECTS) \$(FLAGS)
clean:
rm -f \$(OUTNAME)
```

Another question is how I can easily do the matrix-matrix multiply and matrix-vector multiply using C program. Is there any function in MKL or something can do this? If so, can you add that to the above program? thanks very much!

1 Solution
Employee
3,105 Views

The complex double data type in the C API of MKL is just a struct with a pair of double type numbers, real and imag.

MKL doesn't have arithmetic functions (such as multiply, conjugate, etc.) that operate on scalar complex numbers. But you can find these functions in the standard C99 complex.h.

MKL has arithmetic functions that operates on vectors of complex numbers. Check the "VML Mathematical Functions" chapter in the MKL reference manual.

MKL provides BLAS functions for matrix-matrix and matrix-vector multiplications. All S, D, C, Z data types are supported. Check the "BLAS and Sparse BLAS Routines" chapter in the MKL reference manual.

2 Replies
Employee
3,106 Views

The complex double data type in the C API of MKL is just a struct with a pair of double type numbers, real and imag.

MKL doesn't have arithmetic functions (such as multiply, conjugate, etc.) that operate on scalar complex numbers. But you can find these functions in the standard C99 complex.h.

MKL has arithmetic functions that operates on vectors of complex numbers. Check the "VML Mathematical Functions" chapter in the MKL reference manual.

MKL provides BLAS functions for matrix-matrix and matrix-vector multiplications. All S, D, C, Z data types are supported. Check the "BLAS and Sparse BLAS Routines" chapter in the MKL reference manual.

Beginner
3,105 Views

Zhang Z (Intel) wrote:

The complex double data type in the C API of MKL is just a struct with a pair of double type numbers, real and imag.

MKL doesn't have arithmetic functions (such as multiply, conjugate, etc.) that operate on scalar complex numbers. But you can find these functions in the standard C99 complex.h.

MKL has arithmetic functions that operates on vectors of complex numbers. Check the "VML Mathematical Functions" chapter in the MKL reference manual.

MKL provides BLAS functions for matrix-matrix and matrix-vector multiplications. All S, D, C, Z data types are supported. Check the "BLAS and Sparse BLAS Routines" chapter in the MKL reference manual.

Hi Zhang Z:

Thanks very much for you reply. I think I will assign the value of MKL complex data to a C double complex variable, then use it as I wish. Thank you for providing me the additional information about the BLAS.

cheers.