Aplicatie Pentru Predictie de Date

Serii de timp

Predicția unei valori a unei variabile la un anumit moment de timp in viitor este numită prognoză. Prognoza meteo este un exemplu concludent al acestui tip de strădanie: Ce temperatură va fi mâine la ora 12 ziua? O întrebare similară legata de afaceri este si aceasta: Care va fi prețul de închidere, mâine, al acțiunilor companiei „Microsoft”? Mulți dintre noi vor paria probabil pe faptul că persoana care face prognoza meteo face un lucru mai bun decât un om de afaceri sau un economist când prognozează un preț pe acțiune, deși in multe cazuri, prognozele meteo, chiar și acelea făcute de persoane avizate, pot fi greșite. Schimbări neanticipate in condițiile atmosferice fac ca prognozele meteo sa nu fie exacte, la fel si cum variații neașteptate in mediul economic afectează prognozele economice.

Cu toate acestea, prognoza este baza activităților economice si a legăturilor de afaceri. Rezerva de bani pentru următoarele doua luni, prețul grâului in octombrie care a fost recoltat in iulie, cererea de prăjitoare de pâine in preajma sărbătorilor de iarnă, numărul persoanelor angajate din Chicago in anul viitor; toate acestea sunt date necesare unor persoane sau măcar ar trebuie să poată sa le prognozeze cu ceva acuratețe. Metodele de prognoză includ flerul unei singure persoane, opinia comună a mai multor experți bazată pe experiența lor și ieșirea unui model matematic care folosește ca intrare date înregistrate anterior. În mod ideal, se poate presupune că un grup de experți, ce au la îndemână o bază de date înregistrată anterior, o experiență îndelungată in economie și o abilitate in afaceri, poate face niște prognoze foarte exacte. Cu toate acestea, se știe ca astfel de grupuri de experți nu sunt infailibile. Totuși, prognoza trebuie făcută și se pare că experții sunt cei care ar trebui să o facă.

Pentru a prognoza rezerva de bani ar trebui să fi un economist cu experiență; pentru a prezice cererea pentru un nou produs ar trebui să ai experiență in studierea pieței, pentru a prognoza trendul acțiunilor la bursă ar fi trebuit să fi studiat in prealabil piața. În timp ce nimeni nu poate să înțeleagă totul despre problemele care pot apare la generarea prognozelor, sunt câteva principii comune pentru toate tipurile de prognoze care pot fi învățate de oameni care nu sunt experți in domeniul in care se va face predicția. Un minim necesar care ar trebui știut pentru a face o prognoză este constituit din câteva lucruri despre serii de timp și caracteristicile lor.

O serie de timp este o secvență de observații a unor valori făcute la același interval de timp asupra unei anumite variabile.

O serie de timp, prin definiție, este, neapărat, un set de date înregistrate anterior. Valorile variabilei trebuie observate pentru a fi înregistrate și nu se poate observa o valoare viitoare. Dar ,uneori, trecutul poate fi folositor pentru viitorul imediat, și de aceea, seriile de timp sunt informații vitale pentru cei care fac prognoze.

Studiul unei seri de timp începe prin recunoașterea a patru componente, toate sau unele, fiind prezente in secvența de date colectată in timp. Acestea sunt: componenta de direcție, componenta de perioadă, componenta de ciclicitate și componenta aleatoare.

Componenta de direcție indică tendința pe o perioadă de timp lungă, și poate fi rezultatul schimbărilor în cadrul populației, inflației, politicilor guvernamentale de reglementare, sau alți factori care produc schimbări graduale în timp. Direcția generală a unei serii de timp este de obicei componenta de bază a unei prognoze, dar acel număr de bază va fi ajustat pe baza celorlalte componente.

Componenta ciclică este asociată cu așa-numitul ciclu de afaceri, dar asta nu înseamnă că este regulat. Vânzările unui obiect de lux, cum ar fi un video-recorder, cresc intr-o perioadă de dezvoltare economică și poate scădea intr-o perioadă de recesiune. Când dobânzile sunt mari, vânzările pot descrește, și așa mai departe. Acest efect ciclic este greu de prezis cum este și greu de prognozat momentul apariției unei recesiuni sau a unei scăderi a dobânzii, dar acest ciclu economic există. Componenta ciclică a unei serii de timp încearcă să contracareze efectul acestui ciclu economic.

O componentă care poate fi prognozată cu o mai mare acuratețe este componenta periodică. În timp ce ciclul economic, dezvoltare – recesiune – dezvoltare, se poate produce, să zicem, la 5 ani, componenta periodică este un fenomen anual. (și astfel ea nu va fi prezentă intr-o serie de timp unde intervalul între observații este de un an sau mai mult). Vânzările la multe tipuri de bunuri de consum tind să fie la cel mai mare nivel în lunile noiembrie și decembrie și cele mai mici în ianuarie și februarie. Produse ca rachetele de tenis sau undițele pot atinge cota maximă de vânzări vara și cota minimă iarna. Cererea de locuri de muncă este cea mai mare vara când studenții își caută locuri de muncă temporare. Componenta periodică este cea mai ușor de prognozat dintre toate componentele. De fapt, predictibilitatea sa este ceea ce o deosebește de componenta ciclică.

Cea mai greu de prezis componentă este cea aleatoare. Este analogă „erorii” intr-un model de regresie. Este sursa variației ramase după ce au fost considerate contribuțiile tuturor celorlalte componente. Această componentă este rezultatul forțelor neregulate, de durată mică, ale căror cauze sunt prea complexe sau prea puțin înțelese pentru a fi modelate matematic. Dacă componenta aleatoare este mare în comparație cu celelalte componente, duce la a fi imposibil de făcut o prognoză. Dar dacă aceasta este nesemnificativă în comparație cu celelalte se poate face o predicție corectă bazată pe seria de timp.

Direcția, periodicitatea și componenta ciclică sunt deseori numite componente sistematice ale seriei de timp, ceea ce un inginer electronist ar numi semnal, în timp ce componenta aleatoare este analogă zgomotului. Obiectivul predicției cu serii de timp este de a filtra zgomotul și de a face o predicție a semnalului în viitor.

Exemplul 1

Contemporary Electronics promovează un brand de calculatoare personale. Vănzările lunare, în mii de unității, sunt afișate pentru o perioadă de 4 ani in tabelul 1. Această serie de timp de 48 de luni are graficul in figura 1.

O scurtă inspecție a seriei de timp desenată in figura 1 denotă prezența a cel puțin trei din cele patru componente. Vânzările tind să ajungă la un nivel ridicat la sfârșit de an și apoi să scadă drastic la începutul anului ce urmează, din care rezultă prezența unei componente periodice. Faptul că felul variațiilor se schimbă de la an la an, aceasta implică și prezența unei componente aleatoare.

Tabelul 1: Vânzări lunare pe anii 1980 – 1983

Știind că economia a avut o perioadă de recesiune în anii 1981 și 1982 dar și-a revenit în 1983, se ajunge la concluzia că este prezentă și o componentă ciclică ce reflectează condițiile generale în care se desfășurau activitățile economice. De fapt, această componentă pare să aibă cea mai mare influență asupra vânzărilor.

Figura1: Vânzări lunare

Doar prin simpla observare a graficului se poate detecta foarte greu o direcție regulată (în afară de tendința datelor de a urmării ciclul economic). Dacă se folosește regresie liniară simplă, direcția ar fi reprezentată de o linie ascendentă gradual. Dacă totuși, seria de timp s-ar fi oprit la sfârșitul anului 1982, direcția estimată ar fi fost o linie-treaptă descendentă.

Seria de timp înfățișată in tabelul 1 și graficul 1 au fost găsită în felul următor. O „direcție” sau un „nivel dorit” a fost desenat, apoi s-a suprapus un model periodic, a fost desenată apoi o curbă care reprezintă ciclul economic, și apoi au fost incluse si variații aleatoare. Apoi au fost adăugate vânzările asociate fiecărei componentă pentru a produce seria de timp finală. Curbele asociate componentelor sunt înfățișate in figura 2.

Figura 2: Componentele seriei de timp din fig.1

Cele patru componente din figura 2 nu ar putea fi văzute pentru un set de date real; tot ce s-ar putea vedea ar fi seria de timp prezentată in figura 1. Pentru a face o prognoză trebuie totuși identificate direcția, componenta ciclică și cea periodică. De exemplu, dacă s-ar putea stabili o direcție generală, ar fi posibilă ajustarea direcției pentru componenta periodică (stabilirea unui index periodic este una din căi). Apoi, dacă ar fi găsită componenta ciclică ar putea fi comparată cu un grafic al ciclului economic pentru a vedea dacă urmărește acest grafic sau are tendința de a anticipa sau a rămâne în urmă. Astfel de informații ar fi foarte folositoare pentru a alcătui o prognoză.

Medii alunecătoare

Un mod de a estima direcția generală este de a aplica o analiză regresională asupra seriei de timp. Pentru a face acest lucru ar trebui totuși să particularizăm prin folosirea unui model liniar sau exponențial care sa dea direcția. Astfel am face o presupunere care s-ar putea dovedi greșită. Un mod de a evita astfel de presupuneri este utilizarea mediilor alunecătoare.

Se folosesc mediile alunecătoare pentru a netezi seria de timp în scopul observării mai ușoare a direcției. Astfel de medii sunt calculate folosind un număr fix de unități de timp, și făcând media succesiv pe acel interval, pentru fiecare medie mutându-se intervalul cu o unitate. Acest proces care pare complex la prima vedere este de fapt foarte simplu. Exemplul 2 ilustrează procesul determinării unei medii alunecătoare.

