PDA

View Full Version : [C] Minimizzazione di funzione


salvodel
04-12-2007, 13:05
Ho una funzione che mi minimizza una funzione di variabili con la seguente intestazione(solo i primi quattro termini sono importanti)
minimizzazione(funzione, derivata, p, x, m, n, 1000, opts, info, NULL, NULL, NULL)

Funziona nel seguente modo: se ho una funzione di variabili reali del del tipo z(x,y)= 5*x+2*y+4
per passarla alla funzione minimizzazione devo scrivere due funzioni: minimizzazione e derivata;
La prima sarà del tipo:

void funzione(double *p, double *x, int m, int n, void *data)
{
for(i=0;i<2;i++)
x[i]=5*p[0]+2*p[1]+4;
}
La seconda sarà identica dove però invece della funzione inserirò la sua derivata.

A questo punto sorge spontanea la mia domanda: se ho molte variabile e voglio scrive la funzione in modo piu sintetico posso farlo?
Esempio banale:
f(x)=sommatoria x_i con i che va da 1 a millllle:D scherzo comunque facciamo un numero elevato.

Nel primo caso farei:
{
for(i=0;i<2;i++)
x[i]=p[0]+p[1]+p[2]+p[3]+........+p[999];
}

Questo mi bloccherebbe e non mi permetterebbe di fare cio che voglio. Secondo voi se faccio una cosa di questo tipo la funzione minimizzazione capisce ancora che p sono i parametri da minimizzare?

{
for(i=0;i<1000;i++)
somma+=p[i];

for(i=0;i<1000;i++)
x[i]=somma;
}

Scusate se ripropongo un dubbio che mi assale....
Grazie a tutti.
Ciao

salvodel
05-12-2007, 02:00
Come mai nemmeno un commentino? Mi sono espresso male?

Help, I need somebody,
Help, not just anybody,
Help, you know I need someone, help.

cionci
05-12-2007, 09:11
Per quale motivo non dovrebbe riuscirci anche nel primo caso ?

salvodel
05-12-2007, 13:47
Per quale motivo non dovrebbe riuscirci anche nel primo caso ?

Nel primo caso ci riesce e come. Negli esempi forniti fa proprio cosi. Il mio problema è di creare delle variabili intermedie da associare ai puntatori p.
Ad esempio mi creo la matrice
for(kk=0; kk<S; kk++)
for(jj=0; jj<N+1; jj++)
wid1[kk][jj]=p[jj+kk*(N+1)];

e poi utilizzo questa invece di p. Come dicevo anche prima non posso utilizzare p poiche mi renderebbe le formule bloccate e non potrei cambiarle di "dimensioni" in questo modo posso utilizzare sia una variabile p[0] che n variabili p[N].
Che ne dici?:confused:
Grazie

mad_hhatter
05-12-2007, 17:41
vediamo se ho capito il problema:

tu ora utilizzi le componenti di p chiamandole esplicitamente p[0], ... p[i].

e hai il problema di i che assume valori elevati...

beh, se questo è il problema, è un falso problema :-)

tu hai un vettore p e questo è quello che devono conoscere le funzioni "funzione" e la funzione "minimizzazione". Questo garantisce che qualunque sia p le tue funzioni lo useranno correttamente.

Ora tutto quello che devi fare è non chiamare esplicitamente le componenti di p, ma farlo in maniera implicita, così:

void funzione(double *p, double *coeff, double *x, int m, int n, void *data)
{
for(i=0;i<2;i++)
x[i] = coeff[0];
for (int j=1; j < coeff.lenght; j++)
x[i]+=coeff[j]*p[j-1];
}

dove coeff è un vettore lungo |p|+1, contenente i coefficienti dei termini p[0], p[1], ecc... il primo valore corrisponde al termine noto della funzione da calcolare (nell'esempio del tuo primo post è il +4)

salvodel
06-12-2007, 13:52
vediamo se ho capito il problema:

tu ora utilizzi le componenti di p chiamandole esplicitamente p[0], ... p[i].

e hai il problema di i che assume valori elevati...

beh, se questo è il problema, è un falso problema :-)

tu hai un vettore p e questo è quello che devono conoscere le funzioni "funzione" e la funzione "minimizzazione". Questo garantisce che qualunque sia p le tue funzioni lo useranno correttamente.

Ora tutto quello che devi fare è non chiamare esplicitamente le componenti di p, ma farlo in maniera implicita, così:

