CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - SMA - poddaje się

SMA - poddaje się

dział ogólny

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » poniedziałek, 17 stycznia 2011, 18:04

Tak to u mnie wygląda niestety ten kod co mi dałeś nie działa :| mam taki błąd:


Skoro działa u mnie to i u Ciebie musi. Testowałeś mój kod, czy też mój kod po przerobieniu?! :roll:
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » poniedziałek, 17 stycznia 2011, 18:17

Czy AdresSMA to pozycja od której zaczyna się wyliczanie SMA, czyli to numer okresu, dzień od którego zaczyna się liczenie SMA?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Corvis » poniedziałek, 17 stycznia 2011, 21:25

Twój kod przetestowałem na oddzielnej aplikacji i działa, bo niestety moja trzyma dane w wektorze taki jak podałem :| i musiałem ją przystosować. Wkleiłem jak to zrobiłem. Zaraz będe jeszcze dumał.


AdresSMA to adres w wektorze z którego pobieram dane do średniej bo dane mam zorganizowane tak:


wektor danych [0] - [data godzina] [0][1][2][3][4]

czyli jeżeli AdresSMA jest 0 to pobieram dane do średniej z pierwszego elementu wektora danych.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: SMA - poddaje się

Nowy postprzez Corvis » poniedziałek, 17 stycznia 2011, 22:28

Baronie wziąłem swój kod przerobiłem na szybko tak, żebym mógł go odpalić bez przeróbek:

KOD cpp:     UKRYJ  
// ....
std::vector<long double> tmp;
std::vector<long double> wynik;

for(int t = 0; t < DanePrzeliczone.size(); t++) tmp.push_back(DanePrzeliczone[t].WartosciTikow[Adres]);

sum(tmp,wynik,0,0,3);
// ....
 


I dalej mam Stack Overflow :o

Zaczynam się zastanawiać gdzie tu tkwi problem czy w rekurencji czy czymś innym - bo to już jakaś paranoja. Ten 1 kod co sam napisałem liczenie iteracyjne działał dobrze, ale wolno. Coś pokombinuje z tą rekurencją, nawet dla ciekawości własnej. Bo coś tu jest nie tak
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: SMA - poddaje się

Nowy postprzez Corvis » wtorek, 18 stycznia 2011, 09:57

Jeszcze jedna obserwacja, jeżeli liczy się SMA od 0 elementu czyli od początku to średnia zaczyna wyprzedać dane i wygląda to jak by przepowiadała co będzie hehe. Dlatego SMA trzeba liczyć nie od 0 elementu tylko od ostatniego w wektorze.