Exemplul 2

Se cosideră datele din primele 7 luni care apar in tabelul 1. Vom obține trei medii alunecătoare pe o perioadă de câte cinci luni.

Aceste medii, aflate la mijlocul intervalului folosit pentru calcularea lor (luna din mijocul intervalului de cinci luni) sunt arătate in tabelul 2.

Tabelul 2: Medii pe cate 5 luni

Cum fiecare din medii este calculată pe un interval de 5 luni, ele nu variază așa de mult ca valorile din fiecare lună, ele tind să netezească datele de intrare. Se vede cum următoarea medie calculată nu mai folosește prima valoare folosită la calculul precedent si adaugă următoarea valoare din serie care nu a fost folosită. Astfel trei numere (din cele cinci) sunt utilizate din nou la calculul mediei următoare.

Să presupunem că se dorește determinarea direcției unei serii de timp cu componentă periodică prin utilizarea mediei alunecătoare. Pare rezonabilă folosirea unei medii pe 12 luni astfel încât fiecare medie să conțină câștigul pe un an întreg la fiecare lună. Singura problemă este că nu există o lună de mijloc pentru a fi asociată cu media (pică exact intre luni numărul de 12 luni fiind par). Pentru a rezolva această problemă vom face media a două medii alunecătoare adiacente, calculând o medie alunecătoare centrată care pică exact într-o lună din seria de timp originală. Acest proces ușurează desenarea punctelor ce reprezintă mediile și tragerea unor concluzii pe baza graficului asupra direcției.

Exemplul 3

Se va calcula toate mediile alunecătoare pe intervalul de 12 luni pentru datele privind vânzările din tabelul 1 și vor fi prezentate în tabelul 3. Prima medie este a valorilor din luna ianuarie până în decembrie anul 1980.

Tabelul 3: Mediile pe 12 luni si mediile centate.

Dacă s-ar fi desenat punctul asociat primei medii ar fi fost undeva între iunie și iulie 1980, pe când a doua medie ar fi căzut între iulie și august. Dar media primelor două medii alunecătoare, media alunecătoare centrată, ar fi asociată lunii iulie, pe când media celei de-a doua și a treia medie ar fi asociată lunii august. Astfel

Continuând astfel se determină toate valorile din tabelul 3.

Efectul de netezire al mediei alunecătoare se vede cel mai bine pe graficul asociat. Seria de timp originală cu date despre vânzările companiei Contemporary Electronics și mediile alunecătoare centrate sunt înfățișate în figura 3.

Figura 3: Mediile alunecătoare centrate

Mediile alunecătoare centrate sunt asociate cu o combinație a direcției și a componentei ciclice, așa cum se vede si pe figura 3.l asociat. Seria de timp originală cu date despre vânzările companiei Contemporary Electronics și mediile alunecătoare centrate sunt înfățișate în figura 3.

Figura 3: Mediile alunecătoare centrate

Mediile alunecătoare centrate sunt asociate cu o combinație a direcției și a componentei ciclice, așa cum se vede si pe figura 3. Se observă caracterul de netezire rezultat în urma medieri centrate.

Netezire exponențială

Un dezavantaj al folosirii mediei alunecătoare este imposibilitatea asocierii fiecărei medii la un punct din seria originală. În tabelul 3 se poate vedea că nu există o medie centrată pentru primele 6 luni și pentru ultimele 6 luni. Dacă direcția indicată de modul de netezire este folosit la prognoză, atunci media alunecătoare nu este potrivită din moment ce nu se poate ști direcția în zona finală. Mai mult, media alunecătoare nu conține toate informațiile disponibile în seria de timp referitoare la datele dinaintea momentului asociat mediei. (observațiile datelor seriei de timp îndepărtate nu sunt reflectate în valoarea mediei). O procedură care nu are nici unul din dezavantajele de mai sus este metoda netezirii exponențiale.

Metoda netezirii exponențiale a devenit cunoscută ca o metodă de prognoză pentru o mare categorie de serii de date. Metoda a fost dezvoltată independent de către Brown și Holt. Brown lucra pentru Marina Statelor Unite în al doilea război mondial, unde trebuia să conceapă un sistem de urmărire pentru submarine. Mai târziu a aplicat această tehnică pentru a face o predicție a cererii de piese de schimb (o problema de control de inventar). A descris aceste idei în cartea sa din 1959 despre controlul inventarului. Cercetarea efectuată de Holt a fost sponsorizată de Biroul Cercetării Navale; în mod independent, el a dezvoltat modele netezite exponențial pentru procese constante, procese cu direcții lineare și date periodice.

Gardner a propus o clasificare unitară a metodelor de netezire expoențială.

Atât metoda cât și motivele folosirii acestui proces sunt ușor de înțeles. Ideea este de a lua în calcul toate observațiile anterioare cât și cele mai recente, dar se atribuie o pondere fiecărei valori astfel încât unei valori foarte îndepărtate i se atribuie o pondere foarte mică. Acest proces devine foarte ușor de înțeles dacă se observă că se folosește o ecuație recursivă la care s-a stabilit o anumită pondere w.

Fie y1 prima valoare din serie, y2 a doua, și așa mai departe, astfel încât yt este a t valoare. Fie St valoarea netezită la momentul de timp t. Se alege o pondere w 0 w 1, și fie

și

unde St-1 este valoarea netezită la momentul de timp t-1. Astfel

și așa mai departe. Cum 0 w 1, y1 are din ce în ce mai mică ponderea în fiecare din calculele lui St așa cum se întâmplă și cu y2 și toate celelalte valori ale lui y. Valoarea inițială aleasă pentru w dă ponderea în calculul termenului S, pentru fiecare y, și aceste ponderi devin pentru un y dat, din ce în ce mai mici pe măsură ce se depărtează de termenul S.

Calculele sunt făcute totuși cu ecuația de bază

nu cu termenii individuali y. Exemplul 4 ilustrează acest proces.

Exemplul 4

Se consideră seria de timp y1 = 5, y2 = 8, y3 = 10, y4 = 9, y5 = 7. Valorile netezite corespunzătoare folosind w = 0.4 sunt:

Tot ceea ce este necesar pentru orice valoare netezită exponențial este ponderea w, termenul curent y și termenul anterior S.

„Arta” acestei metode stă în alegerea valorii ponderii w. Dacă w = 0.1, de exemplu, atunci 1 – w = 0.9 și valoarea anterioară are o pondere mult mai mare decât valoarea curentă, implicând faptul că se pune mare importanță pe valorile trecute. Dacă w=0.9 atunci 1-w = 0.1 rezultând faptul că valorile foarte recente sunt importante datele anterioare pierzându-se în calcul. O regulă de bază care poate fi trasă de aici este: Dacă seria este regulată, cu puține variațiuni aleatoare, atunci o valoare mică a lui w va face ca datele anterioare să conteze în calculul valorii curente a lui S, în timp ce, pentru o serie cu multe iregularități, o valoare mare aleasă pentru w va pune accentul pe valorile imediat precedente ale lui S.

Exemplul 5

Pentru a ilustra metoda netezirii exponențiale și pentru a vedea cum arată o astfel de serie după acest procedeu, se va considera o serie de vânzări înregistrate la fiecare 3 luni timp de 8 ani, reprezentând vânzările de lichior din statul Wyoming. Datele, împreună cu valorile netezite exponențial sunt date în tabelul 4, iar în figura 4 sunt desenate aceste serii. S-a folosit o pondere de w=0.3.

Tabelul 4: Vânzările de lichior în statul Wyoming pe sferturi de an pentru anii 1975-1982

Figura 4: Vânzările de lichior și seria netezită exponențial

Seria de timp ce redă vânzările de lichior, desenată în figura 4, pare să fie foarte ușor de prognozat. În fiecare an, în ultimul sfert, compania înregistrează cele mai mari vânzări, care apoi au o decădere pregnantă în primul sfert din următorul an. Direcția, ușor de observat din seria netezită exponențial, este în mod regulat ascendentă, cu un model anual ce se repetă în fiecare an. Totuși în anul 1982 vânzările par să înregistreze o cădere față de direcția preconizată printr-o metodă de regresie liniară. Valorile obținute prin netezire exponențială înfățișează această schimbare de direcție și astfel poate sta la baza unei prognoze corecte.

Modelul seriei de timp multiplicative

Analiza seriilor de timp deseori presupune că fiecare componentă este un factor (un multiplicator) al valorii observate. Fie Yi a i-a valoare observată, și Ti, Si Ci și Ri respectiv direcția, perioada, factorul de ciclicitate și cel aleator, modelul multiplicativ al unei valori observate este

Folosind acest model nu însemnă că termenii seriei sunt rezultatele acestor înmulțiri specifice, dar poate furniza o idee asupra structurii seriei.

Analiștii seriilor de timp sunt adesea interesați de descompunerea unei serii. Această descompunere este uneori realizată folosind fracții. De exemplu, se presupune că s-a estimat o serie combinată care redă componenta de direcție și cea ciclică. Apoi se pot folosi estimările, ca divizori formând fracții de genul . Cum în modelul multiplicativ reprezintă se poate identifica fracția rezultată ca fiind sau un efect combinat din componenta periodică și cea aleatoare.

În mod evident, cheia acestui tip de analiză este folosirea unui model multiplicativ.

