Newsgroup: it.comp.lang.c++
Titolo: deque... ancora

Salve,
volevo anche sapere, sono OT a parlare della classe deque qui? è cpp
standard?
La domanda è:
Non funziona il ciclo che mi permette di trovare min e max scorrendo la
coda. Nessun errore di compilazione.
nel .h:
 typedef double *dataIn;
 typedef std::deque<dataIn> pdDeque;
 pdDeque ISTDequeD;
nel cpp:
double *temp;
eppoi
  dequesize=ISTDequeD.size();
  for( int  i = 0;  i< dequesize ; i++ )
   {
   temp=ISTDequeD[ i ];
  Message("KV (%lf)\n",temp[4]);
   if (KVmin<temp[4]) KVmin=temp[4];
   if (KVmax>temp[4]) KVmax=temp[4];
    }
ora temp = sempre l'ultimo elemento della deque per tutto il ciclo, cioè
quel message lì mi butta fuori 8 volte l'ultimo per ogni ciclo!
Dove sta l'errore, mi sembra ok?
grazie, ciao

 la coda. Nessun errore di compilazione.
Perchè non usare gli algoritmi standard max_element e min_element?
es:
#include <deque>
#include <algorithm>
#include <iostream>
int main()
{
  std::deque<int> d;
  d.push_back(1);
  d.push_back(7);
  d.push_back(3);
  d.push_back(13);
  std::deque<int>::iterator i_max;
  i_max=std::max_element(d.begin(),d.end());
  std::deque<int>::iterator i_min;
  i_min=std::min_element(d.begin(),d.end());
  std::cout << "Max: " << *i_max << std::endl;
  std::cout << "Min: " << *i_min << std::endl;
}
-- 
Gerolamo

   i_min=std::min_element(d.begin(),d.end());
non credo possa funzionare.
La mia coda č una coda di array di double. Devo trovare il max e il min
confronando tutti gli elementi della coda presenti in quarta posizione.
nel tuo caso hai una deque di int, č molto diverso.
Cmq dopo devo fare un ciclo for anche per dei confronti.
Grazie ciao

 confronando tutti gli elementi della coda presenti in quarta posizione.
 template< typename ArrayT, int Position >
  struct array_pos_less
  {   bool operator()( const ArrayT& a, const ArrayT& b ) const
     { return a[Position] < b[Position];
     }
  };
 typedef double*                  dataIn;
 typedef std::deque<dataIn>       pdDeque;
 typedef array_pos_less<dataIn,4> dataIn_4th_less;
 pdDeque d;
 pdDeque::iterator i_min = std::min_element( d.begin(),d.end(),
dataIn_4th_less() );
Max

 dataIn_4th_less() );
Ok qui crei un iteratore. Non capisco dove si trova il valore minimo trovato
e come usarlo.
Per esempio c'è un altro for dopo che mi serve, trovato il min e il max, per
trovare un delta=(max-min)/3, e capire se i valori nella coda sono alti,
medi o bassi rispettivamente agli intervalli trovati. ogni volta che i
valori in coda cambiano, cambiano anche gli intervalli.
Altro problema: non solo quelli in pos. 4, anche quelli in pos 3 e 2!
L'esempio che riportavo è uno stralcio.
  for( i = 0;  i< dequesize ; i++ )
   {
   temp=ISTDequeD[ i ];
   if (temp[4]>KVmin && temp[4]<(KVmin+deltaKV) && patternKV[i]==0)
tempKV++;
    else if (temp[4]>(KVmin+deltaKV) && temp[4]<(KVmin+(2*deltaKV)) &&
patternKV[i]==1) tempKV++;
    else if (temp[4]>(KVmin+(2*deltaKV)) && temp[4]<KVmax &&
patternKV[i]==2) tempKV++;
    }
dove patternKV è un array di otto interi che possono assumere valore 0,1 o
2.
è un confronto tra pattern, di cui uno discreto e uno continuo (reale).
Ora scritto come l'ho scritto mi sembra molto leggibile, ma con tutti sti
iteratori non riesco a venirne fuori...
Grazie e scusa se non so programmare :)

 valori in coda cambiano, cambiano anche gli intervalli.
