Calcolo Numerico: Esercitazione di Laboratorio...

22
Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini [email protected] 18 febbraio 2012 Esercizio Implementare l’algoritmo CORDIC per il calcolo delle funzioni circolari e delle funzioni iperboliche. Implementare sia la modalità ROTATION sia la modalità VECTOR (funzioni inverse). Mostrare con un esempio che per le funzioni iperboliche è necessario ripetere ogni passo per approssimare correttamente l’algoritmo. Il metodo CORDIC serve per calcolare le funzioni elementari effettuando solo addizioni, shift e una moltiplicazione. Tale metodo è molto utile quando non c’è una moltiplicazione hardware e quindi è esseziale fare meno moltiplicazioni possibili. Trova impiego per esempio all’interno di al- cune calcolatrici da tavolo. L’idea che sta alla base della modalità ROTATION è la seguente: se si ruota nel piano il vettore (1, 0) di un angolo θ, allora le coordinate del nuovo punto sono (cosθ, sinθ); la rotazione dell’angolo θ verrà effettuata con una successione di n rotazioni elementari ciascuna di costo trascurabile. Con questa modalità è possibile calcolare le funzioni seno e coseno di un certo angolo così come le relative funzioni trigonometriche iperboliche. Segue il codice C della funzione che permette di calcolare il seno e coseno di un certo angolo θ utilizzando il metodo CORDIC nella modalità ROTATION. void cordic_r(double theta, double *sin, double *cos) { // compute sin and cos values by rotation method // -1.74... =< theta in radian <= 1.74... double k,s,a,b,c,d,e,f,g,h,l,m,appx,appy,sigma; int i,n; *sin=0; *cos=1; n=54; // rotations number k=1; for(i=0;i<n;i++) // compute costant k { a=(double)-2*i; b=pow(2,a); c=sqrt(1+b); d=1/c; k=k*d; 1

Transcript of Calcolo Numerico: Esercitazione di Laboratorio...

Page 1: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

Calcolo Numerico: Esercitazione di Laboratorio N.3

Marco Trentini [email protected]

18 febbraio 2012

Esercizio

Implementare l’algoritmo CORDIC per il calcolo delle funzioni circolari e delle funzioni iperboliche.Implementare sia la modalità ROTATION sia la modalità VECTOR (funzioni inverse). Mostrarecon un esempio che per le funzioni iperboliche è necessario ripetere ogni passo per approssimarecorrettamente l’algoritmo.

Il metodo CORDIC serve per calcolare le funzioni elementari effettuando solo addizioni, shift euna moltiplicazione. Tale metodo è molto utile quando non c’è una moltiplicazione hardware equindi è esseziale fare meno moltiplicazioni possibili. Trova impiego per esempio all’interno di al-cune calcolatrici da tavolo.

L’idea che sta alla base della modalità ROTATION è la seguente: se si ruota nel piano il vettore(1, 0) di un angolo θ, allora le coordinate del nuovo punto sono (cosθ, sinθ); la rotazione dell’angoloθ verrà effettuata con una successione di n rotazioni elementari ciascuna di costo trascurabile. Conquesta modalità è possibile calcolare le funzioni seno e coseno di un certo angolo così come le relativefunzioni trigonometriche iperboliche.

Segue il codice C della funzione che permette di calcolare il seno e coseno di un certo angolo θ

utilizzando il metodo CORDIC nella modalità ROTATION.

void cordic_r(double theta, double *sin, double *cos)

{

// compute sin and cos values by rotation method

// -1.74... =< theta in radian <= 1.74...

double k,s,a,b,c,d,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

*sin=0;

*cos=1;

n=54; // rotations number

k=1;

for(i=0;i<n;i++) // compute costant k

{

a=(double)-2*i;

b=pow(2,a);

c=sqrt(1+b);

d=1/c;

k=k*d;

1

Page 2: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

}

s=0;

for(i=0;i<n;i++) // compute rotations and sin and cos values

{

if(s>theta)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atan(e);

g=sigma*f;

s=s+g; // rotation

h=sigma*e;

l=*sin * h;

appx=*cos-l;

m=*cos * h;

appy=m+*sin;

*cos=appx;

*sin=appy;

}

*sin=*sin*k; // sin value

*cos=*cos*k; // cos value

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridi seno e coseno utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta;

double cordic_sin,cordic_cos;

for(theta=-1.85;theta<1.9;theta=theta+0.01)

{

cordic_r(theta, &cordic_sin, &cordic_cos);

printf("theta %.5lf\n",theta);

printf("sin\n");

printf("cordic %.25lf\n",cordic_sin);

printf("sin() %.25lf\n",sin(theta));

printf("cos\n");

printf("cordic %.25lf\n",cordic_cos);

2

Page 3: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

printf("cos() %.25lf\n",cos(theta));

printf("\n");

}

return 0;

}

In questo modo andiamo a confrontare i valori risultanti dalla funzione CORDIC in esame con quellidelle funzioni trigonometriche seno e coseno applicate su un certo range di angoli θ. Segue un pezzodi output rilevante.

...

...

theta -1.77000

sin

cordic -0.9851603975295764037412027

sin() -0.9802244727880454755464257

cos

cordic -0.1716362174465750622953664

cos() -0.1978888146091090094458309

theta -1.76000

sin

cordic -0.9851603975295764037412027

sin() -0.9821543171376184711007795

cos

cordic -0.1716362174465750622953664

cos() -0.1880768388928800993742385

theta -1.75000

sin

cordic -0.9851603975295764037412027

sin() -0.9839859468739369230405600

cos

cordic -0.1716362174465750622953664

cos() -0.1782460556494920855818975

theta -1.74000

sin

cordic -0.9857191788355539330268584

sin() -0.9857191788355534889376486

cos

cordic -0.1683974479490762954370098

cos() -0.1683974479490770170819758

theta -1.73000

sin

cordic -0.9873538397007167732866151

sin() -0.9873538397007164402197077

cos

cordic -0.1585320006441978124556158

cos() -0.1585320006441977569444646

theta -1.72000

sin

cordic -0.9888897660047017978968142

3

Page 4: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

sin() -0.9888897660047014648299069

cos

cordic -0.1486507002713633451840280

cos() -0.1486507002713636504953598

...

...

theta 1.72000

sin

cordic 0.9888897660047012427853019

sin() 0.9888897660047010207406970

cos

cordic -0.1486507002713662317638921

cos() -0.1486507002713662872750433

theta 1.73000

sin

cordic 0.9873538397007164402197077

sin() 0.9873538397007159961304978

cos

cordic -0.1585320006442007267910554

cos() -0.1585320006442003937241481

theta 1.74000

sin

cordic 0.9857191788355533779153461

sin() 0.9857191788355530448484387

cos

cordic -0.1683974479490791265057226

cos() -0.1683974479490796261060837

theta 1.75000

sin

cordic 0.9851603975295764037412027

sin() 0.9839859468739364789513502

cos

cordic -0.1716362174465750622953664

cos() -0.1782460556494947223615810

theta 1.76000

sin

cordic 0.9851603975295764037412027

sin() 0.9821543171376179159892672

cos

cordic -0.1716362174465750622953664

cos() -0.1880768388928827361539220

...

...

Possiamo notare che la funzione CORDIC in esame converge con −1.74 . . . ≤ θ(radianti) ≤ 1.74 . . .ossia −99.7◦ . . . ≤ θ(gradi) ≤ 99.7◦ . . .. Oltre questo range non abbiamo una buona approssimazio-ne.

Segue il codice C della funzione che permette di calcolare il seno e coseno iperbolico di un certoangolo utilizzando il metodo CORDIC nella modalità ROTATION.

4

Page 5: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

void cordic_rh(double theta, double *sinh, double *cosh)

{

// compute sinh and cosh values by rotation method

// -2.11... =< theta in radian <= +2.11...

double k,k2,s,a,b,c,d,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

*sinh=0;

*cosh=1;

n=54;

k=1;

for(i=1;i<n;i++) // compute costant k

{

a=(double)-2*i;

b=pow(2,a);

c=sqrt(1-b);

d=1/c;

k=k*d;

}

s=0;

for(i=1;i<n;i++) // compute rotations and sin and cos values

{

if(s>theta)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atanh(e);

g=sigma*f;

s=s+g; //rotation

h=sigma*e;

l=*sinh * h;

appx=*cosh+l;

m=*cosh * h;

appy=m+*sinh;

*cosh=appx;

*sinh=appy;

// repeat the step

if(s>theta)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

5

Page 6: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

f=atanh(e);

g=sigma*f;

s=s+g;

h=sigma*e;

l=*sinh * h;

appx=*cosh+l;

m=*cosh * h;

appy=m+*sinh;

*cosh=appx;

*sinh=appy;

}

k2=k*k;

*sinh=*sinh*k2;

*cosh=*cosh*k2;

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridel seno e coseno iperbolico utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta;

double cordic_sinh,cordic_cosh;

for(theta=-2.15;theta<2.16;theta=theta+0.01)

{

cordic_rh(theta, &cordic_sinh, &cordic_cosh);

printf("theta %.5lf\n",theta);

printf("sinh\n");

printf("cordic %.25lf\n",cordic_sinh);

printf("sinh() %.25lf\n",sinh(theta));

printf("cosh\n");

printf("cordic %.25lf\n",cordic_cosh);

printf("cosh() %.25lf\n",cosh(theta));

printf("\n");

}

return 0;

}

In questo modo andiamo a confrontare i valori risultanti dalla funzione CORDIC con quelli dellefunzioni trigonometriche seno e coseno iperboliche per un particolare range di valori di θ. Segue unpezzo di output rilevante.

6

Page 7: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

...

...

theta -2.13000

sinh

cordic -4.0674318638878332876629429

sinh() -4.1480147587938613895630624

cosh

cordic 4.1885560718904120136585334

cosh() 4.2668520526462714315130142

theta -2.12000

sinh

cordic -4.0674318638878332876629429

sinh() -4.1055529295881196816253578

cosh

cordic 4.1885560718904120136585334

cosh() 4.2255845580995767818421882

theta -2.11000

sinh

cordic -4.0635016590966506200288677

sinh() -4.0635016590966426264230904

cosh

cordic 4.1847396255300353118400380

cosh() 4.1847396255300246536990016

theta -2.10000

sinh

cordic -4.0218567421573414577551375

sinh() -4.0218567421573379050414587

cosh

cordic 4.1443131704103199908217903

cosh() 4.1443131704103199908217903

theta -2.09000

sinh

cordic -3.9806140142438106721556323

sinh() -3.9806140142438075635311634

cosh

cordic 4.1043011500612678332799987

cosh() 4.1043011500612625042094805

...

...

theta 2.09000

sinh

cordic 3.9806140142437991258361762

sinh() 3.9806140142437946849440777

cosh

cordic 4.1043011500612571751389623

cosh() 4.1043011500612500697116047

theta 2.10000

sinh

7

Page 8: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

cordic 4.0218567421573307996141011

sinh() 4.0218567421573254705435829

cosh

cordic 4.1443131704103102208591736

cosh() 4.1443131704103075563239145

theta 2.11000

sinh

cordic 4.0635016590966390737094116

sinh() 4.0635016590966301919252146

cosh

cordic 4.1847396255300255418774213

cosh() 4.1847396255300122192011258

theta 2.12000

sinh

cordic 4.0674318638878332876629429

sinh() 4.1055529295881072471274820

cosh

cordic 4.1885560718904120136585334

cosh() 4.2255845580995634591658927

theta 2.13000

sinh

cordic 4.0674318638878332876629429

sinh() 4.1480147587938480668867669

cosh

cordic 4.1885560718904120136585334

cosh() 4.2668520526462581088367187

...

...

Possiamo notare che la funzione CORDIC in esame converge con −2.11 . . . ≤ θ(radianti) ≤ 2.11 . . .ossia −120.89◦ . . . ≤ θ(gradi) ≤ 120.89◦ . . .. Oltre questo range non abbiamo una buona approssi-mazione.

Facciamo notare che è necessario ripetere tutte le iterazioni (anche se in realtà possiamo ripe-terne solo alcune) affinchè il metodo converga in modo corretto per certi valori dell’angolo θ.Per verificarlo procediamo in questo modo: costruiamo la stessa funzione senza la ripetizione delleiterazioni.

void cordic_rh_NO(double theta, double *sinh, double *cosh)

{

// as cordic_rh without repeat the steps

double k,s,a,b,c,d,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

*sinh=0;

*cosh=1;

n=54;

k=1;

8

Page 9: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

for(i=1;i<n;i++) // compute costant k

{

a=(double)-2*i;

b=pow(2,a);

c=sqrt(1-b);

d=1/c;

k=k*d;

}

s=0;

for(i=1;i<n;i++) // compute rotations and sin and cos values

{

if(s>theta)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atanh(e);

g=sigma*f;

s=s+g; //rotation

h=sigma*e;

l=*sinh * h;

appx=*cosh+l;

m=*cosh * h;

appy=m+*sinh;

*cosh=appx;

*sinh=appy;

}

*sinh=*sinh*k;

*cosh=*cosh*k;

}

Ora valutiamo entrambe le funzioni per alcuni valori di θ per i quali sappiamo che la funzionecorretta (quella con la ripetizioni dei passi) converge. Usiamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta;

double cordic_sinh,cordic_cosh;

double cordic_sinh_no,cordic_cosh_no;

for(theta=-2.15;theta<2.16;theta=theta+0.01)

9

Page 10: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

{

cordic_rh(theta, &cordic_sinh, &cordic_cosh);

cordic_rh_NO(theta, &cordic_sinh_no, &cordic_cosh_no);

printf("theta %.5lf\n",theta);

printf("sinh\n");

printf("cordic %.25lf\n",cordic_sinh);

printf("cordic no %.25lf\n",cordic_sinh_no);

printf("sinh() %.25lf\n",sinh(theta));

printf("cosh\n");

printf("cordic %.25lf\n",cordic_cosh);

printf("cordic no %.25lf\n",cordic_cosh_no);

printf("cosh() %.25lf\n",cosh(theta));

printf("\n");

}

return 0;

}

