Aufgrund einer Wartung wird GitLab am 04.06. zwischen 8:00 und 10:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 04.06. between 8:00 and 10:00 am.

ita_sph_DSHT_matrix.m 3.28 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
function out = ita_sph_DSHT_matrix(sampling, varargin)
% matrix = ita_sph_DSHT_matrix(sampling, varargin)
% returns a matrix to proceed a discrete SHerical harmonic transform:
% value_SH = matrix*value_spatial (value_SH and value_spatial : column-vectors)
%
% input:
%   an itaSamplingSH or an itaSamplingSHReal - object, that contains 
%   (coordinate object with complex or real SHerical 
%
% options: 
% - method: there are several DSHT-methods. Select one:
%      - weighted_least_square
%      - least_square
%      - weighted_quadrature (see Dis Zotter or DA Martin Kunkemöller)
%
% - tol: maximum allowed regularization parameter for methods which use 
%         moore penrose pseudo inverse (via single value decomposition)
%
% this function is used in itaBalloon
% Martin Kunkemöller August 2010

% <ITA-Toolbox>
% This file is part of the application SphericalHarmonics for the ITA-Toolbox. All rights reserved. 
% You can find the license for this m-file in the application folder. 
% </ITA-Toolbox>


sArgs = struct('method','weighted_least_square','tol',[]);
if nargin > 2
    sArgs = ita_parse_arguments(sArgs,varargin);
end
if isempty(sampling.Y)
	error('Your sampling contains no spherical harmonic basefunctions');
end
SH = sampling.Y;

switch sArgs.method
    case 'least_square'
        % Zotter S.75 (244) :  estimate coef, so that:
        %    error = (value - Y*coef)'*(value - Y*coef) --> min
        if isempty(sArgs.tol)
            cond_Y = cond(SH,2);
            if cond_Y > 100
                disp(['WARNING: condition of matrix s.Y is: ' num2str(cond_Y)]);
                disp('This may cause imprecise results. Consider defining a tolerance number. Then I can improove the matrix inversion via single value decomposition');
            end
            out = pinv(SH);
        else            
            out = pinv(SH, sArgs.tol);
        end        
    
        
    case 'weighted_least_square'

        % Zotter S.75 (244) :  estimate coef, so that:
        %    error = (value - Y*coef)'*diag(weights)*(value - Y*coef) --> min
        
        %TO DO: Müsste eigentlich wurst sein. Checken!!!
        weights = sampling.weights/sum(sampling.weights);
        Y = bsxfun(@times, SH, sqrt(weights));
       
        if isempty(sArgs.tol)
            cond_Y = cond(SH,2);
            if cond_Y > 100
                disp(['WARNING: condition of matrix s.Y is: ' num2str(cond_Y)]);
                disp('This may cause imprecise results. Consider defining a maximum tolerance. Then matrix inversion can be improoved via single value decomposition');
            end
            out = bsxfun(@times, pinv(Y), sqrt(weights).');
            
        else
            out = bsxfun(@times, pinv(Y, sArgs.tol), sqrt(weights).');
        end
        
        
    case 'weighted_quadrature'
        if sum(sampling.weights) - 4*pi > 1e-6
            error('If you use this method, your "weights" must have a sum equal 4 pi');
        end 
        disp('WARNING: Use this method only with an orthogonal sampling like "equiangular" or "gaussian"! Otherwise "weighted_least_squares" should be better!');
        % Williams Fourier Acoustics S.192 (6.49)
        % Dissertation Zotter S.73 (237) 
        
        out = SH' * diag(sampling.weights);
    otherwise
        error('Unknown method. Choose "leastsquares" or "quadrat"');
end