void funzione(double *p, double *coeff, double *x, int m, int n, void *data)
{
for(i=0;i<2;i++)
x[i] = coeff[0];
for (int j=1; j < coeff.lenght; j++)
x[i]+=coeff[j]*p[j-1];
}

dove coeff è un vettore lungo |p|+1, contenente i coefficienti dei termini p[0], p[1], ecc... il primo valore corrisponde al termine noto della funzione da calcolare (nell'esempio del tuo primo post è il +4)

Grazie per avermi risposto per l'ennesima volta. Provo a spiegarmi anche se penso che tu mi abbia gia risposto. La funzione utilizza il vettore p per indicare le variabili da calcolare. Quindi per scriver f(x,y)=5x+7y devo scrivere f(x,y)=5*p[0]+7*p[1].
Siccome ho una matrice volevo sapere se associando p[] ad una matrice la funzione riusciva a lavorare lo stesso. In modo banale se volessi avere un'aspetto simbolico posso fare una cosa del genere, partendo sempre dalla stessa funzione f(x,y)=5x+7y

prima dico che x=p[0] ed y=p[1]
a questo punto se scrivo la mia funzione come f(x,y)=5x+7y lui è in grado di capire che x è p[0] ed y è p[1]?
Contorto?
Confido in un po di pazienza.....
Ciao

mad_hhatter
06-12-2007, 17:01
Grazie per avermi risposto per l'ennesima volta. Provo a spiegarmi anche se penso che tu mi abbia gia risposto. La funzione utilizza il vettore p per indicare le variabili da calcolare. Quindi per scriver f(x,y)=5x+7y devo scrivere f(x,y)=5*p[0]+7*p[1].
Siccome ho una matrice volevo sapere se associando p[] ad una matrice la funzione riusciva a lavorare lo stesso. In modo banale se volessi avere un'aspetto simbolico posso fare una cosa del genere, partendo sempre dalla stessa funzione f(x,y)=5x+7y

prima dico che x=p[0] ed y=p[1]
a questo punto se scrivo la mia funzione come f(x,y)=5x+7y lui è in grado di capire che x è p[0] ed y è p[1]?
Contorto?
Confido in un po di pazienza.....
Ciao

un po' contorto, sì...
chiariamo prima un po' di termini, per non far casino.

cosa intendi per "associare p[] a una matrice"? p, con un solo indice, è un vettore monodimensionale (o matrice-riga). un vettore del tipo h[i][j] è una matrice classica a 2 dimensioni... tu cosa intendi?

venendo all'ultima domanda, se dici x=p[0] assegni a x il valore numerico di p[0] all'istante dell'assegnazione. se successivamente fai p[0] = <altro valore>, x manterrà il vecchio valore p[0], non quello nuovo...

cosa vuoi dire con "lui è in grado di capire che x E' p[0]"? specifica il significato preciso di quel "è". intendi che hanno lo stesso valore o che sono la stessa entità matematica? nel secondo caso la risposta è no: x è x, p[0] è p[0], a meno che tu non faccia in modo che x e p[0] abbiano SEMPRE lo stesso valore...

salvodel
07-12-2007, 12:00
un po' contorto, sì...
chiariamo prima un po' di termini, per non far casino.

cosa intendi per "associare p[] a una matrice"? p, con un solo indice, è un vettore monodimensionale (o matrice-riga). un vettore del tipo h[i][j] è una matrice classica a 2 dimensioni... tu cosa intendi?

venendo all'ultima domanda, se dici x=p[0] assegni a x il valore numerico di p[0] all'istante dell'assegnazione. se successivamente fai p[0] = <altro valore>, x manterrà il vecchio valore p[0], non quello nuovo...

cosa vuoi dire con "lui è in grado di capire che x E' p[0]"? specifica il significato preciso di quel "è". intendi che hanno lo stesso valore o che sono la stessa entità matematica? nel secondo caso la risposta è no: x è x, p[0] è p[0], a meno che tu non faccia in modo che x e p[0] abbiano SEMPRE lo stesso valore...

Ti ringrazio per la pazienza. Riprovo a ripetere tutto da capo.
La funzione minimizzazione ha seguente intestazione
void funzione(double *p, double *x, int m, int n, void *data)

se io volessi trovare il minimo della funzione f(x)=5x^2+x+3 dovrei scrivere cosi:
f=5*p[0]*p[0]+p[0]+3
Se la funzione è di due variabili f(x,y)=x^2+y^2+x+y+7 allora il tutto diventa
f=p[0]*p[0]+p[1]*p[1]+p[0]+p[1]+7
Come vedi ad ogni puntatore o ad ogni elemento del vettore p[] corrisponde una variabile. Il mio problema è poter scrivere una funzione senza utilizzare direttamente p[] ma un'altro formalismo. Ti facevo l'esempio
x=p[0] ed y=p[1]
\\f=5*p[0]+7*p[1] cosi si puo scrivere ma io voreri sciverla come segue. Si puo?
f=5*x+7*y

Se ti linco linko l'algoritmo che utilizzo e gli dai un occhiata forse capisci meglio.
http://www.ics.forth.gr/~lourakis/levmar/levmar-2.1.3.tgz
Se riesci a dare un occhiata al file lmdemo.c ci sono un po di funzioni. Io vorrei poter riscriverne una funzione non utilizzando direttamente p[] ma utilizzando una matrice. Se non è chiaro il discorso della matrice non ti preoccupare. Il mio dubbio è legato al formalismo con cui scrivere le funzioni come nel caso precendete.
Spero di non aver ulteriormente complicato la situazione.

PS
Un unico favore...oltre a quelli che gia mi hai fatto. Se mi molli:cry: me lo dici cosi non aspetto con ansia una tua risposta:(:D

mad_hhatter
07-12-2007, 12:14
mollarti non ti mollo, tranquillo. l'unica cosa è il tempo libero: lavoro, quindi non sempre posso risponderti in tempi brevi... tra oggi e domani do un'occhiata al link che hai postato, comunque posso dirti da subito che, posto di scrivere ogni volta prima dell'uso x_i = p[i], puoi tranquillamente usare la variabile x_i al posto di p[i], ma ti ricordo che l'uguaglianza non è semantica ma riguarda il valore al momento dell'assegnazione.

per l'algoritmo ci risentiamo prima possibile

mad_hhatter
08-12-2007, 13:07
ho dato un'occhiata al file lmdemo.c...

devo dire che alcune cose mi sembrano un po' strane, come ad esempio l'istruzione

for(i=0; i<n; ++i)
x[i]=((1.0-p[0])*(1.0-p[0]) + ROSD*(p[1]-p[0]*p[0])*(p[1]-p[0]*p[0]));


il membro di destra non dipende da i, quindi per ogni i x[i] riceve lo stesso valore... allora perche' ripetere il calcolo n volte?

comunque, ancora non mi e' ben chiaro quale sia lo scoglio... se tu vuoi scrivere x, y al posto di p[0], p[1] non vedo perche' tu non possa farlo... l'unica cosa e' il numero di variabili: se ne hai due ok, se ne hai 100 tanti auguri :)

ripeto comunque che un estratto del codice che stai scrivendo aiuterebbe molto, perche' finora non ho capito molto bene quale sia il tuo ostacolo

salvodel
08-12-2007, 14:28
ho dato un'occhiata al file lmdemo.c...

devo dire che alcune cose mi sembrano un po' strane, come ad esempio l'istruzione

for(i=0; i<n; ++i)
x[i]=((1.0-p[0])*(1.0-p[0]) + ROSD*(p[1]-p[0]*p[0])*(p[1]-p[0]*p[0]));


il membro di destra non dipende da i, quindi per ogni i x[i] riceve lo stesso valore... allora perche' ripetere il calcolo n volte?

Poiche è una minimizzazione la funzione necessità di almeno tante equazioni quanti sono i parametri. Quindi se ho m parametri devo fornire almeno m=n "soluzioni" o dati o come li volgiamo chiamare a secondo di quello che stiamo facendo. In questo caso ho una funzione in due variabili e per come credo di aver capito che funziona lui, vuole almeno due soluzioni dell'equazione. Essendo la funzione del tipo f(x,y)=0 nel main fa un ciclo in cui assegna a x[i] il valore zero. Aquesto punto ha la sua bella funzioncina e prova a risolverla. Spero che almeno qui sia stato chiaro.....ora torno a parlare di C e .....:D

comunque, ancora non mi e' ben chiaro quale sia lo scoglio... se tu vuoi scrivere x, y al posto di p[0], p[1] non vedo perche' tu non possa farlo... l'unica cosa e' il numero di variabili: se ne hai due ok, se ne hai 100 tanti auguri :)
Nel senso che è uno sbattimento :eekk: o che non si puo fare? Oppure erano gli Auguri per l'Immacolata:rotfl: Nel caso grazie ed Auguri anche a te.
ripeto comunque che un estratto del codice che stai scrivendo aiuterebbe molto, perche' finora non ho capito molto bene quale sia il tuo ostacolo
Ma il mio "codice" è solamente scrivere la funzione in modo corretto di cui ne abbiamo gia discusso qui:
http://www.hwupgrade.it/forum/showthread.php?t=1613588
Se vui provo a scriverti la funzione e poi casomai mi dici come la scriveresti tu per farla minimizzare alla function. Tutto qui:cry: !
Oggi ho trovato un po di errori matematici che avevo fatto. Adesso riaggiusto il tutto e provo a vedere se va.
Ciao e di nuovo grazie mille.