Prognoză

Scopul discuției din capitolul precedent a fost acela de a introduce seriile de timp și componentele lor, cât și de a prezenta câteva metode de netezire a datelor utile în a identifica direcții și cicluri. Se poate merge mai departe acum prin extinderea acestor noțiuni care vor fi folosite în procesul de predicție.

Sunt foarte multe procedee de prognozare bazate pe serii de timp. Se vor prezenta aici: indici periodici, prognoză folosind netezire exponențială, modele autoregresive.

Indici periodici

Un index periodic lunar (sau la trei luni) încearcă să înregistreze fluctuațiile lunare (sau la trei luni). De fapt acești indici sunt valorile medii ale raportului , raport ce a fost descris în capitolul anterior. Atunci când sunt medii alunecătoare rapoartele se numesc raport al mediei alunecătoare. Caracterul de medie al acestor rapoarte este în sensul de valoare mediană ponderată. Cel mai ușor de înțeles acest lucru este de a folosi un exemplu.

Exemplul 6

Se va face referință la datele privind vânzările companiei Contemporary Electronics din exemplul 1 și tabelul 1 ce conține datele originale Yi și mediile alunecătoare centrate . Vom calcula 12 indici periodici pentru fiecare lună a anului (tabelul 5).

Tabelul 5: Calcularea indicilor periodici

Primele patru coloane din tabel numite „rapoarte anuale” sunt de fapt rapoarte ale mediilor alunecătoare. Apoi în următoarea coloană este raportul median, raportul mediu în mărime din cele trei rapoarte disponibile pentru fiecare lună. Raportul median ar trebui să redea media efectului periodic, eliminând rapoartele cele mai mari și cele mai mici. Raportul median ar fi un indice periodic nimerit dar de obicei se mai face încă un pas. Se observă că suma rapoartelor mediene din tabelul 6 este 11.865. Pentru a calcula un set de 12 indici și suma lor să fie 12 se folosește relația

Se observă că indicii din ultima coloană adunați dau 12.001 dar acest lucru se întâmplă din cauza rotunjirilor.

Exemplul 7

Acum după ce s-au stabilit indicii (lunari) periodici se va încerca să se facă o prognoză a vănzărilor pe următoarele 6 luni. Pentru a face aceasta trebuie să se extindă curba sugerată de media alunecătoare centrată pentru a se stabili o direcție pentru valorile viitoare. Prognoza va fi atât de exactă cât este și „ghicirea” direcției, chiar și ajustată cu ajutorul indicilor periodici.

Dacă se presupune că ciclul economic și-ar putea stinge urcarea până la sfârșitul anului 1984, dar continuă totuși să crească, se poate considera ca direcția va crește de la 9.0 la 10.0 în primele șase luni ale anului 1984. Apoi se va folosi indicele periodic ca multiplicator pentru a obține prognozele lunare. Aceste prognoze, alături de vânzările reale în primele șase luni (obținute prin extinderea curbei din figura 2) sunt prezentate în tabelul 6.

Tabelul 6: Prognoza pe 6 luni folosind indicii periodici

În acest caz nu se poate vedea cât de bune sunt prognozele, deoarece atât valorile reale ale vânzărilor cât și direcția au fost determinate arbitrar. Exemplul a fost dat doar pentru a ilustra metoda indicilor periodici.

Predicție folosind netezire exponențială

După ce am discutat mai pe larg această metodă în capitolul precedent se poate trece direct la ecuația recursivă ce face predicția prin netezire exponențială. Fie

unde Ft este valoarea prezisă la momentul de timp t (ceea ce se vrea determinat) At-1 este valoarea reală observată la momentul t-1, Ft-1 este valoarea prezisă la momentul t-1 și W este binențeles ponderea aleasă. Când se folosește netezirea exponențială, este indicată de către specialiști utilizarea unei valori care să nu depășească 0.3.

Acest tip de prognoză va furniza un singur număr, valoarea prezisă pentru următoarea perioadă de timp, bazată pe ultima valoare prezisă și pe ultima observație. De exemplu, vom pondera valoarea prezisă pentru Aprilie cu cea observată pentru Aprilie pentru a rezulta valoarea prezisă pentru Mai. După ce se face observația valorii reale pentru Mai, se poate face o predicție pentru cea din iunie și așa mai departe.

Exemplul 8

Se va folosi datele privind vânzările de lichior conținute în tabelul 4 ca bază pentru prognoza din acest exemplu. Ținând seama că aceste date sunt cât se poate de reale se va observa cât de bună este o astfel de metodă de predicție. Pentru a face acest lucru, trebuie știute valorile reale ale vânzărilor de lichior pentru a face comparație. Se va folosi datele achiziționate pe anul 1980 ca bază pentru prognoza anilor 1981 și 1982.

Se observă în figura 4 direcția și efectele periodice până spre sfârșitul anului 1980. Se poate folosi valoarea vânzărilor de pe ultimul interval de 3 luni din anul 1980, 11.3 și ca valoare prezisă, valoarea netezită exponențial în exemplul 5. Apoi, folosind W = 0.2 valoarea prognozată pentru primul sfert de an din 1981 este

Apoi, după ce se face înregistrarea vânzărilor din primul sfert din 1981 de doar 6.8 milioane se face prognoza pentru al doilea sfert de an

Calcule similare dau rezultatele din coloana „prognoza netezita” în tab. 7.

Tabelul 7: Prognoze folosind netezirea exponențială ajustată periodic

Valorile obținute în această coloană nu sunt în întregime satisfăcătoare. Se pare că pot prezice foarte bine direcția generală a vânzărilor dar nu reflectă și efectele periodice care sunt prezente în această serie de timp. Cu toate astea pot fi buni indicatori ai direcției și se pare că pentru date fără componente periodice această metodă oferă o prognoză adecvată ce netezește efectele variației aleatoare.

De vreme ce se știe de prezența componentei periodice în vânzările de lichior ale statului Wyoming, pare indicată ajustarea direcție cu ajutorul indicilor periodici. Se pot folosi datele din anii 1976 până în 1980 pentru a stabili indicii periodici (anul 1975 este considerat ca bază pentru curba netezită și nu ar putea furniza rapoartele corect). Acești indici, prognozele netezite, prognozele ajustate cu indicii periodici pentru anii 1981 și 1982 și valorile reale ale vânzărilor sunt prezentate în tabelul 7. Se poate observa calitatea prognozelor în figura 5.

Figura 5: Prognoza vânzărilor de lichior pe perioade de câte 3 luni

Prognozele netezite exponențial și ajustate pe baza indicilor periodici sunt foarte aproape de valorile reale ale vânzărilor în toate cele 8 perioade pentru care au fost făcute. Se vede, de asemenea, că valorile prognozate nu mai indică o direcție ascendentă, cum s-a sugerat în figura 5, ci arată faptul rămân la un nivel constant ba chiar au o descreștere spre sfârșitul anului 1982. Astfel, am obținut prognoze foarte bune pentru fiecare din intervalele de cate 3 luni ca și schimbarea de direcție a vânzărilor.

Modele autoregresive

Economiștii folosesc modele autoregresive pentru prognoze când există corelații între valorile lui y separate prin perioade de timp fixe. De exemplu, dacă se bănuiește că valoarea observată acum este legată cu cea observată cu două perioade de timp în urmă, se poate exprima acest lucru prin modelul

De fapt s-a folosit un model de regresie obișnuit dar variabila x este o valoare anterioră a lui y. Pentru un alt exemplu, dacă yt depinde de valoare anterioară a lui y cât și de cea cu 12 luni în urmă, se va scrie

Astfel de modele autoregresive au avantajul autocorelării datelor dar și cel al ușurinței în analiza regresională pentru predicții.

Exemplul 9

Datele conținute în tabelul 8 reprezintă veniturile din vânzări și din taxe, în milioane de dolari, pe intervale de câte 3 luni, pe anii 1978 – 1982. Se va folosi datele aparținând anilor 1978 – 1980 și se va face o prognoză a câștigurilor de pe anii 1981 și 1982 utilizând modelul autoregresiv. Deci, se va folosi datele înregistrate de pe trei ani pentru a prognoza veniturile pe următorii doi ani, care se cunosc de altfel, și se va face o comparație pentru a vedea cât de bună a fost predicția.

Tabelul 8: Venituri din vânzări și taxe în statul Wyoming

La o simplă inspecție a datelor din tabelul 8 nu se observă o componentă periodică pregnantă, dar se vede o asemănare a valorilor adiacente. Se mai observă că valorile pentru aceași perioadă dar în ani diferiți sunt, de asemenea, corelate. De aici rezultă următorul model autoregresiv

În tabelul 9 se observă datele folosite pentru estimarea parametrilor ecuației, de la t=5 până la t=12. Coloana „estimări” reprezintă valorile estimate corespunzătoare punctelor folosite în estimarea coeficiențiilor, iar coloana „prognoze” conține prognozele pentru cele opt sferturi ale anilor 1981 și 1982. Aceste prognoze sunt făcute pas cu pas imediat cum datele sunt disponibile pentru anii 1981 și 1982.

Ecuația estimată rezultată este

Tabelul 9: Venituri din taxe: estimări și prognoze

Numerele din coloanele „estimări” și „prognoze” sunt obținute din această ecuație. Seria originală, estimările pentru anii 1979 și 1980, și prognozele pentru 1981 și 1982 sunt desenate în figura 6.

