function A=BTrigCoeffs(X,Y)

% визначаємо кількість елементів вектора X та транспонуємо у випадку, якщо
% подано вектор-рядок
[m,n]=size(X);
if m==1
    X=X';
    [m,n]=size(X);
end

% якщо передано лише один аргумент - це значення функції, а значення
% аргументу будуємо
if nargin==1
    Y=X;
    X=[1:m];
    X=X';
else
    % якщо Y не транспоновано - транспонуємо
    [m1,n1]=size(Y);
    if m1==1
        Y=Y';
    end
end

Xt=X; Yt=Y;

C(1)=1; C(2)=1; C(3)=0; flag=0;
yOld=getFunction(Xt,Yt,C);

while (flag==0)
    C(2)=findC2(Xt,Yt,m,C);
    yNew=getFunction(Xt,Yt,C);
    C(3)=findC3(Xt,Yt,m,C);
    yNew=getFunction(Xt,Yt,C);
    C(1)=findC1(Xt,Yt,m,C);
    yNew=getFunction(Xt,Yt,C);
    if abs(yNew-yOld)<0.0001
        flag=1;
    end
    yOld=yNew
end
A=C;

% =========================================================================
function RES=findC1(X,Y,m,C)

mIter=1000;
cIter=0;
flag=0;
xOld=C(1);

wx=C(2)*X; wxf=wx+C(3); cos_wxf=cos(wxf);
dfda2=cos_wxf.*cos_wxf; dfda2=dfda2*2; dfda2=sum(dfda2);

while flag==0
    dfda=xOld*cos_wxf; dfda=dfda-Y; dfda=dfda.*cos_wxf; dfda=dfda*2; dfda=sum(dfda);

    xNew=xOld-dfda/dfda2;
    cErr=abs(xNew-xOld);
    if (cErr<0.0001) || (cIter>mIter)
        flag=1;
    end
    cIter=cIter+1
    xOld=xNew;
end
RES=xNew;

% =========================================================================
function RES=findC2(X,Y,m,C)

mIter=1000;
cIter=0;
flag=0;
xOld=C(2);

while flag==0
    wx=xOld*X; wxf=wx+C(3); cos_wxf=cos(wxf); sin_wxf=sin(wxf);
    acos_wxf=C(1)*cos_wxf;
    
    dfdw=acos_wxf-Y; dfdw2=dfdw;
    dfdw=dfdw.*sin_wxf; dfdw=dfdw.*X; dfdw=dfdw*(-2*C(1)); dfdw=sum(dfdw);
    dfdw2=dfdw2.*cos_wxf; dfdw2=dfdw2-C(1)*(sin_wxf.*sin_wxf); dfdw2=dfdw2.*X; dfdw2=dfdw2.*X;
    dfdw2=dfdw2*(-2*C(1)); dfdw2=sum(dfdw2);
    
    xNew=xOld-dfdw/dfdw2;
    cErr=abs(xNew-xOld);
    if (cErr<0.0001) || (cIter>mIter)
        flag=1;
    end
    cIter=cIter+1
    xOld=xNew;
end
RES=xNew;

% =========================================================================
function RES=findC3(X,Y,m,C)

mIter=1000;
cIter=0;
flag=0;
xOld=C(3);

wx=C(2)*X;

while flag==0
    wxf=wx+xOld; cos_wxf=cos(wxf); sin_wxf=sin(wxf);
    acos_wxf=C(1)*cos_wxf;

    dfdf=acos_wxf-Y; dfdf2=dfdf;
    dfdf=dfdf.*sin_wxf; dfdf=dfdf*(-2*C(1)); dfdf=sum(dfdf);
    dfdf2=dfdf2.*cos_wxf; dfdf2=dfdf2-C(1)*(sin_wxf.*sin_wxf); dfdf2=dfdf2*(-2*C(1));
    dfdf2=sum(dfdf2);

    xNew=xOld-dfdf/dfdf2;
    cErr=abs(xNew-xOld);
    if (cErr<0.0001) || (cIter>mIter)
        flag=1;
    end
    cIter=cIter+1
    xOld=xNew;
end
RES=xNew;

% =========================================================================
function RES=getFunction(X,Y,C)

RES=C(2)*X; RES=RES+C(3); RES=cos(RES); RES=RES*C(1);
RES=RES-Y;
RES=RES.*RES;
RES=sum(RES);
