classdef nfftUnitTests
  %UNITTEST Summary of this class goes here
  %   Detailed explanation goes here
  
  properties
    perform_exhaustive_tests_flag = 0;

    testcases_1d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_2_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_2_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_2_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_2_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_4_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_4_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_4_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_4_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_10_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_10_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_10_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_20_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_20_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_20_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_50_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_50_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_50_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_1d_50_50.txt')};

    testcases_adjoint_1d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_2_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_2_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_2_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_2_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_4_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_4_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_4_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_4_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_10_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_10_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_10_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_20_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_20_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_20_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_50_1.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_50_10.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_50_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_1d_50_50.txt')};

%    initializers_direct = nfftTestcaseInitDelegate('init_guru', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE);
    initializers_1d = {nfftTestcaseInitDelegate('init_1d', 8, [], []) ...
                       nfftTestcaseInitDelegate('init', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_class_no_flags', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,FFT_OUT_OF_PLACE), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE)};

    testcases_1d_online = {nfftTestcaseDelegateOnline(1, 50, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 100, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 200, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 500, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 1000, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 2000, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 5000, 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(1, 10000, 50, 'trafo')};
                         
    testcases_adjoint_1d_online = {nfftTestcaseDelegateOnline(1, 50, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 100, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 200, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 500, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 1000, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 2000, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 5000, 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(1, 10000, 50, 'adjoint')};

    testcases_2d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_10_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_10_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_10_20_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_20_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_20_10_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_20_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_2d_20_20_50.txt')};

    testcases_adjoint_2d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_10_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_10_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_10_20_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_20_10_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_20_10_50.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_20_20_20.txt') ...
                         nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_2d_20_20_50.txt')};

    initializers_2d = {nfftTestcaseInitDelegate('init_2d', 8, [], []) ...
                       nfftTestcaseInitDelegate('init', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_class_no_flags', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,FFT_OUT_OF_PLACE), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE)};

    testcases_2d_online = {nfftTestcaseDelegateOnline(2, [50,50], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(2, [70,100], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(2, [100,70], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(2, [100,100], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(2, [200,200], 50, 'trafo') ...
                           %nfftTestcaseDelegateOnline(2, [500,500], 50, 'trafo') ...
                           %nfftTestcaseDelegateOnline(2, [1000,1000], 50, 'trafo') ...
                           };

    testcases_adjoint_2d_online = {nfftTestcaseDelegateOnline(2, [50,50], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(2, [70,100], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(2, [100,70], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(2, [100,100], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(2, [200,200], 50, 'adjoint') ...
                           %nfftTestcaseDelegateOnline(2, [500,500], 50, 'adjoint') ...
                           %nfftTestcaseDelegateOnline(2, [1000,1000], 50, 'adjoint')
                           };

    testcases_3d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_3d_10_10_10_10.txt')};

    testcases_adjoint_3d_file = {nfftTestcaseDelegateFile('/var/www/debian/nfft3/nfft-3.5.0/tests/data/nfft_adjoint_3d_10_10_10_10.txt')};

    initializers_3d = {nfftTestcaseInitDelegate('init_3d', 8, [], []) ...
                       nfftTestcaseInitDelegate('init', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_class_no_flags', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,FFT_OUT_OF_PLACE), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_FULL_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE)};

    testcases_3d_online = {nfftTestcaseDelegateOnline(3, [24,32,30], 77, 'trafo') ...
                           nfftTestcaseDelegateOnline(3, [50,50,50], 50, 'trafo')};

    testcases_adjoint_3d_online = {nfftTestcaseDelegateOnline(3, [24,32,30], 77, 'adjoint') ...
                           nfftTestcaseDelegateOnline(3, [50,50,50], 50, 'adjoint')};


    initializers_4d = {nfftTestcaseInitDelegate('init', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_class_no_flags', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 8, [], []) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,FFT_OUT_OF_PLACE), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 8, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE)};

    testcases_4d_online = {nfftTestcaseDelegateOnline(4, [14,14,14,14], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(4, [24,32,30,10], 65, 'trafo')};

    testcases_adjoint_4d_online = {nfftTestcaseDelegateOnline(4, [14,14,14,14], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(4, [24,32,30,10], 65, 'adjoint')};

    initializers_5d = { ...
                       nfftTestcaseInitDelegate('init_class_no_flags', 3, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 3, 0, 0) ...
                       nfftTestcaseInitDelegate('init_class', 3, [], []) ...
                       nfftTestcaseInitDelegate('init_guru', 3, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 3, bitor(PRE_PSI,FFT_OUT_OF_PLACE), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_guru', 3, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 3, bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT), FFTW_ESTIMATE) ...
                       nfftTestcaseInitDelegate('init_class_flags', 3, bitor(PRE_PSI,bitor(FFT_OUT_OF_PLACE,NFFT_OMP_BLOCKWISE_ADJOINT)), FFTW_ESTIMATE)};

    testcases_5d_online = {nfftTestcaseDelegateOnline(5, [8,6,6,10,6], 50, 'trafo') ...
                           nfftTestcaseDelegateOnline(5, [8,6,12,6,6], 65, 'trafo')};

    testcases_adjoint_5d_online = {nfftTestcaseDelegateOnline(5, [14,6,6,10,14], 50, 'adjoint') ...
                           nfftTestcaseDelegateOnline(5, [14,6,12,6,14], 65, 'adjoint')};

  end
  
  methods
    function ok = check_single(~, testcase, init_delegate, check_delegate, trafo_delegate)
      ok = 0;
      
      testcase = testcase.setup;
      
      init_name = init_delegate.name;
      if strcmp(init_name, 'init_guru')
        no_pre = 1;
        if bitand(init_delegate.flags, PRE_PSI) ~= 0
          init_name = sprintf('%s_pre_psi', init_name);
          no_pre = 0;
        end
        if bitand(init_delegate.flags, PRE_FULL_PSI) ~= 0
          init_name = sprintf('%s_pre_full_psi', init_name);
          no_pre = 0;
        end
        if no_pre
          init_name = sprintf('%s_no_psi', init_name);
        end
      elseif strcmp(init_name, 'init_class_flags')
        no_pre = 1;
        if bitand(init_delegate.flags, PRE_PSI) ~= 0
          init_name = 'init_class_pre_psi';
          no_pre = 0;
        end
        if bitand(init_delegate.flags, PRE_FULL_PSI) ~= 0
          init_name = 'init_class_pre_full_psi';
          no_pre = 0;
        end
        if no_pre
          init_name = 'init_class_no_psi';
        end
      end
      fprintf(', %-23s', init_name);
      [init_delegate, plan] = init_delegate.init(testcase.d, testcase.N, testcase.M);

      fprintf(', m = %2d', init_delegate.m);
      fprintf(', %-14s', trafo_delegate.name);

      if isnumeric(plan)
        nfft_set_x(plan, testcase.x.');
        nfft_precompute_psi(plan);
      else
        plan.x = testcase.x;
      end

      run_test = 1;
%       if (trafo_delegate.isCheck)
%         check = trafo_delegate.check(plan);
%         if check ~= 0
%           fprintf(' -> %-4s (','OK');
%           fprintf('%s', check);
%           fprintf(')\n');
%           ok = 1;
%           run_test = 0;
%         end
      if (trafo_delegate.isCost)
        cost = trafo_delegate.cost(plan);
        if (cost > 0.1)
          fprintf(' -> %-4s (cost too high)\n','OK');
          ok = 1;
          run_test = 0;
        end
      end
      
      if run_test
        plan = check_delegate.prepare(plan, testcase.f, testcase.f_hat);
        
        plan = trafo_delegate.trafo(plan);
        
        % Standard NFFT error measure.
        err = check_delegate.compare(plan, testcase.f, testcase.f_hat);
        bound = trafo_delegate.acc(init_delegate.m, init_delegate.sigma);
        ok = err < bound;
        if ~ok; okstr = 'FAIL'; else okstr = 'OK'; end;
        fprintf(' -> %-4s %.3e (%.3e)\n', okstr, err, bound);
      end
      
      testcase.destroy;
      if isnumeric(plan)
        nfft_finalize(plan);
      else
        delete(plan);
      end
    end

    function result = check_many(h, testcases, initializers, check_delegate, trafos)
      result = 1;
      for k=1:length(trafos)
        for i=1:length(testcases)
          for j=1:length(initializers)
            r = h.check_single(testcases{i}, initializers{j}, check_delegate, trafos{k});
            result = min(result, r);
          end
        end
      end
    end
    
    function result = nfft_check_1d_direct_file(h)
      result = h.check_many(h.testcases_1d_file, h.initializers_1d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo_direct')});
    end
    
    function result = nfft_check_1d_fast_file(h)
      result = h.check_many(h.testcases_1d_file, h.initializers_1d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_1d_direct_file(h)
      result = h.check_many(h.testcases_adjoint_1d_file, h.initializers_1d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint_direct')});
    end
    
    function result = nfft_check_adjoint_1d_fast_file(h)
      result = h.check_many(h.testcases_adjoint_1d_file, h.initializers_1d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_1d_online(h)
      result = h.check_many(h.testcases_1d_online, h.initializers_1d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_1d_online(h)
      result = h.check_many(h.testcases_adjoint_1d_online, h.initializers_1d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_2d_direct_file(h)
      result = h.check_many(h.testcases_2d_file, h.initializers_2d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo_direct')});
    end

    function result = nfft_check_2d_fast_file(h)
      result = h.check_many(h.testcases_2d_file, h.initializers_2d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_2d_direct_file(h)
      result = h.check_many(h.testcases_adjoint_2d_file, h.initializers_2d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint_direct')});
    end

    function result = nfft_check_adjoint_2d_fast_file(h)
      result = h.check_many(h.testcases_adjoint_2d_file, h.initializers_2d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_2d_online(h)
      result = h.check_many(h.testcases_2d_online, h.initializers_2d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_2d_online(h)
      result = h.check_many(h.testcases_adjoint_2d_online, h.initializers_2d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_3d_direct_file(h)
      result = h.check_many(h.testcases_3d_file, h.initializers_3d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo_direct')});
    end

    function result = nfft_check_3d_fast_file(h)
      result = h.check_many(h.testcases_3d_file, h.initializers_3d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_3d_direct_file(h)
      result = h.check_many(h.testcases_adjoint_3d_file, h.initializers_3d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint_direct')});
    end

    function result = nfft_check_adjoint_3d_fast_file(h)
      result = h.check_many(h.testcases_adjoint_3d_file, h.initializers_3d, nfftTestcaseCheckDelegate('adjoint'),  {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_3d_online(h)
      result = h.check_many(h.testcases_3d_online, h.initializers_3d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_3d_online(h)
      result = h.check_many(h.testcases_adjoint_3d_online, h.initializers_3d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_4d_online(h)
      result = h.check_many(h.testcases_4d_online, h.initializers_4d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_4d_online(h)
      result = h.check_many(h.testcases_adjoint_4d_online, h.initializers_4d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
    function result = nfft_check_5d_online(h)
      result = h.check_many(h.testcases_5d_online, h.initializers_5d, nfftTestcaseCheckDelegate('trafo'), {nfftTestcaseTrafoDelegate('trafo')});
    end
    
    function result = nfft_check_adjoint_5d_online(h)
      result = h.check_many(h.testcases_adjoint_5d_online, h.initializers_5d, nfftTestcaseCheckDelegate('adjoint'), {nfftTestcaseTrafoDelegate('adjoint')});
    end
    
  end
end
