Dzień dobry. Muszę napisać program w C++, który powinien wygenerować sygnał opisany przez taką zależność:
\(\displaystyle{ t=0,...,1 s}\)
\(\displaystyle{ f _{s}=10kHz}\)
\(\displaystyle{ g\left( t\right) = \frac{2}{ \pi } \sum_{p=1}^{30} \frac{ \left( -1^{p} \right) }{p}\left[ \cos \left( \frac{p \cdot \pi \cdot 0.05f _{s}}{0.15f _{s}} \right)-1 \right]\sin \left( \frac{p \cdot \pi \cdot t}{0.15f _{s}} \right)}\)
Domyślam się, że skoro czas trwania ma wynosić 1 sekundę, a częstotliwość wynosi 10000 Hz, to trzeba tu zrobić pętlę for od 1 do 10000, ale nie za bardzo wiem, jak podejść do tej sumy od \(\displaystyle{ p=1}\) do \(\displaystyle{ p=30}\), tzn. jaka jest jej zależność od kolejnych iteracji. Czy mogłabym prosić o jakieś wskazówki?
[C++] generowanie sygnału
- Igor V
- Użytkownik
- Posty: 1605
- Rejestracja: 16 lut 2011, o 16:48
- Płeć: Mężczyzna
- Lokalizacja: Polska
- Podziękował: 18 razy
- Pomógł: 604 razy
Re: [C++] generowanie sygnału
Nie no, \(\displaystyle{ f_s}\) to pewnie częstotliwość próbkowania, więc jest ustalona (zresztą pisze).
Zrób pierwszą pętlę po ilości kwantów czasu \(\displaystyle{ t}\), które musisz sobie jakoś wyznaczyć z tego przedziału \(\displaystyle{ [0, 1]}\) (np: liniowo). Drugą (wewnętrzną) zrób po \(\displaystyle{ p \in \{1,2\dots 30\}}\) gdzie sumujesz wartości.-- 28 paź 2017, o 17:22 --EDIT: Tak, liniowo - bo wyznaczysz sobie te punkty z \(\displaystyle{ f_s}\) po prostu. Czyli ta pierwsza pętla zgadza się z tym co napisałaś.
Zrób pierwszą pętlę po ilości kwantów czasu \(\displaystyle{ t}\), które musisz sobie jakoś wyznaczyć z tego przedziału \(\displaystyle{ [0, 1]}\) (np: liniowo). Drugą (wewnętrzną) zrób po \(\displaystyle{ p \in \{1,2\dots 30\}}\) gdzie sumujesz wartości.-- 28 paź 2017, o 17:22 --EDIT: Tak, liniowo - bo wyznaczysz sobie te punkty z \(\displaystyle{ f_s}\) po prostu. Czyli ta pierwsza pętla zgadza się z tym co napisałaś.
-
- Użytkownik
- Posty: 18
- Rejestracja: 16 sty 2016, o 19:20
- Płeć: Kobieta
- Lokalizacja: Polska
- Podziękował: 11 razy
Re: [C++] generowanie sygnału
Napisałam coś takiego:
Chyba tak to powinno być zrobione?
Niestety czasami
Kod: Zaznacz cały
double czas[10000];
double g[10000];
double pi = M_PI;
double t, dzialanie, suma = 0.0;
for (int i=0; i<10000; ++i)
{
t=(i+1.0)/10000.0;
czas[i]=t;
for (int j=0; j<30; ++j)
{
dzialanie = (std::pow((-1.0),j) / j) * (cos((j*pi*0.05*10000.0) / (0.15*10000.0))-1.0) * sin((j*pi*t)/(0.15*10000.0));
if((dzialanie==dzialanie)==false)
dzialanie=0;
suma=suma+dzialanie;
}
g[i]=(2/pi)*suma;
std::cout << czas[i] << " "<< g[i] << std::endl;
}
Niestety czasami
dzialanie
dawało -nan
, więc wtedy ustawiam jego wartość na 0. Ogólnie po wypisaniu czas[i]
i g[i]
do pliku i złożeniu z tego wykresu \(\displaystyle{ g\left( t\right)}\) wychodzi coś takiego:
Ostatnio zmieniony 29 paź 2017, o 10:09 przez qwerz, łącznie zmieniany 1 raz.
- Igor V
- Użytkownik
- Posty: 1605
- Rejestracja: 16 lut 2011, o 16:48
- Płeć: Mężczyzna
- Lokalizacja: Polska
- Podziękował: 18 razy
- Pomógł: 604 razy
Re: [C++] generowanie sygnału
1. Nie powinnaś porównywać typów zmiennoprzecinkowych przez \(\displaystyle{ ==}\) ze względu na zaokrąglenia. Trzeba dawać zawsze jakiś margines.
2. Masz wartości niezdefiniowane zapewne dlatego że dla \(\displaystyle{ j = 0}\) jest dzielenie przez \(\displaystyle{ 0}\).
3. Nie jestem przekonany do końca na temat metody generacji czasu.
4. Uwaga praktyczna - wszelkie parametry najwygodniej zapisywać w postaci nazw i tak ich używać. Jak zmieni Ci się jakiś to nie musisz potem grzebać po całym programie + pstwo pomyłki przy zamianie jest mniejsze.
Ogólnie wyszło mi coś podobnego (w sensie kształtu), tyle że inne wartości.
2. Masz wartości niezdefiniowane zapewne dlatego że dla \(\displaystyle{ j = 0}\) jest dzielenie przez \(\displaystyle{ 0}\).
3. Nie jestem przekonany do końca na temat metody generacji czasu.
4. Uwaga praktyczna - wszelkie parametry najwygodniej zapisywać w postaci nazw i tak ich używać. Jak zmieni Ci się jakiś to nie musisz potem grzebać po całym programie + pstwo pomyłki przy zamianie jest mniejsze.
Kod: Zaznacz cały
#include <iostream>
#include <math.h>
using namespace std;
const double F_S = 10e3;
const double LEFT_TIME_POINT = 0;
const double RIGHT_TIME_POINT = 1;
const int MAX_SUM_INDEX = 30;
const double PI = M_PI;
double fancy_signal(int max_sum_index, double pi, double f_s, double time_point)
{
double output = 0;
for(int i = 1; i <= max_sum_index; i++)
{
output += (pow(-1, i)/i)*(cos((i*pi*0.05)/0.15) - 1)*sin((i*pi*time_point)/(0.15*f_s));
}
output = (2/pi)*output;
return output;
}
int main()
{
double time = RIGHT_TIME_POINT - LEFT_TIME_POINT;
int number_of_points = (int)F_S*time;
double step = time/(number_of_points - 1);
double g[number_of_points];
double time_vector[number_of_points];
for(int i = 0; i < number_of_points; i++)
{
time_vector[i] = LEFT_TIME_POINT + i*step;
g[i] = fancy_signal(MAX_SUM_INDEX, PI, F_S, time_vector[i]);
}
return 0;
}
Kod: Zaznacz cały
http://wstaw.org/h/52f30151129/