mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Effiziente Implementierung von ARCTAN fuer uCs


Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich suche eine effiziente Implementierung von ARCTAN fuer einen kleinen 
Microcontroller. CORDIC ist mir zuviel. Es muss klein, schnell und ohne 
Divisionen sein, Eingangsbereich Z.B. 32 Bit im 16.16 Format, um die 
0,000x bei grossen X darstellen zu können, Rechnung in einem Quadranten, 
Ausgang Winkel -/- 255, d.h. es reicht eine Genauigkeit von einem halben 
Grad.
Die Rechnung müsste dann wohl auf ein Viertel Grad genau sein.
Tabelle würde Ich vermeiden wollen,

Autor: WS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wikipedia kennst Du?
x(1+0,28x*x) und so?
Viel einfacher geht es wohl nicht.

Beitrag #5115144 wurde vom Autor gelöscht.
Autor: Markus W. (elektrowagi78) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Tabelle wäre aber wohl das Einfachste bei den wenigen Werten.

Den ARCTAN kann man auch mit einer Wurzel nachbilden, aber die ist auch 
nicht einfacher zu berechnen. Nach mehreren Iterationen gibt es einen 
Wert, der dann doch nur Ungenau ist.

Welcher Controller?

Autor: Der Zahn der Zeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WS schrieb:
> x(1+0,28x*x) und so?
Interessant. Aber in Wikipedia steht x/(1+0,28x*x) (für |X| <= 1, andere 
Bereiche ähnlich), und die Division tut dem Meister offensichtlich weh. 
Aber es ist nur eine Division.

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kommst du an den TAN (also den Einganganswert für den ARCTAN)?

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, wenn man x und y kennt ( oder Real- und Imaginärteil), dann geht das 
einfacher:

Beitrag "Goertzel-Algorithmus und Signed Fractional Format"

Cheers
Detlef