Din figura 6 se vede că ecuația autoregresivă reproduce foarte bine datele din care a fost obținută, cele dinaintea anului 1981. Prognozele din anul 1981, nu sunt departe de valorile reale înregistrate. Dar în anul 1982 s-a înregistrat o cădere serioasă a veniturilor, iar prognozele bazate pe datele din 1978-1980 sunt mult prea mari. De aici se trag următoarele concluzii: pericolul în a extrapola prea departe în afara intervalului de date, și capacitatea modelului autoregresiv ales de a reproduce doar un model anterior înregistrat și incapabilitatea de a anticipa o schimbare.

Dacă prognoza se bazează doar pe date înregistrate anterior, se vor ivi probleme în cazul în care modelul evoluției anterioare diferă de cel actual. Persoana cea mai nimerită să facă o astfel de prognoză ar fi aceea cu experiență în problema respectivă.

Figura 6: Venituri din vânzări și taxe prognozate

Defectul modelului autoregresiv poate fi cauzat de forma particulară a modelului ales și nu neaparat din cauza noțiunii de autoregresie. De exemplu, ceea ce este numit model autoregresiv „naiv” este modelul ce face prognoza pe baza venitului din sfertul de an precedent. Pentru exemplul prezentat mai sus acesta ar fi

și ar parea mai bun decât cel folosit.

Alte metode de predicție

Uneori o bază de date nu este disponibilă, cum ar fi în cazul vănzărilor unui produs nou creat și introdus pe piață. Atunci ar trebui folosite metode ce nu se bazează pe date înregistrate anterior. Prognozele sunt deseori date de către un consiliu de experți sau prin metoda Delphi, ce împlică folosirea unui grup de experți dar evită situații în care majoritatea își spune cuvântul. Metodele studierii pieții, ce implică utilizarea datelor statistice, sunt foarte utilizate, în special la lansarea unor produse noi.

Printre metodele bazate pe colecții de date se mai numără și media alunecătoare ponderată exponențial, netezirea exponențială de ordinul doi, și metoda de predicție Box-Jenkins, aceasta fiind destinată seriilor de timp cu evoluție complexă.

Anexa: Listing-ul aplicației „Forecast”

#if !defined(AFX_CONVERTDLG_H__24E42A24_53D4_4ACD_AD1E_B4B25664284D__INCLUDED_)

#define AFX_CONVERTDLG_H__24E42A24_53D4_4ACD_AD1E_B4B25664284D__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// ConvertDlg.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CConvertDlg dialog

class CConvertDlg : public CDialog

{

// Construction

public:

CConvertDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CConvertDlg)

enum { IDD = IDD_DIALOG_CONVERT };

CString m_strDestination;

CString m_strSource;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CConvertDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CConvertDlg)

afx_msg void OnButtonOpendestination();

afx_msg void OnButtonOpensource();

virtual void OnOK();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CONVERTDLG_H__24E42A24_53D4_4ACD_AD1E_B4B25664284D__INCLUDED_)

// ConvertDlg.cpp : implementation file

//

#include "stdafx.h"

#include "forecast.h"

#include "ConvertDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

#define DEFAULT_TXTEXT _T("txt")

#define DEFAULT_TESTTEXT _T("fcs")

#define DEFAULT_TESTFILENAME _T("MyFile")

/////////////////////////////////////////////////////////////////////////////

// CConvertDlg dialog

CConvertDlg::CConvertDlg(CWnd* pParent /*=NULL*/)

: CDialog(CConvertDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CConvertDlg)

m_strDestination = _T("");

m_strSource = _T("");

//}}AFX_DATA_INIT

}

void CConvertDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CConvertDlg)

DDX_Text(pDX, IDC_EDIT_DESTINATION, m_strDestination);

DDV_MaxChars(pDX, m_strDestination, 1024);

DDX_Text(pDX, IDC_EDIT_SOURCE, m_strSource);

DDV_MaxChars(pDX, m_strSource, 1024);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CConvertDlg, CDialog)

//{{AFX_MSG_MAP(CConvertDlg)

ON_BN_CLICKED(IDC_BUTTON_OPENDESTINATION, OnButtonOpendestination)

ON_BN_CLICKED(IDC_BUTTON_OPENSOURCE, OnButtonOpensource)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CConvertDlg message handlers

void CConvertDlg::OnButtonOpendestination()

{

static char BASED_CODE szFilter[] = "forecast Files(*.fcs)|*.fcs||";

CFileDialog dlg( FALSE,

DEFAULT_TESTTEXT,

DEFAULT_TESTFILENAME,

OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY,

szFilter,

NULL );

if( dlg.DoModal() == IDOK )

{

m_strDestination = dlg.GetPathName();

UpdateData( FALSE );

// m_ctrlSource.SetWindowText( dlg.GetPathName() );

// GetDlgItem( IDC_EDIT_SOURCE )->SetWindowText( dlg.GetPathName() );

}

}

void CConvertDlg::OnButtonOpensource()

{

static char BASED_CODE szFilter[] = "Text Files(*.txt)|*.txt|All Files (*.*)|*.*||";

CFileDialog dlg( TRUE,

DEFAULT_TXTEXT,

NULL,

OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,

szFilter,

NULL );

if( dlg.DoModal() == IDOK )

{

m_strSource = dlg.GetPathName();

UpdateData( FALSE );

// m_ctrlSource.SetWindowText( dlg.GetPathName() );

// GetDlgItem( IDC_EDIT_SOURCE )->SetWindowText( dlg.GetPathName() );

}

}

void CConvertDlg::OnOK()

{

UpdateData( TRUE );

if( m_strDestination.IsEmpty() || m_strSource.IsEmpty() )

{

AfxMessageBox( _T("Missing File !!!") );

return;

}

CStdioFile sf( m_strSource, CFile::modeRead );

CPointArray arPoint;

CString strLine;

while( sf.ReadString( strLine ) )

{

TRACE( strLine + _T("\n") );

if( strLine.IsEmpty() )

continue;

int nPosition = strLine.Find( ' ' );

if( nPosition > 0 )

{

CString str;

str = strLine.Left( nPosition );

str.TrimLeft();

str.TrimRight();

int x = atoi( (LPCTSTR)str );

strLine = strLine.Right( strLine.GetLength() – nPosition – 1);

strLine.TrimLeft();

strLine.TrimRight();

int y = atoi( (LPCTSTR)strLine );

CPoint point( x, y );

arPoint.push_back( point );

}

else

{

AfxMessageBox( _T("Bad File !!!") );

arPoint.clear();

sf.Close();

return;

}

}

sf.Close();

CFile df( m_strDestination, CFile::modeCreate | CFile::modeWrite );

CArchive ar( &df, CArchive::store );

// dimenssion

int lu = (int)arPoint.size();

ar << lu;

// elements

for( CPointArray::iterator it = arPoint.begin(); it != arPoint.end(); it++ )

{

ar << it->x;

ar << it->y;

}

int l = 0;

ar << l;

ar << l;

ar << l;

AfxMessageBox( _T("Converted Successfully !") );

arPoint.clear();

ar.Close();

}

Clasa ConvertDlg are ca principal scop conversia fisierelor text (*.TXT) ce conțin date în formatul propriu aplicației. Astfel se pot converti fișiere salvate din alte aplicații în format text (Excel, Matlab, etc.) sau pur si simplu cele create cu oricare editor de texte.

Dupa cum se poate vedea din imaginea de mai sus dialogul contine doua casete de dialog cu cate un buton pentru browse. Prima este destinată fișierului sursă (*.TXT), iar cea de-a doua celui destinație (*.FCS). Pentru a efectua conversia se apasă butonul “Convert” și dacă acțiunea a fost încununată de succes va apare un mesaj in acest sens.

Formatul propriu de fișier conține pe lângă vectorul cu seria de date și dimensiunea acesteia și vectorii cu datele prognozate pe baza seriei pentru a evita recalcularea de fiecare dată caând este deschis fișierul. Calculele se efectuează doar o dată atunci când se alege din meniul principal Tools – Calcul și Afișare Grafic și fișierul nu conține aceste date.

#if !defined(AFX_DLGCALCULSES_H__DAB11623_A1EE_4EE3_9722_5D7C5979C3CF__INCLUDED_)

#define AFX_DLGCALCULSES_H__DAB11623_A1EE_4EE3_9722_5D7C5979C3CF__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// DlgCalculSES.h : header file

//

#include "ForecastDoc.h"

/////////////////////////////////////////////////////////////////////////////

// CDlgCalculSES dialog

class CDlgCalculSES : public CDialog

{

// Construction

public:

CDlgCalculSES(CWnd* pParent = NULL); // standard constructor

// Attributes

public:

CForecastDoc* m_pDoc;

// Dialog Data

//{{AFX_DATA(CDlgCalculSES)

enum { IDD = IDD_CALCUL_SMA_SES };

CEdit m_CK;

CEdit m_CAlfa;

int m_intk;

int m_nAlfa;

int m_nmet;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CDlgCalculSES)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CDlgCalculSES)

virtual void OnOK();

afx_msg void OnRadioSma();

afx_msg void OnRadioSes();

afx_msg void OnRadioDes();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DLGCALCULSES_H__DAB11623_A1EE_4EE3_9722_5D7C5979C3CF__INCLUDED_)

// DlgCalculSES.cpp : implementation file

//

#include "stdafx.h"

#include "forecast.h"

#include "DlgCalculSES.h"

#include "forecastDoc.h"

#include "forecastView.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CDlgCalculSES dialog