Segue un pezzo di output rilevante.

...

...

theta -1.86000

sinh

cordic -3.1340320705305781956440114

cordic no -1.2626472333732827735275350

sinh() -3.1340320705305781956440114

cosh

cordic 3.2897047008985738081321415

cordic no 1.6106762666486416080147137

cosh() 3.2897047008985751403997710

theta -1.85000

sinh

cordic -3.1012911781441094838385197

cordic no -1.2626472333732827735275350

sinh() -3.1012911781441117042845690

cosh

cordic 3.2585283444577402001129940

cordic no 1.6106762666486416080147137

cosh() 3.2585283444577388678453644

theta -1.84000

sinh

cordic -3.0688604174598781426652749

cordic no -1.2626472333732827735275350

sinh() -3.0688604174598776985760651

cosh

cordic 3.2276778435668020961202274

cordic no 1.6106762666486416080147137

cosh() 3.2276778435667980993173387

...

...

10

Page 11: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

theta 1.61000

sinh

cordic 2.4014618068792210614503801

cordic no 1.2626472333732827735275350

sinh() 2.4014618068792206173611703

cosh

cordic 2.6013494209543668311823694

cordic no 1.6106762666486416080147137

cosh() 2.6013494209543654989147399

theta 1.62000

sinh

cordic 2.4275958087401279250627795