Ps. Jaki jest czas na edycję posta bo chciałem dopisać do ostatniego i nie mogłem :-(
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » wtorek, 18 stycznia 2011, 10:21

czyli jeżeli AdresSMA jest 0 to pobieram dane do średniej z pierwszego elementu wektora danych.


Nie bardzo rozumiem... :roll:

Może zrób tak, że ten adres SMA będziesz pobierał przed funkcją, a do funkcji przekażesz tylko vektor zawierający okresy, liczbę dni dla których wyliczasz okresy i numer okresu od którego zaczyna się liczenie okresów.

KOD cpp:     UKRYJ  
/*

SMA1 = (10 + 15 + 20)                = 45  / 3 = 15;
SMA2 = (15 + 20 + 25)                = 60  / 3 = 20
SMA3 = (20 + 25 + 30)                = 75  / 3 = 25
SMA4 = (25 + 30 + 17)                = 72  / 3 = 24
SMA4 = (30 + 17 + 11)                = 58  / 3 = 19.33
*/

void sum(vector<long double> P, vector<long double> &graphPoints, int days,
        int adresSMA) /* days - ilość okresów dla których liczone jest SMA; adresSMA - okres od którego zaczyna się liczenie SMA */
{
  int p = 0;
  int size = adresSMA;
  long double value = 0;

  while(size <= P.size() - days)
  {

   if(p < days)
   {
    value = value + P[adresSMA];
    adresSMA += 1;
    p += 1;
   }
   else
   {
    long double sma = value / days ;
    size++;
    graphPoints.push_back( ( sma ) );
    adresSMA = size;
    p = 0;
    value = 0;
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSMAClick(TObject *Sender)
{
 vector<long double> P;
 P.push_back(10);
 P.push_back(15);
 P.push_back(20);
 P.push_back(25);
 P.push_back(30);
 P.push_back(17);
 P.push_back(11);

 vector<long double> graphPoints;

 sum(P, graphPoints, 3, 2); /* dla 3 okresów począwszy od okresu 3 (liczone od 0) */

 /* sprawdzam co zawiera vektor graphPoint  */
 for(int i = 0; i < graphPoints.size(); i++)
 {
  ListBox1->Items->Add( FloatToStr( graphPoints[i] ) );
 }
}


Zrezygnowałem z rekurencji, gdyż nie przyspieszała już działania funkcji. Dla 100 000 okresów funkcja wykonała obliczenia w 40 ms.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » wtorek, 18 stycznia 2011, 10:45

Dla Twoich potrzeb powinno to chyba wyglądać tak:

KOD cpp:     UKRYJ  
struct Tik {
        TDateTime DataGodzina;
        vector<long double> WartosciTikow;
};
//---------------------------------------------------------------------------
void sum(vector<Tik> P, vector<long double> &graphPoints, int days,
        int adresSMA, int countTik) /* countTick - numer elementu vektora zawierającego strukturę Tik */
{
  int p = 0;
  int size = adresSMA;
  long double value = 0;

  while(size <= P[countTik].WartosciTikow.size() - days)
  {

   if(p < days)
   {
    value = value + P[countTik].WartosciTikow[adresSMA];
    adresSMA += 1;
    p += 1;
   }
   else
   {
    long double sma = value / days ;
    size++;
    graphPoints.push_back( ( sma ) );
    adresSMA = size;
    p = 0;
    value = 0;
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSMAClick(TObject *Sender)
{
 vector<Tik> DanePrzeliczone;

 vector<long double> P;
 P.push_back(10);
 P.push_back(15);
 P.push_back(20);
 P.push_back(25);
 P.push_back(30);
 P.push_back(17);
 P.push_back(11);

 Tik structSMA;
 structSMA.DataGodzina = Now();
 structSMA.WartosciTikow = P;

 DanePrzeliczone.push_back(structSMA);

 vector<long double> graphPoints;

 sum(DanePrzeliczone, graphPoints, 3, 2, 0);

 /* sprawdzam co zawiera vektor graphPoint  */
 for(int i = 0; i < graphPoints.size(); i++)
 {
  ListBox1->Items->Add( FloatToStr( graphPoints[i] ) );
 }
}


Funkcja sum wylicza SMA tylko dla jednego elementu wektora struktury Tik, by obliczyć SMA dla wszystkich elementów trzeba wywołać funkcje wielokrotnie, czyli:

KOD cpp:     UKRYJ  
for(int i = 0; i < DanePrzeliczone.size(); i++) sum(DanePrzeliczone, graphPoints, 3, 2, i);


Drugie argument funkcji sum również powinien być typu vector, ale nie musi być typy struktury, bo nie chcesz przechowywać przecież SMA wyliczonych dla wszystkich elementów ze struktury w jednym wektorze.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Corvis
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Corvis » wtorek, 18 stycznia 2011, 11:23

Dzięki wielkie za pomoc, wieczorem sprawdzę jak to wszystko działa.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » wtorek, 18 stycznia 2011, 11:50

Z wykorzystaniem dynamicznej macierzy wektorów można by to zrobić tak:

KOD cpp:     UKRYJ  
struct Tik {
        TDateTime DataGodzina;
        vector<long double> WartosciTikow;
};

typedef vector< long double > graphPoints;
typedef vector< graphPoints > macierz;

//---------------------------------------------------------------------------
void sum(vector<Tik> P, macierz &mac, int days,
        int adresSMA, int countTik, int m)
{
  int p = 0;
  int size = adresSMA;
  long double value = 0;

  while(size <= P[countTik].WartosciTikow.size() - days)
  {

   if(p < days)
   {
    value = value + P[countTik].WartosciTikow[adresSMA];//P[adresSMA];
    adresSMA += 1;
    p += 1;
   }
   else
   {
    long double sma = value / days ;
    size++;
    mac[m].push_back( ( sma ) );
    adresSMA = size;
    p = 0;
    value = 0;
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSMAClick(TObject *Sender)
{
 vector<Tik> DanePrzeliczone;

 vector<long double> P;
 P.push_back(10);
 P.push_back(15);
 P.push_back(20);
 P.push_back(25);
 P.push_back(30);
 P.push_back(17);
 P.push_back(11);

 Tik structSMA;
 structSMA.DataGodzina = Now();
 structSMA.WartosciTikow = P;

 DanePrzeliczone.push_back(structSMA);

 graphPoints gP;

 macierz mac;
 mac.push_back(gP);

 sum(DanePrzeliczone, mac, 3, 2, 0, 0);

 /* sprawdzam co zawiera vektor macierz  */
 for(int i = 0; i < mac[0].size(); i++)
 {
  ListBox1->Items->Add( FloatToStr( mac[0][i] ) );
 }
}


Wtedy w pętli wypełnianie macierzy wynikami SMA wyglądałoby tak:

KOD cpp:     UKRYJ  
struct Tik {
        TDateTime DataGodzina;
        vector<long double> WartosciTikow;
};

typedef vector< long double > graphPoints;
typedef vector< graphPoints > macierz;
//---------------------------------------------------------------------------
void sum(vector<Tik> P, graphPoints &gP, int days,
        int adresSMA, int countTik)
{
  int p = 0;
  int size = adresSMA;
  long double value = 0;

  while(size <= P[countTik].WartosciTikow.size() - days)
  {

   if(p < days)
   {
    value = value + P[countTik].WartosciTikow[adresSMA];
    adresSMA += 1;
    p += 1;
   }
   else
   {
    long double sma = value / days ;
    size++;
    gP.push_back( ( sma ) );
    adresSMA = size;
    p = 0;
    value = 0;
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSMAClick(TObject *Sender)
{
 vector<Tik> DanePrzeliczone;

 vector<long double> P;
 P.push_back(10);
 P.push_back(15);
 P.push_back(20);
 P.push_back(25);
 P.push_back(30);
 P.push_back(17);
 P.push_back(11);

 vector<long double> P2;
 P2.push_back(5);
 P2.push_back(8);
 P2.push_back(11);
 P2.push_back(14);
 P2.push_back(17);
 P2.push_back(20);
 P2.push_back(23);

 Tik structSMA;
 structSMA.DataGodzina = Now();
 structSMA.WartosciTikow = P;

 DanePrzeliczone.push_back(structSMA);

 structSMA.WartosciTikow = P2;
 DanePrzeliczone.push_back(structSMA);

 graphPoints gP;

 macierz mac;

 for(int i = 0; i < DanePrzeliczone.size(); i++)
 {
  sum(DanePrzeliczone, gP, 3, 2, i);
  mac.push_back(gP);
  gP.clear();
 }

 /* sprawdzam co zawiera vektor macierz  */
 for(int i = 0; i < mac.size(); i++)
 {
  for(int j = 0; j < mac[i].size(); j++)
   ListBox1->Items->Add( FloatToStr( mac[i][j] ) );

  ListBox1->Items->Add(" ----------- ");
 }
}


U mnie to działa. Trochę namieszałem z tymi macierzami, ale kolejna struktura byłaby gorszym wyjściem.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Corvis
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez polymorphism » wtorek, 18 stycznia 2011, 12:14

Mała uwaga: vectory przekazuj przed referencje, a nie jak teraz przez wartość (no, chyba że ma to jakieś uzasadnienie).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Cyfrowy Baron » wtorek, 18 stycznia 2011, 12:30

Przypuszczam, że chodzi Tobie o ten wektor jako argument funkcji: vector<Tik> P
Nie przekazuję go przez referencję, gdyż chcę się w ten sposób zabezpieczyć, przed potencjalnymi zmianami jakie mogłyby zajść w tym wektorze wewnątrz funkcji, a nie powinny. Mógłbym oczywiście użyć referencji, ale wtedy argument musiałby być typu const:

KOD cpp:     UKRYJ  
void sum(const vector<Tik> &P, macierz &mac, int days,
        int adresSMA, int countTik, int m)


Poza tym co zyskam na tej referencji? Co z dodatkowym kosztem dereferencji?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez polymorphism » wtorek, 18 stycznia 2011, 12:30

Mógłbym oczywiście użyć referencji, ale wtedy argument musiałby być typu const:

I tak to powinno być zrobione. Tak zwane const corectness jest wbrew pozorom ważne.

Poza tym co zyskam na tej referencji?

Nie robisz kopii vectora.

Co z dodatkowym kosztem dereferencji?

Żaden koszt.
Ostatnio edytowano wtorek, 18 stycznia 2011, 12:33 przez polymorphism, łącznie edytowano 1 raz
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Corvis
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Corvis » poniedziałek, 15 października 2012, 08:41

Witam,

Odświeżę trochę temat, zrobiłem to tak:

KOD cpp:     UKRYJ  
int Adres = wyk.ParametryFunkcji[0].Wartosc; // Wartość adresu danych
int okres = wyk.ParametryFunkcji[1].Wartosc; // okres średniej
double suma = 0;
double val = 0;
int Max = 0;

for(int t = KONIEC_LICZENIA - 1; t >= POCZATEK_LICZENIA ; t--) {
        Max = t - okres;
        if(Max <= 0) Max = 0;
        while(Max != t) {
                val = DanePrzeliczone[Max].WartosciTikow[Adres];
                suma+=val;
                Max++;
        }
        DanePrzeliczone[t].WartosciTikow[Adres] = suma/okres;
        suma=0;
}
 


EDIT:

Siedzę dalej w temacie średnich - tym razem w problemie optymalizacji.

Baronie twój kod który ostatnio podałeś dla 2 000 000 tików i okresu średniej 1000 wykonuje się u mnie ok 7-8 sekund, ten co ja podałem bardzo podobnie. Pytanie za 100 punktów, czy da się to trochę przyśpieszyć ??
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: SMA - poddaje się

Nowy postprzez polymorphism » niedziela, 4 listopada 2012, 11:22

A może to po prostu musi zająć te parę sekund, co?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: SMA - poddaje się

Nowy postprzez Corvis » niedziela, 4 listopada 2012, 11:24

Widziałem program gdzie dla okresu 1000 liczy się to 2 sekundy :) Albo ktoś oszukuje i upraszcza liczenie albo po prostu są jakieś sposoby żeby to ogarnąć.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Poprzednia stronaNastępna strona

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości