首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么eig()和ishermitian()在不同的计算机和MATLAB版本上有不同的行为方式?

为什么eig()和ishermitian()在不同的计算机和MATLAB版本上有不同的行为方式?
EN

Stack Overflow用户
提问于 2017-11-17 00:32:13
回答 2查看 180关注 0票数 1

我将首先简明扼要地陈述我的问题和情况,然后详细介绍我迄今在解决这些问题方面取得的进展。

函数eig()在计算机体系结构和MATLAB版本的不同组合上的行为是不同的,我注意到了两种方式。首先,对于相同的精确码,输出的特征值和特征向量的阶数不同。现在,我在几个地方读到,MATLAB不能保证输出中的特定顺序,所以为了安全起见,应该在输出之后进行排序,所以即使我认为这是一个更大问题的一部分,我还是让它滑过。行为不同的另一种方式是,在它们的顺序不上升的情况下,特征值是错误的。这就是为什么我知道它们是错误的:我处理的是规模不大的复Hermitian矩阵,而我得到的特征值是复杂的,但是对于Hermitian矩阵,它们应该是真实的。在顺序上升的体系结构/版本组合中,特征值也是真实的,它们应该是真实的。当它们很复杂的时候,想象的部分就像机器的感受器,所以很明显它们根本不应该在那里。所以,这件事的麻烦之处在于,当它不应该是复杂的时候,就拿出它的真实部分,然后排序。这方面的一个实际问题是,当eig()使用它认为矩阵不是Hermitian的例程时,它所花费的时间是它的两倍长,占用的内存是它的两倍,大概是因为复杂而不是实数。所以,问题是,这是为什么,我们有办法绕过它吗?

很抱歉做了长时间的介绍。我注意到的一件事是,在具有正确特征值的体系结构/版本组合中,如果我直接给出一个复杂的Hermitian矩阵给ishermitian(),它也会给出正确的答案。当特征值不正确时,ishermitian()也不正确。下面是一些简单的例子。所以,我的想法是,eig()正在测试矩阵是否像ishermitian()那样是Hermitian的。

对于具有不正确特征值的体系结构/版本组合,对于一些简单的内容,ishermitian()仍然是正确的:

代码语言:javascript
运行
复制
>> test=[1 2 3]+[4 5 6]*1i; 
>> mat=test'*test;
>> ishermitian(mat)

ans =

     1

复向量及其共轭转置的外积定义为Hermitian矩阵。所以我们可以用一个矩阵再试一次,这个矩阵和我处理的矩阵大小差不多。来自同一台计算机:

代码语言:javascript
运行
复制
>> test=randn(1,64)+randn(1,64)*1i;
>> mat=test'*test;
>> ishermitian(mat)

ans =

     0

我们可以看到与eig()相应的问题

代码语言:javascript
运行
复制
>> vals=eig(mat);       
>> whos vals
  Name       Size            Bytes  Class     Attributes

  vals      64x1              1024  double    complex   

现在,在另一台计算机上,相同的代码:

代码语言:javascript
运行
复制
>> test=randn(1,64)+randn(1,64)*1i;
>> mat=test'*test;
>> ishermitian(mat)

ans =

     1

>> vals=eig(mat);
>> whos vals
  Name       Size            Bytes  Class     Attributes

  vals      64x1               512  double              

我已经在各种系统上测试过这一点,而且我没有注意到任何关于架构或版本对此负责的规则,所以我不会对所有这些细节感到厌烦。但我很好奇,一个结果和另一个结果相比有多频繁。根据我目前的经验,这似乎是一半半。奇怪的是,在同一台电脑上:

代码语言:javascript
运行
复制
>> test2=test';
>> mat=test2*test;
>> ishermitian(mat)

ans =

     0

>> vals=eig(mat);
>> whos vals
  Name       Size            Bytes  Class     Attributes

  vals      64x1              1024  double    complex   

所以,如果你把转位分配给另一个变量,就会出现一些精度问题,比如在另一台计算机上,但如果你不这样做,它就会工作。我是不是遗漏了为什么会发生这样的事情,或者有什么方法可以绕过它呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-17 22:29:10

我正准备写一些东西,用一些小量把数字加起来,但我偶然发现了这个随机的东西,它似乎能在任何地方解决这个问题:

代码语言:javascript
运行
复制
>> test=randn(1,64)+randn(1,64)*1i;
>> mat=test'*test;             
>> ishermitian(mat)

ans =

     0

>> vals=eig(mat);
>> whos vals
  Name       Size            Bytes  Class     Attributes

  vals      64x1              1024  double    complex   

>> mat=(mat+mat')/2;
>> ishermitian(mat)

ans =

     1

>> vals=eig(mat);
>> whos vals
  Name       Size            Bytes  Class     Attributes

  vals      64x1               512  double              

现在我在任何地方都能得到所有预期的结果,而且花费的时间是预期的一半,等等。很明显,mat=(mat+mat')/2;在某种程度上解决了一个舍入/精确问题,但我不知道为什么会这样做。从理论上讲,这个操作应该让我回到我已经拥有的东西,因为mat==mat',如果它是Hermitian的话,但是在这个例子中,无论出于什么原因,我们都知道mat~=mat'。有什么想法,为什么这一行动是像一个小回合?

票数 1
EN

Stack Overflow用户

发布于 2017-11-17 01:47:00

要克服这个问题,可以尝试将矩阵转到某个(小的)程度,或者只是通过复制(不涉及任何数字操作)显式地生成矩阵hermitian。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47341428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档