CDlgCalculSES::CDlgCalculSES(CWnd* pParent /*=NULL*/)

: CDialog(CDlgCalculSES::IDD, pParent)

{

//{{AFX_DATA_INIT(CDlgCalculSES)

m_intk = 0;

m_nAlfa = 0;

m_nmet = 0;

//}}AFX_DATA_INIT

#pragma message ( __WARN__ " This is a user defined warning !" )

}

void CDlgCalculSES::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CDlgCalculSES)

DDX_Control(pDX, IDC_K, m_CK);

DDX_Control(pDX, IDC_ALPHA, m_CAlfa);

DDX_Text(pDX, IDC_K, m_intk);

DDX_Text(pDX, IDC_ALPHA, m_nAlfa);

DDX_Radio(pDX, IDC_RADIO_SMA, m_nmet);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CDlgCalculSES, CDialog)

//{{AFX_MSG_MAP(CDlgCalculSES)

ON_BN_CLICKED(IDC_RADIO_SMA, OnRadioSma)

ON_BN_CLICKED(IDC_RADIO_SES, OnRadioSes)

ON_BN_CLICKED(IDC_RADIO_DES, OnRadioDes)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CDlgCalculSES message handlers

void CDlgCalculSES::OnOK()

{

UpdateData( TRUE );

if( m_intk <0 || m_intk > 10)

{

AfxMessageBox( _T("Missing File !!!") );

return;

}

ASSERT_VALID(m_pDoc);

double suma=0;

double dsma[100],ses[100],des[100];

m_pDoc->m_arSma.clear();

m_pDoc->m_arSes.clear();

m_pDoc->m_arDes.clear();

double alfa = (double)m_nAlfa / 100;

CPointArray::iterator it = m_pDoc->m_arPoint.begin() + m_intk – 1;

int lung = m_pDoc->m_arPoint.end() – m_pDoc->m_arPoint.begin();

for( int j = 0; j < (lung – m_intk + 1); j++)

{

suma = 0;

for( int i = 0; i < m_intk; i++ )

{

suma=suma + it->y;

it–;

}

it = it + m_intk+1;

dsma[j]=suma / m_intk;

m_pDoc->m_arSma.push_back(dsma[j]);

}

// pt ses

it = m_pDoc->m_arPoint.begin();

ses[0] = it->y;

des[0] = it->y;

for( j = 1; j < lung; j++)

{

it++;

ses[j] =(double) (alfa * it->y + (1 – alfa) * ses[j-1]);

m_pDoc->m_arSes.push_back(ses[j]);

des[j] = (alfa * ses[j] + (1 – alfa) * des[j-1]);

m_pDoc->m_arDes.push_back(des[j]);

}

//UpdateData( FALSE );

m_pDoc->OnSaveDocument(m_pDoc->GetPathName());

CDialog::OnOK();

}

void CDlgCalculSES::OnRadioSma()

{

if( ! (m_CK.EnableWindow()))

m_CK.EnableWindow(TRUE);

m_CAlfa.EnableWindow(FALSE);

}

void CDlgCalculSES::OnRadioSes()

{

if( ! m_CAlfa.EnableWindow())

m_CAlfa.EnableWindow(TRUE);

m_CK.EnableWindow(FALSE);

}

void CDlgCalculSES::OnRadioDes()

{

if( ! m_CAlfa.EnableWindow())

m_CAlfa.EnableWindow(TRUE);

m_CK.EnableWindow(FALSE);

}

Clasa CDlgCalculSES asociată ferestrei de dialog din figura de mai jos este destinată efectuării calculelor specifice metodei alese. În partea superioară a ferestrei sunt trei butoane radio prin care se alege metoda efectuării prognozei: metoda mediei alunecătoare, metoda netezirii exponențiale simple și metoda netezirii exponențiale duble.

Dacă se alege prima metodă trebuie introdus numărul de pași, k, necesari calculului mediei. Se calculează astfel media celor k-1 elemente anterioare pentru fiecare element în parte.

Dacă se alege a doua sau a treia metodă trebuie introdusă ponderea alpha, necesară la calculul netezirii exponențiale simple și duble.

La apăsarea butonului “OK” calculele sunt salvate în fișier și este afișat graficul seriei originale suprapus cu cel prognozat pe baza datelor inițiale.

După cum se vede și in imagine de mai sus fereastra mai conține sub grafic o legendă, iar în partea dreaptă un tabel cu datele originale, cu cele prognozate de program și eroarea predicției făcute.

// forecast.h : main header file for the FORECAST application

//

#if !defined(AFX_FORECAST_H__57C4BB29_6A82_448E_8D51_0BF0749C1647__INCLUDED_)

#define AFX_FORECAST_H__57C4BB29_6A82_448E_8D51_0BF0749C1647__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

#include "resource.h" // main symbols

/////////////////////////////////////////////////////////////////////////////

// CForecastApp:

// See forecast.cpp for the implementation of this class

//

class CForecastApp : public CWinApp

{

public:

CForecastApp();

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CForecastApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CForecastApp)

afx_msg void OnAppAbout();

// NOTE – the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_FORECAST_H__57C4BB29_6A82_448E_8D51_0BF0749C1647__INCLUDED_)

// forecast.cpp : Defines the class behaviors for the application.

//

#include "stdafx.h"

#include "forecast.h"

#include "MainFrm.h"

#include "forecastDoc.h"

#include "forecastView.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CForecastApp

BEGIN_MESSAGE_MAP(CForecastApp, CWinApp)

//{{AFX_MSG_MAP(CForecastApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

// NOTE – the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

// Standard file based document commands

// ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CForecastApp construction

CForecastApp::CForecastApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

/////////////////////////////////////////////////////////////////////////////

// The one and only CForecastApp object

CForecastApp theApp;

/////////////////////////////////////////////////////////////////////////////

// CForecastApp initialization

BOOL CForecastApp::InitInstance()

{

AfxEnableControlContainer();

// Standard initialization

// If you are not using these features and wish to reduce the size

// of your final executable, you should remove from the following

// the specific initialization routines you do not need.

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

// Change the registry key under which our settings are stored.

// TODO: You should modify this string to be something appropriate

// such as the name of your company or organization.

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

LoadStdProfileSettings(); // Load standard INI file options (including MRU)

// Register the application's document templates. Document templates

// serve as the connection between documents, frame windows and views.

CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CForecastDoc),

RUNTIME_CLASS(CMainFrame), // main SDI frame window

RUNTIME_CLASS(CForecastView));

AddDocTemplate(pDocTemplate);

// Enable DDE Execute open

EnableShellOpen();

RegisterShellFileTypes(TRUE);

// Parse command line for standard shell commands, DDE, file open

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line

if (!ProcessShellCommand(cmdInfo))

return FALSE;

// The one and only window has been initialized, so show and update it.

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

// Enable drag/drop open

m_pMainWnd->DragAcceptFiles();

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

// No message handlers

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

// App command to run the dialog

void CForecastApp::OnAppAbout()

{

CAboutDlg aboutDlg;

aboutDlg.DoModal();

}

/////////////////////////////////////////////////////////////////////////////

// CForecastApp message handlers

Clasa CforecastApp este de fapt nucleul aplicației, modulul principal al programului. Tot aici este definită si fereastra “About” a programului.

// forecastDoc.h : interface of the CForecastDoc class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_FORECASTDOC_H__B0AE5B10_44DE_4B6D_9B05_4C45F5870924__INCLUDED_)

#define AFX_FORECASTDOC_H__B0AE5B10_44DE_4B6D_9B05_4C45F5870924__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

typedef enum

{

STATE_READY,

STATE_LOADED,

STATE_CALCULATED

}EState;

class CForecastDoc : public CDocument

{

protected: // create from serialization only

CForecastDoc();

DECLARE_DYNCREATE(CForecastDoc)

// Attributes

public:

CPointArray m_arPoint;

DoubleArray m_arSma;

DoubleArray m_arSes;

DoubleArray m_arDes;

int m_intmet;

EState m_eState;

// Operations

public:

void ChangeState( const EState nNewState );

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CForecastDoc)

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar);

virtual void DeleteContents();

virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CForecastDoc();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// Generated message map functions

protected:

//{{AFX_MSG(CForecastDoc)

// NOTE – the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_FORECASTDOC_H__B0AE5B10_44DE_4B6D_9B05_4C45F5870924__INCLUDED_)

// forecastDoc.cpp : implementation of the CForecastDoc class

//

#include "stdafx.h"

#include "forecast.h"

#include "forecastDoc.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CForecastDoc

IMPLEMENT_DYNCREATE(CForecastDoc, CDocument)

BEGIN_MESSAGE_MAP(CForecastDoc, CDocument)

//{{AFX_MSG_MAP(CForecastDoc)

// NOTE – the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CForecastDoc construction/destruction

CForecastDoc::CForecastDoc()

{

// clear status

m_eState = STATE_READY;

}

CForecastDoc::~CForecastDoc()

{

}

BOOL CForecastDoc::OnNewDocument()

