[V D] = eig(A)
给出具有不一致符号的特征向量,有时第一个条目是正的,有时是负的。这对于一般用途是可以的,但不幸的是,对于我的工作,我需要一致的标志。例如,在针对不同A
的一系列此类评估中。例如,我希望所有特征向量的第一个条目是正的。有哪些有效的方法来实现这一目标?
这就是我的想法:翻转符号的if-else语句(如果第一个条目为负,则翻转)。但似乎效率不高,因为我必须多次评估特征向量。
答案 0 :(得分:0)
您可以使用第一个元素来确定符号并翻转矩阵:
[V, D] = eig(A * sign(A(1)));
希望这有帮助。
答案 1 :(得分:0)
只有时间会告诉我们什么表现更好,但复杂性方面,查看第一个元素是非常有效的,只有当你发现它有错误的符号时才对整个向量进行操作。
所以,如果你有
E = rand(n)-0.5;
然后这个解决方案:
if E(1)<0
E = -E;
end
平均运行1 + n / 2个元素
像
这样的东西E = E * sign(E(1))
将对1 + n个元素进行操作。
话虽如此,如果您发现速度差异值得优化,我会感到惊讶,因此请随意选择最直观的解决方案。
答案 2 :(得分:0)
首先,一般来说,特征值和特征向量可能很复杂。在我们谈论sign
时应该考虑到这一点。在这里,我假设您希望所有特征向量的第一个元素是 real 和 positive 。
这可以通过以下方式使用bsxfun
进行矢量化:
[V, D] = eig(A);
% get the sign of the first row:
signs = sign(V(1, :));
% multiply all columns by the complex conjugate of sign of the first element:
V = bsxfun(@times, V, conj(signs));
如果你将这个方法的速度与if
语句循环进行比较,你会发现我的建议有点慢。但要做到这一点,应该将这种方法与能够处理复杂值的等效循环进行比较。这是我测试的结果:
% the loop solution:
for ii = 1:size(V, 2)
V(:, ii) = V(:, ii) * conj(sign(V(1, ii)));
end
% A = rand(2);
------------------- With BSXFUN
Elapsed time is 0.744195 seconds.
------------------- With LOOP
Elapsed time is 0.500803 seconds.
% A = rand(10);
------------------- With BSXFUN
Elapsed time is 0.828464 seconds.
------------------- With LOOP
Elapsed time is 0.835429 seconds.
% A = rand(100);
------------------- With BSXFUN
Elapsed time is 1.421716 seconds.
------------------- With LOOP
Elapsed time is 4.286256 seconds.
如您所见,这取决于您的应用程序。如果你有许多小矩阵,循环解决方案看起来更方便。另一方面,如果你正在处理更大的矩阵,那么矢量化解决方案肯定会更有效地完成工作。