实际上是否可以在c / c ++中计算复杂矩阵的矩阵指数?
我设法使用GNU Science Library中的blas函数获取两个复杂矩阵的乘积。对于matC = matA * matB:
gsl_blas_zgemm (CblasNoTrans, CblasNoTrans, GSL_COMPLEX_ONE, matA, matB, GSL_COMPLEX_ZERO, matC);
我已经设法通过使用未记录的
获得矩阵的矩阵指数gsl_linalg_exponential_ss(&m.matrix, &em.matrix, .01);
但这似乎不接受复杂的论点。
有没有这样做?我曾经认为c ++能够做任何事情。现在我觉得它过时而神秘......
答案 0 :(得分:3)
有几个选择:
修改gsl_linalg_exponential_ss
代码以接受复杂矩阵
将复杂的NxN矩阵写为真正的2N x 2N矩阵
对角化矩阵,取特征值的指数,并将矩阵旋转回原始基础
使用可用的复杂矩阵产品,根据其定义实现矩阵指数:exp(A) = sum_(n=0)^(n=infinity) A^n/(n!)
您必须检查哪种方法适合您的问题。
C ++是一种通用语言。如上所述,如果您需要特定的功能,您必须找到可以执行此操作的库或自行实现它。或者,您可以使用MatLab和Mathematica等软件。如果这太贵了,那么有开源替代品,例如贤者和八度。
答案 1 :(得分:1)
“我曾经认为c ++能够做任何事情” - 如果一个通用语言在其核心内置了复杂的数学,那么该语言就会出现问题。
毛皮这样非常具体的任务有一个广为接受的解决方案:图书馆。编写自己的,或更好的,使用已有的。
我自己很少需要C ++中复杂的矩阵,我总是使用Matlab和类似的工具。但是,如果您了解Matlab,那么http://www.mathtools.net/C_C__/Mathematics/index.html可能会引起您的兴趣。
还有一些其他库可能会有所帮助:
答案 2 :(得分:0)
我也在考虑这样做,编写复杂的NxN矩阵,因为真正的2N x 2N矩阵是解决问题的最佳方法,然后使用gsl_linalg_exponential_ss()
。
假设 A=Ar+i*Ai
,,其中A
是复杂矩阵,Ar
和Ai
是真正的矩阵。然后编写新矩阵 B=[Ar Ai ;-Ai Ar]
(这里矩阵用matlab表示法编写)。现在计算 B
的指数,即 eB=[eB1 eB2 ;eB3 eB4]
,然后A
的指数由 {{ 1}} 强>
(总结矩阵 eA=eB1+1i.*eB2
和 eB1
)。
答案 3 :(得分:0)
我编写了一个代码,用gsl函数计算复数矩阵的矩阵指数,gsl_linalg_exponential_ss(& m.matrix,& em.matrix,.01); 这里有完整的代码和编译结果。我用Matlab检查了结果,结果一致。
#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);
}