function pass = test_battery(pref)
% A large battery of functions. 

if ( nargin < 1 ) 
    pref = chebfunpref; 
end 
tol = 1e8 * pref.cheb3Prefs.chebfun3eps;

Battery = {@(x,y,z) cos(pi*x.*y.*z),...                                        % 1
    @(x,y,z) cos(2*pi*x.*y.*z),...                                             % 2
    @(x,y,z) cos(3*pi*x.*y.*z),...                                             % 3
    @(x,y,z) cos(4*pi*x.*y.*z),...                                             % 4
    @(x,y,z) cos(5*pi*x.*y.*z),...                                             % 5
    @(x,y,z) cos(6*pi*x.*y.*z),...                                             % 6
    @(x,y,z) cos(7*pi*x.*y.*z),...                                             % 7
    @(x,y,z) sin(pi*x.*y.*z),...                                               % 8
    @(x,y,z) sin(8*pi*x.*(1-x).*y.*(1-y).*z.*(1-z)),...                        % 9
    @(x,y,z) sin(8*pi*x.*(1-x).*y.*(1-y).*z.*(1-z).*(x-y-z).^2),...            % 10
    @(x,y,z) cos(0*pi*(x-y-z).^2),...                                          % 11
    @(x,y,z) cos(pi*(x-y-z).^2),...                                            % 12
    @(x,y,z) cos(2*pi*(x-y-z).^2),...                                          % 13
    @(x,y,z) exp(sin(4*pi./(1+x)).*sin(4*pi./(1+y)).*sin(4*pi./(1+z))),...     % 14
    @(x,y,z) log(1+x.*y.*z),...                                                % 15
    @(x,y,z) cos(pi*x.*sin(pi*y)) + cos(pi*y.*z.*sin(pi*x.*z)),...             % 16
    @(x,y,z) cos(2*pi*x.*sin(pi*y).*cos(pi*z)) + cos(2*pi*y.*sin(pi*x)),...    % 17
    @(x,y,z) (1-x.*y.*z)./(1+x.^2+y.^2),...                                    % 18
    @(x,y,z) cos(pi*x.*y.^2.*z.^3).*cos(pi*z.*y.^2.*x.^3),...                  % 19
    @(x,y,z) cos(2*pi*x.*y.^2.*z.^3).*cos(2*pi*y.*x.^2.*z.^3),...              % 20
    @(x,y,z) cos(3*pi*x.*y.^2.*(1+z)).*cos(3*pi*y.*x.^2.*(1+z)),...            % 21      
    @(x,y,z) (x-y)./(3-x.^2+z.^2),...                                          % 22            
    @(x,y,z) exp(-y.*x.^2.*z) + exp(-x.*y.^2.*z),...                           % 23
    @(x,y,z) exp((1-x.^2.*z)./(1+y.^2.*z)) + exp((1-y.^2.*z)./(1+x.^2.*z)),... % 24
    @(x,y,z) 10.^(-x.*y.*z),...                                                % 25
    @(x,y,z) 10.^(-10*x.*y.*z),...                                             % 26
    @(x,y,z) sin(x+y+z),...                                                    % 27
    @(x,y,z) exp(x+y+z).*cos(x+y+z),...                                       % 28
    @(x,y,z) cos(pi/4+x+y+z),...                                               % 29
    @(x,y,z) cos(pi/3+5*x+5*y+5*z),...                                        % 30
    @(x,y,z) (x+y+z).^12,...                                                   % 31
    @(x,y,z) exp(x.^2.*y.^2.*z.^2).*cos(x+y+z),...                             % 32
    @(x,y,z) sin(x.*y.*z)+x+y+z,...                                            % 33
    @(x,y,z) cos(100*x)-cos(100*y)-cos(100*z),...                              % 34
    @(x,y,z) x-y+z,...                                                         % 35
    @(x,y,z) -sin(x).*(sin(x.^2/pi).^2 - sin(y).*sin(y.^2/pi).^2) - sin(z).*sin(z.^2/pi).^2,...                  % 36
    @(x,y,z) -x.*sin(sqrt(abs(0.2+x))) - y.*sin(sqrt(abs(0.3+y))) - z.*sin(sqrt(abs(0.1+z))),...                % 37 
    @(x,y,z) (x.^2+y.^2+z.^2)/4000 - cos(x).*cos(y/sqrt(2)) .* cos(z/sqrt(3))+1,...                             % 38
    @(x,y,z) exp(1./(1+(((x+1)/2).*((y+1)/2).*(z+1)/2).^2)),...                % 39
    @(x,y,z) 2*exp(exp((x+1)/2)),...                                           % 40
    };

% Exact values for definite integrals computed with MATLAB's symbolic
% toolbox.
exact = [
    0.8461106227350253, ...
    0.6052157118483288, ...
    0.4697661749231274, ...
    0.3886397051915788, ...
    0.3330920107414529, ...
    0.2928314960173565, ...
    0.2619772790103158, ...
    0.3226674912855009, ...
    0.1153949594968427, ...
    0.0463743346003271, ...
    1.0, ...
    0.3854484437166375, ...
    0.2595975105701650, ...
    1.0700418045865364, ...
    0.1103040719136995, ...
    1.1941278093664705, ...
    0.4916086077355209, ...
    0.5741043338997425, ...
    0.9381453489074456, ...
    0.8830048694732021, ...
    0.3411136775418946, ...
    0.0101828389788635, ...
    1.8529116285910792, ...
    4.2715143503929390, ...
    0.7859343211742496, ...
    0.3352208605577725, ...
    0.8793549306454008, ...
    -0.801590008944990, ...
    -0.577703137905825, ...
    -0.008766419956637, ...
    5220.0021978021978, ...
    0.0366931467095498, ...
    1.6224340287967378, ...
    0.0050636564110975, ...
    0.5, ...
    -0.022434416365347, ...
    -1.181086511303566, ...
    0.2694080277004217, ...
    2.3340368233541618, ...
    17.816513659679896, ...
    ];

dom = [0 1 0 1 0 1];
for jj=1:1:length(Battery)
    % Test construction from the function handle:
    g = chebfun3(Battery{jj}, dom);
    pass(5*jj-4) = abs(sum3(g) - exact(jj)) < tol;
    
    % Test construction from the Chebfun3 object:
    % 1: Without specifying the variable to be separated in Phase 1:
    h = chebfun3(@(x,y,z) g(x,y,z), dom);
    pass(5*jj-3) = abs(sum3(h) - exact(jj)) < tol;
    
    % 2: Different variables specified to be separated in Phase 1. The
    % goal is to check that constructor has no issues with any choice of
    % variable chosen for the first separation.
    h1 = chebfun3(@(x,y,z) g(x,y,z), dom, 'fiberDim', 1);
    pass(5*jj-2) = abs(sum3(h1) - exact(jj)) < tol;
    
    h2 = chebfun3(@(x,y,z) g(x,y,z), dom, 'fiberDim', 2);
    pass(5*jj-1) = abs(sum3(h2) - exact(jj)) < tol;
        
    h3 = chebfun3(@(x,y,z) g(x,y,z), dom, 'fiberDim', 3);
    pass(5*jj) = abs(sum3(h3) - exact(jj)) < tol;
    
end

end