Non ho capito, calcoli il delta e poi ?

 restituisce quell'elemento di deque che contiene il massimo 4to valore.
minimo no massimo

 Non ho capito, calcoli il delta e poi ?
Allora, devo confrontare la coda di 8 elementi (son sempre 8, perchè quando
ne arriva uno nuovo faccio un push_back e un pop_front, una sorta di
finestra) con un pattern predefinato a tre valori
Allora supponiamo che i miei 8 elementi siano 1, 2, 4, 3.5, 7, 9.4, 10.5, 5
Il mio pattern 1,0,0,1,2,2,0,1.
trovo min e max: min=1 max=10.5. => delta= 9.5/3= facciamo 3.2 per comodità
di calcolo (esempio a caso)
allora primo elemento è 1, sta tra min e min+delta, quindi valore basso. Il
pattern da 1 al primo elemento, quindi valore medio, quindi non ci siamo
secondo elemento 2, sta tra 1 e 4.2, valore basso, confronto col secondo del
pattern, che è 0, quindi ok!
e così via.
Conto quanto riscontri positivi ci sono
Ecco perchè debbo ciclare sulla deque, è una deque di array di double di cui
mi interessano i valori alla pos 2,3 e 4  di ciascun elemento della deque,
che vengon confrontati con 3 pattern distinti.
Il valore alla pos 0 e 1 non servono per questo, son valori di controllo.
Questo perchè sono output che mi arrivano in ingresso, e così son fatti.
Il mio metodo mi faceva avere per ogni iterazione del ciclo for una
variabile temp definita come double *temp, e quindi era semplice fare
temp[4] e confrontarlo col pattern. Un iteratore come lo gestisco, non
riesco a capire cosa sia.
Se dovessi confrontare i_min con un double, come faccio? Che cos'è i_min
esattamente?
grazie ciao

 Conto quanto riscontri positivi ci sono
Questo credo che non esista standard. Però abbiamo transform che potrebbe
fare al caso nostro.
typedef vector<int> Pattern; // il tuo pattern
Pattern inp(a[0], a[8]); // se avevi il pattern in un array lo carichi nel
vector inp
Pattern out;
template <class ArrayT, int Position>
class check_delta
{
    double min, max, delta;
    check_delta(double a, double b, double c): min(a), max(b), delta(c) {}
    int operator(const ArrayT& a)
                {if a[Position-1]<(min+delta) return 0; if
a[Position-1]>max-delta return 2; return 1;)}
}
Quindi chiamare transform usando questo nuovo oggetto funzione:
transform(d.begin(), d.end(), out.begin(), check_delta<Data, 4>((*i_min)[4],
(*i_min)[4], delta))
Adesso se non vado errando in out dovrebbe esserci il tuo output pattern da
confrontare con l'input pattern.
Confronti i due vettori e hai finito.

Ciao e infinitamente grazie, sei stato disponibilissimo...
ora provo e ti faccio sapere.
Una curiosità residua:
for( int  i = 0;  i< dequesize ; i++ )
   {
   temp=ISTDequeD[ i ];
  Message("KV (%lf)\n",temp[4]);
   if (KVmin<temp[4]) KVmin=temp[4];
   if (KVmax>temp[4]) KVmax=temp[4];
    }
perchè non va secondo te? è sbagliato scorrere una deque in questo modo?
l'output di message è sempre il valore in testa alla coda, non so perchè
Ciao

e altra cosa:
che differenza pratica c'è tra una deque e un vector?
Forse avrei fatto meglio a creare un vector?
Ciao grazie

Ciao
sempre per capirne di più di iteratori:
se scrivessi così lo troveresti sensato?
 typedef double *dataIn;
 typedef std::deque<dataIn> pdDeque;
 typedef pdDeque::iterator pdDequeiter;
 pdDeque ISTDequeD;
 pdDequeiter ISTiter;
double  *ISTdouble
ISTdouble=m_dDequeIST.front();
//son tutti dei double quelli sotto
  KVmin=ISTdouble[4];
  KVmax=ISTdouble[4];
  Legmin=ISTdouble[3];
  Legmax=ISTdouble[3];
  NPSmin=ISTdouble[2];
  NPSmax=ISTdouble[2];
