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!