function [bestc, bestg, bestcv] = libsvm_gridsearch(label, inst, varargin)

    if isempty(varargin),
        wide_grid = 0;
    else
        wide_grid = varargin{1};
    end

    if wide_grid == 0,

    % from http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f803

        bestcv = 0;
        for log2c = -1:3,
          for log2g = -4:1,
            cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)];
            cv = svmtrain(label, inst, cmd);
            if (cv >= bestcv),
              bestcv = cv; bestc = 2^log2c; bestg = 2^log2g;
            end
            fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv);
          end
        end
        
    else

        bestcv = 0;
        for log2c = -5:2:15,
          for log2g = -15:2:3,
            cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)];
            cv = svmtrain(label, inst, cmd);
            if (cv >= bestcv),
              bestcv = cv; bestc = 2^log2c; bestg = 2^log2g;
              bestlog2c = log2c; bestlog2g = log2g;
            end
            fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv);
          end
        end

        
        startc = bestlog2c-2; endc = bestlog2c+2;
        startg = bestlog2g-2; endg = bestlog2g+2;
        fprintf('Refining search from c=%g to %g, g=%g to %g\n', startc, endc, startg, endg);
        
        bestcv = 0;
        for log2c = startc:0.25:endc,
          for log2g = startg:0.25:endg,
            cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)];
            cv = svmtrain(label, inst, cmd);
            if (cv >= bestcv),
              bestcv = cv; bestc = 2^log2c; bestg = 2^log2g;
            end
            fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv);
          end
        end

    end

end