cordic no 1.2626472333732827735275350

sinh() 2.4275958087401257046167302

cosh

cordic 2.6254945078237432731782519

cordic no 1.6106762666486416080147137

cosh() 2.6254945078237401645537830

theta 1.63000

sinh

cordic 2.4539725722049094969179350

cordic no 1.2626472333732827735275350

sinh() 2.4539725722049077205610956

cosh

cordic 2.6499021463318168656542184

cordic no 1.6106762666486416080147137

cosh() 2.6499021463318164215650086

...

...

Possiamo notare che la funzione senza la ripetizione di tutte le iterazioni produce dei risultati sba-gliati. Ecco quindi una piccola dimostrazione pratica della necessità di ripetizione di alcuni passi(nel nostro caso tutti) per approssimare correttamente l’algoritmo.

Con la modalità VECTOR è possibile calcolare le funzioni inverse di seno e coseno (arcsin e arccos)e le rispettive funzioni inverse iperboliche (arcsinh e arccosh). L’idea che sta alla base della modalitàVECTOR è la seguente: si ruota nel piano il vettore (1, 0) affinchè la sua componente y nel caso diarcoseno (o x nel caso di arcocoseno) è uguale a una costante c data in input. L’angolo necessarioper allineare la componente considerata alla costante c sarà il valore dell’arcoseno o dell’arcocoseno(a seconda della componente considerata). Quindi abbiamo che c = An · θ, dove An è il guadagnodell’algoritmo di CORDIC che dipende dal numero di iterazioni dello stesso e θ è l’angolo di cuivogliamo conoscere l’arcoseno e/o arcocoseno.

