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)) );