lunedì 19 settembre 2011

I logaritmi come li fanno i computer — parte 6

Abbiamo visto come calcolare velocemente, ed economicamente, seno e coseno. Di conseguenza possiamo calcolare anche la tangente, uguale al rapporto seno fratto coseno. Ora vediamo come calcolare la funzione inversa della tangente, cioè l'arcotangente (lo so che dovevamo calcolare i logaritmi, ma per farlo dobbiamo prima passare di qua).

Allora, il problema è quello di calcolare l'angolo la cui tangente è, per esempio, 2.

L'idea è quella di prendere il ventaglio, partire dal risultato (data la tangente, possiamo conoscere seno e coseno) e procedere all'indietro, andando verso lo zero. Cosa che avevamo già fatto per il calcolo del seno e del coseno; ciò che cambia qui è il punto di partenza: il rapporto tra S0 C0 deve essere uguale alla tangente dell'angolo (e non è nemmeno necessario che questi valori siano davvero il seno e il coseno di un angolo, vanno bene numeri qualsiasi, purché il loro rapporto sia uguale alla tangente dell'angolo che stiamo cercando). Ecco l'algoritmo, molto simile a quello che abbiamo già incontrato:

Z0 = 0,
S0C0T,
Zm+1 = Zm-DmAm,
Cm+1 = Cm-DmSm/2m,
Sm+1 = Sm+DmCm/2m.

Questa volta il segno di D è governato dal segno di C e S: DC e S devono avere segno opposto. Se la variabile Z è inizializzata a zero, alla fine assumerà il valore dell'angolo che stiamo cercando. Ed ecco il programmino:


from math import atan,sin,cos,pi

ango={}
seni={}
cosi={}

for i in xrange(24):
 ango[i]=atan(1./2**i)
 cosi[i]=cos(ango[i])



def arcotangente(x):
 
 z0=0
 c0=1
 s0=x
 d=1.

 for i in xrange(24):
  if c0*s0<0:
   z1=z0-ango[i]
   c1=c0-d*s0
   s1=s0+d*c0
  else:
   z1=z0+ango[i]
   c1=c0+d*s0
   s1=s0-d*c0

  z0=z1
  c0=c1
  s0=s1
  d/=2
 
 return z0

v1 = arcotangente(70./180*pi)
v2 = atan(70./180*pi)

print v1,v2,abs(v1-v2)


Che restituisce questo output:

0.884869508989 0.88486958315 7.41605976629e-08

Ora abbiamo tutto. Per i logaritmi ci servono le funzioni iperboliche.

Nessun commento: