%% FanPall Algorithm
function [S,a,b] = FanPall(A,b)
m = length(A);
if mod(m,2) == 0
    [S,a,b] = subFanPallEven(A,b);
else
    [S,a,b] = subFanPallOdd(A,b);
end
end

%% Even
function [S,a,b] = subFanPallEven(A,b)
m = length(A);
[T,d] = reorderEigen_skew(A);
a = d(1:m/2);
if length(b) ~= length(a)-1
    b = zeros(length(a)-1,1);
    for i =1:length(a)-1
        b(i) = (a(i)-a(i+1))/2+a(i+1);
    end
end

v = zeros(m-1,1);
for i = 1:length(b)
    num = 1;
    den = b(i)^2;
    flag = 0;
    for j = 1:length(a)
        if abs(b(i)^2-a(j)^2)<10^(-8)
            num = 0;
        end 
        num = num*(b(i)^2-a(j)^2);
        if i ~= j && j<=length(a)-1
            if b(i)==b(j)
                flag = 1;
            end 
            den = den*(b(i)^2-b(j)^2);
        end
    end
    if abs(num/2/den)<10^(-3)
        num = 0;
        den = 1;
    end 
    if -num/2/den<0
        num;
    end 
    if flag ~=1
        v(2*i-1) = sqrt(-num/2/den);
        v(2*i) = sqrt(-num/2/den);
    else
        v(2*i-1) = 0;
        v(2*i) = 0;
    end
end
v(end) = prod(a)/prod(b);

if norm(imag(v))>10^-4
    error('imaginary part in v')
else
    v = real(v);
end

A_ = [kron(diag(b),[0 1;-1 0]),zeros(2*length(b),1),v(1:end-1);zeros(1,2*length(b)+1),v(end);-v(1:end)',0];
[T_,d_] = reorderEigen_skew(A_);
S = T*T_';
end

%% Odd
function [S,a,b] = subFanPallOdd(A,b)
m = length(A);

[T,d] = reorderEigen_skew(A);
a = d(1:floor(m/2));

if length(b) ~= length(a)
    b = zeros(length(a),1);
    for i =1:length(a)-1
        b(i) = (a(i)-a(i+1))/2+a(i+1);
    end
    b(end) = a(end)/2;
end

v = zeros(2*length(b),1);
for i = 1:length(a)
    num = 1;
    den = 1;
    flag = 0;
    for j = 1:length(a)
        num = num*(b(i)^2-a(j)^2);
        if i ~= j
            if b(i) == b(j)
                flag = 1;
            else
                den = den*(b(i)^2-b(j)^2);
            end
        end
    end
    if abs(num)<10^(-8)
        num = 0;
    end 
    if abs(num/2/den)<10^(-8)
        num = 0;
        den = 1;
    end 
    if -num/2/den<0
        %disp(' ');
    end 
    if flag ~=1
        v(2*i-1) = sqrt(-num/2/den);
        v(2*i) = sqrt(-num/2/den);
    else
        v(2*i-1) = 0;
        v(2*i) = 0;
    end
end

A_ = [kron(diag(b),[0 1;-1 0]),v;-v',0];

[T_,d_] = reorderEigen_skew(A_);
S = T*T_';
end
