Newsgroup: it.comp.lang.visual-basic
Titolo: [VB6] - Array e valore massimo

In una function ho definito due variabili cosě:
dim over(10) as double
dim under(10) as double
Una volta che ho tutti i valori del vettore, esiste un comando che mi
estragga il valore massimo al volo?
O devo per forza costruire un loop?
Grazie

O devo per forza costruire un loop?
La seconda che hai detto ;-)
-- 
ciao, hal

 ha scritto nel messaggio

Ouch
a questo punto io c'ho ggrossa ggrisi...
vabbuň mi do da fare :D
Ciao e denghiu

 vabbuň mi do da fare :D
Ti preoccupi per 10/11 elementi?

 Ti preoccupi per 10/11 elementi?
Non sono i 10/11 elementi.
Il fatto è che la cosa non è così semplice.
Ho a che fare con un numero di frames che puàò arrivare anche a 300000 e
devo costruirmi un grafico tipo curva gaiussiana, ma non so da dove iniziare
:(
Ciao

 devo costruirmi un grafico tipo curva gaiussiana, ma non so da dove iniziare
Dipende, come sono organizzati i dati ? Comunque non ci vuole
molto tempo, ti faccio un esempio al volo:
      Debug.Print "avvio - " & Timer
      Dim N As Long
      Dim Maggiore As Long
      Dim A(300000) As Double
      Debug.Print "riempio matrice - " & Timer
      For N = 0 To 300000
            A(N) = CDbl(300001 * Rnd) ' solo per metterci dentro qualcosa...
      Next N
      Debug.Print "verifico elemento maggiore - " & Timer
      For N = 0 To 300000
            If A(N) > Maggiore Then Maggiore = A(N)
            ' If N Mod 10000 = 0 Then Debug.Print A(N)
            ' buttato lě tanto per controllare che ci fossero
            ' davvero dei numeri, non mi fidavo :-)
      Next N
      Debug.Print "elemento maggiore = " & Maggiore
      Debug.Print "controllo effettuato - " & Timer
Qui su un vecchio 200 Mhz (duecento, non due gigahertz :-) )
ci mette quattro-cinque decimi di secondo a fare il controllo.
Ah, dall'IDE :-). Dal compilato, circa tre volte di meno, senza
nessuna ottimizzazione avanzata.
Bye, G.

            If A(N) > Maggiore Then Maggiore = A(N)
giusto per pignoleria (per il cineamatore), inizializzerei Maggiore al
valore del primo elemento dell'array... non per risparmiare
un'iterazione, ma metti che (in un caso generico) il valore massimo sia
< 0 ti restituirebbe un risultato non vero...
Ciao,
Moreno
-- 
sirri at morenosoft dot com
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------

 devo costruirmi un grafico tipo curva gaiussiana, ma non so da dove
iniziare
Capisco, mi basavo sul tuo post.
Ma (come dici e com'è ovvio) li devi caricare, controlla in quel ciclo qual
è e dov'è il valore più alto...
Se la ricerca deve essere ripetuta per altri valori, allora non c'è altro
che il ciclo.
Però, in tutta sincerità e con tale mole di valori, ho la sensazione che
mettere tutto su database (oltre che, eventualmente, in memoria) e sfruttare
SQL per fare ricerche particolari, ... alla fine paghi.

 giusto per pignoleria
...
anch'io... dimensionerei Maggiore come Double, non come Long.
... a dir il vero ... io non dimensionerei affatto :-P

 SQL per fare ricerche particolari, ... alla fine paghi.
Il fatto è questo.
Vi spiego meglio la situazione così è + chiaro con cosa ho a che fare.
durante la compressione viene generato un file che cntiene le statistiche
riguardanti il filmato. Si tratta di un file binario costituito da elementi
di 68 bytes, uno per ogni frame.
Io leggo da ciascuno di questi la dimensione del frame, calcolo tutto quello
che mi serve, min, max, media, e tutti i dettagli che non sto a menzionarvi
per non seccarvi, e in ultima analisi devo mostrare una specie di
distribuzione di questi frames.
I dieci elementi di cui parlavo sono (in realtà 2x10):
10 elementi rappresentativi dei frames + piccoli della media con passo di
10%
10 elementi rappresentativi dei frames + grandi della media con passo del
50%
Non posso poggiare su un database, o meglio il database ce l'ho già ed è il
file binario .stats da cui leggo le info
Per graficare uso una picturebox e il comando line. Mi serviva trovare
l'elemento + grande della seconda serie per scalare opportunamente la
picture, e poi disegnare la curva.
Il fatto è che mi sono arreso non riuscendo a trovare una maniera decente di
fare la curva siggh...
per calcolare i frames massimo e minimo me ne sono uscito molto
spartanamente inserendo nel mio loop un banale:
            If maxFS < newRecord.FrameSize Then
                maxFS = newRecord.FrameSize
            End If
            If newRecord.FrameSize < minFS And newRecord.FrameSize <> 0 Then
                minFS = newRecord.FrameSize
            End If
FS = frame size ;)
Grazie a tutti per la collaborazione davvero.
Avete idea di dove possa trovare informazioni su come costruire una
gaussiana? grazie

 anch'io...
