A2B_octa_matrix.m 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. %% -*- mode: octave -*-
  2. %%
  3. %% Copyright 2007, Aaron Heller, All Rights Reserved
  4. %% heller@ai.sri.com
  5. %%
  6. %% This program is free software: you can redistribute it and/or modify
  7. %% it under the terms of the GNU General Public License as published by
  8. %% the Free Software Foundation, either version 3 of the License, or
  9. %% (at your option) any later version.
  10. %%
  11. %% This program is distributed in the hope that it will be useful,
  12. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. %% GNU General Public License for more details.
  15. %%
  16. %% You should have received a copy of the GNU General Public License
  17. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. function [A2B pv max_err] = A2B_octa_matrix(Y, X, v_z_factor)
  19. % fit 4x4 matrix to measured mic data
  20. %
  21. % Y is the n x m matrix of measurments (’observations’),
  22. % n is number of measurement directions
  23. % m is number of microphones
  24. % X is the n x 3 matrix of are the direction cosines of the
  25. % measurment directions (’predictor variables’)
  26. % pv is the matrix of unknowns to be estimated
  27. % so Y = X pv
  28. if (nargin < 2 )
  29. X = measurement_dirs_z0(size(Y,1));
  30. end
  31. X1 = [ ones(size(Y,1), 1) X ];
  32. pv = X1 \ Y;
  33. max_err = max (Y - (X1 * pv));
  34. pv = octa_fill_v_z( pv )';
  35. ipv = pinv(pv);
  36. A2B = ([1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 1] * ipv)';
  37. end
  38. function X = measurement_dirs_z0(n)
  39. if (nargin < 1)
  40. n = 8;
  41. end
  42. x_range = 0 : 2*pi/n : 2*pi*(n-1)/n;
  43. u_range = [(0 : 4*pi/n : 2*pi*(n-1)/n) (0 : 4*pi/n : 2*pi*(n-1)/n)];
  44. X = [ cos(x_range)' sin(x_range)' zeros(n,1) cos(u_range)' sin(u_range)' ];
  45. end
  46. function pv = octa_fill_v_z (pv, signs, elevation)
  47. if (nargin < 2)
  48. signs = [ +1 -1 +1 -1 +1 -1 +1 -1];
  49. end;
  50. if (nargin < 3)
  51. z_factor = sqrt(2)/2;
  52. else
  53. z_factor = tan(elevation);
  54. end;
  55. for i = 1:8
  56. pv(4,i) = signs(i) * sqrt( pv(2,i)^2 + pv(3,i)^2 ) * z_factor;
  57. end;
  58. end