diff core/magnatagatune/MTTMixedFeatureSlaney08GenreBasicSmPCA.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/magnatagatune/MTTMixedFeatureSlaney08GenreBasicSmPCA.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,264 @@
+% --
+% This class loads and hanles the aufdio features included with the MTT
+% Library
+% --- 
+classdef MTTMixedFeatureSlaney08GenreBasicSmPCA < MTTAudioFeature & handle
+    
+    properties(Constant = true)
+        
+        my_revision = str2double(substr('$Rev$',  5, -1));
+    end
+    
+    properties
+        
+        % ---
+        % Set default parameters
+        % ---
+        my_basetype = 'MTTMixedFeatureSlaney08GenreBasicSm';
+        
+        my_params = MTTAudioFeature.inherited_params(...
+            'MTTMixedFeatureSlaney08GenreBasicSm', ...
+            'min_pca_var', 0, ... % fraction of variance to keep
+            'max_pca_coeffs', 0, ...% max. number of final coefficients
+            'norm_pre_pca', 1, ...% normalise pca coefficients after transformation
+            'norm_post_pca', 1 ...
+        );
+    end
+    % ---
+    % member functions
+    % ---
+    methods
+        
+        % ---
+        % constructor: pointer to feature in database
+        % ---
+        function feature = MTTMixedFeatureSlaney08GenreBasicSmPCA(varargin)
+
+            feature = feature@MTTAudioFeature(varargin{:});
+        end
+        
+        % ---
+        % load feature data from xml file
+        % ---
+        function data = extract(feature, clip)
+        % load feature data by parsing xml
+            
+            global globalvars;
+            
+            % ---
+            % we extract the base features, and save 
+            % the pointers to these.
+            % the main work is then done in the define_global_transf
+            % and finalise functions.
+            % ---
+            data.basefeat = clip.features(feature.my_basetype,...
+                feature.my_params); 
+
+            % save info data
+            data.info.type = class(feature);
+            data.info.owner_id = clip.id;
+            data.info.creatorrev = feature.my_revision;
+            
+            % save param data
+            data.info.params = feature.my_params;
+            
+            % prepare field for final features
+            data.final.vector = [];
+            data.final.dim = 0;
+            data.final.vector_info.labels = {};
+        end
+        
+        function define_global_transform(features)
+            
+            if numel(features) == 1
+                error ('Insert feature array for this method');
+            end
+            
+            % ---
+            % We collect all the relevant genretag 
+            % features and get the transform on this basis.
+            % ---
+            for i = 1:numel(features)
+            	basef(i) = features(i).data.basefeat;
+            end
+            
+            % call the features own transsform function
+            basef.define_global_transform();
+            
+            % ---
+            % finalise the basic features, and 
+            % get the feature vectors;
+            % ---
+            X = basef.vector();
+            
+            % check dataset dimension
+            if numel(features) < basef.dim;
+                
+                error ('Not enough feature vectors for PCA calculation. need %d samples', ...
+                    basef.dim);
+            end
+            
+            % ---
+            % NOTE: should the data be normalised and scaled to -1:1 
+            % instead of being in a range of 0-1 AND max-min = 1
+            % --- 
+            if features(1).my_params.norm_pre_pca == 1
+                                
+                [X, pstd] = mapminmax(X,-1,1);
+                common.pca.pre_norm = pstd;
+            elseif features(1).my_params.norm_pre_pca == 2
+                
+                [X, pstd] = mapstd(X,0,1);
+                common.pca.pre_norm = pstd;
+            end
+
+            
+            % ---
+            % get and apply the principal component analysis
+            % NOTE: the variance percentile is applied here, too.
+            % ---
+
+            [Y, ps] = processpca(X, 0);
+            common.pca.transform = ps;
+            
+            % ---
+            % get cumulative sum of variance, and decide on cutoff
+            % point
+            % --- 
+            v = cumsum(var(Y'));
+            v = v / max(v);
+            common.pca.transform.varpart = v;
+            
+            if features(1).my_params.min_pca_var > 0
+                            
+                min_pca_idx = find(v >= features(1).my_params.min_pca_var,1, 'first');
+                
+                % save into pca structure
+                common.pca.transform.yrows = min_pca_idx;
+                
+            end 
+            
+            % normalise pca values after processing
+            if features(1).my_params.norm_post_pca
+                
+                [Y,pmm] = mapminmax(Y,0,1);
+                common.pca.post_norm = pmm;
+                
+            end
+            
+            % ---
+            % set common feature values for mixed features
+            % ---
+            features(1).my_db.set_common(common);            
+            
+            % save the transformed features straight away!
+            features.finalise(Y);
+        end
+        
+        function finalise(feature, final)
+        % applies a final transformation and
+        % collects the information of this feature within a single vector
+        % see info for types in specific dimensions
+        
+            % determine size
+            if feature(1).my_params.max_pca_coeffs > 0
+
+                max_size = min(feature(1).common.pca.transform.yrows, ...
+                    feature(1).my_params.max_pca_coeffs);
+            else
+
+                max_size = feature(1).common.pca.transform.yrows;
+            end
+
+
+            % prepare information
+            info = {'PCA'};
+            if isfield(feature(1).common.pca.transform, 'varpart')
+                info(2:max_size) = num2cell(feature(1).common.pca.transform.varpart(2:max_size));
+            else
+                info(2:max_size) = num2cell(2:max_size);
+            end
+
+        
+            % check if features have been finalised already
+            if nargin == 2 && isempty(final)
+                
+                % the final vector etc already are set to zero;
+                return;
+                
+            elseif nargin == 2 && (numel(feature) == size(final, 2))
+                    
+                for i = 1:numel(feature)
+                    
+                    % save final vector and description
+                    feature(i).data.final.vector = final(1:max_size,i);
+                    feature(i).data.final.dim = max_size;
+                    feature(i).data.final.vector_info.labels = info;
+                end
+                
+            else
+            % features have to be transformed first
+            % ---
+            % TODO: this code remains untested
+            % ---
+            
+            % check for neccesary parameters
+                if isempty(feature(1).my_db.commondb)
+
+                    error('Define the global transformation first')
+                    return;
+                end
+             
+
+                for i = 1:numel(feature)
+
+                    % check for neccesary parameters
+                    if isempty(feature(i).my_db.commondb)
+
+                        error('Define the global transformation first')
+                    end
+                    
+                    % ---
+                    % get feature vector and apply transformation
+                    % ---
+                    X = feature(i).data.basefeat.vector();
+                    
+                    % ---
+                    % apply normalisation used for removing mean 
+                    % in training data
+                    % ---
+                    if feature(1).my_params.norm_pre_pca == 1
+                                
+                        X = mapminmax('apply', X, feature(1).common.pca.pre_norm);
+                    elseif feature(1).my_params.norm_pre_pca == 2
+
+                        X = mapstd('apply', X, feature(1).common.pca.pre_norm);
+                    end
+ 
+                    % apply PCA transform
+                    vec = processpca('apply', X, feature(1).common.pca.transform);
+                    
+                    % normalise pca values after transformation
+                    if feature(1).my_params.norm_post_pca
+
+                        vec = mapminmax('apply', vec,...
+                            feature(1).common.pca.post_norm);
+                    end
+                    
+                    % ---
+                    % cut vector to final size. 
+                    % NOTE: this should be done before
+                    % transformation to reduce computation time
+                    % ---
+                    vec = vec(1:max_size);
+                    
+                    % save final vector and description
+                    feature(i).data.final.vector = vec;
+                    feature(i).data.final.dim = numel(vec);
+                    feature(i).data.final.vector_info.labels = info;
+                end
+            end
+        end
+        
+    end
+end
\ No newline at end of file