Segue il codice C della funzione che permette di calcolare l’arcoseno di un certo angolo utilizzandoil metodo CORDIC nella modalità VECTOR.

void cordic_arcsin(double w, double *arcsin)

{

// compute arcsin value by vector method

// of an angle >= -0.98... <= 0.98... (in radian)

double x,y,s,e,f,g,h,l,m,appx,appy,sigma;

11

Page 12: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

int i,n;

x=1;

y=0;

n=54;

s=0;

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

{

if(y>=w)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atan(e);

g=sigma*f;

s=s+g;

h=sigma*e;

l=y * h;

appx=x-l;

m=x * h;

appy=m+y;

x=appx;

y=appy;

}

*arcsin=s;

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridell’arcoseno utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta,an;

double cordic_asin;

compute_an(&an,54);

for(theta=-1;theta<1.01;theta=theta+0.01)

{

cordic_arcsin(theta*an, &cordic_asin);

printf("theta %.5lf\n",theta);

12

Page 13: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

printf("cordic %.25lf\n",cordic_asin);

printf("asin() %.25lf\n",asin(theta));

printf("\n");

}

return 0;

}

La funzione compute_an calcola il guadagno dell’algoritmo in base al numero di passi dello stesso.Segue il suo codice C.

void compute_an(double *an,int n)

