Ciao Andbin,
ho seguito il tuo consiglio:
Ossia, ho creato un file di intestazione .h ed il corrispondente file dell'implementazione .c, ma nulla da fare.
Ho creato un banalissimo main di prova, ma quando provo ad utilizzare una funzione mi da errore del linker: undefinided reference.
Ora ti posto il codice:
Header struttura.h
//Header file contenente la definizione delle strutture dati per
//rappresentare e gestire una rete neurale feed-forward, e le
//operazioni utili ai fini della lettura da file e della inizializzazione
//di tali strutture.
//La lettura di una rete neurale avviene da file .net, compatibile
//con lo standard Stuttgart JNNS.
#ifndef _STRUTTURA_H_
#define _STRUTTURA_H_
struct node{
int funzione_act; //Tipo di funzione di attivazione
int funzione_out; //Tipo di funzione di output
float valore_in; //Valore di input
float valore; //Valore di output
float soglia; //Valore del bias
};
typedef struct node info_nodo;
typedef struct {
char nome[30];
int N; //Numero totale dei nodi della rete
float *w; //Vettore dei pesi
int nodi_input;//Numero nodi di input
int nodi_out; //Numero nodi di output
info_nodo *nodo;
} rete_neurale;
//////////////////////////////////////////////////////
//Data una stringa ne estrae un numero convertendolo in float
float estract_float(char *, int);
//Restituisce il prossimo carattere speciale |
int next_only_tab(char *, int);
//Restituisce il prossimo carattere speciale '|' ':' o ','
int next_tab(char *, int);
//Estrae il prossimo carattere valido
void estract_str(char *, int , char *);
//Lagge dal file .net il tipo di algoritmo di apprendimento
void read_learning(FILE *, char *);
//Lagge dal file .net il tipo di algoritmo di aggiornamento
void read_update(FILE *, char *);
//Legge dal file .net il nome della rete
void read_nome(FILE *, char *);
//Legge la configurazione della rete
void read_unit(FILE *, rete_neurale, int *, int *, int *);
//Inizializza la struttura ai valori di default
void init(rete_neurale ,int ,int,int,char *,char *);
//Legge i pesi e le connessioni presenti nella rete
void read_weigth(FILE *, rete_neurale , int , int , int );
//Legge dal file .net i parametri di default della rete
void read_def(FILE *, float *, float *, char *, char *, char *);
rete_neurale leggiretefile (char *);
//Lagge dal file .net il numero di nodi della rete
int read_units(FILE *);
//Legge dal file .net il numero di connessioni della rete
int read_conness(FILE *);
//Controlla la fine di un rigo non delimitato da alcun carattere speciale
int contr_fine(char *, int);
//Calcola i valori di uscita dei nodi, dati gli ingressi
rete_neurale calcola_feed_forward (rete_neurale);
#endif
funzione struttura.c
#include "struttura.h"
#include <string.h>
float estract_float(char *buf, int index)
//Data una stringa ne estrae un numero convertendolo in float
{
int i, j=0;
float num;
char stringa[15];
i=index+1;
while ((buf[i]!='|')&&(buf[i]!=':') && (buf[i]!=','))
{
if (buf[i]!=' ')
{
stringa[j]=buf[i];
j++;
}
i++;
}
stringa[j]='\0';
num=atof(stringa);
return num;
}
int next_only_tab(char *buf, int index)
//Restituisce il prossimo carattere speciale |
{
index++;
while (buf[index]!='|')
index++;
return index;
}
int next_tab(char *buf, int index)
//Restituisce il prossimo carattere speciale '|' ':' o ','
{
index++;
while ((buf[index]!='|') && (buf[index]!=':') && (buf[index]!=','))
index++;
return index;
}
char estract_c(char *buf, int index)
//Estrae il prossimo carattere valido
{
char car;
int i;
i=index+1;
while (buf[i]!='|')
{
if (buf[i]!=' ')
{
car=buf[i];
break;
}
i++;
}
return car;
}
void read_learning(FILE *fd, char *learning)
//Lagge dal file .net il tipo di algoritmo di apprendimento
{
char stringa[25];
fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"learning")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"function")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(learning,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}
void read_update(FILE *fd, char *update)
//Lagge dal file .net il tipo di algoritmo di aggiornamento
{
char stringa[25];
fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"update")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"function")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(update,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}
//Legge dal file .net il nome della rete
void read_nome(FILE *fd, char *nome)
{
char stringa[25];
fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"network")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"name")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(nome,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}
void read_unit(FILE *fd, rete_neurale rete, int *in, int *hi, int *out)
//Legge la configurazione della rete
{
char *res, buf[200];
int index, num_input=0, num_hidden=0, num_output=0;
int i, act_d=0, out_d=0, actv_d=0, outv_d=0, type_d=0;
char nome[20], act_str[20], out_str[20], type;
float act, bias;
fscanf(fd,"%s",buf);
while (strcmp(buf,"sites")!=0)
fscanf(fd,"%s\n",buf);
fscanf(fd,"%s\n",buf);//Legge il rigo dei tab
for (index=1; index<=rete.N;index++)
{
act_d=0;
out_d=0;
actv_d=0;
outv_d=0;
type_d=0;
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
exit(1);
i=next_tab(buf,0);//Salta di due tab in avanti
i=next_tab(buf,i);
estract_str(buf,i,nome);//Estrae il nome del nodo
i=next_tab(buf,i);
if (buf[i+1]=='|')
actv_d=1; //Caso funzione di default
else{
rete.nodo[index].valore_in=estract_float(buf,i);//Estrae il valore di attivazione
rete.nodo[index].valore=rete.nodo[index].valore_in;
}
i=next_tab(buf,i);
if (buf[i+1]=='|')
outv_d=1; //Caso funzione di default
else
rete.nodo[index].soglia=estract_float(buf,i);//Estrae il valore del bias
i=next_tab(buf,i);
if (buf[i+1]=='|')
type_d=1; //Caso funzione di default
else
type=estract_c(buf,i);//Estrae il tipo del nodo
i=next_tab(buf,i);//Salta di due tab in avanti
i=next_only_tab(buf,i);
if (buf[i+1]=='|')
act_d=1; //Caso funzione di default
else
estract_str(buf,i,act_str);//Estrae la funzione di attiv.
i=next_tab(buf,i);
if (buf[i+1]=='|')
out_d=1; //Caso funzione di default
else
estract_str(buf,i,out_str);//Estrae la funzione di output
if (type=='i')
num_input++;
if (type=='h')
num_hidden++;
if (type=='o')
num_output++;
if (act_d==0)
rete.nodo[index].funzione_act=str2int(act_str);
if (out_d==0)
rete.nodo[index].funzione_out=str2int(out_str);
}
*in= num_input;
*hi= num_hidden;
*out= num_output;
}
void init(rete_neurale rete,int act_d,int bias_d,int tipo_d,char *act_fun_d,char *out_fun_d)
//Inizializza la struttura ai valori di default
{
int i, j, d, act, out, N;
N=rete.N+1;
act=str2int(act_fun_d);
out=str2int(out_fun_d);
for (i=1; i<=rete.N; i++)
{
rete.nodo[i].soglia=bias_d;
rete.nodo[i].valore_in=act_d;
rete.nodo[i].valore=act_d;
rete.nodo[i].funzione_act=act;
rete.nodo[i].funzione_out=out;
}
//Inizializzazione vettore dei pesi
for(j=0;j<=rete.N;j++)
{
for(d=0;d<=rete.N;d++)
rete.w[j*N+d]=-bias_d;
}
}
void read_weigth(FILE *fd, rete_neurale rete, int in, int hi, int out)
//Legge i pesi e le connessioni presenti nella rete
{
char buf[200], *res;
int N, num, index, i=0, j=0, numero_nodi=0 ,max, flag=0;
float peso;
max=in;
N=rete.N+1;
fscanf(fd,"%s",buf);
while (strcmp(buf,"source:weight")!=0)
fscanf(fd,"%s\n",buf);
fscanf(fd,"%s\n",buf);//Legge il rigo dei tab
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
exit(1);
//Per tutti i nodi non di input
for (j=in+1;j<=in+hi+out;j++){
index=(int)estract_float(buf,-1);//Estrae l'indice del nodo ricevente
i=next_tab(buf,0);//Salta due tab
i=next_tab(buf,i);
numero_nodi=0;//Inizializzazione
flag=0;
if (j==in+hi+1)
max=hi;
while (flag==0){
while ((buf[i+2]!='\0')&& (flag==0))
{
num=(int)estract_float(buf,i);//Estrae l'indice del nodo collegato
numero_nodi++;
i=next_tab(buf,i);//Salta i due punti
peso=estract_float(buf,i);
if (numero_nodi<max)
i=next_tab(buf,i);//Salta la virgola
else
flag=1;
//Inserisce l'indice del nodo afferente ed il peso
rete.w[index*N+num]=peso;
}
i=0;
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
break;
//printf("%s\n",buf);
}
}
}
void read_def(FILE *fd, float *act_d, float *bias_d, char *tipo_d, char *act_fun_d, char *out_fun_d)
//Legge dal file .net i parametri di default della rete
{
char stringa[25], *res, buf[200];
char car;
float layer, subnet;
int index;
fscanf(fd,"%s",stringa);
while (strcmp(stringa,"out")!=0)
fscanf(fd,"%s",stringa);
fscanf(fd,"%s\n",stringa);
if (strcmp(stringa,"func")==0)
fscanf(fd,"%s\n",buf);//Legge una riga intera
res=fgets(buf,200,fd);
if( res==NULL )
exit(1);
*act_d=estract_float(buf,-1);
index=next_tab(buf,0);//aggiorna il nuovo indice di tabulazione
*bias_d=estract_float(buf,index);
index=next_tab(buf,index);
*tipo_d=estract_c(buf,index);
index=next_tab(buf,index);
subnet=estract_float(buf,index);
index=next_tab(buf,index);
layer=estract_float(buf,index);
index=next_tab(buf,index);
estract_str(buf,index,act_fun_d);
index=next_tab(buf,index);
estract_str(buf,index,out_fun_d);
}
rete_neurale leggiretefile (char *nomefile)
{
char nome[30];
char *delim;
char *last;
char check[30];
int N, conness, in, hi, out;
int i, j, d;
float act_d, bias_d;
char tipo_d, act_fun_d[25], out_fun_d[25], learning[25], update[25];
FILE *fd;
int conta=0;
int num_afferenti=0;
rete_neurale rete;
// Controlla che l'estensione del file sia .net
strcpy(check, nomefile);
delim = strtok(check, ".");
while (delim != NULL){
last = delim;
delim = strtok(NULL, ".");
}
if(strcmp(last, "net") != 0){
printf("\nWarning: Stai aprendo un file con estensione diversa da .net\n");
getch();
}
//---------------------------------------------- END CHECK
fd=fopen(nomefile,"r");
if(fd == NULL){
printf("\nImpossibile aprire il file %s \n\n",nomefile);
system("pause");
exit(0);
}
//Lettura del nome della rete
read_nome(fd,nome);
strcpy(rete.nome,nome);
//Lettura del numero totale di nodi
rete.N=read_units(fd);
N=rete.N+1;
//Lettura del numero di connessioni
conness=read_conness(fd);
//Lettura del tipo di apprendimento e dell'ordine di aggiornamento
read_learning(fd,learning);
read_update(fd,update);
//Lettura dei valori di default
read_def(fd,&act_d,&bias_d,&tipo_d,act_fun_d,out_fun_d);
//Inizializzazione alla dimensione letta
rete.w=(float *)malloc(N*N*sizeof(float));
rete.nodo=(info_nodo *)malloc(N*sizeof(info_nodo));
//Inizializzazione delle strutture
init(rete,act_d,bias_d,tipo_d,act_fun_d,out_fun_d);
//Per tutti i nodi di input
read_unit(fd,rete,&in,&hi,&out);
//Aggiornamento del numero di nodi input e output nella rete
rete.nodi_input=in;
rete.nodi_out=out;
//Aggiorna i valori dei pesi ai bias
for(i=1;i<=rete.N;i++)
rete.w[i*N]=-rete.nodo[i].soglia;
//Inserisce il valore dei pesi nelle connessioni
read_weigth(fd,rete,in,hi,out);
fclose(fd);
return(rete);
}
int read_units(FILE *fd)
//Lagge dal file .net il numero di nodi della rete
{
char stringa[25];
int units=0;
fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"no.")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"of")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"units")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%d",&units);
break;
}
}
}
fscanf(fd,"%s",stringa);
}
return units;
}
int read_conness(FILE *fd)
//Legge dal file .net il numero di connessioni della rete
{
char stringa[25];
int conness=0;
fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"no.")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"of")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"connections")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%d",&conness);
break;
}
}
}
fscanf(fd,"%s",stringa);
}
return conness;
}
int contr_fine(char *buf, int index)
//Controlla la fine di un rigo non delimitato da alcun carattere speciale
{
int i;
i=index;
while (buf[i]!='\0')
i++;
if (buf[i-1]==',')
return 1;
else
return 0;
}
rete_neurale calcola_feed_forward (rete_neurale rete)
//Calcola i valori di uscita dei nodi, dati gli ingressi
{
int N=rete.N+1;
int i,j,s,k;
//Per tutti i nodi di input Calcola il valore di uscita
//tramite la funzione teta di attivazione
for (j=1; j<=rete.nodi_input; j++)
{
// rete.nodo[j].valore_in=rete.nodo[j].valore_in-rete.nodo[j].soglia;
rete.nodo[j].valore=teta(rete.nodo[j].valore_in,rete.nodo[j].funzione_out);
}
//Per tutti i nodi Hidden
for(k=rete.nodi_input+1;k<=rete.N-rete.nodi_out;k++)
{
rete.nodo[k].valore_in=rete.nodo[k].soglia;
//Per tutti i nodi di input
for (i=1;i<=rete.nodi_input;i++)
rete.nodo[k].valore_in+=rete.nodo[i].valore*rete.w[k*N+i];
rete.nodo[k].valore=teta(rete.nodo[k].valore_in,rete.nodo[k].funzione_act);
}
//Per tutti i nodi di output
for(k=rete.N-rete.nodi_out+1;k<=rete.N;k++)
{
rete.nodo[k].valore_in=rete.nodo[k].soglia;
//Per tutti i nodi Hidden
for (i=rete.nodi_input+1;i<=rete.N-rete.nodi_out;i++)
rete.nodo[k].valore_in+=rete.nodo[i].valore*rete.w[k*N+i];
rete.nodo[k].valore=teta(rete.nodo[k].valore_in,rete.nodo[k].funzione_act);
}
return rete;
}
funzione di prova
#include <stdio.h>
#include "struttura.h"
main()
{
char buf[] = "ciao pirla;";
int ind;
printf("\n\nProva utilizzo libreria:\n\n");
ind = next_tab(buf, 0);
return 0;
}
Pensando fosse un problema del dev, ho provato ad aggiungere il percorso contenente il mio progetto negli include del compilatore (sostituendo "struttura.h" con <struttura.h>) ma nulla da fare!!!
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.