mad_hhatter
08-12-2007, 17:11
Poiche è una minimizzazione la funzione necessità di almeno tante equazioni quanti sono i parametri. Quindi se ho m parametri devo fornire almeno m=n "soluzioni" o dati o come li volgiamo chiamare a secondo di quello che stiamo facendo. In questo caso ho una funzione in due variabili e per come credo di aver capito che funziona lui, vuole almeno due soluzioni dell'equazione. Essendo la funzione del tipo f(x,y)=0 nel main fa un ciclo in cui assegna a x[i] il valore zero. Aquesto punto ha la sua bella funzioncina e prova a risolverla. Spero che almeno qui sia stato chiaro.....ora torno a parlare di C e .....:D


Nel senso che è uno sbattimento :eekk: o che non si puo fare? Oppure erano gli Auguri per l'Immacolata:rotfl: Nel caso grazie ed Auguri anche a te.

Ma il mio "codice" è solamente scrivere la funzione in modo corretto di cui ne abbiamo gia discusso qui:
http://www.hwupgrade.it/forum/showthread.php?t=1613588
Se vui provo a scriverti la funzione e poi casomai mi dici come la scriveresti tu per farla minimizzare alla function. Tutto qui:cry: !
Oggi ho trovato un po di errori matematici che avevo fatto. Adesso riaggiusto il tutto e provo a vedere se va.
Ciao e di nuovo grazie mille.

