classdef data_set
    properties (SetAccess = immutable)
        type string  % 'train' or 'test'
        n_samples uint32
        batch_size uint32
        language
        samples_per_utterance uint32
        filename_prefix
    end
    
    methods
        function obj = data_set(language, samples_per_utterance)
            obj.language = language;
            obj.samples_per_utterance = samples_per_utterance;
            obj.n_samples = samples_per_utterance * language.n_utterances;

            % not really used for now, but for the future
            obj.type = "train"; % in the future might be extended with "test"
            obj.batch_size = obj.n_samples; % in the future, you can train with batches
        end
    
        function batch_data = generate_observations(obj)
            % preallocate space for generated data
            full_data = zeros(obj.n_samples, obj.language.n_input_nodes);

            for i = 1:obj.language.n_utterances
                utterance = obj.language.utterances(i);
            
                for j = 1:obj.samples_per_utterance
                    sound_vector = utterance.sound.sample_and_create_input_vector;
                    meaning_vector = utterance.meaning.create_input_vector;
                    full_data((i-1)*obj.samples_per_utterance + j, :) = [sound_vector meaning_vector];
                end
               
                disp("Generated " + obj.samples_per_utterance + " " + obj.type + " samples of an utterance " + utterance.name);
            end

            assert(size(full_data, 1) == obj.n_samples, "logical error: wrong total number of samples")
            disp('Size of the ' + obj.type + ' dataset = ' + obj.n_samples);

            % randomise the dataset 
            random_order = randperm(obj.n_samples);
            
            n_batches = obj.n_samples/obj.batch_size;
            batch_data = zeros(obj.batch_size, obj.language.n_input_nodes, n_batches);
            for b = 1:n_batches
                batch_data(:, :, b) = full_data(random_order(1 + (b-1) * obj.batch_size : b * obj.batch_size), :);
            end
            clear full_data;
        end
    end
end