Vabbe' allora ditelo che cercate il pelo... l'ho detto che ho
buttato lì quattro righe. :-P
Un Paperino "ma come cacchio ho fatto a sparare quell'as long..." :-(

       Debug.Print "controllo effettuato - " & Timer
Che dire?
questo controllo č senza dubbio velocissimo...
ma secondo voi mi conviene caricare tutto il file in un arrai di cui poi
leggo ad uno ad uno gli elementi?
Considerato che gli elementi come ho detto possono arrivare a 300000 e che
ciascuno č di 68 bytes, non č piů conveniente dal punto di vista della
memoria leggere il file in un loop? Rischierei di mandare in crash il proggo
su macchine con poca ram vero?
grassie

su macchine con poca ram vero?
300000 elementi da 68 byte l'uno sono quasi 20MB di ram...
-- 
ciao, hal

 gaussiana? grazie
Attenzione, una gaussiana è un tipo particolare di curva, che
rappresenta dei dati che hanno un tipo particolare di distribuzione;
non è detto che la curva che devi disegnare tu si riveli una gaussiana.
Ipotizza (tanto per "morenosirrare" un po' ;-) ) di avere un filmato
con tutti fotogrammi neri o tutti bianchi, i dati avranno tutti lo
stesso valore, quindi graficamente saranno tutti sullo stesso punto.
Immagina un filmato con metà dei fotogrammi neri e metà bianchi,
avrai due punti separati e basta... e via dicendo.
Forse (e dico forse, non conosco i dati che usi) hai bisogno di fare
un istogramma delle frequenze dei valori che trovi, qualcosa tipo
questo (usa un font fisso per vedere) ?
                     **
                  *******
                ************
             *****************
            *******************
           *********************
          ***********************
          ***********************
         *************************
       *****************************
    ***********************************
*******************************************
oppure la sola curva di questo tipo ?
                     **
                  *      *
                *          *
             *               *
            *                 *
           *                   *
          *                     *
          *                     *
         *                       *
       *                           *
    *                                 *
*                                         *
In questo caso ti basta ottenere dai dati che hai un array
dei valori che ricadono entro determinate fasce, una per
ogni punto della curva, scalare i dati a misura della picture,
e tracciare le linee. Nel caso posta qualche riga dei dati
e spiega come li decodifichi.
P.S.: hai pensato ad un controllo MSChart ?
No sai, non si sa mai... :-)
Bye, G.

 leggo ad uno ad uno gli elementi?
Solo se devi usare tutti i dati di quei 68 bytes, IMHO potrebbe
convenirti. Come dice giustamente Hal è un bel po' di ram
che se ne va (vero però che se vuoi lavorare su dei video,
quella macchina ne dovrebbe avere in abbondanza...).
Altrimenti, sì, crei un UDF (Type) che contenga quei 68 bytes,
leggi i dati dal file con la classica Get, decodifichi e metti
nell'array solo quello che ti serve e poi fai il controllo e tutte
le statistiche che vuoi. In teoria, potresti anche fare una
lettura da file ogni tipo di dati (o a gruppi, magari), ma non
so quanto ti convenga... Ancora meglio, fare le statistiche
_mentre_ leggi dal file, e questo è sicuramente il metodo
più leggero, perché non hai bisogno di occupare memoria
tranne quella degli array dei risultati.
Bye, G.

"hal1961"
Va bene fare le ore piccole, ma tu... che ore fai ? ;-)
Bye, G.

questo (usa un font fisso per vedere) ?
                     **
                  *******
                ************
             *****************
            *******************
           *********************
          ***********************
          ***********************
         *************************
       *****************************
    ***********************************
*******************************************
Diciamo che hai colto nel segno. Mi sono espresso male.
L'ideale sarebbe questo:
la grandezza dei frames varia attorno alla media entro un range che io
stabilisco calcolando frame max e min. Io dovrei fare un grafico così fatto:
ascissa: il range: ad esempio da -99 a +500, con sullo zero l'asse che
rappresenta la media
ordinata: densità di frames per valore (es: 30 frames con valore pari al
50%della media, eccetera)
praticamente una cosa così:
http://www.moviemaniac.altervista.org/grafico.htm

