diff --git a/linalg/frobenius_inner.m b/linalg/frobenius_inner.m index 2a7ef162..d8fd59bd 100644 --- a/linalg/frobenius_inner.m +++ b/linalg/frobenius_inner.m @@ -1,10 +1,21 @@ function d=frobenius_inner(A,B) -% FROBENIUS_INNER Short description of frobenius_inner. -% FROBENIUS_INNER Long description of frobenius_inner. +% FROBENIUS_INNER Computes the Frobenius inner product. +% D=FROBENIUS_INNER(A,B) computes the Frobenius inner product between +% matrices A and B. The Frobenius inner product is given by +% A:B := tr(A'*B) = sum_ij A_ij B_ij +% +% Note: +% The computation is of course not carried out by the trace formula, +% which is very inefficient, but by a more efficient method. % % Example (run) +% A = rand(4,5); +% B = rand(4,5); +% fprintf('A:B=%g\n', frobenius_inner(A, B)); +% % computing the Frobenius norm +% fprintf('||A||_F=%g=%g\n', sqrt(frobenius_inner(A, A)), norm(A,'fro')); % -% See also +% See also NORM, TRACE % Elmar Zander % Copyright 2010, Inst. of Scientific Computing, TU Braunschweig diff --git a/linalg/subspace_angle.m b/linalg/subspace_angle.m deleted file mode 100644 index 997f1681..00000000 --- a/linalg/subspace_angle.m +++ /dev/null @@ -1,26 +0,0 @@ -function theta=subspace_angle(A1,A2) -% SUBSPACE_ANGLE Short description of subspace_angle. -% SUBSPACE_ANGLE Long description of subspace_angle. -% -% Example (run) -% -% See also - -% Elmar Zander -% Copyright 2010, Inst. of Scientific Computing, TU Braunschweig -% $Id$ -% -% This program is free software: you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by the -% Free Software Foundation, either version 3 of the License, or (at your -% option) any later version. -% See the GNU General Public License for more details. You should have -% received a copy of the GNU General Public License along with this -% program. If not, see . - - -[Q1,R1]=qr(A1,0); -[Q2,R2]=qr(A2,0); -C=Q1'*Q2; -s=svd(C); -theta=acos(s); diff --git a/linalg/subspace_angles.m b/linalg/subspace_angles.m new file mode 100644 index 00000000..2458d35d --- /dev/null +++ b/linalg/subspace_angles.m @@ -0,0 +1,47 @@ +function [theta,U,V]=subspace_angles(A,B) +% SUBSPACE_ANGLES Compute the principal angles between subspaces. +% THETA=SUBSPACE_ANGLES(A, B) computes the principal angles THETA between +% subspaces spanned by the matrices A and B. For a definition see [1] +% section 12.4.3. +% +% [THETA,U,V]=SUBSPACE_ANGLES(A, B) also computes the principal vectors +% and returns them in U and V. +% +% References +% [1] G. Golub and C. F. Van Loan, Matrix Computations, 3rd ed. John +% Hopkins University Press +% +% Example (run) +% A = rand(7, 3); +% B = rand(7, 5); +% [theta, U, V] = subspace_angles(A, B) +% +% See also SUBSPACE, SUBSPACE_DISTANCE + +% Elmar Zander +% Copyright 2010, Inst. of Scientific Computing, TU Braunschweig +% +% This program is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation, either version 3 of the License, or (at your +% option) any later version. +% See the GNU General Public License for more details. You should have +% received a copy of the GNU General Public License along with this +% program. If not, see . + + +[QA,RA]=qr(A,0); %#ok +[QB,RB]=qr(B,0); %#ok +C=QA'*QB; +if nargout>1 + [Y,S,Z]=svd(C); + q=min(size(A,2),size(B,2)); + U=QA*Y(:,1:q); + V=QB*Z(:,1:q); + s=diag(S); +else + s=svd(C); +end +% clamp s between 0 and 1 +s=max(min(s,1),0); +theta=acos(s); diff --git a/linalg/subspace_distance.m b/linalg/subspace_distance.m index 0a408ff8..1d1a1468 100644 --- a/linalg/subspace_distance.m +++ b/linalg/subspace_distance.m @@ -1,10 +1,35 @@ -function dist=subspace_distance(A,B) -% SUBSPACE_DISTANCE Short description of subspace_distance. -% SUBSPACE_DISTANCE Long description of subspace_distance. +function dist=subspace_distance(A, B, varargin) +% SUBSPACE_DISTANCE Compute distance between subspaces. +% DIST=SUBSPACE_DISTANCE(A, B) computed the distance between the +% subspaces A and B. % +% Options +% type: {'mlab'}, 'gv', 'wwf' +% Compute the distance compatible to the matlab subspace functions +% ('mlab', default), according to [1] section 2.6.3 ('gv'), or +% according to 2 ('wwf'). Note, that the last method only works, if +% the subspaces have the same size. Note further, that in that case +% method 'mlab' and 'gv' coincide. +% +% References +% [1] G. Golub and C. F. Van Loan, Matrix Computations, 3rd ed. John +% Hopkins University Press, +% [2] Xi-Chen Sun, Xiao Wang, Qiansheng Cheng, Jufu Feng: On Subspace +% Distances, LMAM, School of Mathematical Sciences,Peking +% www.math.pku.edu.cn:8000/var/preprint/620.pdf‎ +% % Example (run) +% A=rand(10,3); +% B=rand(10,5); +% subspace_distance(A, B) +% subspace_distance(A, B, 'type', 'gv') % -% See also +% B=rand(10,3); +% subspace_distance(A, B) +% subspace_distance(A, B, 'type', 'gv') +% subspace_distance(A, B, 'type', 'wwf') +% +% See also SUBSPACE, SUBSPACE_ANGLES % Elmar Zander % Copyright 2010, Inst. of Scientific Computing, TU Braunschweig @@ -18,17 +43,28 @@ % received a copy of the GNU General Public License along with this % program. If not, see . -if ~iscell(A) - A=orth(A); - B=orth(B); - if size(A,2)run) -% unittest_subspace_angle -% -% See also SUBSPACE_ANGLE, TESTSUITE - -% Elmar Zander -% Copyright 2010, Inst. of Scientific Computing, TU Braunschweig -% $Id$ -% -% This program is free software: you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by the -% Free Software Foundation, either version 3 of the License, or (at your -% option) any later version. -% See the GNU General Public License for more details. You should have -% received a copy of the GNU General Public License along with this -% program. If not, see . - -munit_set_function( 'subspace_angle' ); - -e1=unitvector(1,4); -e2=unitvector(2,4); -e3=unitvector(3,4); -e4=unitvector(4,4); - -test([e1, e2], [e1, e2]); -test([e1, e2], [e1, e3]); -test([e1, e2], [e3, e4]); -test([e1, e2], [e1, -e2+e4]); - -A=rand(7,5); B=rand(7,5); -assert_equals( asin(subspace_distance(A,B)), subspace(A,B) ) -A=[A, A]; B=[B, B]; -assert_equals( asin(subspace_distance(A,B)), subspace(A,B) ) -A=rand(7,5); B=rand(7,3); -assert_equals( asin(subspace_distance(A,B)), subspace(A,B) ) -A=rand(7,3); B=rand(7,5); -assert_equals( asin(subspace_distance(A,B)), subspace(A,B) ) - -function test(A1,A2) -theta=subspace_angle(A1,A2); -dist=subspace_distance(A1,A2); -assert_equals( dist, sin(theta(2)) );