Pull to refresh

Приближение синуса и косинуса полиномом 2 степени

Reading time 3 min
Views 4K

На сайте habr.com/ru уже были похожие публикации осенью 2021 года:

Как посчитать синус быстрее всех

Как посчитать синус быстро

Не на Habr Как сделать быструю функцию для вычисления синуса? топик начат в 2003 году последний отклик в 2020 году.

Целью данной публикации попытка предложить способ расчета синуса и косинуса достаточно быстро для тех платформ, где отсутствуют эти функции (микроконтроллеры) или там где скорость расчета важнее точности.

Мне кажется, что выпуклые функции синус и косинус можно аппроксимировать не только рядом Тейлора ( многочленом вида a*x + b*x^3 +c*x^5 ... ) , а обычной параболой поведенной через точки 1,2,3 как на рисунке.

Точки 1 и 2 базовые, размещаются с определенным задаваемым шагом. В скрипте Scilab это переменная step. Координаты точки 3 будем вычислять таким образом, чтобы в ней было максимальное отклонение синуса ( или косинуса ) от отрезка 1-2.

Ниже приведены скрипты на Scilab для расчета коэффициентов полинома второй степени на интервале [ 0 ... pi /2] и графики отклонений для от функций синуса и косинуса .

Расчет коэффициентов для синуса на Scilab

/// синус
function [a,b,c]=  koef_parabola(x1,y1,x2,y2,x3,y3)
   /// расчет коэффициентов параболы по 3 точкам 
    a1= y3 -  ( x3*(y2-y1)+ x2*y1 -x1*y2 )/( x2-x1)
    a2=   x3*( x3-x1-x2 ) + x1*x2  
    a= a1 /a2
    b =( y2-y1)/( x2-x1) - a*( x1+x2)
    c=( x2*y1 - x1*y2) / (x2-x1)   + a * x1*x2
endfunction

kol_int =12   /// количество интервалов на отрезке 0 ... %pi/ 2
kol_funct =kol_int+1
step =%pi/ ( 2*kol_int)  /// шаг
point0_x =0:step:%pi/ 2
point0_sin = cos(point0_x)
aa_sin =1:1:(kol_int)
bb_sin =1:1:(kol_int)
cc_sin =1:1:(kol_int)
    xx1=0
    yy1=1
for ii=1:1:kol_int
    xx2=xx1+step
    yy2=cos(xx2)
    wsp1 =(yy2-yy1)/(xx2-xx1)  /// наклон
    xx3=asin(-wsp1)   /// координаты центральной точки
    yy3= sqrt( 1- wsp1^2)  ///  cos(xx3)
     [aa,bb,cc]=koef_parabola( xx1,yy1,xx2,yy2,xx3,yy3)
     aa_sin(ii)=aa
     bb_sin(ii)=bb
     cc_sin(ii)=cc         
     xx1=xx2
     yy1=yy2
end
 ///вывод шага и коэффициентов
 disp( step,aa_sin,bb_sin,cc_sin) 
    xx1=0
   xx2=step 
for ii=1:1:kol_int
int01=[xx1:0.005:xx2]    
a1=aa_sin(ii)
b1=bb_sin(ii)
c1=cc_sin(ii)
 plot(int01, (cos(int01) -  a1*int01^2 -b1*int01-c1 ) )
   xx1=xx1+step
   xx2=xx2+step 
end

Пример отклонений для синуса

график отклонений полинома второй степени от синуса на интервале 0 ... Пи/ 2 при разбиении на 8 интервалов ( размер интервала =Пи/ 16 примерно = 0.196 )

Расчет коэффициентов для косинуса на Scilab

function [a, b, c]=koef_parabola(x1, y1, x2, y2, x3, y3)
   /// расчет коэффициентов параболы по 3 точкам 
    a1= y3 -  ( x3*(y2-y1)+ x2*y1 -x1*y2 )/( x2-x1)
    a2=   x3*( x3-x1-x2 ) + x1*x2  
    a= a1 /a2
    b =( y2-y1)/( x2-x1) - a*( x1+x2)
    c=( x2*y1 - x1*y2) / (x2-x1)   + a * x1*x2
endfunction
kol_int =12   /// количество интервалов на отрезке 0 ... %pi/ 2
kol_funct =kol_int+1
step =%pi/ ( 2kol_int)  /// шаг
point0_x =0:step:%pi/ 2
point0_sin = cos(point0_x)
aa_sin =1:1:(kol_int)
bb_sin =1:1:(kol_int)
cc_sin =1:1:(kol_int)
xx1=0
yy1=1
for ii=1:1:kol_int
xx2=xx1+step
yy2=cos(xx2)
wsp1 =(yy2-yy1)/(xx2-xx1)  /// наклон
xx3=asin(-wsp1)   /// координаты центральной точки
yy3= sqrt( 1- wsp1^2)  ///  cos(xx3)
[aa,bb,cc]=koef_parabola( xx1,yy1,xx2,yy2,xx3,yy3)
aa_sin(ii)=aa
bb_sin(ii)=bb
cc_sin(ii)=cc
xx1=xx2
yy1=yy2
end
///вывод шага и коэффициентов
disp( step,aa_sin,bb_sin,cc_sin)
xx1=0
xx2=step
for ii=1:1:kol_int
int01=[xx1:0.005:xx2]
a1=aa_sin(ii)
b1=bb_sin(ii)
c1=cc_sin(ii)
plot(int01, (cos(int01) -  a1*int01^2 -b1*int01-c1 ) )
xx1=xx1+step
xx2=xx2+step
end

Пример отклонений для косинуса

график отклонений полинома второй степени от синуса на интервале 0 ... Пи/ 2 при разбиении на 12 интервалов

Синус таблица коэффициентов полинома степени 2 для 8 интервалов

( шаг Пи / 16 )

Я не привожу кода на каком либо языке или псевдокода, дабы не засорять публикацию, каждый желающий может подобрать себе коэффициенты полинома степени 2 для аппроксимации и написать свою функцию. По значению аргумента x вычисляем номер интервала, запоминаем коэффициенты и подставляем из в формулу полинома

Tags:
Hubs:
-9
Comments 25
Comments Comments 25

Articles