//ciclo per il min
  for(ISTiter= ISTDequeD.begin();  ISTiter !=ISTDequeD.end(); ISTiter++)
   {
  Message("KV (%lf)\n",*ISTiter[4]);
   if (KVmin<*ISTiter[4]) KVmin=*ISTiter[4];
   if (KVmax>*ISTiter[4]) KVmax=*ISTiter[4];
   if (Legmin<*ISTiter[3]) Legmin=*ISTiter[3];
   if (Legmax>*ISTiter[3]) Legmax=*ISTiter[3];
   if (NPSmin<*ISTiter[2]) NPSmin=*ISTiter[2];
   if (NPSmax>*ISTiter[2]) NPSmax=*ISTiter[2];
   }
Voglio capire, non sminuisco il lavoro che hai fatto con i template, solo
per capire come funzionano questi iteratori.
Per esempio così non va, *ISTiter[4] mi da un valore a caso, appena provato
in debug.
Non capisco nulla, mi sento molto idiota!


Scusa ma assegni un nuovo minimo se temp[4] č MAGGIORE del minimo corrente?
in KVmin ottieni il massimo, non il minimo. L'opposto per KVmax, o sono io
che sono che devo passare al golf? Inoltre non ho capito cosa faccia
Message, funziona a mo' di printf?
Per il resto credo che questo modo di operare sia semanticamente corretto ma
non č certamente quello a cui avevano pensato i tizi che avevano progettato
le STL.

 wrote in message
fyrya.121891$3M4.2...@news1.tin.it...

Io mi sono studiato il vector, la deque è l'astrazione di una coda, quindi
*credo* fornisca solamente i metodi per supportare la coda (push_back e
pop_front e altri) quindi niente insert e niente erase, per esempio, però
non ne sono sicuro, non ho mai usato le deque. Se a te serve una coda hai
fatto bene a usare la deque, è lì apposta, altrimenti è meglio usare il
vector. A proposito, al posto di un array di double, come elementi della
coda avresti dovuto metterci un vector di double, in questo modo:
deque< vector<double> > miacoda;
Che mi sembrerebbe più elegante.

::iterator' (or there is no acceptable conversion)
Perchè?
Se volessi mettere quell'array di double in un altro array?
Grazie ciao

 temp =ISTiter[4]
Scusa ho sbagliato:
temp=ISTiter;
non va
temp=*ISTiter non da errori di compilazione, ma i valori son sbagliati.
Forse facendo un cast?
Grazie... della pazienza :)

 in debug.
Ecco appunto, giacchè mi hai messo il dubbio ho controllato sul librone e ho
scoperto che [] ha priorità maggiore di * (che peraltro è molto più in basso
di quanto invece non credevo). Ciò significa che *ISTiter[4] viene
interpretato con "prendi il quinto elemento della coda ed applicagli la
dereferenza", quindi ottieni il primo valore dell'array in posizione 5 della
deque.
Ciao

 deque.
  for(ISTiter= ISTDequeD.begin();  ISTiter !=ISTDequeD.end(); ISTiter++)
   {
  if (KVmin>(*ISTiter)[4]) KVmin=(*ISTiter)[4];
   if (KVmax<(*ISTiter)[4]) KVmax=(*ISTiter)[4];
   if (Legmin>(*ISTiter)[3]) Legmin=(*ISTiter)[3];
   if (Legmax<(*ISTiter)[3]) Legmax=(*ISTiter)[3];
   if (NPSmin>(*ISTiter)[2]) NPSmin=(*ISTiter)[2];
   if (NPSmax<(*ISTiter)[2]) NPSmax=(*ISTiter)[2];
   }
Non va!
Cicla sempre sullo stesso elemento!
Giuro che non capisco!
Ho controllato gli elementi che vengon messi nella deque e ci sono!
Non so dove stia l'errore!

 Cicla sempre sullo stesso elemento!
