Készítsen sine keresési táblázatban a C ++

szavazat
10

Hogyan átírni a következő pszeudokódokra C ++?

real array sine_table[-1000..1000]
    for x from -1000 to 1000
        sine_table[x] := sine(pi * x / 1000)

Létre kell hozni egy sine_table keresési táblázat.

A kérdést 10/09/2010 22:57
a forrás felhasználó
Más nyelveken...                            


6 válasz

szavazat
6

Azt akarja, a std::sin()funkciót <cmath>.

Válaszolt 10/09/2010 23:00
a forrás felhasználó

szavazat
4
long double sine_table[2001];
for (int index = 0; index < 2001; index++)
{
    sine_table[index] = std::sin(PI * (index - 1000) / 1000.0);
}
Válaszolt 10/09/2010 23:03
a forrás felhasználó

szavazat
3


double table[1000] = {0};
for (int i = 1; i <= 1000; i++)
{
    sine_table[i-1] = std::sin(PI * i/ 1000.0);
}

double getSineValue(int multipleOfPi){ if(multipleOfPi == 0) return 0.0; int sign = 1; if(multipleOfPi < 0){ sign = -1;
} return signsine_table[signmultipleOfPi - 1]; }

Csökkentheti a tömb hossza 500, egy trükk sin (pi / 2 +/- szög) = +/- cos (szög). Tehát áruház bűn és cos 0 pi / 4. Nem emlékszem, honnan a fejem tetején, de felgyorsult a programom.

Válaszolt 11/09/2010 00:29
a forrás felhasználó

szavazat
25

Csökkentheti a méretét, a tábla 25% -a az eredeti csak értékek tárolására az első negyedben, azaz x [0, pi / 2].

Ehhez a keresési rutin csak meg kell feltérképezni az összes x értékei az első negyedben egyszerű trigonometrikus azonosságok:

  • sin (x) = - sin (-x), hogy feltérképezzük a kvadráns IV I
  • sin (x) = sin (pi - x), hogy feltérképezzük a kvadráns II I

A térkép a kvadráns III I alkalmazni mind identitásokat, azaz sin (x) = - sin (PI + x)

Hogy ez a stratégia segít attól függ, mennyi memória használat kérdésekben az Ön esetében. De úgy tűnik, pazarló tárolni négyszer annyi értéket, amennyire szüksége van, csak hogy elkerülje az összehasonlítás és a kivonás vagy két közben elemzéssel.

Azt második Jeremy ajánlása mérhető, hogy az épület egy asztal jobb, mint csak a std :: sin (). Még az eredeti nagy asztal, akkor meg kell tölteni ciklus során minden táblázatkikeresési átalakítani az érv a legközelebbi növekménye pi / 1000, és akkor veszítesz pontossága ebben a folyamatban.

Ha tényleg próbál kereskedni pontosság sebesség, akkor megpróbálhatja közelítő sin () függvény segítségével csak az első néhány szempontból a Taylor-sor bővítése.

  • sin (x) = x - x ^ 3/3! + X ^ 5/5! ..., ahol ^ jelentése hatványozás és! képviseli a faktoriális.

Természetesen, a hatékonyság, akkor precompute a faktoriális és használja az alsó hatáskörét x kiszámításához magasabbak, mint pl use x ^ 3 számításakor x ^ 5.

Egy utolsó pont, a csonkolt Taylor-sor felett pontosabb értékek közelebb a nullához, ezért is érdemes feltérképezni, hogy az első vagy a negyedik negyedben előtt kiszámítjuk a közelítő sine.

Kiegészítés: egy még további lehetséges fejlesztések két megfigyelésen alapult:
1. Ön tudja számítani minden trigonometrikus funkció, ha ki tudja számítani mind a szinusz és koszinusz az első oktáns [0, pi / 4]
2. A Taylor sorfejtés középpontú a nulla pontosabb közel nulla

Tehát, ha úgy döntenek, hogy a csonka Taylor-sor, akkor a pontosság növelésére (vagy kevesebb kifejezést hasonló pontossággal) hozzárendelésével vagy a szinusz vagy koszinusz, hogy a szög a [0, pi / 4] segítségével identitásokat, mint sin (x) = cos (pi / 2-x) és cos (x) = sin (pi / 2-x) mellett az is a fenti (például, ha x> pi / 4, ha már leképezve a első negyedben.)

Vagy ha úgy döntenek, hogy egy táblázatból mind a szinusz és koszinusz, akkor is kap a két kisebb asztal, hogy csak lefedett az a [0, pi / 4] rovására másik lehetséges összehasonlítás és kivonás a keresési hozzárendelni a kisebb tartományban. Akkor lehetne akár kevesebb memóriát az asztalok között, vagy használja ugyanazt a memóriát, de finomabb részletesség és pontosság.

Válaszolt 11/09/2010 00:55
a forrás felhasználó

szavazat
4

Még egy pont: hívó trigonometrikus függvények is drága. Ha azt szeretnénk, hogy előkészítse a keresési táblázat a szinusz állandó lépés - lehet menteni a számítási időt, a rovására néhány potenciális pontosság veszteség.

Fontolja meg a minimális lépés „a”. Vagyis azt, hogy szükség van sin (a), sin (2a), sin (3a), ...

Akkor lehet csinálni a következő ütéshez: Először számítsuk sin (a) és cos (a). Ekkor minden egymást követő lépésben használja a következő trigonometrikus egyenletek:

  • sin ([n + 1] * a) = sin (n * a) * cos (a) + cos (n * a) * sin (a)
  • cos ([n + 1] * a) = cos (n * a) * cos (a) - sin (n * a) * sin (a)

A hátránya ennek a módszernek, hogy az eljárás során a kerekítési hiba halmozódik.

Válaszolt 19/09/2010 18:37
a forrás felhasználó

szavazat
3

Egy másik közelítés egy könyv, vagy valami

streamin ramp;
streamout sine;

float x,rect,k,i,j;

x = ramp -0.5;

rect = x * (1 - x < 0 & 2);
k = (rect + 0.42493299) *(rect -0.5) * (rect - 0.92493302) ;
i = 0.436501 + (rect * (rect + 1.05802));
j = 1.21551 + (rect * (rect - 2.0580201));
sine = i*j*k*60.252201*x;

teljes beszélgetés itt: http://synthmaker.co.uk/forum/viewtopic.php?f=4&t=6457&st=0&sk=t&sd=a

Feltételezem, hogy tudod, hogy egy osztály egy sokkal lassabb, mint megszorozzuk decimális szám, / 5 mindig lassabb, mint a * 0,2

ez csak egy közelítés.

is:

streamin ramp;
streamin x;  // 1.5 = Saw   3.142 = Sin   4.5 = SawSin
streamout sine;
float saw,saw2;
saw = (ramp * 2 - 1) * x;
saw2 = saw * saw;

sine = -0.166667 + saw2 * (0.00833333 + saw2 * (-0.000198409 + saw2 * (2.7526e-006+saw2 * -2.39e-008)));
sine = saw * (1+ saw2 * sine);
Válaszolt 29/03/2013 23:14
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more