Quantcast
Channel: Recent posts
Viewing all articles
Browse latest Browse all 190

How to use complex data type in MKL C program?

$
0
0

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
FLAGS= -L$(MKLPATH) -I$(MKLINCLUDE)  -I$(MODPATH)    -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core  -liomp5 -lm -lpthread

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!


Viewing all articles
Browse latest Browse all 190

Trending Articles