function y = benchFunktionND(x, benchmark, NormFlag)
%
% Benchmark functions for n input dimensions. input must be normalized to
% [0,1].
% Matlab Code by B. Hartmann (Oct. 13, 2010)
%

if nargin < 3
    NormFlag = 0;
end

n = size(x,2); % number of input dimensions
switch benchmark
    case 'hyperbel'
        
        y = hyperbel(x,n);
        
    case 'parabola'
        
        y = parabola(x,n);
        
    case 'perm'
        
        x = x*2*n-n;
        y = perm(x,n);
        
        
    case 'trid'
        
        x = x*2*n^2-n^2;
        y = trid(x,n);
        
    case 'zakh'
        
        x = x*15-5;
        y = zakh(x,n);
        
    case 'hyperbelGauss'
        
        y = hyperbelGauss(x);
        
    case 'obliqueHyperbel'
        
        y = obliqueHyperbel(x,n);
        
end

if NormFlag
    % Normalization to interval [0,1]
    y = (y-min(y))./(max(y)-min(y));
end

end



function y = obliqueHyperbel(x,n)
%
% Hyperbel function y = 0.1/(0.1+(1-x(1))/n+(1-x(2))/n+ ... +(1-x(n))/n)
% Matlab Code by B. Hartmann (Oct. 13, 2010)
%
den = 0.0005;
weights = 1:n;
weights = weights/sum(weights)*1.5;
for i = 1:n
    den = den+(1-weights(i)*x(:,i));
end
y = 0.1./den;
end

function y = hyperbel(x,n)
%
% Hyperbel function y = 0.1/(0.1+(1-x(1))/n+(1-x(2))/n+ ... +(1-x(n))/n)
% Matlab Code by B. Hartmann (Oct. 13, 2010)
%
den = 0.05;
for i = 1:n
    den = den+(1-x(:,i))/n;
end
y = 0.1./den;
end

function y = parabola(x,n)
%
% Parabola function y = 1-sum (x(i)-0.5)^2
% Matlab Code by B. Hartmann (Oct. 13, 2010)
%
y = 1;
for i = 1:n
    y = y-(x(:,i)-0.5).^2;
end
end

function y = perm(x,n)
%
% Perm function
% Matlab Code by A. Hedar (Nov. 23, 2005).
% The number of variables n should be adjusted below.
% The default value of n = 4.
%
b = 0.5;
s_out = 0;
for k = 1:n;
    s_in = 0;
    for j = 1:n
        s_in = s_in+(j^k+b)*((x(:,j)/j).^k-1);
    end
    s_out = s_out+s_in.^2;
end
y = s_out;
end

function y = trid(x,n)
%
% Trid function
% Matlab Code by A. Hedar (Nov. 23, 2005).
% The number of variables n should be adjusted below.
% The default value of n = 10.
%
s1 = 0;
s2 = 0;
for j = 1:n;
    s1 = s1+(x(:,j)-1).^2;
end
for j = 2:n;
    s2 = s2+x(:,j).*x(:,j-1);
end
y = s1-s2;
end

function y = zakh(x,n)
%
% Zakharov function
% Matlab Code by A. Hedar (Nov. 23, 2005).
% The number of variables n should be adjusted below.
% The default value of n = 2.
%
s1 = 0;
s2 = 0;
for j = 1:n;
    s1 = s1+x(:,j).^2;
    s2 = s2+0.5*j*x(:,j);
end
y = s1+s2.^2+s2.^4;
end

function [yOut] = hyperbelGauss(inputMatrix)

% Calculate test function as combination of hyperbola and Gaussian function
%
%  [yOut] = hyperbelGauss(inputMatrix,gheight,hheight)
%
%
% Inputs
%
% inputMatrix: [number of samples] x [number of inputs] matrix
%
% Outputs
%
% yOut:        [number of samples] x 1 vector


% Get input-dimension
inputDim  = size(inputMatrix,2);

% Setup for test function
c       = zeros(1,inputDim); % Centers for Gaussian
% sigma   = 0.5;               % Standard deviation (equally for all inputs)
% hheight = 1;                 % Maximum height of the Gaussian function
% gheight = 0.5;               % Maximum height of the hyperbola function
sigma   = 0.25;               % Standard deviation (equally for all inputs)
hheight = 1;                 % Maximum height of the Gaussian function
gheight = 0.75;               % Maximum height of the hyperbola function


% Evaluate values of the hyperbel- and gauss-function
yHyperbel = hheight*hyperbelG(inputMatrix);
%yGauss    = (gheight-yHyperbel(1))*gauss(inputMatrix,c,sigma);
yGauss    = (gheight - hyperbelG(zeros(1, inputDim)))*gauss(inputMatrix,c,sigma);

% Evaluate yOut
yOut = yHyperbel + yGauss;


    function y = hyperbelG(u)
        %
        % Hyperbel function y = 0.1/(0.1+(1-u(1))/n+(1-u(2))/n+ ... +(1-u(n))/n)
        % Matlab Code by B. Hartmann (Oct. 13, 2010)
        %
        n = size(u,2);
        den = 0.1;
        for i = 1:n
            den = den+(1-u(:,i))/n;
        end
        y = 0.1./den;
    end


    function y = gauss(u,c,sigma)
        %         y = zeros(size(u,1),1);
        %         for ii = 1:size(u,1)
        %             y(ii,1) = exp(-0.5*(sqrt((u(ii,:)-c)*sigma*(u(ii,:)-c).'))^2);
        %         end
        
        [N n] = size(u);
        x = zeros(N,1);
        for i = 1:n
            x = x + ((u(:,i)-c(i))/sigma).^2;
        end
        y = exp(-0.5*x);
        
    end
end % end hyperbelgauss
