PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/R2-1-x/octave-forge/main/vrml/best_dir.m

#
MATLAB | 182 lines | 172 code | 10 blank | 0 comment | 14 complexity | c1d886d9abc778f77be5ceffd02d5c5d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. ## Copyright (C) 2002 Etienne Grossmann. All rights reserved.
  2. ##
  3. ## This program is free software; you can redistribute it and/or modify it
  4. ## under the terms of the GNU General Public License as published by the
  5. ## Free Software Foundation; either version 2, or (at your option) any
  6. ## later version.
  7. ##
  8. ## This is distributed in the hope that it will be useful, but WITHOUT
  9. ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. ## for more details.
  12. ##
  13. ## [d,w,rx,cv,wx] = best_dir( x, [a , sx ] )
  14. ##
  15. ## Some points x, are observed and one assumes that they belong to
  16. ## parallel planes. There is an unknown direction d s.t. for each
  17. ## point x(i,:), one has :
  18. ##
  19. ## x(i,:)*d == w(j(i)) + noise
  20. ##
  21. ## where j is known(given by the matrix a ), but w is unknown.
  22. ##
  23. ## Under the assumption that the error on x are i.i.d. gaussian,
  24. ## best_dir() returns the maximum likelihood estimate of d and w.
  25. ##
  26. ## This function is slower when cv is returned.
  27. ##
  28. ## INPUT :
  29. ## -------
  30. ## x : D x P P points. Each one is the sum of a point that belongs
  31. ## to a plane and a noise term.
  32. ##
  33. ## a : P x W 0-1 matrix describing association of points (rows of
  34. ## x) to planes :
  35. ##
  36. ## a(p,i) == 1 iff point x(p,:) belongs to the i'th plane.
  37. ##
  38. ## Default is ones(P,1)
  39. ##
  40. ## sx : P x 1 Covariance of x(i,:) is sx(i)*eye(D).
  41. ## Default is ones(P,1)
  42. ## OUTPUT :
  43. ## --------
  44. ## d : D x 1 All the planes have the same normal, d. d has unit
  45. ## norm.
  46. ##
  47. ## w : W x 1 The i'th plane is { y | y*d = w(i) }.
  48. ##
  49. ## rx : P x 1 Residuals of projection of points to corresponding plane.
  50. ##
  51. ##
  52. ## Assuming that the covariance of x (i.e. sx) was known
  53. ## only up to a scale factor, an estimate of the
  54. ## covariance of x and [w;d] are
  55. ##
  56. ## sx * mean(rx.^2)/mean(sx) and
  57. ## cv * mean(rx.^2)/mean(sx), respectively.
  58. ##
  59. ## cv : (D+W)x(D+W)
  60. ## Covariance of the estimator at [d,w] ( assuming that
  61. ## diag(covariance(vec(x))) == sx ).
  62. ##
  63. ## wx : (D+W)x(D*P)
  64. ## Derivatives of [w;d] wrt to x.
  65. ##
  66. ## Author : Etienne Grossmann <etienne@cs.uky.edu>
  67. ## Created : March 2000
  68. ##
  69. function [d,w,rx,cv,wx] = best_dir( x, a, sx )
  70. [D,P] = size(x) ;
  71. ## Check dimension of args
  72. if nargin<2,
  73. a = ones(P,1) ;
  74. elseif size(a,1) != P,
  75. error ("best_dir : size(a,1)==%d != size(x,2)==%d\n",size(a,1),P);
  76. ## keyboard
  77. end
  78. if isempty (a)
  79. error ("best_dir : a is empty. This will not do!\n");
  80. ## keyboard
  81. end
  82. W = size(a,2) ;
  83. if nargin<3,
  84. sx = ones(P,1) ;
  85. else
  86. if prod(size(sx)) != P,
  87. error ("best_dir : sx has %d elements, rather than P=%d\n",
  88. prod(size(sx)),P);
  89. ## keyboard
  90. end
  91. if !all(sx)>0,
  92. error ("best_dir : sx has non positive element\n");
  93. ## keyboard
  94. end
  95. end
  96. sx = sx(:);
  97. ## If not all points belong to a plane, clean a.
  98. keep = 0 ;
  99. if ! all(sum([a';a'])), # trick for single-column a
  100. ## if verbose, printf ("best_dir : Cleaning up useless rows of 'a'\n"); end
  101. keep = find(sum([a';a'])) ;
  102. ## [d,w,cv] = best_dir(x(keep,:),a(keep,:),sx(keep)) ;
  103. ## return ;
  104. x = x(:,keep);
  105. a = a(keep,:);
  106. sx = sx(keep);
  107. P_orig = P ;
  108. P = prod(size(keep));
  109. end
  110. ## If not all planes are used, remove some rows of a.
  111. if !all(sum(a)),
  112. keep = find(sum(a)) ;
  113. if nargout >= 4,
  114. [d,ww,rx,cv2] = best_dir(x,a(:,keep),sx) ;
  115. cv = zeros(W+D,W+D) ;
  116. cv([1:3,3+keep],[1:3,3+keep]) = cv2 ;
  117. else
  118. [d,ww,rx] = best_dir(x,a(:,keep),sx) ;
  119. end
  120. w = zeros(W,1);
  121. w(keep) = ww ;
  122. return
  123. end
  124. ## Now, a has rank W for sure.
  125. ## tmp = diag(1./sx) ;
  126. tmp = (1./sx)*ones(1,W) ;
  127. tmp2 = inv(a'*(tmp.*a))*(a.*tmp)' ; ;
  128. tmp = x*(eye(P) - tmp2'*a') ;
  129. ## tmp = tmp*diag(1./sx)*tmp' ;
  130. tmp = (tmp.*(ones(D,1)*(1./sx)'))*tmp' ;
  131. [u,S,v] = svd(tmp) ;
  132. d = v(:,D) ;
  133. w = tmp2*x'*d ;
  134. rx = (x'*d - a*w) ;
  135. if nargout >= 4,
  136. wd = [w;d];
  137. ## shuffle = ( ones(D,1)*[0:P-1]+[1:P:P*D]'*ones(1,P) )(:) ;
  138. ## [cv,wx] = best_dir_cov(x',a,sx,wd) ;
  139. ## ## wx = wx(:,shuffle) ;
  140. [cv,wx] = best_dir_cov(x,a,sx,wd) ;
  141. ## [cv2,wx2] = best_dir_cov2(x,a,sx,wd) ;
  142. ## if any(abs(cv2(:)-cv(:))>eps),
  143. ## printf("test cov : bug 1\n") ;
  144. ## keyboard
  145. ## end
  146. ## if any(abs(wx2(:)-wx(:))>eps),
  147. ## printf("test cov : bug 2\n") ;
  148. ## keyboard
  149. ## end
  150. end
  151. if keep,
  152. tmp = zeros(P_orig,1) ;
  153. tmp(keep) = rx ;
  154. rx = tmp ;
  155. if nargout >= 5,
  156. k1 = zeros(1,P_orig) ; k1(keep) = 1 ; k1 = kron(ones(1,D),k1) ;
  157. tmp = zeros(D+W,P_orig*D) ;
  158. tmp(:,k1) = wx ;
  159. wx = tmp ;
  160. end
  161. end
  162. endfunction