{

if (!CDocument::OnNewDocument())

return FALSE;

// TODO: add reinitialization code here

// (SDI documents will reuse this document)

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CForecastDoc serialization

void CForecastDoc::Serialize(CArchive& ar)

{

double dx;

if (ar.IsStoring())

{ // dimenssion

ar << (int)m_arPoint.size();

// elements

for( CPointArray::iterator it = m_arPoint.begin(); it != m_arPoint.end(); it++ )

{

ar << it->x;

ar << it->y;

}

ar << (int)m_arSma.size();

// sma

for (DoubleArray::iterator it1 = m_arSma.begin(); it1 != m_arSma.end(); it1++ )

ar << *it1;

//ses

ar << (int)m_arSes.size();

for (DoubleArray::iterator it2 = m_arSes.begin(); it2 != m_arSes.end(); it2++ )

ar << *it2;

ar << (int)m_arDes.size();

for (DoubleArray::iterator it3 = m_arDes.begin(); it3 != m_arDes.end(); it3++ )

ar << *it3;

}

else

{

int nLength;

ar >> nLength;

for( int i = 0; i < nLength; i++ )

{

int x;

ar >> x;

int y;

ar >> y;

CPoint point( x, y );

m_arPoint.push_back( point );

}

int nSmaLung;

ar >> nSmaLung;

if(nSmaLung)

{

for( int i = 0; i < nSmaLung; i++ )

{

ar >> dx;

//double punct;

m_arSma.push_back( dx );

}

}

//ses

int nSesLung;

ar >> nSesLung;

if(nSesLung)

{

for(i = 0; i < nSesLung; i++ )

{

dx;

ar >> dx;

//double punct;

m_arSes.push_back( dx );

}

}

int nDesLung;

ar >> nDesLung;

if(nDesLung)

{

for(i = 0; i < nDesLung; i++ )

{

dx;

ar >> dx;

//double punct;

m_arDes.push_back( dx );

}

}

}

}

/////////////////////////////////////////////////////////////////////////////

// CForecastDoc diagnostics

#ifdef _DEBUG

void CForecastDoc::AssertValid() const

{

CDocument::AssertValid();

}

void CForecastDoc::Dump(CDumpContext& dc) const

{

CDocument::Dump(dc);

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CForecastDoc commands

void CForecastDoc::DeleteContents()

{

// clear status

m_eState = STATE_READY;

// clear points array

m_arPoint.clear();

//m_arSma.clear();

CDocument::DeleteContents();

}

BOOL CForecastDoc::OnOpenDocument(LPCTSTR lpszPathName)

{

if (!CDocument::OnOpenDocument(lpszPathName))

return FALSE;

// change current state

ChangeState( STATE_LOADED );

return TRUE;

}

void CForecastDoc::ChangeState( const EState nNewState )

{

m_eState = nNewState;

UpdateAllViews( NULL );

}

Clasa CforecastDoc se ocupă, în special, de operațiunile specifice oricarui document, fișier specific aplicației. Aici este redefinită serializarea fișierului, adică salvarea, deschiderea și structura fișierului în sine.

// forecastView.h : interface of the CForecastView class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_FORECASTVIEW_H__95C7A4B6_413D_48D1_A86D_1372C86CC2D6__INCLUDED_)

#define AFX_FORECASTVIEW_H__95C7A4B6_413D_48D1_A86D_1372C86CC2D6__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

class CForecastView : public CView

{

protected: // create from serialization only

CForecastView();

DECLARE_DYNCREATE(CForecastView)

// Attributes

public:

// Operations

public:

CForecastDoc* GetDocument();

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CForecastView)

public:

virtual void OnDraw(CDC* pDC); // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CForecastView();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// bool m_bUpdateNow;

// Generated message map functions

protected:

//{{AFX_MSG(CForecastView)

afx_msg void OnToolsConvertfiles();

afx_msg void OnSmaSes();

afx_msg void OnUpdateSmaSes(CCmdUI* pCmdUI);

afx_msg void OnToolsInput();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

#ifndef _DEBUG // debug version in forecastView.cpp

inline CForecastDoc* CForecastView::GetDocument()

{ return (CForecastDoc*)m_pDocument; }

#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_FORECASTVIEW_H__95C7A4B6_413D_48D1_A86D_1372C86CC2D6__INCLUDED_)

// forecastView.cpp : implementation of the CForecastView class

//

#include "stdafx.h"

#include "forecast.h"

#include "forecastDoc.h"

#include "forecastView.h"

#include "ConvertDlg.h"

#include "DlgCalculSES.h"

#include "InputDLG.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CForecastView

IMPLEMENT_DYNCREATE(CForecastView, CView)

BEGIN_MESSAGE_MAP(CForecastView, CView)

//{{AFX_MSG_MAP(CForecastView)

ON_COMMAND(ID_TOOLS_CONVERTFILES, OnToolsConvertfiles)

ON_COMMAND(ID_SMA_SES, OnSmaSes)

ON_UPDATE_COMMAND_UI(ID_SMA_SES, OnUpdateSmaSes)

ON_COMMAND(ID_TOOLS_INPUT, OnToolsInput)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CForecastView construction/destruction

CForecastView::CForecastView()

{

// m_bUpdateNow = false;

}

CForecastView::~CForecastView()

{

}

BOOL CForecastView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return CView::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

// CForecastView drawing

void CForecastView::OnDraw(CDC* pDC)

{

CForecastDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

int nState = pDC->SaveDC();

//double smabuf[100],max;

switch( pDoc->m_eState )

{

case STATE_READY:

{

CString strText( _T("Ready bitch …") );

//pDC->TextOut( 50, 50, strText );

}

break;

case STATE_LOADED:

{

/*for( CPointArray::iterator it = pDoc->m_arPoint.begin();

it != pDoc->m_arPoint.end();

it++ )

{

CString strText;

int nCurrent = it – pDoc->m_arPoint.begin();

strText.Format( _T("Punctul %d : %d %d"),

nCurrent,

it->x,

it->y );

pDC->TextOut( 50, 50 + nCurrent * 15, strText );

}*/

pDC->TextOut( 50, 50 , "Datele au fost incarcate din fisier. " );

pDC->TextOut( 50, 80 , "Folositi meniul pentru a calcula si afisa graficul");

}

break;

case STATE_CALCULATED:

{

CString str,strsma,strses;

/*for(DoubleArray::iterator it1 = pDoc->m_arSma.begin();

it1 != pDoc->m_arSma.end();

it1++ )

{

int nCurr = it1 – pDoc->m_arSma.begin();

strsma.Format( _T(" sma [%d] = %f"),nCurr, *it1);

pDC->TextOut(50, 50 +nCurr *40, strsma);

}

for(DoubleArray::iterator it2 = pDoc->m_arDes.begin();

it2 != pDoc->m_arDes.end();

it2++ )

{

int nCurr = it2 – pDoc->m_arDes.begin();

strses.Format( _T(" des [%d] = %f"),nCurr, *it2);

pDC->TextOut(50 +nCurr *25, 50 , strses);

}*/

CRect rect;

GetClientRect (&rect);

pDC->SetMapMode (MM_ISOTROPIC);

pDC->SetWindowExt (1000, 1000);

pDC->SetViewportExt (rect.Width (), -rect.Height ());

pDC->SetViewportOrg (10, rect.Height () / 2);

pDC->MoveTo(0, 0);

pDC->SelectStockObject(LTGRAY_BRUSH);

CPen* poldPen = pDC->GetCurrentPen();

CPen pn,pn_axe,pn_sma;

CBrush* br = pDC->GetCurrentBrush();

//CBrush br;

pn.CreatePen(PS_SOLID,3,RGB(0,0,255));

pn_axe.CreatePen(PS_SOLID,5,RGB(128,128,255));

pn_sma.CreatePen(PS_SOLID,2,RGB(255,0,0));

//br.CreateSolidBrush(RGB(10,10,10));

RECT rctB = {0,-200,900,400};

pDC->FillRect(&rctB,br);

pDC->SelectObject(&pn_axe);

pDC->LineTo(900, 0);

pDC->MoveTo(0,-200);

pDC->LineTo(0, 400);

pDC->SetPixel( 0, 0, RGB( 255, 0, 0 ) );

pDC->SelectObject(poldPen);

int i=0,nCurr, npctx;

double max,maxx,maxy;

CPointArray::iterator it;

DoubleArray::iterator it1;

max = *(pDoc->m_arSma.begin());

int lung = pDoc->m_arPoint.end() – pDoc->m_arPoint.begin();

for(it = pDoc->m_arPoint.begin();it != pDoc->m_arPoint.end(); it++ )

{

//maxx = it – pDoc->m_arPoint.begin();

if (maxy < it->y)

{

maxy = it->y;

}

}

pDC->SelectObject(&pn);

pDC->MoveTo(600/lung,(pDoc->m_arPoint.begin()->y)*200/maxy);

nCurr = 0;

for(it = pDoc->m_arPoint.begin(); it != pDoc->m_arPoint.end(); it++ )

{

i++;

//pDC->SetPixel(i*600/lung, (it->y)*200/maxy, RGB(255,255,0));

pDC->LineTo(i*600/lung, (it->y)*200/maxy);

pDC->Ellipse(i*600/lung – 10, (it->y)*200/maxy + 10, i*600/lung + 10, (it->y)*200/maxy – 10);

str.Format( _T(" y [%d] = %d"),i, it->y);

pDC->TextOut(940, -490 + i*47, str);

}

pDC->MoveTo(600/lung,(pDoc->m_arPoint.begin()->y)*200/maxy);

switch(pDoc->m_intmet)

{

case 0:

{

pDC->TextOut(20,460,"Metoda mediei alunecatoare");

for(it1 = pDoc->m_arSma.begin();it1 != pDoc->m_arSma.end(); it1++ )

{

npctx = it1 – pDoc->m_arSma.begin();

if (max < *it1)

{

max = *it1;

}

}

it = pDoc->m_arPoint.begin()+lung-npctx-1;

pDC->SelectObject(&pn_sma);

for(it1 = pDoc->m_arSma.begin();it1 != pDoc->m_arSma.end(); it1++ )

{

nCurr = it1 – pDoc->m_arSma.begin()+1;

pDC->LineTo(nCurr*600/npctx, (*it1)*200/max);

//pDC->SetPixel(nCurr*200/npctx, (*it1)*200/max, RGB(255,0,0));

str.Format( _T(" y [%d] = %.2f"),nCurr+lung-npctx-1, *it1);

pDC->TextOut(1300, -490 + (nCurr+lung-npctx-1)*47, str);

str.Format( _T(" e = %.2f"), ((float)(it->y) – (*it1)));

pDC->TextOut(1670, -490 + (nCurr+lung-npctx-1)*47, str);

it++;

}

}

break;

case 1:

{

pDC->TextOut(20,460,"Metoda netezirii exponentiale simple");

pDC->SelectObject(&pn_sma);

//pDC->MoveTo(0,0);

for(it1 = pDoc->m_arSes.begin();it1 != pDoc->m_arSes.end(); it1++ )

{

npctx = it1 – pDoc->m_arSes.begin();

if (max < *it1)

{

max = *it1;

}

}

it = pDoc->m_arPoint.begin()+lung-npctx-1;

for(it1 = pDoc->m_arSes.begin();it1 != pDoc->m_arSes.end(); it1++ )

{

nCurr = it1 – pDoc->m_arSes.begin()+1;

pDC->LineTo(nCurr*600/npctx, (*it1)*200/max);

//pDC->SetPixel(nCurr*200/npctx, (*it1)*200/max, RGB(255,0,0));

str.Format( _T(" y [%d] = %.2f"),nCurr+lung-npctx-1, *it1);

pDC->TextOut(1300, -490 + (nCurr+lung-npctx-1)*47, str);

str.Format( _T(" e = %.2f"), ((float)(it->y) – (*it1)));

pDC->TextOut(1670, -490 + (nCurr+lung-npctx-1)*47, str);

it++;

}

}

break;

case 2:

{

pDC->TextOut(20,460,"Metoda netezirii exponentiale duble");

pDC->SelectObject(&pn_sma);

//pDC->MoveTo(0,0);

for(it1 = pDoc->m_arDes.begin();it1 != pDoc->m_arDes.end(); it1++ )

{

npctx = it1 – pDoc->m_arDes.begin();

if (max < *it1)

{

max = *it1;

}

}

it = pDoc->m_arPoint.begin()+lung-npctx-1;

for(it1 = pDoc->m_arDes.begin();it1 != pDoc->m_arDes.end(); it1++ )

{

nCurr = it1 – pDoc->m_arDes.begin()+1;

pDC->LineTo(nCurr*600/npctx, (*it1)*200/max);

//pDC->SetPixel(nCurr*200/npctx, (*it1)*200/max, RGB(255,0,0));

str.Format( _T(" y [%d] = %.2f"),nCurr+lung-npctx-1, *it1);

pDC->TextOut(1300, -490 + (nCurr+lung-npctx-1)*47, str);

str.Format( _T(" e = %.2f"), ((float)(it->y) – (*it1)));

pDC->TextOut(1670, -490 + (nCurr+lung-npctx-1)*47, str);

it++;

}

}

break;

}

pDC->TextOut(20,-220,"Legenda:");

pDC->TextOut(20,-280,"Seria originala: ");

pDC->MoveTo(440,-310);

pDC->SelectObject(&pn);

pDC->LineTo(700,-310);

pDC->TextOut(20,-340,"Seria prognozata: ");

pDC->MoveTo(440,-370);

pDC->SelectObject(&pn_sma);

pDC->LineTo(700,-370);

pDC->TextOut(920, 492, "Seria originala");

pDC->TextOut(1300, 492, "Seria prognozata");

pDC->TextOut(1700,492, "Eroarea");

pDC->MoveTo(900,443);

pDC->SelectObject(&pn_axe);

pDC->LineTo(1900,443);

pDC->MoveTo(1250,495);

pDC->LineTo(1250,-500);

pDC->MoveTo(1680,495);

pDC->LineTo(1680,-500);

/*

//pDC->RestoreDC( nState );*/

}

break;

}

pDC->RestoreDC(nState);

}

/////////////////////////////////////////////////////////////////////////////

// CForecastView diagnostics

#ifdef _DEBUG

void CForecastView::AssertValid() const

{

CView::AssertValid();

}

void CForecastView::Dump(CDumpContext& dc) const

{

CView::Dump(dc);

}

CForecastDoc* CForecastView::GetDocument() // non-debug version is inline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CForecastDoc)));

return (CForecastDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CForecastView message handlers

void CForecastView::OnToolsConvertfiles()

{

CConvertDlg dlg;

dlg.DoModal();

}

void CForecastView::OnSmaSes()

{

CForecastDoc* pDoc = GetDocument();

ASSERT_VALID( pDoc );

CDlgCalculSES dlg;

dlg.m_pDoc = GetDocument();

if( dlg.DoModal() )

{

pDoc->m_intmet = dlg.m_nmet;

pDoc->ChangeState( STATE_CALCULATED );

}

}

void CForecastView::OnUpdateSmaSes(CCmdUI* pCmdUI)

{

pCmdUI->Enable( GetDocument()->m_arPoint.size() ? TRUE : FALSE );

}

void CForecastView::OnToolsInput()

{

CInputDLG dlg;

dlg.DoModal();

}

Clasa CforecastView se ocupă de afișarea în fereastra principală a programului a graficului și a tabelului cu datele originale, cele prognozate și eroarea obținută.

#if !defined(AFX_INPUTDLG_H__9BCB4A21_7801_11D6_A2D5_00C0DFF62C75__INCLUDED_)

#define AFX_INPUTDLG_H__9BCB4A21_7801_11D6_A2D5_00C0DFF62C75__INCLUDED_

#include "StdAfx.h" // Added by ClassView

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// InputDLG.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CInputDLG dialog

class CInputDLG : public CDialog

{

// Construction

public:

CPointArray m_arPoint;

CInputDLG(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CInputDLG)

enum { IDD = IDD_INPUT };

CEdit m_CElem;

int m_nElem;

CString m_sVector;

CString m_strDest;

//}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CInputDLG)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CInputDLG)

afx_msg void OnButtonOpendestination();

virtual void OnOK();

afx_msg void OnExit();

afx_msg void OnCancel();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_INPUTDLG_H__9BCB4A21_7801_11D6_A2D5_00C0DFF62C75__INCLUDED_)

// InputDLG.cpp : implementation file

//

#include "stdafx.h"

#include "forecast.h"

#include "InputDLG.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

#define DEFAULT_TESTTEXT _T("fcs")

#define DEFAULT_TESTFILENAME _T("MyFile")

/////////////////////////////////////////////////////////////////////////////

// CInputDLG dialog

CInputDLG::CInputDLG(CWnd* pParent /*=NULL*/)

: CDialog(CInputDLG::IDD, pParent)

{

//{{AFX_DATA_INIT(CInputDLG)

m_nElem = 0;

m_sVector = _T("");

m_strDest = _T("");

//}}AFX_DATA_INIT

}

void CInputDLG::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CInputDLG)

DDX_Control(pDX, IDC_ELEMENT, m_CElem);

DDX_Text(pDX, IDC_ELEMENT, m_nElem);

DDX_Text(pDX, IDC_VECTOR, m_sVector);

DDX_Text(pDX, IDC_EDIT_DESTINATION, m_strDest);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CInputDLG, CDialog)

//{{AFX_MSG_MAP(CInputDLG)

ON_BN_CLICKED(IDC_BUTTON_OPENDESTINATION, OnButtonOpendestination)

ON_BN_CLICKED(ID_EXIT, OnExit)

ON_BN_CLICKED(ID_CANCEL, OnCancel)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CInputDLG message handlers

void CInputDLG::OnOK()

{

CPointArray arPoint;

UpdateData(TRUE);

int i;

int y = m_nElem;

int x = i++;

CPoint point( x, y );

m_arPoint.push_back( point );

char *str;

_itoa(y,str,10);

m_sVector = m_sVector + str + "; ";

UpdateData(FALSE);

//GetDlgItem(IDC_ELEMENT)->SetFocus();

m_CElem.SetFocus();

m_CElem.SetSel(0,-1);

}

void CInputDLG::OnButtonOpendestination()

{

static char BASED_CODE szFilter[] = "forecast Files(*.fcs)|*.fcs||";

CFileDialog dlg( FALSE,

DEFAULT_TESTTEXT,

DEFAULT_TESTFILENAME,

OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY,

szFilter,

NULL );

if( dlg.DoModal() == IDOK )

{

m_strDest = dlg.GetPathName();

UpdateData( FALSE );

// m_ctrlSource.SetWindowText( dlg.GetPathName() );

// GetDlgItem( IDC_EDIT_SOURCE )->SetWindowText( dlg.GetPathName() );

}

}

void CInputDLG::OnExit()

{

CFile df( m_strDest, CFile::modeCreate | CFile::modeWrite );

CArchive ar( &df, CArchive::store );

// dimenssion

int lu = (int)m_arPoint.size();

ar << lu;

// elements

for( CPointArray::iterator it = m_arPoint.begin(); it != m_arPoint.end(); it++ )

{

ar << it->x;

ar << it->y;

}

int l = 0;

ar << l;

ar << l;

ar << l;

AfxMessageBox( _T("Datele au fost salvate!") );

m_arPoint.clear();

ar.Close();

CDialog::OnCancel();

}

void CInputDLG::OnCancel()

{

CDialog::OnCancel();

}

Clasa CInputDLG are drept scop implementarea unui nou dialog, de data asta pentru introducerea de la tastatură a datelor. Elementele se introduc unul câte unul, apăsând butonul “Enter” (nu tasta Enter!). Elementele sunt introduse într-un vector afișat intr-o casetă text în partea centrală a dialogului. Salvarea vectorului în fișier pentru efectuarea calculelor se face prin apăsarea butonului “Salvează” după ce în prealabil s-a ales numele fișierului în caseta text din partea inferioară. Dacă se dorește părăsirea dialogului fără salvarea vectorului se apasă butonul “Cancel”.

// MainFrm.h : interface of the CMainFrame class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__918252A9_9F21_4DA6_B2E3_780B6049488E__INCLUDED_)

#define AFX_MAINFRM_H__918252A9_9F21_4DA6_B2E3_780B6049488E__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

class CMainFrame : public CFrameWnd

{

protected: // create from serialization only

CMainFrame();

DECLARE_DYNCREATE(CMainFrame)

// Attributes

public:

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMainFrame)

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CMainFrame();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected: // control bar embedded members

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

CReBar m_wndReBar;

// Generated message map functions

protected:

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

// NOTE – the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__918252A9_9F21_4DA6_B2E3_780B6049488E__INCLUDED_)

// MainFrm.cpp : implementation of the CMainFrame class

//

#include "stdafx.h"

#include "forecast.h"

#include "MainFrm.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

// NOTE – the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code !

ON_WM_CREATE()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

static UINT indicators[] =

{

ID_SEPARATOR, // status line indicator

ID_INDICATOR_CAPS,

ID_INDICATOR_NUM,

ID_INDICATOR_SCRL,

};

/////////////////////////////////////////////////////////////////////////////

// CMainFrame construction/destruction

CMainFrame::CMainFrame()

{

// TODO: add member initialization code here

}

CMainFrame::~CMainFrame()

{

}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

return -1;

if (!m_wndToolBar.CreateEx(this) ||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed to create toolbar\n");

return -1; // fail to create

}

if (!m_wndReBar.Create(this) ||

!m_wndReBar.AddBar(&m_wndToolBar))

{

TRACE0("Failed to create rebar\n");

return -1; // fail to create

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status bar\n");

return -1; // fail to create

}

// TODO: Remove this if you don't want tool tips

m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |

CBRS_TOOLTIPS | CBRS_FLYBY);