ho capito che ha bisogno di n equazioni, ma sta di fatto che per n volte ricalcola un valore che non dipende dall'indice dell'iterazione... quindi bastava calcolarlo una volta e assegnare poi tale valore a ogni x[i]... ma e' solo un dettaglio.

tanti auguri nel senso che se hai 100 variabili, usando p[i] puoi usare le variabili implicitamente, ma se devi scrivere a mano x, y, ecc o anche p[0], p[1]... ecc esplicitamente, beh... e' un po' lungo da fare :)

salvodel
10-12-2007, 11:27
ho capito che ha bisogno di n equazioni, ma sta di fatto che per n volte ricalcola un valore che non dipende dall'indice dell'iterazione... quindi bastava calcolarlo una volta e assegnare poi tale valore a ogni x[i]... ma e' solo un dettaglio.

Il problema infatti è scriverla una volta. Io ho fatto proprio cosi, ho scritto la funzione una volta e poi con un ciclo for lo assegnata m volte a x[i].

tanti auguri nel senso che se hai 100 variabili, usando p[i] puoi usare le variabili implicitamente, ma se devi scrivere a mano x, y, ecc o anche p[0], p[1]... ecc esplicitamente, beh... e' un po' lungo da fare :)

Appena posso ti mando la formula e come l'ho scritta nel programmino.
Inoltre volevo chiederti se riesci a capire se c'è un limite massimo di parametri che può minimizzare oppure no?
Grazie di nuovo.

salvodel
11-12-2007, 17:21
ho capito che ha bisogno di n equazioni, ma sta di fatto che per n volte ricalcola un valore che non dipende dall'indice dell'iterazione... quindi bastava calcolarlo una volta e assegnare poi tale valore a ogni x[i]... ma e' solo un dettaglio.

tanti auguri nel senso che se hai 100 variabili, usando p[i] puoi usare le variabili implicitamente, ma se devi scrivere a mano x, y, ecc o anche p[0], p[1]... ecc esplicitamente, beh... e' un po' lungo da fare :)

Adesso gira...anche se solo la versione "castrata":muro: cioè solo la funzione senza lo jacobiano.
Speriamo in meglio....:cry:

mad_hhatter
11-12-2007, 17:23
Adesso gira...anche se solo la versione "castrata":muro: cioè solo la funzione senza lo jacobiano.
Speriamo in meglio....:cry:

beh, mi pare una notizia positiva!