From 7c242fabfaf38411ee567736416a3a123802f0a9 Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Sat, 8 Feb 2025 19:15:34 +0100 Subject: [PATCH] pusho per testare nel threadripper --- cifar-10-batches/batches.meta.txt | 1 - cifar-10-batches/readme.html | 1 - classificatore_singolo | Bin 0 -> 22008 bytes classificatore_singolo.c | 124 +++++++++++++++++++ dataset_manager.h | 74 +++++++++++ percettroni.h | 198 +++++++++++++++++++++++++++--- rete_cifar10.c | 33 ----- rete_neurale | Bin 0 -> 20640 bytes rete_neurale.c | 162 ++++++++++++++++++++++++ tempCodeRunnerFile.c | 1 + visualizzatore | Bin 0 -> 17160 bytes visualizzatore.h | 75 +++++++++++ 12 files changed, 617 insertions(+), 52 deletions(-) delete mode 100644 cifar-10-batches/readme.html create mode 100755 classificatore_singolo create mode 100644 classificatore_singolo.c create mode 100644 dataset_manager.h delete mode 100644 rete_cifar10.c create mode 100755 rete_neurale create mode 100644 rete_neurale.c create mode 100644 tempCodeRunnerFile.c create mode 100755 visualizzatore create mode 100644 visualizzatore.h diff --git a/cifar-10-batches/batches.meta.txt b/cifar-10-batches/batches.meta.txt index cc82768..fa30c22 100644 --- a/cifar-10-batches/batches.meta.txt +++ b/cifar-10-batches/batches.meta.txt @@ -8,4 +8,3 @@ frog horse ship truck - diff --git a/cifar-10-batches/readme.html b/cifar-10-batches/readme.html deleted file mode 100644 index e377ade..0000000 --- a/cifar-10-batches/readme.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/classificatore_singolo b/classificatore_singolo new file mode 100755 index 0000000000000000000000000000000000000000..082dc53b1b0ba5c0770f30f559cb2912bd9d6b47 GIT binary patch literal 22008 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 zsize; i++) { + printf("Percettrone %d ->", i); + for(int j = 0; j < layer->percettroni->size; j++) { + printf("\t peso %d, valore: %f",j, layer->percettroni[i].pesi[j]); + layer->percettroni[i].pesi[j] += 1; + } + printf("\n"); + } +} \ No newline at end of file diff --git a/dataset_manager.h b/dataset_manager.h new file mode 100644 index 0000000..3c8c7dd --- /dev/null +++ b/dataset_manager.h @@ -0,0 +1,74 @@ +#include +#include + +#define N_PIXEL 3072 //1024 pixel * 3 (R, G, B) + +//Siccome il char è un byte che rappresenta il valore tra 0 e 255. Per evitare confusioni definisco il tipo "byte" come in Java +typedef unsigned char byte; + +// Singola istanza del dataset. +typedef struct { + byte categoria; + byte immagine[N_PIXEL]; +} Istanza; + +//Questo tipo fornisce il vettore delle istanze e il size (dimensione) del vettore +typedef struct { + int size; + Istanza *istanze; +} Dataset; + +Dataset* get_dataset(char *); + +//Questo metodo legge il file in questione e restituisce un puntatore a Dataset se il file esiste, altrimenti NULL +//Ritorna un puntatore perchè in questo caso posso gestire il ritorno NULL. +Dataset* get_dataset(char *path) { + + Dataset *set = (Dataset *) malloc(sizeof(Dataset)); + FILE *file; + Istanza istanza; + Istanza *istanze = (Istanza *)malloc(sizeof(Istanza)); + + file = fopen(path, "rb"); + if(file == NULL) + return NULL; + + int numero_righe = 0; + + //Fino a quando questo fread restituisce 1 significa che il file contiene ancora roba + while(fread(&istanze[numero_righe].categoria, sizeof(byte), 1, file) == 1) { + if(fread(istanze[numero_righe].immagine, sizeof(byte), N_PIXEL, file) == N_PIXEL) { + numero_righe ++; + istanze = (Istanza *)realloc(istanze, sizeof(Istanza) * (numero_righe + 1)); + //printf("Caricata nel sistema riga %d\n", numero_righe); + } + } + + //Dataset set; + (*set).size = numero_righe; + (*set).istanze = istanze; + + fclose(file); + + return set; +} + +/* void main() { + char *path = "cifar-10-batches/data_batch_1.bin"; + + //Carico il dataset e controllo che non sia nullo + Dataset *dataset = get_dataset(path); + if(dataset == NULL) { + printf("Oggetto dataset nullo\n"); + return; + } + + //Lo copio in una seconda variabile per non dover mettere sempre * davanti al nome e libero la memoria occupata dal puntatore + Dataset set = *dataset; + free(dataset); + + //Stampa di debug + for(int i = 0; i < set.size; i++) { + printf("n: %d. Categoria: %d\n", i, (int)set.istanze[i].categoria); + } +} */ \ No newline at end of file diff --git a/percettroni.h b/percettroni.h index f1810de..bf9c990 100644 --- a/percettroni.h +++ b/percettroni.h @@ -8,40 +8,108 @@ In output ci sono 10 percettroni, ognuno di essi è associato ad una categoria del CIFAR10. Alla fine dell'addestramento, la previsione sarà data dal percettrone di output che avrà il valore 1 rispetto agli altri 9. */ -#include -#include -#define INPUT_LIV1 3072 -#define INPUT_LIV2 256 -#define INPUT_LIV3 128 +#include +#include "dataset_manager.h" double LRE = 0.2; +double soglia_sigmoide = 0.5; typedef struct { double *pesi; double bias; - double lre; + int size; } Percettrone; -double randomico(); -void inzializza_percettrone(Percettrone*, int); -double funzione_sigmoide(Percettrone, int[], int); +typedef struct { + Percettrone *percettroni; + int size; +} Layer; +typedef struct { + Layer *layers; + int size; +} ReteNeurale; + +double randomico(); + +Percettrone inzializza_percettrone(int); +ReteNeurale inizializza_rete_neurale(int); +Layer inizializza_layer(int, int); + +double sigmoide_byte(Percettrone, byte*, int); +double sigmoide_double(Percettrone, double*, int); +double *funzioni_attivazione_layer_byte(Layer, byte*); +double *funzioni_attivazione_layer_double(Layer, double*); + +void correggi_layer_interni(ReteNeurale*, double**, double**); +void correggi_layer_input(Layer*, double**, double**, byte*, int); + +int previsione(double); + +//Questa funzione genera un valore reale random compreso nell'intervallo [-1, 1] double randomico() { // Genero numeri nell'intervallo [-1,1] return ((double)(rand() % 101 * 0.01 * 2 ) -1); } -void inizializza_percettrone(Percettrone *p, int n_pesi) { - p->pesi = (double*)malloc(sizeof(double) * n_pesi ); +//Questa funzione inizializza il percettrone allocando la memoria in base al numero dei pesi che voglio ed inizializza il loro valore usando randomico() +Percettrone inizializza_percettrone(int n_pesi) { + Percettrone p; + p.pesi = (double*) malloc(sizeof(double) * n_pesi); for(int i = 0; i < n_pesi; i++) - p->pesi[i] = randomico(); + p.pesi[i] = randomico(); - p->bias = randomico(); - p->lre = LRE; + p.bias = randomico(); + + p.size = n_pesi; + + return p; } -double funzione_sigmoide(Percettrone p, int valori[], int n_input) { +//Questa funzione inizializza una rete neurale. Diamo il numero di layer desiderato e restituisce un ReteNeurale +ReteNeurale inizializza_rete_neurale(int n_layers) { + ReteNeurale r; + r.layers = (Layer*)malloc(sizeof(Layer) * n_layers); + r.size = n_layers; + + return r; +} + +//Questa funzione serve ad inizializzare il singolo layer con il numero di percettroni che vogliamo +//Ogni percettrone a sua volta viene automaticamente inizializzato con il numero di pesi che vogliamo e coi valori di partenza +Layer inizializza_layer(int n_percettroni, int n_pesi) { + Layer layer; + layer.percettroni = (Percettrone *)malloc(sizeof(Percettrone) * n_percettroni); + + for(int i = 0; i < n_percettroni; i++) { + layer.percettroni[i] = inizializza_percettrone(n_pesi); + } + + layer.size = n_percettroni; + + return layer; +} + +//Questa funzione viene usata per il primo livello perchè ha un vettore di byte (unsigned char) in input +double sigmoide_byte(Percettrone p, byte *valori, int n_input) { + + double sommatoria = 0.0; + for(int i = 0; i < n_input; i++) { + sommatoria += ((double)valori[i] * p.pesi[i]); + } + //printf("sommatoria= %f\n", sommatoria); + double funzione = sommatoria + p.bias; + double potenza_e = exp(-funzione); + //printf("potenza_e= %f\n", potenza_e); + //formula sigmoide + double risultato = 1 / ( 1 + potenza_e); + //printf("risultato= %f\n", risultato); + return risultato; +} + +//Questa funzione viene usata per gli altri livelli dove gli input sono double, ossia i valori della sigmoide dei livelli precedenti +double sigmoide_double(Percettrone p, double *valori, int n_input) { double sommatoria = 0.0; for(int i = 0; i < n_input; i++) { @@ -49,10 +117,106 @@ double funzione_sigmoide(Percettrone p, int valori[], int n_input) { } double funzione = sommatoria + p.bias; + //printf("sommatoria= %f\n", sommatoria); double potenza_e = exp(-funzione); - + //printf("potenza_e= %f\n", potenza_e); //formula sigmoide double risultato = 1 / ( 1 + potenza_e); + //printf("risultato= %f\n", risultato); return risultato; -} \ No newline at end of file +} + +//Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei byte come inputs +double *funzioni_attivazione_layer_byte(Layer layer, byte *inputs) { + + double *funzioni = (double*)malloc(sizeof(double) * layer.size); + + for(int i = 0; i < layer.size; i++) { + funzioni[i] = sigmoide_byte(layer.percettroni[i], inputs, layer.percettroni[i].size); + } + + return funzioni; +} + +//Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei double come inputs (le sigmoidi del livello precedente) +double *funzioni_attivazione_layer_double(Layer layer, double *inputs) { + + double *funzioni = (double*)malloc(sizeof(double) * layer.size); + + for(int i = 0; i < layer.size; i++) { + funzioni[i] = sigmoide_double(layer.percettroni[i], inputs, layer.percettroni[i].size); + } + + return funzioni; +} + +//Questa funzione restituisce il valore 0,1 in base alla soglia di attivazione della funzione sigmoide +int previsione(double valore) { + if(valore >= soglia_sigmoide) + return 1; + else + return 0; +} + +void correggi_layer_interni(ReteNeurale *rete, double **gradienti, double **sigmoidi) { + + for(int indice_layer = rete->size-1; indice_layer > 0; indice_layer--) { + for(int indice_percettrone = 0; indice_percettrone < rete->layers[indice_layer].size; indice_percettrone++) {//Numero percettroni + + for(int indice_peso = 0; indice_peso < rete->layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++) {//Numero pesi + gradienti[indice_layer][indice_percettrone] = gradienti[rete->size-1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone])); + + rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] -= (gradienti[indice_layer][indice_percettrone] * LRE * sigmoidi[indice_layer-1][indice_percettrone]); + + //if(indice_layer == 3) + // printf("qui ci arrivo layer: %d, percettrone: %d, input:%d, peso: %f\n", indice_layer, indice_percettrone, indice_peso, rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso]); + + //printf("gradiente applicato %f, sigmoide %f\n", gradienti[indice_layer][indice_percettrone], sigmoidi[indice_layer][indice_percettrone]); + } + rete->layers[indice_layer].percettroni[indice_percettrone].bias -= (gradienti[indice_layer][indice_percettrone] * LRE); + //printf("bias: %f\n", rete->layers[indice_layer].percettroni[indice_percettrone].bias); + } + } +} + +void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, byte *inputs, int n_layers) { + //L'indice del layer d'ingresso che prende byte per input + int indice_layer = 0; + for(int indice_percettrone = 0; indice_percettrone < layer->size; indice_percettrone++) {//Numero percettroni + for(int indice_peso = 0; indice_peso < layer->percettroni->size; indice_peso++) { //Numero pesi + + gradienti[indice_layer][indice_percettrone] = gradienti[n_layers-1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone])); + layer->percettroni[indice_percettrone].pesi[indice_peso] -= (gradienti[indice_layer][indice_percettrone] * LRE * inputs[indice_peso]); + } + layer->percettroni[indice_percettrone].bias -= (gradienti[indice_layer][indice_percettrone] * LRE); + } +} + + + + + + +/* void correggi_pesi_layer(Percettrone[], int, int, double**, double[], double[]); +void correggi_pesi_layer_uno(Percettrone[], int, int, double**, byte[], double[]); + +void correggi_pesi_layer(Percettrone percettroni_layer[], int size_percettroni, int size_inputs, double **gradienti, double inputs[], double gradienti_bias[]) { + for(int i = 0; i < size_percettroni; i++) { + // Non termina questo for + for(int j = 0; j < size_inputs; j++) { + percettroni_layer[i].pesi[j] -= LRE * gradienti[i][j] * inputs[j]; + } + percettroni_layer[i].bias -= LRE * gradienti_bias[i]; + } +} + +void correggi_pesi_layer_uno(Percettrone percettroni_layer[], int size_percettroni, int size_inputs, double **gradienti, byte inputs[], double gradienti_bias[]) { + + for(int i = 0; i < size_percettroni; i++) { + for(int j = 0; j < size_inputs; j++) { + percettroni_layer[i].pesi[j] -= LRE * gradienti[i][j] * inputs[j]; + } + percettroni_layer[i].bias -= LRE * gradienti_bias[i]; + } +} */ diff --git a/rete_cifar10.c b/rete_cifar10.c deleted file mode 100644 index 4937428..0000000 --- a/rete_cifar10.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include "percettroni.h" - -#define PERCETTRONI_1 256 -#define PERCETTRONI_2 128 -#define PERCETTRONI_OUT 10 - -void main() { - srand(time(NULL)); - - Percettrone livello_uno[PERCETTRONI_1]; - Percettrone livello_due[PERCETTRONI_2]; - Percettrone livello_out[PERCETTRONI_OUT]; - - for(int i = 0; i < PERCETTRONI_1; i++) { - inizializza_percettrone(&livello_uno[i], INPUT_LIV1); - if(i < PERCETTRONI_2) { - inizializza_percettrone(&livello_due[i], INPUT_LIV2); - if(i < PERCETTRONI_OUT) - inizializza_percettrone(&livello_out[i], INPUT_LIV3); - } - } - - for(int i = 0; i < PERCETTRONI_1; i++) { - printf("\nPercettrone esterno %d: w78: %f, bias: %f",i, livello_uno[i].pesi[77], livello_uno[i].bias); - if(i < PERCETTRONI_2) { - printf("\n\tPercettrone interno %d: w78: %f, bias: %f", i, livello_due[i].pesi[77], livello_due[i].bias); - if(i < PERCETTRONI_OUT) - printf("\n\t\tPercettrone output %d: w78: %f, bias: %f", i, livello_out[i].pesi[77], livello_out[i].bias); - } - } -} \ No newline at end of file diff --git a/rete_neurale b/rete_neurale new file mode 100755 index 0000000000000000000000000000000000000000..fb620de0be2098f1b465087c393611abc1d49be3 GIT binary patch literal 20640 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 G75@WigE;m8 literal 0 HcmV?d00001 diff --git a/rete_neurale.c b/rete_neurale.c new file mode 100644 index 0000000..9a865cc --- /dev/null +++ b/rete_neurale.c @@ -0,0 +1,162 @@ +#include +#include +#include "percettroni.h" + +#define PERCETTRONI_1 256 +#define PERCETTRONI_2 128 +#define PERCETTRONI_OUT 10 + +#define MAX_EPOCHE 1 + +double** alloca_memoria_bidimensionale(int, int); + +void main() +{ + srand(time(NULL)); + + Percettrone livello_uno[PERCETTRONI_1]; + Percettrone livello_due[PERCETTRONI_2]; + Percettrone livello_out[PERCETTRONI_OUT]; + + for (int i = 0; i < PERCETTRONI_1; i++) + { + inizializza_percettrone(&livello_uno[i], INPUT_LIV1); + if (i < PERCETTRONI_2) + { + inizializza_percettrone(&livello_due[i], INPUT_LIV2); + if (i < PERCETTRONI_OUT) + inizializza_percettrone(&livello_out[i], INPUT_LIV3); + } + } + + Dataset *set_appoggio = get_dataset("cifar-10-batches/data_batch_1.bin"); + if (set_appoggio == NULL) + return; + + Dataset dataset = *set_appoggio; + free(set_appoggio); + + // Ciclo esterno per contare le epoche + for (int indice_epoca = 0; indice_epoca < MAX_EPOCHE; indice_epoca++) + { + + // Ciclo interno per contare tutte le istanze del dataset da analizzare nell'epoca corrente + for (int indice_dataset = 0; indice_dataset < dataset.size; indice_dataset++) + { + + // Qui memorizzo tutte le sigmoidi della rete + double sigmoidi_livello_uno[PERCETTRONI_1]; + double sigmoidi_livello_due[PERCETTRONI_2]; + double sigmoidi_livello_out[PERCETTRONI_OUT]; + + // Livello 1 + // Ho 256 percettroni da riempire + for (int i = 0; i < PERCETTRONI_1; i++) + sigmoidi_livello_uno[i] = funzione_sigmoide_primo_livello(livello_uno[i], dataset.istanze[indice_dataset].immagine, INPUT_LIV1); + + // Livello 2 + // Ho 128 percettroni da riempire + for (int i = 0; i < PERCETTRONI_2; i++) + sigmoidi_livello_due[i] = funzione_sigmoide(livello_due[i], sigmoidi_livello_uno, INPUT_LIV2); + + // Livello OUT + // Ho 10 percettroni da riempire + for (int i = 0; i < PERCETTRONI_OUT; i++) + { + sigmoidi_livello_out[i] = funzione_sigmoide(livello_out[i], sigmoidi_livello_due, INPUT_LIV3); + printf("Sigmoide %d: %f\n", i, sigmoidi_livello_out[i]); + } + + // Determinare l'errore e la previsione + // Ho 10 percettroni in uscita, la previsione è che uno sarà 1 mentre tutti gli altri 0. + // Il percettrone con 1 è quello di indice dataset.istanze[indice_dataset].categoria + int indice_corretto = dataset.istanze[indice_dataset].categoria; + + double errori[PERCETTRONI_OUT]; + + printf("Fino a qui ci arrivo 1\n"); + + double **gradienti_out = alloca_memoria_bidimensionale(PERCETTRONI_OUT, INPUT_LIV3); + double gradienti_bias_out[PERCETTRONI_OUT]; + + double **gradienti_2 = alloca_memoria_bidimensionale(PERCETTRONI_2, INPUT_LIV2); + double gradienti_bias_2[PERCETTRONI_2]; + + double **gradienti_1 = alloca_memoria_bidimensionale(PERCETTRONI_1, INPUT_LIV1); + double gradienti_bias_1[PERCETTRONI_1]; + + // Per ogni percettrone di uscita vedo se ha commesso errore e mi calcolo il gradiente + for (int i = 0; i < PERCETTRONI_OUT; i++) + { + // Se la i corrisponde all'indice corretto, la previsione dovrebbe essere 1, se non lo è c'è errore + if (i == indice_corretto) + { + if (prevedi(sigmoidi_livello_out[i]) != 1) + { // Errore + errori[i] = 1 - sigmoidi_livello_out[i]; + + for (int j = 0; j < INPUT_LIV3; j++) + gradienti_out[i][j] = errori[i] * sigmoidi_livello_out[i] * (1 - sigmoidi_livello_out[i]) /* * sigmoidi_livello_due[j] */; + gradienti_bias_out[i] = errori[i] * sigmoidi_livello_out[i] * (1 - sigmoidi_livello_out[i]); + + //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello output + + for (int j = 0; j < PERCETTRONI_2; j++) + { + for (int k = 0; k < INPUT_LIV2; k++) + gradienti_2[j][k] = gradienti_out[i][j] * sigmoidi_livello_due[j] * (1 - sigmoidi_livello_due[j]); + gradienti_bias_2[j] = gradienti_out[i][j] * sigmoidi_livello_due[j] * (1 - sigmoidi_livello_due[j]); + + //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello due + + for (int y = 0; y < PERCETTRONI_1; y++) + { + for (int z = 0; z < INPUT_LIV1; z++) + gradienti_1[y][z] = gradienti_out[i][j] * gradienti_2[j][y] * sigmoidi_livello_uno[y] * (1 - sigmoidi_livello_uno[y]); + gradienti_bias_1[y] = gradienti_out[i][j] * gradienti_2[j][y] * sigmoidi_livello_uno[y] * (1 - sigmoidi_livello_uno[y]); + + //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello uno + } + } + } + } + else + { + // Qui determino quando deve valere zero + } + } + + printf("Fino a qui ci arrivo 2\n"); + /* + Devo dichiarare i gradienti col malloc + */ + correggi_pesi_layer(livello_out, PERCETTRONI_OUT, INPUT_LIV3, gradienti_out, sigmoidi_livello_due, gradienti_bias_out); + printf("Fino a qui ci arrivo 3\n"); + correggi_pesi_layer(livello_due, PERCETTRONI_2, INPUT_LIV2, gradienti_2, sigmoidi_livello_uno, gradienti_bias_2); + printf("Fino a qui ci arrivo 4\n"); + correggi_pesi_layer_uno(livello_uno, PERCETTRONI_1, INPUT_LIV1, gradienti_1, dataset.istanze[indice_dataset].immagine, gradienti_bias_1); + printf("Fino a qui ci arrivo 5\n"); + } + } + + // Stampa di debug + /* for(int i = 0; i < PERCETTRONI_1; i++) { + printf("\nPercettrone esterno %d: w78: %f, bias: %f",i, livello_uno[i].pesi[77], livello_uno[i].bias); + if(i < PERCETTRONI_2) { + printf("\n\tPercettrone interno %d: w78: %f, bias: %f", i, livello_due[i].pesi[77], livello_due[i].bias); + if(i < PERCETTRONI_OUT) + printf("\n\t\tPercettrone output %d: w78: %f, bias: %f", i, livello_out[i].pesi[77], livello_out[i].bias); + } + }*/ + + printf("\r"); +} + +double** alloca_memoria_bidimensionale(int x, int y) { + double **vettore = (double **)malloc(sizeof(double*) * x); + + for(int i = 0; i < x; i++) + vettore[i] = (double *)malloc(sizeof(double) * y); + + return vettore; +} \ No newline at end of file diff --git a/tempCodeRunnerFile.c b/tempCodeRunnerFile.c new file mode 100644 index 0000000..a27cc13 --- /dev/null +++ b/tempCodeRunnerFile.c @@ -0,0 +1 @@ +printf("qui ci arrivo else\n"); \ No newline at end of file diff --git a/visualizzatore b/visualizzatore new file mode 100755 index 0000000000000000000000000000000000000000..8496919d96bc4782a276e937f1cc0327069a40e2 GIT binary patch literal 17160 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 literal 0 HcmV?d00001 diff --git a/visualizzatore.h b/visualizzatore.h new file mode 100644 index 0000000..ded1525 --- /dev/null +++ b/visualizzatore.h @@ -0,0 +1,75 @@ +#include +#include "percettroni.h" + +#define IMAGE_WIDTH 32 +#define IMAGE_HEIGHT 32 +#define SCALE_FACTOR 2 + +BITMAP *buffer; +BITMAP *image; + +void init_allegro() { + allegro_init(); + install_keyboard(); + install_mouse(); + set_color_depth(32); + set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); + buffer = create_bitmap(800,600); + image = create_bitmap(IMAGE_WIDTH, IMAGE_HEIGHT); + show_mouse(screen); +} + +void load_current_image(Dataset *set) { + int indice = rand()%set->size; + for (int y = 0; y < IMAGE_HEIGHT; y++) { + for (int x = 0; x < IMAGE_WIDTH; x++) { + int r = set->istanze[indice].immagine[y * IMAGE_WIDTH + x]; + int g = set->istanze[indice].immagine[1024 + y * IMAGE_WIDTH + x]; + int b = set->istanze[indice].immagine[2048 + y * IMAGE_WIDTH + x]; + putpixel(image, x, y, makecol(r, g, b)); + } + } +} + +void draw_interface() { + clear_to_color(buffer, makecol(255, 255, 255)); + + // Calcola la posizione per centrare l'immagine ingrandita + int scaled_width = IMAGE_WIDTH * SCALE_FACTOR; + int scaled_height = IMAGE_HEIGHT * SCALE_FACTOR; + int image_x = (800 - scaled_width) / 2; + int image_y = (600 - scaled_height) / 2 - 20; // Sposta leggermente sopra per fare spazio al pulsante + + // Disegna l'immagine ingrandita + stretch_blit(image, buffer, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, image_x, image_y, scaled_width, scaled_height); + + // Disegna il pulsante "prossima" + int button_width = 150; + int button_height = 40; + int button_x = (800 - button_width) / 2; + int button_y = 600 - 60; // Posizione in basso + rectfill(buffer, button_x, button_y, button_x + button_width, button_y + button_height, makecol(200, 200, 200)); + textout_centre_ex(buffer, font, "prossima", button_x + button_width / 2, button_y + 10, makecol(0, 0, 0), -1); + + // Copia il buffer sullo schermo + blit(buffer, screen, 0, 0, 0, 0, 800, 600); +} + +void handle_input(Dataset *set) { + if (mouse_b & 1) { + int mx = mouse_x; + int my = mouse_y; + + // Coordinate del pulsante + int button_width = 150; + int button_height = 40; + int button_x = (800 - button_width) / 2; + int button_y = 600 - 60; + + // Controlla se il clic è avvenuto sul pulsante + if (mx >= button_x && mx <= button_x + button_width && my >= button_y && my <= button_y + button_height) { + load_current_image(set); + rest(200); // Debounce + } + } +} \ No newline at end of file