{

double a,b,c;

int i;

*an=1;

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

{

a=(double)-2*i;

b=pow(2,a);

c=sqrt(1+b);

*an=*an*c;

}

}

Usando il main sopra riportato andiamo a confrontare i valori risultanti dalla funzione CORDICcon quelli della funzione trigonometrica arcoseno per un particolare range di valori di θ. Segue unpezzo di output rilevante.

...

...

theta -1.00000

cordic -1.7432866204723400649356790

asin() -1.5707963267948965579989817

theta -0.99000

cordic -1.4934722396714201764211793

asin() -1.4292568534704692684300653

theta -0.98000

cordic -1.3704614844717748489699716

asin() -1.3704614844717768473714159

theta -0.97000

cordic -1.3252308092796041272265484

asin() -1.3252308092796045713157582

...

...

theta 0.96000

13

Page 14: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

cordic 1.2870022175865725166943321

asin() 1.2870022175865738489619616

theta 0.97000

cordic 1.3252308092796094562970666

asin() 1.3252308092796103444754863

theta 0.98000

cordic 1.3704614844717810662189095

asin() 1.3704614844717841748433784

theta 0.99000

cordic 1.4934722396714201764211793

asin() 1.4292568534704794824818919

...

...

Possiamo notare che la funzione CORDIC in esame converge con −0.98 . . . ≤ θ(radianti) ≤ 0.98 . . .ossia −56.14◦ . . . ≤ θ(gradi) ≤ 56.14◦ . . .. Oltre questo range non abbiamo una buona approssima-zione.

Segue il codice C della funzione che permette di calcolare l’arcocoseno di un certo angolo utilizzandoil metodo CORDIC nella modalità VECTOR.

void cordic_arcos(double w, double *arcos)

{

// compute arcos value by vector method

// of an angle >= -0.17... <= 0.6... (in radian)

double x,y,s,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

x=1;

y=0;

n=54;

s=0;

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

{

if(x>=w)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atan(e);

g=sigma*f;

s=s-g;

h=sigma*e;

l=y * h;

appx=x-l;

14

Page 15: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

m=x * h;

appy=m+y;

x=appx;

y=appy;

}

*arcos=s;

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridell’arcocoseno utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta,an;

double cordic_acos;

compute_an(&an,54);

for(theta=-0.2;theta<0.65;theta=theta+0.01)

{

cordic_arcos(theta*an, &cordic_acos);

printf("theta %.5lf\n",theta);

printf("cordic %.25lf\n",cordic_acos);

printf("acos() %.25lf\n",acos(theta));

printf("\n");

}

return 0;

}

In questo modo andiamo a confrontare i valori risultanti dalla funzione CORDIC con quelli dellafunzione trigonometrica arcocoseno per un particolare range di valori di θ. Segue un pezzo di outputrilevante.

...

...

theta -0.19000

cordic 1.7432866204723400649356790

