PDA

Visualizza la versione completa : [C++] Problema variabile...


StelK
13-10-2008, 00:08
Salve a tutti,
ho un problema davvero stupido ma molto fastidioso.
Sto lavorando a un programma con le classi in C++ e queste sono le definizioni di due funzioni all'interno di una classe:


void Neuron::setValue(double cv) {
nvalue = cv;
// cout << "Valore = " << nvalue << endl;
}

double Neuron::returnValue() {
return nvalue;
}

Come vedete, la prima setta solamente il valore di una variabile (dichiarata private) e la seconda ne restituisce (o almeno dovrebbe) il valore.
In realta' dopo aver chiamato setValue() su un oggetto, se chiamo, alla riga dopo, returnValue() non mi restituisce quel valore, ma numeri del tipo -4.27493e-39 e simili. Non so assolutamente cosa fare, anche perche' ho provato di tutto. La cosa strana e' che se metto un cout come quello commentato all'interno della funzione setValue() mi stampa il valore corretto, e poi returnValue() restituisce tutt'altro.

Grazie dell'aiuto,
Ciao ciao

oregon
13-10-2008, 00:16
Posta la parte del codice del tuo main in cui utilizzi l'oggetto cosi' come hai detto.

Posta anche la classe con i vari membri.

StelK
13-10-2008, 00:24
La parte dove uso la funzione e' questa:

void NeuralNet::run(vector<double> inputs) {
double totInput = 0;
for (int i = 0; i < layers.size(); i++) { // Per ogni livello
cout << "---------------------------------------------------\n\n";
cout << "Sono al layer " << i << endl;
if (i == 0) { // Se sono al primo layer prendo l'input dai neuroni di input
for (int j = 0; j < layers[i].numNeurons(); j++) {
for (int k = 0; k < numInputs; k++) {
totInput += layers[i].getNeuron(j).getWeight(k) * inputs[k];
}
layers[i].getNeuron(j).setValue(Sigmoid(totInput));
cout << "Sigmoid(totInput) per il neurone (" << i << ", " << j << ") e' " << Sigmoid(totInput) << endl;
cout << "Sigmoid(totInput) per il neurone (" << i << ", " << j << ") e' " << layers[i].getNeuron(j).returnValue() << endl;
totInput = 0;
}
} else {
for (int j = 0; j < layers[i].numNeurons(); j++) {
for (int k = 0; k < numNHL; k++) {
totInput += layers[i].getNeuron(j).getWeight(k) * layers[i-1].getNeuron(k).returnValue();
cout << layers[i-1].getNeuron(k).returnValue() << endl;
}
cout << "totInput per il neurone (" << i << ", " << j << ") e' " << totInput << endl;
layers[i].getNeuron(j).setValue(Sigmoid(totInput));
totInput = 0;
}
}
}
}

E' all'interno di un'altra classe che contiene il vettore layers da quale richiamo il singolo oggetto su cui eseguire la funzione... Chiaramente l'output della seconda e' della terza riga in grassetto, sebbene dovrebbe essere uguale, e' diverso.

La classe Neuron e' la seguente:


class Neuron {
public:
Neuron(int in_links);
void setValue(double cv);
double returnValue();
int numWeights() const;
double getWeight(int i);
private:
double nvalue;
vector<double> weights;
};

leonard_shelby
13-10-2008, 01:20
layers come lo definisci ? :master:

StelK
13-10-2008, 13:25
vector<NeuronLayer> layers;
In pratica e' un vettore di oggetti di un'altra classe... La classe neuron layer contiene al suo interno un vettore di neuroni (a cui accedo tramite la funzione getNeuron()).
Il problema non penso che stia qui, comunque, perche' quando chiamo per esempio un'altra funzione tipo numWeights() in questa maniera:

layers[i].getNeuron(j).numWeights()
mi restituisce il valore corretto.
Bah...

StelK
13-10-2008, 14:54
Ahh.. e' spuntata ora un'altra magia e cioe' che se direttamente da main() creo un oggetto Neuron (che in genere non creo perche' creo solo un oggetto della classe NeuralNet la quale li incorpora e li gestisce tutti) e chiamo su di lui setValue() e poi getValue() restituisce il valore giusto, per esempio:

Neuron A(15); // 15 e' un altro parametro irrilevante
A.setValue(0.12);
cout << A.getValue() << endl; // Questo stampa 0.12!!

mondobimbi
13-10-2008, 16:32
quando una variabile cambia il suo valore in modo inaspettato una delle cause potrebbe essere il fatto di sovrascrivere quella parte di memoria a causa, normalmente, di un vettore o altra variabile che esce dai suoi limiti.
Purtroppo questo genere di errore di difficile debugging.
Dovresti innanzitutto inserire un controllo dei limiti dei vettori che utilizzi o, se usi le STD di verificare che utilizzi solo delle funzioni membre che facciano questo controllo.
Dovresti inoltre verificare cosa dichiari prima della variabile incriminata, nella stessa classe o in un' altra classe, normalmente il compilatore ha allocato lo spazio nello stesso ordine.
Verifica con il debugger il momento in cui la variabile cambia il suo valore, probabilmente il reo la variabile che la precede.
Purtroppo solo tu che conosci il codice da te scritto puoi trovare il bug.
ciao
sergio

StelK
13-10-2008, 16:50
Allora, ho controllato un po il codice...
La cosa strana e' che la funzione setValue() non funziona solo quando la chiamo all'interno della classe NeuralNet mentre se la chiamo da altre classi che contengono al loro interno oggetti Neuron funziona.
Quei valori strani che vi ho mostrato prima erano solamente perche' la variabile non era settata, ma impostando per la variabile un valore di default tipo 0 essa continua a mantiene il valore di default anche dopo la chiamata a setValue(); di conseguenza che sia proprio setValue() a non settare bene la variabile, sebbene se metto al suo interno un cout e mi faccio stampare la variabile appena modificata il valore risulti corretto...
Non so piu' che fare -.-
Sono sicuro che e' uno di quegli errori stupidi che poi si correggono da soli quando riscrivi il codice da capo per la disperazione anche se quello che hai riscritto e' in fin dei conti lo stesso...

shodan
13-10-2008, 18:17
Questa funzione:


layers[i].getNeuron(j)

restituisce un Neuron giusto? (Non un Neuron* o un Neuron&).
Se cos allora lavori solo su una copia del Neuron contenuto nella catena, quindi il valore settato viene subito perso.

StelK
13-10-2008, 18:34
Ohhhhh :dh:
Finalmente ho risolto... il fatto era che avevo pure provato a modificare e a far restituire un Neuron* e non aveva funzionato lo stesso, probabilmente perche' dovev fare restituire anche un NeuronLayer* visto che le funzioni le richiamo a catena:

layers[i]->getNeuron(j)->getValue()
Probabilmente in quel modo mi restituiva anche una copia del livello e per questo non funzionava.
Grazie mille.....

Loading