return 0;

}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CMainFrame diagnostics

#ifdef _DEBUG

void CMainFrame::AssertValid() const

{

CFrameWnd::AssertValid();

}

void CMainFrame::Dump(CDumpContext& dc) const

{

CFrameWnd::Dump(dc);

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CMainFrame message handlers

Clasa CMainFrame se ocupă cu afișarea meniului, toolbarului, și cadrul ferestrei principale.

// stdafx.h : include file for standard system include files,

// or project specific include files that are used frequently, but

// are changed infrequently

//

#if !defined(AFX_STDAFX_H__1289AA6C_EA9C_4CD8_9F04_C45309AD5573__INCLUDED_)

#define AFX_STDAFX_H__1289AA6C_EA9C_4CD8_9F04_C45309AD5573__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

#include <vector>

using namespace std;

typedef vector<CPoint> CPointArray;

typedef vector<double> DoubleArray;

#define __no2str__( no ) #no

#define __indir__( x ) __no2str__( x )

#define __WARN__ __FILE__ "(" __indir__( __LINE__ ) ") : warning C7070: "

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__1289AA6C_EA9C_4CD8_9F04_C45309AD5573__INCLUDED_)

// stdafx.cpp : source file that includes just the standard includes

// forecast.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

Bibliografie:

„Quantitive Methods for Management Decesions” – William P. Cooke