acos() 1.7619584733259563424923044

theta -0.18000

cordic 1.7432866204723400649356790

acos() 1.7517827780414443328282914

15

Page 16: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

theta -0.17000

cordic 1.7416259959240010246617203

acos() 1.7416259959240010246617203

theta -0.16000

cordic 1.7314869797468075418578337

acos() 1.7314869797468070977686239

theta -0.15000

cordic 1.7213645995715829428718280

acos() 1.7213645995715824987826181

...

...

theta 0.58000

cordic 0.9520676361226447781405113

acos() 0.9520676361226450001851163

theta 0.59000

cordic 0.9397374860168745680510938

acos() 0.9397374860168747900956987

theta 0.60000

cordic 0.9272952180016114098748403

acos() 0.9272952180016117429417477

theta 0.61000

cordic -1.7432866204723400649356790

acos() 0.9147357358699733653750741

theta 0.62000

cordic -1.7432866204723400649356790

acos() 0.9020536235925242785071987

...

...

Possiamo notare che la funzione CORDIC in esame converge con −0.17 . . . ≤ θ(radianti) ≤ 0.6 . . .ossia −9.74◦ . . . ≤ θ(gradi) ≤ 34.37◦ . . .. Oltre questo range non abbiamo una buona approssima-zione.

Segue il codice C della funzione che permette di calcolare l’arcoseno iperbolico di un certo an-golo utilizzando il metodo CORDIC nella modalità VECTOR.

void cordic_arcsinh(double w, double *arcsinh)

{

// compute arcsinh value by vector method

// of an angle >= -1.26... <= 1.26... (in radian)

double x,y,s,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

16

Page 17: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

x=1;

y=0;

n=54;

s=0;

for(i=1;i<n;i++)

{

if(y>=w)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atanh(e);

g=sigma*f;

s=s+g;

h=sigma*e;

l=y * h;

appx=x+l;

m=x * h;

appy=m+y;

x=appx;

y=appy;

}

*arcsinh=s;

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridell’arcoseno iperbolico utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta,anh;

double cordic_asinh;

compute_anh(&anh,54);

for(theta=-1.28;theta<1.29;theta=theta+0.01)

{

cordic_arcsinh(theta*anh, &cordic_asinh);

printf("theta %.5lf\n",theta);

printf("cordic %.25lf\n",cordic_asinh);

printf("asinh() %.25lf\n",asinh(theta));

17

Page 18: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

printf("\n");

}

return 0;

}

La funzione compute_anh calcola il guadagno dell’algoritmo in base al numero di passi dellostesso. Segue il suo codice C.

void compute_anh(double *anh,int n)

{

double a,b,c;

int i;

*anh=1;

for(i=1;i<n;i++)

{

a=(double)-2*i;

b=pow(2,a);

c=sqrt(1-b);

*anh=*anh*c;

}

}

Usando il main sopra riportato andiamo a confrontare i valori risultanti dalla funzione CORDICcon quelli della funzione trigonometrica arcoseno iperbolico per un particolare range di valori di θ.Segue un pezzo di output rilevante.

...

...

theta -1.28000

cordic -1.0554693737354847726805929

asinh() -1.0661976449070125205764725

theta -1.27000

cordic -1.0554693737354847726805929

asinh() -1.0600262371581044007484707

theta -1.26000

cordic -1.0538247603460848544898454

asinh() -1.0538247603460844104006355

theta -1.25000

cordic -1.0475930126492589700148983

asinh() -1.0475930126492587479702934

theta -1.24000

cordic -1.0413307920087899738348369

asinh() -1.0413307920087899738348369

...

...

18

Page 19: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

theta 1.24000

cordic 1.0413307920087913061024665

asinh() 1.0413307920087910840578616

theta 1.25000

cordic 1.0475930126492598581933180

asinh() 1.0475930126492598581933180

theta 1.26000

cordic 1.0538247603460857426682651

asinh() 1.0538247603460857426682651

theta 1.27000

cordic 1.0554693737354847726805929

asinh() 1.0600262371581055109714953

theta 1.28000

cordic 1.0554693737354847726805929

asinh() 1.0661976449070136307994972

...

...

