Complex matrix exponential in C++

一笑奈何 提交于 2021-01-27 06:52:24

问题


Is it actually possible to calculate the Matrix Exponential of a Complex Matrix in c / c++?

I've managed to take the product of two complex matrices using blas functions from the GNU Science Library. for matC = matA * matB:

gsl_blas_zgemm (CblasNoTrans, CblasNoTrans, GSL_COMPLEX_ONE, matA, matB, GSL_COMPLEX_ZERO, matC);

And I've managed to get the matrix exponential of a matrix by using the undocumented

gsl_linalg_exponential_ss(&m.matrix, &em.matrix, .01);

But this doesn't seems to accept complex arguments.

Is there anyway to do this? I used to think c++ was capable of anything. Now I think its outdated and cryptic...


回答1:


Several options:

  1. modify the gsl_linalg_exponential_ss code to accept complex matrices

  2. write your complex NxN matrix as real 2N x 2N matrix

  3. Diagonalize the matrix, take the exponential of the eigenvalues, and rotate the matrix back to the original basis

  4. Using the complex matrix product that is available, implement the matrix exponential according to it's definition: exp(A) = sum_(n=0)^(n=infinity) A^n/(n!)

You have to check which methods are appropriate for your problem.

C++ is a general purpose language. As mentioned above, if you need specific functionality you have to find a library that can do it or implement it yourself. Alternatively you could use software like MatLab and Mathematica. If that's too expensive there are open source alternatives, e.g. Sage and Octave.




回答2:


"I used to think c++ was capable of anything" - if a general-purpose language has built-in complex math in its core, then something is wrong with that language.

Fur such very specific tasks there is a well-accepted solution: libraries. Either write your own, or much better, use an already existing one.

I myself rarely need complex matrices in C++, I always used Matlab and similar tools for that. However, this http://www.mathtools.net/C_C__/Mathematics/index.html might be of interest to you if you know Matlab.

There are a couple other libraries which might be of help:

  • http://eigen.tuxfamily.org/index.php?title=Main_Page
  • http://math.nist.gov/lapack++/



回答3:


I was also thinking to do the same, writing your complex NxN matrix as real 2N x 2N matrix is the best way to solve the problem, then use gsl_linalg_exponential_ss().

Suppose A=Ar+i*Ai, where A is the complex matrix and Ar and Ai are the real matrices. Then write the new matrix B=[Ar Ai ;-Ai Ar] (Here the matrix is written in matlab notation). Now calculate the exponential of B, that is eB=[eB1 eB2 ;eB3 eB4], then exponential of A is given by, eA=eB1+1i.*eB2
(summing the matrices eB1 and 1i.*eB2).




回答4:


I have written a code to calculate the matrix exponential of the complex matrices with the gsl function, gsl_linalg_exponential_ss(&m.matrix, &em.matrix, .01); Here you have the complete code, and the compilation results. I have checked the result with the Matlab and result agrees.

#include <stdio.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
void my_gsl_complex_matrix_exponential(gsl_matrix_complex *eA, gsl_matrix_complex *A, int dimx)
{
    int j,k=0;
    gsl_complex temp;
    gsl_matrix *matreal =gsl_matrix_alloc(2*dimx,2*dimx);
    gsl_matrix *expmatreal =gsl_matrix_alloc(2*dimx,2*dimx);
    //Converting the complex matrix into real one using A=[Areal, Aimag;-Aimag,Areal]
    for (j = 0; j < dimx;j++)
        for (k = 0; k < dimx;k++)
        {
            temp=gsl_matrix_complex_get(A,j,k);
            gsl_matrix_set(matreal,j,k,GSL_REAL(temp));
            gsl_matrix_set(matreal,dimx+j,dimx+k,GSL_REAL(temp));
            gsl_matrix_set(matreal,j,dimx+k,GSL_IMAG(temp));
            gsl_matrix_set(matreal,dimx+j,k,-GSL_IMAG(temp));
        }

    gsl_linalg_exponential_ss(matreal,expmatreal,.01);

    double realp;
    double imagp;
    for (j = 0; j < dimx;j++)
        for (k = 0; k < dimx;k++)
        {
            realp=gsl_matrix_get(expmatreal,j,k);
            imagp=gsl_matrix_get(expmatreal,j,dimx+k);
            gsl_matrix_complex_set(eA,j,k,gsl_complex_rect(realp,imagp));
        }
    gsl_matrix_free(matreal);
    gsl_matrix_free(expmatreal);
}

int main()
{
    int dimx=4;
    int i, j ;
    gsl_matrix_complex *A = gsl_matrix_complex_alloc (dimx, dimx);
    gsl_matrix_complex *eA = gsl_matrix_complex_alloc (dimx, dimx);

    for (i = 0; i < dimx;i++)
    {
        for (j = 0; j < dimx;j++)
        {
            gsl_matrix_complex_set(A,i,j,gsl_complex_rect(i+j,i-j));
            if ((i-j)>=0)
            printf("%d+%di ",i+j,i-j);
            else
            printf("%d%di  ",i+j,i-j);

        }
        printf(";\n");
    }
    my_gsl_complex_matrix_exponential(eA,A,dimx);
    printf("\n Printing the complex matrix exponential\n");
    gsl_complex compnum;
    for (i = 0; i < dimx;i++)
    {
        for (j = 0; j < dimx;j++)
        {
            compnum=gsl_matrix_complex_get(eA,i,j);
            if (GSL_IMAG(compnum)>=0)
                printf("%f+%fi\t ",GSL_REAL(compnum),GSL_IMAG(compnum));
            else
                printf("%f%fi\t ",GSL_REAL(compnum),GSL_IMAG(compnum));
        }
        printf("\n");
    }
    return(0);
}


来源:https://stackoverflow.com/questions/10049160/complex-matrix-exponential-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!