#ifndef GRAD_DESC_MOD_H
#define	GRAD_DESC_MOD_H

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

typedef enum {
    right = 0,
    left = 1,
    both = 2
} grad_eval;

typedef struct GDM_SYS {
    double **param;
    unsigned int param_count;
    double gradStep;
    grad_eval grad_type;
    double lerning_rate;
    double param_prob;
    double (*error) (void *data);
    void *data;
    FILE *logFile;
    char *filename;
    unsigned int maxIter;
    double maxError;

    double E_middle;
} gdm_sys;

/*
 * Alokuje GDM_SYS
 */
gdm_sys * gdm_alloc(unsigned int n);

/*
 * Uvolni strukturu GDM_SYS.
 */
void gdm_free(gdm_sys *sys);

/*
 * Nastavi ukazatel PPARAM I-ty parametr soustavy SYS.
 */
void gdm_define_param(gdm_sys *sys, unsigned int i, double *pparam);

/*
 * Nastavi I-ty parametr na hodnotu VALUE systemu SYS.
 */
void gdm_set_param(gdm_sys *sys, unsigned int i, double value);

/*
 * Vrati hodnotu I-teho parametru systemu SYS.
 */
double gdm_get_param(gdm_sys *sys, unsigned int i);

/*
 * Vygeneruje nahodne cislo v rozsahu od 0 do 1
 */
double gdm_rand (void);

/*
 * Vypocita gradient I-teho parametru systemu SYS.
 */
double gdm_partial_derivation (gdm_sys *sys, unsigned int i);

/*
 * Spusti optimalizaci systemu SYS.
 */
void gdm_optim (gdm_sys *sys);

#endif	/* GRAD_DESC_MOD_H */