#include <iostream>
#include<deque>
using namespace std;
typedef double tdata;
typedef double* tpdata;
typedef deque<tpdata> tdeque;
typedef tdeque::iterator titer;
int main()
{
 tdeque d;
 tpdata tmp=0;
 int c;
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c+3;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=1;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c*c;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c+2;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c+50;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c+1;}
 d.push_back(tmp);
 tmp=new tdata[10];
 for(c=0;c<10;c++){tmp[c]=c;}
 d.push_back(tmp);
 double KVmin= (d.front())[4];
 double KVmax= (d.front())[4];
 double Legmin= (d.front())[3];
 double Legmax= (d.front())[3];
 double NPSmin= (d.front())[2];
 double NPSmax= (d.front())[2];
 for(titer t= d.begin();t!=d.end(); t++)
    {
  if (KVmin>(*t)[4]) KVmin=(*t)[4];
  if (KVmax<(*t)[4]) KVmax=(*t)[4];
  if (Legmin>(*t)[3]) Legmin=(*t)[3];
  if (Legmax<(*t)[3]) Legmax=(*t)[3];
  if (NPSmin>(*t)[2]) NPSmin=(*t)[2];
  if (NPSmax<(*t)[2]) NPSmax=(*t)[2];
 }
 cout<<KVmin<<" "<<KVmax<<" "<<Legmin<<" "<<Legmax<<" "<<NPSmin<<"
"<<NPSmax;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 tmp=d.front();
 d.pop_front();
 delete tmp;
 return 0;
}
Questo va, l'ho compilato e testato (molto sommariamente)
Uno degli array contiene tutti uno, e infatti i minimi sono 1 1 1 mentre i
massimi sono 52 53 54 poiche uno degli array contiene 50+i dove i è la sua
posizione nell'array.
Credo che il problema sia nell'inserimento perchè l'algoritmo per il calcolo
dei massimi e minimi è il tuo con le variabili cambiate.

Ciao Gabriele e grazie mille,
ho letto il tuo codice ed in effetti sembra identico al mio. Solo che il mio
persevera a non funzionare, benchè abbia controllato, come m'hai suggerito,
l'inserimento valori.
Ti posto qualche riga e qualche uscita, mi dici che ne pensi?
Allora l'inserimento nella mia deque pesca da un'altra deque, riempita da
uno stream di dati proveniente da un blocchetto precedente. In pratica
Eyesweb funziona come simulink di matlab, cioè crei una rete di blocchetti
collegati che computano e si mandano i valori (ecco perchè la mia deque è di
array, mi arrivano array, non la riempio io)
 typedef std::vector<double> Params;
 typedef double *dataIn;
 typedef std::deque<dataIn> pdDeque;
 pdDeque::iterator ISTiter;
 pdDeque m_dDequeIST,ISTDequeD;
Inserimento valori:
 if (!m_dDequeIST.empty() && !start)
  {
  temp=m_dDequeIST.front();
  if (temp[0]==0 && temp[1]==0)
   {
   start=true;
   ISTDequeD.push_back(m_dDequeIST.front());
   m_dDequeIST.pop_front();
   ISTiter= ISTDequeD.begin();
   Message("KV (%lf)\n",(*ISTiter)[4]);
   Message("size (%d)\n",ISTDequeD.size());
   notescounter++;
   }
      else m_dDequeIST.pop_front();
  }
 else if (!m_dDequeIST.empty() && notescounter<8 && start)
  {
  ISTDequeD.push_back(m_dDequeIST.front());
  m_dDequeIST.pop_front();
  ISTiter= ISTDequeD.begin();
  Message("KV (%lf)\n",(*ISTiter)[4]);
  Message("size (%d)\n",ISTDequeD.size());
  notescounter++;
  }
