Ярлыки

_GetPixelIndex (1) _SetPixelIndex (1) 3-phase (1) 800x480 (1) АЦП (1) генератор (1) синхронный усилитель (2) структура (1) учебный курс (1) шаговый двигатель (1) ШИМ (2) accert (1) AD7608 (1) AD8429 (1) ADC (5) amplifer (1) arccos (1) arcsin (1) arctang (2) arctg (3) ARM (2) arm_sqrt_q15 (2) assembler (6) ASSERT (1) atan (2) bit (1) Bitband (1) boot (3) bootlloader (1) BUTTON (1) C (5) C# (1) CAN (2) CC2530 (5) CMSIS (4) command (1) Cordic (1) Core746I (1) CubeMX (4) DBGMCU (2) debug (2) debug.ini (1) delegate (1) Digital Potentiometers (1) DigitalPOT (1) Discovery (1) DMA (9) DMA2D (1) DSP (1) DSP library (1) DWT (1) EFM32 (5) EmWin (9) EXTI (1) FATFS (1) FMC (2) FreeRTOS (2) gl868-dual cmux (1) GPIO (4) GUI (2) GUIBuilder (1) GUIDRV_CompactColor_16 (1) HAL (3) HappyGecko (1) Hard Fault (2) heap (1) I2C (1) ID (1) ILI9320 (1) ILI9325 (1) Initialisation (1) InitLTDC (1) Instrumentithion (1) Interrupt (4) ITR (1) JTAG (1) Keil (5) LCDConf (2) lock-in (1) LTCD (1) LTDC (3) main (1) memory (1) MINI_STM32 Revision 01 (1) nBoot0 (1) NVIC (1) OnePulse (2) OSAL (4) pack (1) phase (1) printf (3) Pulse (1) PWM (12) RCC (2) RCR (1) Register (1) RESET (2) RS232 (3) RSS (1) RTC (3) RTOS-RTX (1) RTT (1) RTX-RTOS (1) SDCard (1) SDRAM (6) Segger (2) SPI (3) sqrt (3) SSD1298 (1) SSD1963 (1) Standart Peripherial Library (3) STANDBAY (1) startup (1) STemWin (8) stepper motor (1) STlink (2) STM32 (17) STM32429ZI (1) STM32Cube (1) STM32DBG.IN (1) STM32F (28) STM32F0 (4) STM32F1 (13) STM32F4 (10) STM32F4 Discovery (1) STM32F407ZG (1) STM32F429 (2) STM32F746 (1) STOP (1) string (1) struct (1) SWD (1) SWD JTAG (1) Synhronization (1) system_stm32f4xx.c (1) SystemInit (1) SysTick (1) task (4) telit (1) TIM (27) typedef (1) UART (1) USART (9) viewer (2) WM_PAINT (1) Z-stack (5) ZigBee (5)

воскресенье, 28 сентября 2014 г.

arctg

Разложение в ряд Маклорена:

y = arctg(x) = x - x^3/3 + x^5/5 - ...               |x| < 1

arctg(1/x) = 1/x - (1/2)x+ (1/5)x5 - .

tan(x) = x/(1-x^2/(3-x^2/(5-x^2/(7-x^2/...))))

Пусть max - больший катет, а min - меньший. Тогда длина гипотенузы приблизительно равна
max + min*min/(2*max)
Её максимальная относительная ошибка равна: 1 - sqrt(2)/1.5 ~ 0.057
А если взять формулу:
max + 0.43*min*min/max, то максимальная относительная ошибка будет ~ 0.01
Если же хочется сделать вычисления проще, то можно взять формулу:
max + 0.41*min, но ошибка будет 0.075
Коэффициенты  подобраны экспериментально с точность 0.01. Можно подобрать точнее.

Еще один пример ряда для x < 1;



Еще одна эмпирически подобранная формула:


//formula  y = -0.30097 + 0.61955*x - 0.001659*x*x
//x :number from 0..100%
//y : angle from 0..45° as approximation of the atan function.
int32_t arctang(int32_t Re, int32_t Im)
{
int32_t a,b,proc,arctg;
proc=a*100.0/b;
//proc_int=a*100/b;
arctg=(-300970 + 619550*proc - 1659*proc*proc)/1000000;
return arctg;

}

Для вычисления арктангенса можно использовать следующий алгоритм:
Вначале проверить знак x, изменить знак, сделав аргумент неотрицательным. Затем если x>1, обратить его: x1=1/x. Затем сокращаем область определения, используя формулу:

atan(x)=pi/6+atan((x*sqrt(3)-1)/(x+sqrt(3))).

Здесь sqrt(3) квадратный корень из 3. При этом необходимо запомнить число шагов (возможно, ноль). После этого, арктангенс на интервале [0,pi/12] аппроксимируется формулой (для single precision, в случае double формула должна быть улучшена!):

atan(x) = x*(0.55913709/(1.4087812+x2) +0.60310579-0.05160454*x2)

Затем к полученному результату добавляется столько pi/6, сколько было шагов сокращения области определения. Затем, в случае обращения, аргумента, результат вычитается из pi/2. Затем, если была смена знака, у результата меняем знак. Для повышенной точности, формулу на участке [0,pi/12] следует брать в виде:

atan(x) = x*(m0+n0*(x*x)+k0/(m1+n1*(x*x)+k1/(m2+n2*(x*x)+k2/(...)))),

то есть в том же виде цепной дроби, как и для single precision, только с некоторыми другими значениями m0,n0,k0;m1,n1,k1;... 

#define M_PI ((float)3.141592653589793)
#define M_PI12 (M_PI/12.F)
#define M_PI6 (M_PI/6.F)
#define M_PI2 (M_PI/2.F)
/* square root of 3 */
#define SQRT3 ((float)1.732050807569)

float Arctan(float x) {
  int sta=0,sp=0;
  float x2,a;
  /* check up the sign change */
  if(x<0.F) {x=-x;sta|=1;}
  /* check up the invertation */
  if(x>1.F) {x=1.F/x;sta|=2;}
  /* process shrinking the domain until x<PI/12 */
  while(x>M_PI12) {
    sp++; a=x+SQRT3; a=1.F/a; x*=SQRT3; x-=1.F; x*=a;
  }
  /* calculation core */
  x2=x*x; a=x2+1.4087812F; a=0.55913709F/a; a+=0.60310579F;
  a-=0.05160454F*x2; a*=x;
  /* process until sp=0 */
  while(sp>0) {a+=M_PI6;sp--;}
  /* invertation took place */
  if(sta&2) a=M_PI2-a;
  /* sign change took place */
  if(sta&1) a=-a;
  return(a);
}

Комментариев нет:

Отправить комментарий