classdef class_model
    
    properties
        dlnet

        name_input
        name_output


        mean_input
        std_input
        mean_output
        std_output
    end
    
    methods
        function obj = class_model()
        end

        function input=norm_input(obj,input,direction)
            if not(exist("direction"))
                direction='';
            end
            if not(strcmp(direction,'inv'))
                input=(input-obj.mean_input)./obj.std_input;
            else
                input=input.*obj.std_input+obj.mean_input;
            end
        end

        function output=norm_output(obj,output,direction)
            if not(exist("direction"))
                direction='';
            end
            if not(strcmp(direction,'inv'))
                output=(output-obj.mean_output)./obj.std_output;
            else
                output=output.*obj.std_output+obj.mean_output;
            end
        end


        function Y=eval(obj,X,varargin)

            default_output = 'mean';
            expected_output= {'mean','std','both','all'};

            if length(obj.dlnet)>1.5
                default_IDnet = 'all';
            else
                default_IDnet = 1;
            end

            p = inputParser;
            addRequired(p,'obj');
            addRequired(p,'X');
            addParameter(p,'IDnet',default_IDnet);
            addParameter(p,'output',default_output ,@(x) any(validatestring(x,expected_output )));

            parse(p,obj,X,varargin{:});


            if strcmp(p.Results.IDnet,'all')
                Y=eval(obj,X,'IDnet',1:length(obj.dlnet),'output','all');
            else
                if length(p.Results.IDnet)>1.5
                    for case_IDnet=1:length(p.Results.IDnet)
                        Y(:,:,case_IDnet)=eval(obj,X,'IDnet',p.Results.IDnet(case_IDnet),'output','all');
                    end
                else
                    dlX=dlarray(obj.norm_input(X),'BC');
                    dlY=predict(obj.dlnet(p.Results.IDnet),dlX);
                    Y=obj.norm_output(double(extractdata(dlY)).','inv');
                end
            end

            if strcmp(p.Results.output,'mean')
                Y=mean(Y,3);
            end
            if strcmp(p.Results.output,'std')
                Y=std(Y,[],3);
            end
            if strcmp(p.Results.output,'both')
                S=std(Y,[],3);
                Y=mean(Y,3);
                Y(:,:,2)=S;
            end
        end
    end
end