Va bene fare le ore piccole, ma tu... che ore fai ? ;-)
Azz... linux mi aveva messo l'orologio un'ora avanti :-(
-- 
un hal che ritorna dal futuro

 e spiega come li decodifichi.
Se lo faccio promettete di non storcere il naso e di non ridere?
Nemeno sotto i baffi, la mia autostima ne risentirebbe moltissimo, sono già
giù di corda :(
O almeno gradirei che mi citaste come quello che più di tutti vi ha fatto
ghignare :D
Here we go:
il record è definito come segue:
Type frameRec
    FrameSize As Long 'dimesine del frame, è quello che ci interessa!!!
    dk_v As Long
    dk_u As Long
    dk_y As Long
    dd_v As Long
    dd_u As Long
    dd_y As Long
    mk_u As Long
    mk_y As Long
    md_u As Long
    md_y As Long
    quant As Long
    kblk As Long
    mblk As Long
    ublk As Long
    Lum_noise As Double
End Type
Tenetevi forte che si ride, qui comincia il mio pastrocchio:
questa function viene richiamata dopo che son state mostrate le statistiche,
e serve solo per disegnare sto benedetto grafico :(
Function ScaleCurve(File As String, Average As Double, Max As Double, Min As
Double)
    Dim undAverage As Double
    Dim eqAverage As Double
    Dim ovAverage As Double
    Dim over(10) As Double
    Dim under(10) As Double
    StatsFile = FreeFile
    Picture1.ScaleWidth = nFrames
    Picture1.ScaleHeight = Max
    Label6.Caption = Picture1.ScaleWidth & " " & ScaleHeight
    Open File For Binary Access Read As StatsFile
    Me.Caption = "Calculating distances from average frame"
    For i = 0 To nFrames - 1
        Seek StatsFile, 5 + 68 * i
        Get StatsFile, , newRecord
 dimensione_del_frame = newrecord.framesize        'lo so che nn mi serve
questo passaggio, l'ho scritto qui solo per chiarire!!!
 ' qui ho tentato di fare una suddivisione in fasce, ma come vedete il mio
metodo spartanissimo fa veramente ridere :D
        If newRecord.FrameSize > Average Then
            If newRecord.FrameSize > (Average * 1.5) Then
                If newRecord.FrameSize > Round(Average * 2, 0) Then
                    If newRecord.FrameSize > Round(Average * 2.5, 0) Then
                        If newRecord.FrameSize > Round(Average * 3, 0) Then
                            If newRecord.FrameSize > Round(Average * 3.5, 0)
Then
                                If newRecord.FrameSize > Round(Average * 4,
0) Then
                                    If newRecord.FrameSize > Round(Average *
4.5, 0) Then
                                        If newRecord.FrameSize >
Round(Average * 5, 0) Then
                                            If newRecord.FrameSize >
Round(Average * 5.5, 0) Then
                                                If newRecord.FrameSize >
Round(Average * 6, 0) Then
                                                    If newRecord.FrameSize >
Round(Average * 6.5, 0) Then
                                                        over(9) = over(9) +
1
                                                    Else: over(10) =
over(10) + 1
                                                    End If
                                                Else: over(0) = over(0) + 1
                                                End If
                                            Else: over(1) = over(1) + 1
                                            End If
                                        Else: over(2) = over(2) + 1
                                        End If
                                    Else: over(3) = over(3) + 1
                                    End If
                                Else: over(4) = over(4) + 1
                                End If
                            Else: over(5) = over(5) + 1
                            End If
                        Else: over(6) = over(6) + 1
                        End If
                    Else: over(7) = over(7) + 1
                    End If
                Else: over(8) = over(8) + 1
                End If
            End If
                ovAverage = ovAverage + 1
        ElseIf newRecord.FrameSize < Average Then
            If newRecord.FrameSize < (Average * 0.9) Then
                If newRecord.FrameSize < (Average * 0.8) Then
                    If newRecord.FrameSize < (Average * 0.7) Then
                        If newRecord.FrameSize < (Average * 0.6) Then
                            If newRecord.FrameSize < (Average * 0.5) Then
                                If newRecord.FrameSize < (Average * 0.4)
Then
                                    If newRecord.FrameSize < (Average * 0.3)
Then
                                        If newRecord.FrameSize < (Average *
0.2) Then
                                            If newRecord.FrameSize <
(Average * 0.1) Then
                                                under(0) = under(0) + 1
                                            Else: under(1) = under(1) + 1
                                            End If
                                        Else: under(2) = under(2) + 1
                                        End If
                                    Else: under(3) = under(3) + 1
                                    End If
                                Else: under(4) = under(4) + 1
                                End If
                            Else: under(5) = under(5) + 1
                            End If
                        Else: under(6) = under(6) + 1
                        End If
                    Else: under(7) = under(7) + 1
                    End If
                Else: under(8) = under(8) + 1
                End If
            Else: under(9) = under(9) + 1
            End If
            undAverage = undAverage + 1
        ElseIf newRecord.FrameSize = Average Then
            eqAverage = eqAverage + 1
        End If
        ProgressBar1.Value = i
        DoEvents
    Next i
    'Next j
    Close StatsFile
    Picture1.Line (0, Picture1.ScaleHeight - Average)-(nFrames,
Picture1.ScaleHeight - Average), &HFF00&
    Text1(32) = undAverage
    Text1(33) = eqAverage
    Text1(34) = ovAverage
    Text2.Text = "Over 550: " & over(10) & vbCrLf & "Over 500: " & over(9) &
vbCrLf & "Over 450: " & over(0) & vbCrLf & "Over 400: " & over(1) & vbCrLf &
"Over 350: " & over(2) & vbCrLf & "Over 300: " & over(3) & vbCrLf & "Over
250: " & over(4) & vbCrLf & "Over 200: " & over(5) & vbCrLf & "Over 150: " &
over(6) & vbCrLf & "Over 100: " & over(7) & vbCrLf & "Over 50: " & over(8) &
vbCrLf & under(0) & vbCrLf & under(1) & vbCrLf & under(2) & vbCrLf &
under(3) & vbCrLf & under(4) & vbCrLf & under(5) & vbCrLf & under(6) &
vbCrLf & under(7) & vbCrLf & under(8) & vbCrLf & under(9)
    Me.Caption = "Maniac® ""little"" Stats editor"
End Function
Ma me so ncartato e non riesco a vedere la luce :(
Sarà pure l'ora :(

 
http://www.moviemaniac.altervista.org/grafico.htm
P.S. ci ho messo anche il programma che sto realizzando e un piccolo file
stats, circa 8000 framse (solo 37K zippato) per i piů curiosi.
Ma temo che domattina non ve ne sbatterŕ giŕ nulla, presi come sarete dai
vostri lavori :D
Ciao a tutti, notte!

 vostri lavori :D
Beh, intanto li ho tirati giù, ma ora proprio non li guardo...
io domattina devo stare qui alle 10, e per lavorare :-))
Appena posso, magari.
Un Paperino "...e che cos'è MMATS ?".

 Un Paperino "...e che cos'è MMATS ?".
Il MMAAT è il mio vero e proprio programma. E' stato con quello che ho
iniziato a smozzicare qualcosina di VB, ed è stato per quello che spesso ho
rotto qui sul NG
e magari Lupo si ricorda il tread lunghissimo sui database protetti con
password, così come CSSoft e altri si ricordano altri post (sono tutti nei
credits).
Se sei così curioso, allora dalla home del mio sito, la trovi in quel link
(basta togliere la pagina grafico.htm, vai nella sezione downloads e
scaricalo. E' una raccolta di tool in continuo "movimento":D
Ciao notte
Io domani devo consegnare un progetto, trattasi di un PEC (Piano esecutivo
Comunale). Roba di piano regolatore :D
Ciao e grazie mille

 Appena posso, magari.
Se poi sei proprio cosě "pazzo" da perdere tempo apresso a me posso passarti
anche il sorgente :D
Ciao

 metodo spartanissimo fa veramente ridere :D
mi soffermo su questo:

puoi risolvere il tutto cosě:
Dim idx As Long
idx = Int(10 * (newRecord.FrameSize / Average))
If idx > 9 Then idx = 9
under(idx) = under(idx) + 1
puoi estendere il concetto anche per l'array over()
con risparmio di codice e vanataggio in termini di prestazioni
termoPilucco.

 ha scritto nel messaggio

Ma tutto questo č... MOSTRUOOOOOOOOOOSOOOOOOOOOO :D
Grazie mille "Termo..."
E dire che mi ero ammazzato per tenere il conto degli if annidati :)
Quanto hai riso quando hai visto il codice?
Ciao

 Quanto hai riso quando hai visto il codice?
naaa... lavoro su codice scritto molto peggio.
termoPilucco

 ha scritto

Azz, c'č di peggio del mio codice?
Ciao ;)

 matematica
Giusto per tua soddisfazione personale, ti dico che solo con questa
ottimizzazione, l'exe passa da 170 a 104 KB.
Niente male no? :D
Ciao

 Niente male no? :D
Eheh.. se  utilizzi spesso la funzione vedrai miglioramenti anche nelle
prestazioni:
prima facevi da 1 a 9 moltiplicazioni per ogni chiamata, adesso fai una
divisione e una moltiplicazione.
termoPilucco



se ruoti il monitor, alla gaussiana un pochino assomiglia... :-)


 se ruoti il monitor, alla gaussiana un pochino assomiglia... :-)
Cazz, vero :D
Non ci avevo fatto caso, mo faccio una picturebox e ci scrivo dentro il
codice rovesciato :D
Ciao