classdef sensitivityAnalysis < hilomot
    % sensitivityAnalysis tries to find out what inputs are the most
    % important ones for an 'accurate' model output.
    %
    % This class is used to quantify the relative importance of the several
    % inputs and their combinations to the model output. There are a few
    % strategies to find input combinations that represents a good
    % trade-off between the number of inputs and the model performance.
    %
    %
    % PROPERTIES:
    %
    % originalInput:        N x p)     All inputs of the original dataset.
    %
    % originalOutput:       (N x q)    All output values of the original
    %                                  dataset.
    %
    % combinationMatrix:    (Nc x p)   Matrix, that contains one input
    %                                  combination per line.
    %
    % fixedInputs:          (1 x pf)   Vector containing the inputs (colum
    %                                  number of 'originalInput'), that
    %                                  maintain in any input combination.
    %
    % sensitivityResults:   noch nicht klar, ob hierfuer eigene Klasse
    %                       erzeugt wird.
    %
    % strategy:             (string)   String, that determines which
    %                                  strategy should be used to find good
    %                                  input combinations.
    %
    %
    % SYMBOLS AND ABBREVIATIONS:
    %
    % LM:  Local model
    %
    % p:   Number of inputs (physical inputs)
    % q:   Number of outputs
    % N:   Number of data samples
    % M:   Number of LMs
    % nx:  Number of regressors (x)
    % nz:  Number of regressors (z)
    % Nc:  Number of input combinations
    % pf:  Number of fixed inputs
    %
    %
    % EXPLANATIONS:
    %
    % 
    
    % LMNtool - Local Model Network Toolbox
    % Julian Belz, 18th-July-2012
    % Institute of Mechanics & Automatic Control, University of Siegen, Germany
    % Copyright (c) 2012 by Prof. Dr.-Ing. Oliver Nelles
    
    % 18.07.12 v0.1
    
    properties
        
        originalInput = [];                 % Original input with all inputs
        originalOutput = [];                % Original output
        combinationMatrix = [];             % Matrix with all input combinations, that are tested
        fixedInputs = [];                   % Inputs that have to be contained in any other input combination
        sensitivityResults = struct('model',{},'lossFunctionValue',{},'ranking',{}); % Contains the results of the sensitivity analysis
        strategy = 'bruteForce';            % The strategy used to find good input combinations
        space2investigate = 'x';            % Determines which input space should be investigated. Only valid values are 'x' and 'z'.
        
    end
    
    
    properties(Hidden=true)
        
    end
    
    
    methods
        % Constructor
        function obj = sensitivityAnalysis(modelObject)
            % If there is a model object passed, save the unscaled input
            % and output matrix
            if nargin == 1
                if ~isempty(modelObject.input)
                    obj.originalInput = modelObject.unscaledInput;
                    obj.input = modelObject.unscaledInput;
                end
                if ~isempty(modelObject.output)
                    obj.originalOutput = modelObject.unscaledOutput;
                    obj.output = modelObject.unscaledOutput;
                end
            end
        end
        % end constructor
        
        obj = findInputCombinations(obj,strategy,minInputs,maxInputs,fixedInputs);
        visualizeSensitivityResults(obj);
        [plotHandles,annotationHandles] = visualizeAICoverNumberOfInputs(obj,axesHandle,numberOfLines,plotOptionObject,fh);
        [markerHandle,lineHandle] = plotOutputOverMeasuredData(obj,inputCombination,measuredInput,measuredOutput,axesHandle,markerColor,plotOptionObject)
        
        % SET and GET methods, to prevent errors later
        function obj = set.space2investigate(obj,value)
            % Make sure, that no other values than 'x' or 'z' can be passed
            % to this property
            if strcmp(value,'x') || strcmp(value,'z')
                obj.space2investigate = value;
            else
                error('You tried to pass a value to the space2investigate-property, that is not allowed. You can only pass "x" or "z".');
            end
        end
        
    end
    
    
    
    methods(Static) % static methods
        combinationMatrix = buildCombinationMatrix(minInputs,maxInputs);
        out = combinations(inputVector,subsetSize);
        [fontname,fontsize,linewidth] = getPlotOptions;
        [model,input,output] = selectDataAndTrainModel(combinationVector,netz);
        abbreviation = determineAbbreviation(inputCombinationVector);
        str = makeDesignationString(indices);
        [lossFunctionValue,aicValue] = evaluateLossFunctionValue(netz,object,kk);
    end
    
    
end