„Basic Bussiness Statistics” – Levine Berenson

Time Series Analysis – StatSoft – http://www.statsoftinc.com

C++ Manual Complet – Herbert Schildt

Utilizare Visual C++ – Jon Bates, Tim Tomkins

Similar Posts

  • Cererea Unei Aplicatii Web Responsive Folosind Cms

    CUPRINS Introducere Creativitatea și imaginația reprezintă unele dintre cele mai importante criterii în realizarea unei aplicații, iar posibilitatea de a lucra cu ultimele tehnologii în dezvoltarea aplicațiilor Web înseamnă o mare provocare pentru orice programator. În societatea actuală producerea și consumul de informație este principalul tip de activitate, informația este recunoscută drept principala resursă. Evoluția…

  • Elaborarea Unui Portal Internet cu Utilizarea Tehnologiilor Open Source

    Teză de licență Elaborarea unui portal internetcu utilizarea tehnologiilor Open Source Cuprins INTRODUCERE CAPITOLUL I. JAVA 1.1 Ce este Java 1.2 Garbeage Collector 1.3 Medii integrate 1.4 Biblioteci si framework-uri CPITOLUL II. FRAMEWORK-URI JAVA 2.1 Spring 2.2 Spring MVC 2.3 JavaServer Pages (JSP) 2.4 Spring Security 2.5 Tiles 2.6 Hibernate Java ORM Framework CPITOLUL III….

  • Proiect de Implementare a Unei Retele de Calculatoare la O Scoala

    PROIECT DE IMPLEMENTARE A UNEI RETELE DE CALCULATOARE LA O SCOALA I INTRODUCERE In ziua de azi Internetul este foarte important deoarece ofera acces la o multitudine de resurse educationale: eLearning, imagini, documentatie etc. si poate ca nu exista institutii unde Internetul sa fie mai important decat scolile. Viteza conexiunilor a crescut mereu, permitand instalarea…

  • Utilizarea Echipamentelor de Retea Studiate Pentru a Observa Asemanarile Si Diferentele Dintre Acestea

    CUPRINS Capitolul 1. Introducere in Packet Tracer 4.1  1.1. Perfectionarea protocoalelor 1.2. Arhitectura extensibila 1.3. Perfectionarea GUI  1.4. Reprezentarea si vizualizarea instumentelor  1.5. Capacități de adnotare si authoring  1.6. Utilitatea lui Packet Tracer 4.1  Capitolul 2. Interfata generala  2.1. Spatiul de lucru si moduri de lucru 2.2. Configurarea preferintelor 2.3. Setarea fundalului  2.4. Primii pasi in Packet Tracer 4.1  2.4.1. Crearea primei retele.  2.4.2. Trimiterea de Mesaje Test Simple in Realtime Mode 2.4.3. Crearea unei Conexiuni pentru un Web Server folosind Browserul Web al PC- ului  2.4.4. Captarea evenimentelor si vizualizarea in Simulation Mode  2.4.5. Interiorul pachetelor in Simulation Mode 2.4.6. Vizualizarea tabelelor de echipamente si resetarea retelei  2.4.7. Recapitularea noilor abilitati  2.5. Tipuri de Conexiuni / Legaturi  Capitolul 3. Cadrul Logic de lucru 3.1. Crearea Dispozitivelor 3.2. Crearea aleatoare a dispozitvelor 3.3. Adaugarea de Module  3.4. Crearea conexiunilor 3.5. Unelte de editare 3.6. Grupareea dispozitivelor Capitolul 4. Spațiul fizic de lucru 4.1. Dispozitive Wireless in cadrul fizic de lucru  4.2. Observatii speciale Capitolul 5. Dispozitive de retea  5.1. Configurarea Fizica si Lista de Comenzi  5.1.1. Configurarea Dispozitivelor  5.1.2. Comenzi de logare IOS  5.1.3. Configurarea Routerelor  5.1.4. Configurari de Rutare 5.1.5. Configurarea Switchurilor  5.1.6. Configurarea PCurilor  5.1.7. Configurarea Serverelor  Capitolul 6. Aplicatie  Primul Caz  Al doilea caz  Capitolul 1. Introducere in Packet Tracer 4.1 Activitatile de laborator sunt o parte importanta a educatiei in domeniul retelelor. Totusi, echipamentul de laborator poate fi o resursa rar intalnita. Packet Tracer furnizeaza simularea vizuala a echipamentelor si a proceselor de retea pentru a compensa provocarile lipsei de echipament. Desi sunt valabile si alte produse de simulare a echipamentelor Cisco, ele nu includ avantajele vizuale din Packet Tracer. Aceasta tehnologie este o cale noua si interesanta pentru a extinde experientele de predare si invatare peste limitele unui laborator traditional. Packet Tracer va ajuta sa rezolvati unele provocari uzuale cu care administratorii de retea se confrunta zilnic, in acelasi timp ajutandu-ne sa exploram noi frontiere in retelistica….

  • Serviciu Web de Analiza Statistica Presei Online

    Lista Figurilor Fig. 1.1.1 Rezultatul studiului referitor la conținutul media online (a) 14 Fig. 1.1.2 Rezultatul studiului referitor la conținutul media online (b) 14 Fig. 2.1.1 Bytecode-ul în limbaj de asamblare pentru „Hello World” 20 Fig. 2.5.1 Rezultatul realizării unui document XML, utilizând Jsoup (1) 26 Fig. 2.5.2 Rezultatul realizării unui document XML, utilizând Jsoup…