Possiamo notare che la funzione CORDIC in esame converge con −1.26 . . . ≤ θ(radianti) ≤ 1.26 . . .ossia −72.19◦ . . . ≤ θ(gradi) ≤ 72.19◦ . . .. Oltre questo range non abbiamo una buona approssima-zione.

Segue il codice C della funzione che permette di calcolare l’arcocoseno iperbolico di un certo angoloutilizzando il metodo CORDIC nella modalità VECTOR.

void cordic_arcosh(double w, double *arcosh)

{

// compute arcosh value by vector method

// of an angle >= 1.21... <= 1.61... (in radian)

double x,y,s,e,f,g,h,l,m,appx,appy,sigma;

int i,n;

x=1;

y=0;

n=54;

s=0;

for(i=1;i<n;i++)

{

if(x>=w)

sigma=-1;

else

sigma=1;

e=pow(2,(double)-i);

f=atanh(e);

g=sigma*f;

19

Page 20: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

s=s+g;

h=sigma*e;

l=y * h;

appx=x+l;

m=x * h;

appy=m+y;

x=appx;

y=appy;

}

*arcosh=s;

}

Per vedere qual’è il range di valori dell’angolo θ entro il quale tale funzione converge ai reali valoridell’arcocoseno iperbolico utilizziamo il seguente main.

// compile as gcc -I./ main.c -lm -o ex3

#include <cordic.h>

#include <stdio.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

//check convergent values

double theta,anh;

double cordic_acosh;

compute_anh(&anh,54);

for(theta=1.01;theta<1.65;theta=theta+0.01)

{

cordic_arcosh(theta*anh, &cordic_acosh);

printf("theta %.5lf\n",theta);

printf("cordic %.25lf\n",cordic_acosh);

printf("acosh() %.25lf\n",acosh(theta));

printf("\n");

}

return 0;

}

In questo modo andiamo a confrontare i valori risultanti dalla funzione CORDIC con quelli dellafunzione trigonometrica arcocoseno iperbolico per un particolare range di valori di θ. Segue unpezzo di output rilevante.

...

...

theta 1.18000

cordic -1.0554693737354847726805929

acosh() 0.5913460951268451060158782

20

Page 21: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

theta 1.19000

cordic -1.0554693737354847726805929

acosh() 0.6070761632470630386748667

theta 1.20000

cordic -1.0554693737354847726805929

acosh() 0.6223625037147789695879396

theta 1.21000

cordic 0.6372373797541088791263064

acosh() 0.6372373797541083240147941

theta 1.22000

cordic 0.6517292837263393145974533

acosh() 0.6517292837263388705082434

theta 1.23000

cordic 0.6658635291565559999327206

acosh() 0.6658635291565551117543009

...

...

theta 1.59000

cordic 1.0389201097727607248089043

acosh() 1.0389201097727607248089043

theta 1.60000

cordic 1.0469679150031896419648092

acosh() 1.0469679150031887537863895

theta 1.61000

cordic 1.0549335963808532667940199

acosh() 1.0549335963808523786156002

theta 1.62000

cordic 1.0554693737354847726805929

acosh() 1.0628191274087777085100015

theta 1.63000

cordic 1.0554693737354847726805929

acosh() 1.0706264039066135662636725

...

...

Possiamo notare che la funzione CORDIC in esame converge con 1.21 . . . ≤ θ(radianti) ≤ 1.61 . . . os-sia 69.32◦ . . . ≤ θ(gradi) ≤ 92.24◦ . . .. Oltre questo range non abbiamo una buona approssimazione.

Concludiamo questa relazione affermando che le nostre calcolatrici scientifiche grafiche (modelloEL-9300 della sharp) non fanno uso del metodo del CORDIC per il calcolo delle funzioni trigono-metriche (o per lo meno non come lo abbiamo implementato ed analizzato noi in questa relazione).Per esempio con le nostre calcolatrici siamo in grado di valutare il seno di 2 radianti, cosa che nonè possibile con il CORDIC in modalità ROTATION. Ci rimane ancora da scoprire come effettiva-mente vengono calcolate le funzioni trigonometriche nelle nostre calcolatrici, ma questa è un’altra

21

Page 22: Calcolo Numerico: Esercitazione di Laboratorio Ndatasked.com/pub/doc/it/articles/num-calc/ex3/ex3.pdf · Calcolo Numerico: Esercitazione di Laboratorio N.3 Marco Trentini mt@datasked.com

storia.

22