Autor: Jürgen S. (engineer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CORDIC ist aber doch gerade für die lumpigen Rechner DIE Methode 
schlechthin.

Was wäre, mit reduzierter Auflösung = weniger Rotationen zu agieren? Mit 
4-5 Schritten müsste sich das doch machen lassen.
http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf

Ansonsten heuristisch annähern, anhand der eigenen Anforderungen, sprich 
lokal erlaubten Abweichungen und der benötigten Bereiche, wobei es sehr 
viel knapper kaum gehen wird. Die billigste Lösung ist wohl die von den 
Telekomikern/Iren hier:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=...

Weitere Denkanstösse hier:
http://www.convict.lu/Jeunes/Math/arctan.htm

Bei Näherungen muss man nur aufpassen, dass es keine minimalen Knicke 
gibt und die Kurve monoton bleibt! Je nach Verwendungszweck muss sogar 
auch die Ableitung monoton und vor allem stetig sein, daher darf es 
keine Plateaus geben. Da fallen viele auf die Nase!

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe nicht den Grund und Vorteil für die Nutzung des Cordic, wenn 
Ich dann doch wieder auf gespeicherte Werte zurückgreifen muss, die ich 
aus Tabllen lesen soll. Dann kann ich gleich nähern.

Autor: Possetitjel (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Meister E. schrieb:

> Ich sehe nicht den Grund und Vorteil für die Nutzung
> des Cordic, wenn Ich dann doch wieder auf gespeicherte
> Werte zurückgreifen muss, die ich aus Tabllen lesen soll.

Es ist Dir also völlig egal, ob Du eine Tabelle mit 512
Werten brauchst oder eine mit nur 16? Merkwürdig.

> Dann kann ich gleich nähern.

Dann mach doch. Ganz ohne Spott: Ich wäre gespannt auf
Deine Lösung.

Autor: Jürgen S. (engineer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem CORDIC wird es eben am schnellsten genau. Natürlich musst Du 
mehrfach auf eine Tabelle zugreifen, aber das müsste man mit einer 
diskreten Abschnittstabelle eben auch. Bei binärem hashing und Bei 512 
Werten mindestens 9x. In der Zeit arbeitest Du auch 3-4 CORDIC 
Iterationen ab.

Klar kann man mit noch weniger Stellen operieren und interpolieren, wenn 
es die Anwendung hergibt, aber man darf eben nicht erwarten, dass man 
mit dem Winkel nochmal irgendwelche Cosinüsse bilden und z.B. Realteil 
errechnen kann zur weiteren Verwendung. Solche simplen Näherungen sind 
i.d.R. finale Operationen für Anzeigen oder für Schätzungen am Besten 
geeignet.

Ansonsten sind das Sonderfälle:

Ich habe mal eine Implementierung in VHDL gemacht, die sehr schnell sein 
müsste und wobei der CORDIC-CORE einfach zu langsam war. Allerdings war 
die Anwendung recht grob und diente nur der Schätzung einer 
Winkelinformation. Ich habe einfach Werte <1.0 per Division gespiegelt, 
um sie in den anderen Ast zu bekommen und den Ausgang der Division, die 
ja als pipeline die bits von oben herunter sukzessive liefert, zur 
Ansteuerung der hash table genutzt. Dann musste Ich nicht "warten" bis 
das Divisionsergebnis komplett feststeht, sondern hat schon nach 2 
Takten die erste Information, in welcher (lokalen) Hälfte der Tabelle 
das Ergebnis liegt. So kann man das auch für Wurzeln machen.

Der Hauptvorteil war, dass man nur sehr geringe Auflösungen und auch 
keine Multiplier für die Rechnung brauchte.

Die Methode ist aber definitiv mal nichts für Microcontroller.

Autor: Thomas U. (thomasu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Wie kommst du an den TAN (also den Einganganswert für den ARCTAN)?

Das war damals auch mein Problem ;-) Den nimmt man über einen 
Tabellenwert. Das ist ja der Trick:
Beitrag "Cordic - Sinussignal"

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Possetitjel schrieb:
> Meister E. schrieb:
> Es ist Dir also völlig egal, ob Du eine Tabelle mit 512
> Werten brauchst oder eine mit nur 16? Merkwürdig.

Nein, es ist nicht egal. Bei der vorliegenden Applikation habe Ich nur 
ein bissl ein Problem, viele Daten schnell hin und her zu bekommen, weil 
Ich alles erst umständlich aus einem etnfernten RAM, wahrscheinlich ROM 
heranschauffeln müsste.

Autor: Possetitjel (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Meister E. schrieb:

> Possetitjel schrieb:
>> Meister E. schrieb:
>> Es ist Dir also völlig egal, ob Du eine Tabelle mit 512
>> Werten brauchst oder eine mit nur 16? Merkwürdig.
>
> Nein, es ist nicht egal. Bei der vorliegenden Applikation
> habe Ich nur ein bissl ein Problem, viele Daten schnell
> hin und her zu bekommen, weil Ich alles erst umständlich
> aus einem etnfernten RAM, wahrscheinlich ROM heranschauffeln
> müsste.

Naja, das spricht doch für CORDIC; dort kann man mMn alles
mit Direktoperanden erschlagen, wenn man die Schleife abrollt.
Insofern verstehe ich Deine Argumente nicht.

Autor: WS (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Edi M. schrieb:
> weil
> Ich alles erst umständlich aus einem etnfernten RAM, wahrscheinlich ROM
> heranschauffeln müsste.

Die wenigen Werte lassen sich eigentlich gut lokal speichern. Was ist 
das für ein Controller, der arctan machen soll aber kaum Speicher hat?

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wissen wir noch nicht genau, was für ein Controller es wird. Aber es 
wird eine kleiner, mickriger mit wenig Platz und wenig Strom.

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edi M. schrieb:

> Aber es wird eine kleiner, mickriger mit wenig
> Platz und wenig Strom.

Naja, Kernfrage ist, ob das Ding schnell multiplizieren
kann oder nicht.

Wenn nicht, wird's auf CORDIC hinauslaufen. Bangemachen
gilt nicht :)
Beim Algorithmus für ATAN kann ich nicht helfen; trotz
der i.d.R. beschissenen Erklärungen habe ich die
sin/cos-Variante verstanden -- wie man aber den ATAN mit
CORDIC berechnet, ist mir unklar.

Falls jedoch ein Multiplizierer vorhanden ist, gibt's
andere Möglichkeiten.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist denn mit einer stückweisen quadratischen Annäherung? Etwas 
rechnen können, wird auch der winzigste Winzigkontrolleur.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Possetitjel schrieb:

> Beim Algorithmus für ATAN kann ich nicht helfen; trotz
> der i.d.R. beschissenen Erklärungen habe ich die
> sin/cos-Variante verstanden -- wie man aber den ATAN mit
> CORDIC berechnet, ist mir unklar.

Das Prinzip für die ATAN Berechnung mit Cordic muss so sein, denke ich:
Du zerlegst Deinen Winkel in die Komponenten 45°, 22.5°, 11.25°, 5.65°, 
2.8125°, 1.40625°, 0.703125° und 0.3515625°, das sollte reichen für das 
geforderte halbe Grad Auflösung. Dann nimmst Du die komplexe Zahl 1+j*0 
und drehst sie um diese Winkel nach dem Muster hier, hab ich schon mal 
referenziert:

Beitrag "Goertzel-Algorithmus und Signed Fractional Format"

Die Drehungen normierst Du so, dass der Realteil 1 bleibt. Der 
Imaginärteil nach den Drehungen ist der gesuchte Wert.

Wäre ein grosser Spass, das mal so zu versuchen.

Cheers
Detlef

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal nachgedacht, das geht viel einfacher. Du rufst einfach die 
Routine aus
Beitrag "Goertzel-Algorithmus und Signed Fractional Format"
so auf:
IntAtan2(foo,1). Eingangsdynamik sind allerdings 16Bit, weiß nicht, ob 
das dem TO reicht.

Cheers
Detlef

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:

> Was ist denn mit einer stückweisen quadratischen Annäherung?

Geht beschissen, wegen der horizontalen Asymptote. Man muss
in ewig viele Teilintervalle zerlegen.

(Gut... ich hatte kubische Splines betrachtet. Macht keinen
großen Unterschied in der Kernaussage.)

> Etwas
> rechnen können, wird auch der winzigste Winzigkontrolleur.

Ein alter Vorschlag von gjlayde sagt, für Winkel über 45°
die Beziehung atan(1/x) = 90 - atan(x) auszunutzen. Das
ist clever, setzt aber effiziente Berechnung von 1/x voraus.

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Vereinfachungen kenne Ich natürlich, aber mit einer Division bin 
Ich genau so weit. Ich denke nochmal etwas nach ...

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edi M. schrieb:

> Diese Vereinfachungen kenne Ich natürlich, aber mit einer
> Division bin Ich genau so weit.

Irgendwie ist das ermüdend.

Für den Kehrwert gibt es eine schnelle, gut konvergente
Iteration - aber die setzt voraus, dass man schnell
multiplizieren kann.
Fällt Dir jetzt vielleicht auf, warum ich weiter oben
nach dem Multiplizieren gefragt habe?

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlef _. schrieb:

> Nochmal nachgedacht, das geht viel einfacher. Du rufst
> einfach die Routine aus
> Beitrag "Goertzel-Algorithmus und Signed Fractional Format"
> so auf:
> IntAtan2(foo,1).

Ja, danke.

Hatte wohl ein gewaltiges Brett vor dem Kopf. Der Unterschied
liegt offenbar nur in Startwert, Drehrichtung und Abbruch-
kriterium -- der Algorithmus bleibt genau gleich.

Wenn man von (0;1) ausgeht und so dreht, dass phi gegen den
gewünschten Winkel geht, bekommt man (cos(phi);sin(phi)).

Geht man aber von (1;y) aus und wählt die Drehungen so,
dass y gegen Null geht, ist der Gesamt-Drehwinkel gerade
atan(y).

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Possetitjel schrieb:

> Wenn man von (0;1) ausgeht

Quatsch: von (1;0) natürlich.

Autor: Jack (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Edi M. schrieb:
> Diese Vereinfachungen kenne Ich natürlich, aber mit einer Division
> bin
> Ich genau so weit. Ich denke nochmal etwas nach ...

Von nichts kommt nichts! Man kann kein Omelett machen ohne Eier zu 
zerbrechen. Einen Tod muss man sterben.

Nahezu ohne Division würde eine altmodische Taylor-Reihe funktionieren.

arctan(x) = x - (x^3)/3 + (x^5)/5 - ... ; für |x| <= 1

Aber nur nahezu, man braucht die erwähnte Vereinfachung:

arctan(x) = pi/2 - arctan(1/x); für |x| > 1

Die Division durch die Konstanten kann man vermeiden wenn man 1, 1/3, 
1/5, 1/7 als Konstanten ablegt und multipliziert. In den Konstanten kann 
man noch das Vorzeichen einarbeiten, dann wird die Iterationsschleife 
etwas einfacher 1, -1/3, 1/5, -1/7.

Die Reihe konvergiert langsam. Entweder nimmt man dass in Kauf, man 
verzichtet auf Genauigkeit oder nimmt etwas anderes, z.b. eine 
Tschebyscheff-Approximation. Die habe ich aber nicht im Kopf.

Ich würde noch mal über das Eingangs erwähnte

arctan(x) = x / (1 + 0,28125 x^2); für |x| <= 1

nachdenken. Auf 
http://www.embedded.com/design/other/4216719/Perfo... 
dröselt das jemand schön auf. Hat man aus der Signalverarbeitung I, Q 
Werte und braucht man arctan(Q/I) gilt:

arctan(Q/I)
= (Q / I) / (1 + 0,28125 * (Q / I)^2)
= (Q * I) / (I^2 + 0,28125 * Q^2)

D.h. die Division Q/I muss man nicht ausführen. Statt dessen hat man 
zwei weitere Multiplikationen. Es bleibt aber die ursprüngliche Division 
auf der rechten Seite.

Der nächste Trick ist dann (siehe Link), dass

0,28125 * Q^2 = (1/4 + 1/32) * Q^2 = Q^2/4 + Q^2/32

Hat man einen angestaubten Prozessor bei dem Schieben schneller als 
Multiplizieren ist und ein Zahlensystem, bei dem nach Rechts schieben 
einer Division durch 2 entspricht, bekommt man

Q^2/4 + Q^2/32 = (Q^2) >> 2 + (Q^2) >> 5

D.h. die Multiplikation mit 0,28125 kann man durch zwei Mal schieben 
ersetzen.

arctan(Q/I)
= (Q * I) / (I^2 + (Q^2) >> 2 + (Q^2) >> 5)

Zum Schluss, das schreibe ich nicht ab (siehe Link), kann man Q/I noch 
in acht Oktanten aufteilen um die Division 1/x in

arctan(x) = pi/2 - arctan(1/x); für |x| > 1

zu ungehen! D.h. die Division kann man sich auch sparen. Es bleibt aber 
eine Division auf der rechten Seite. Einen Tod muss man sterben.

Autor: W.S. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Jack schrieb:
> arctan(Q/I)
> = (Q / I) / (1 + 0,28125 * (Q / I)^2)
> = (Q * I) / (I^2 + 0,28125 * Q^2)

Das finde Ich interessant!

Ich hatte bereits vor Tagen genau darauf hingewiesen:
Beitrag "Re: Effiziente Implementierung von ARCTAN fuer uCs"

Allerdings kannte Ich bisher nur die 0,28 aus der Wikipedia.

Wie ist die Abweichung zu 0,28125 erklären?

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach jetzt sehe Ich es:

Jack schrieb:
> Der nächste Trick ist dann (siehe Link), dass
>
> 0,28125 * Q^2 = (1/4 + 1/32) * Q^2 = Q^2/4 + Q^2/32

Ein wahrlich toller Trick, einfach die Kommastellen 3 und folgende 
wegzulassen, um binär rechnen zu können.

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jack schrieb:
> Nahezu ohne Division würde eine altmodische Taylor-Reihe funktionieren.

Ist noch aufwendiger, läuft auch zu sehr vom Ergebnis weg, alles 
getestet.

Wahrscheinlich wird es eine stückweise Approximation, wo Ich nur linear 
rechnen muss. Keine Division, keine grosse Tabelle.

Autor: Martin O. (ossi-2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Cordic-artiger Algorithmus für atan2(x,y) wobei der Rückgabewinkel 
von 0=0Grad bis 255=360Grad geht.

#include <avr/io.h>
#include <avr/pgmspace.h>


// generated by scaling with 65536.0 :: CORDIC1.PAS
int32_t iCordicSinTab[5]={25080L,12785L,6424L,3216L,1608L} ;
int32_t iCordicCosTab[5]={60547L,64277L,65220L,65457L,65516L} ;


int16_t CordicAmplitude ;

int16_t GetCordicAmplitude(){
  return CordicAmplitude  ;
  }

uint8_t iCordic(int32_t x, int32_t y) {
// compute angle and radius of point (x,y)
// angle is valid from 0 to 255 (256 would mean 2*Pi )
// angle is stored in phi and returned via function
// radius is stored in Amplitude and mus be lower than 2^15-1
// warning, if x near 2^15 and y near 2^15 than radius is too big !

  int32_t s,c,x0,y0,x1,y1,tmp ;
  uint8_t sign,phi,phi1,phiTest,k_cordic ;

// first rotate until x0,y0 are in octant 0    
// 
  x0=x ; y0=y ;
  phi=0 ;
  if ( y0<0 ) { x0=-x0 ; y0=-y0 ; phi=128 ; }
  if ( x0<0 ) { tmp=x0 ; x0=y0 ; y0=-tmp ; phi +=  64 ; }
  sign=0 ;
  if (y0>x0) { sign=1 ; phi += 64 ; tmp=x0 ; x0=y0 ; y0=tmp ; }
  // now x0 >= y0 >=0
 
 // warning: this scales amplitude !! so leave out
 // while (x0>0x7fff) { x0=x0 >> 1 ; y0=y0 >> 1 ; }
 // now rotate in 4 SAR steps with phiTest=16,8,4,2,1
 // and check that x0,y0 stays in octant 0

  phiTest=16 ;
  phi1=0 ;
  k_cordic=0 ;
  while (k_cordic<=4){
    // get cosine(phiTest)=c and sine(phiTest)=ss from table
    c=iCordicCosTab[k_cordic] ;
    s=iCordicSinTab[k_cordic] ;
    // rotate (x0,y0) by phi into (x1,y1)
    x1=( c*x0+s*y0) / 65536L ;
    y1=(-s*x0+c*y0) / 65536L ;
    // change x0,y0 if valid rotation step meaning that we stay in octant 0
    if (y1>=0) { x0=x1 ; y0=y1 ; phi1 += phiTest; }
    phiTest = phiTest >> 1 ;
  k_cordic++ ;
    }
  CordicAmplitude=x0 ;
  if (sign) { phi -= phi1 ; } else { phi += phi1 ; }
  return phi ;
  }

Autor: Jack (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Allerdings kannte Ich bisher nur die 0,28 aus der Wikipedia.
>
> Wie ist die Abweichung zu 0,28125 erklären?

So wie ich es gelernt habe wurde 0,28125 bewusst so gewählt, dass man 
den Trick mit dem Schieben, bei entsprechendem Zahlensystem, anwenden 
kann. Genaueres müsste im Original-Paper stehen. R. Lyons, "Another 
contender in the arctangent race".

Allerdings habe ich das Paper nicht, daher vom Hörensagen: Die 0,28 sind 
abgerundet. Ein genauerer Wert der Konstante ist 0,28086. Such man nach 
einer in der Nähe von 0,28086 liegenden Zahl, bei der man Multiplizieren 
durch Schieben ersetzen kann, landet man bei 1/4 + 1/32 = 0,28125.

0,28125 liegt sogar näher an 0,28086 als 0,28. Der maximale Fehler bei 
0,28125 statt 0,28086 ist nur unwesentlich größer.

Auf der vergeblichen Suche nach dem Paper habe ich noch etwas gefunden:

arctan(x) = pi/4 * x; für |x| <= 1;

Viel einfacher dürfte es kaum gehen. Der Fehler soll in der zweiten 
Stelle hinter dem Komma liegen. Navigieren würde ich damit nicht :-)

Autor: Detlef _a (detlef_a)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
R. Lyons: Understanding Digital Signal Processing

Die arctan Approx. von Lyons steht auf S547, Kap. 13.21

Cheers
Detlef

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier eine Implementierung von mir, die ich vor längerer Zeit einmal für 
einen at89C2051 (8051 Core) geschrieben habe. Mit dem sdcc Compiler 
benötigte diese Routine 307 Byte und bei 12Mhz Taktfrequenz 1.2ms. 
Interne Rechengenauigkeit sind 16Bit. Die sollte man sich gönnen, auch 
wenn das Ergebnis nur 8Bit betragen soll.
const unsigned int tabelle[12] = {8192, 4836, 2555, 1297, 651, 325,
163,  81,   41,   20,   10,  5};
unsigned char cordic_steps = 8; /* Zahl der Schritte im Cordic-Verfahren,
kann während  des Programmablaufs verändert werden.*/
unsigned  int cordic_abs;  /* Länge des Vektors nach der letzten Berechnung.*/
unsigned int cordic(int x, int y)
{
  unsigned char i;
  int temp = x;
  unsigned int angle = 32768;
  if (y < 0)
  {
    x = - y;
    y = temp;
    angle += 16384;
  }
  else
  {
    x      = y;
    y      = -temp;
    angle -= 16384;
  }
  for (i = 0; i < cordic_steps; ++i)
  {
    temp = x;
    if (y < 0)
      {
        x     -= y >> i;
        y     += temp >> i;
        angle -= tabelle[i];
      }
    else
      {
        x      += y >> i;
        y      -= temp >> i;
        angle  += tabelle[i];
      }
  }
  cordic_abs = x;
  return angle;
}

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jack schrieb:
> Ein genauerer Wert der Konstante ist 0,28086.

Ok, Danke!

Autor: Oplas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlef _. schrieb:
> R. Lyons: Understanding Digital Signal Processing
>
> Die arctan Approx. von Lyons steht auf S547, Kap. 13.21
>
> Cheers
> Detlef

Ist das von dir verlinkte PDF eine Raubkopie?

Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jack schrieb:

> Nahezu ohne Division würde eine altmodische Taylor-Reihe
> funktionieren.
>
> arctan(x) = x - (x^3)/3 + (x^5)/5 - ... ; für |x| <= 1

Ja. Allerdings sind die Taylor-Koeffizienten für diesen
Zweck nicht optimal. Der Fehler ist sehr ungleichmäßig
übers Intervall verteilt.

> Aber nur nahezu, man braucht die erwähnte Vereinfachung:
>
> arctan(x) = pi/2 - arctan(1/x); für |x| > 1

Ja. Kehrwert ist aber auch gut iterativ berechenbar.


> Die Reihe konvergiert langsam.

Naja... man kommt mit einem kubischen Polynom aus,
wenn man die Koeffizienten von Hand optimiert.
Restfehler im Intervall [0;1] ungefähr 0.3%.

Autor: Possetitjel (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Oplas schrieb:

> Ist das von dir verlinkte PDF eine Raubkopie?

Sehr unwahrscheinlich.

Da von "... Gewalt gegen eine Person oder [...] Androhung
einer gegenwärtigen Gefahr für Leib und Leben..." mit
hoher Wahrscheinlichkeit keine Rede sein kann, ist der
Tatbestand des Raubes nicht gegeben.

Autor: E. M. (elektromeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist das PDf denn her?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.