Qui in pratica i primi sette valori vengono messi dentro a ISTDequeD
pescandoli con un front dall'altra coda.  Attendo uno start message per
evitare di computare dati a caso e parto! Ho inserito i message per vedere
dopo ogni inserimento che valore era l'ultimo (begin, perchè faccio un
push_back) e quanto lunga è la coda.
Eyesweb tramite l'istruzione message mi da i seguenti messaggi:
(System)  Starting patch...
(System)  Patch started.
(Remote)  KV (91.000000)
(Remote)  size (1)
(Remote)  KV (94.000000)
(Remote)  size (2)
(Remote)  KV (109.000000)
(Remote)  size (3)
(Remote)  KV (113.000000)
(Remote)  size (4)
(Remote)  KV (118.000000)
(Remote)  size (5)
(Remote)  KV (113.000000)
(Remote)  size (6)
(Remote)  KV (127.000000)
(Remote)  size (7)
Come vedi la coda parte vuota e vengono inseriti i valori. Il max
sembrerebbe 127 ed il min 91.
Quindi la coda sembrerebbe avere i valori corretti!
Poi parte il ciclo, dall'ottavo dato:
 else if (!m_dDequeIST.empty() && start)
  {
  ISTDequeD.push_back(m_dDequeIST.front());
  ISTdouble=m_dDequeIST.front();
  m_dDequeIST.pop_front();
  //finding min and max to determine patterns
  //finding average and dev
  dequesize=ISTDequeD.size();
  temp=ISTDequeD.front();
  KVmin=temp[4];
  KVmax=temp[4];
  Legmin=temp[3];
  Legmax=temp[3];
  NPSmin=temp[2];
  NPSmax=temp[2];
  sumKV=0; sum2KV=0; sumLeg=0; sum2Leg=0; sumNPS=0; sum2NPS=0;
  for(ISTiter= ISTDequeD.begin();  ISTiter !=ISTDequeD.end(); ISTiter++)
   {
  Message("size (%d)\n",ISTDequeD.size());
  Message("KV (%lf)\n",(*ISTiter)[4]);
   if (KVmin>(*ISTiter)[4]) KVmin=(*ISTiter)[4];
   if (KVmax<(*ISTiter)[4]) KVmax=(*ISTiter)[4];
   if (Legmin>(*ISTiter)[3]) Legmin=(*ISTiter)[3];
   if (Legmax<(*ISTiter)[3]) Legmax=(*ISTiter)[3];
   if (NPSmin>(*ISTiter)[2]) NPSmin=(*ISTiter)[2];
   if (NPSmax<(*ISTiter)[2]) NPSmax=(*ISTiter)[2];
   sumKV=sumKV+(*ISTiter)[4];
   sum2KV=sum2KV+(sumKV*sumKV);
   sumLeg=sumLeg+(*ISTiter)[3];
   sum2Leg=sum2Leg+(sumLeg*sumLeg);
   sumNPS=sumNPS+(*ISTiter)[2];
   sum2NPS=sum2NPS+(sumNPS*sumNPS);
   }
ecc....
Qui i message li ho messi per vedere che valori ho sull'iteratore della
coda. Ecco come continua Eyesweb:
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
(Remote)  KV (118.000000)
(Remote)  size (8)
ecc...
che è l'ottavo valore inserito, cioè il begin! In pratica l'iteratore non
cicla!
Giuro che non riesco a capire l'origine del problema. Grossa bevuta se ce la
fai!
Scherzi a parte grazie dell'aiuto, se riesci a capire l'origine del problema
te ne sarei veramente grato!
Matteo

 Giuro che non riesco a capire l'origine del problema.
Neppure io.
Ho letto il codice e ho provato a capire passo passo quello che fa.Non sono
riuscito a trovare il motivo del risultato sbagliato e non potendo eseguirlo
non ho potuto approfondire.
Io procederei in questo modo:
prima dell'elaborazione richiederei una bella stampa a video di tutto il
contenuto della coda che ti appresti ad elaborare, oppure la analizzerei
utilizzando le watches e i breackpoints per verificare che contenga
effettivamente quello che deve contenere.
una volta appurato che la coda contiene esattamente quello che dovrebbe
contenere metterei un bel breakpoint all'inizio del ciclo di elaborazione e
verificherei passo passo, istruzione per istruzione, il contenuto di tutte
le variabili in gioco, specialmente l'iteratore, per tutte le istruzioni
delle prime 3 o 4 iterazioni del ciclo. Se č vero che il ciclo va in loop
infinito allora dentro il ciclo deve succedere qualcosa di spiacevole
all'iteratore. Eppure mi sembra che il ciclo sia uguale a quello che ho
fatto io, che sul mio computer funzionava perfettamente quindi non saprei
davvero.
Buona fortuna.