classdef (SharedTestFixtures={mexm_fixture}) minQ_tests < meq_test
  % tests of profile minimum finder
  %
  % [+MEQ MatlabEQuilibrium Toolbox+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved.
  
  properties
    verbosity = false;
  end
  
  properties(TestParameter)
    method = {'minQmex','minQmexm'};
    sq     = struct('positive',-1,'negative',1);
  end
  
  methods(Test,TestTags={'Unit'})
    function test_v_interp1(testCase,method,sq)
      %% A simple profile with a local minimum
      aQ = 1 + linspace(0,1,41).^1.5; % unequally spaced grid
      aQ0 = mean([aQ(1),aQ(end)]);
      qQ = 1 + (aQ-aQ0).^2; % some nonmonotonic profile
      
      [amin,minQ] = feval(method,aQ,sq*qQ,sq);
      
      if testCase.verbosity
        clf;
        subplot(311);
        plot(aQ,sq*qQ,'.-'); hold on;
        plot(amin,minQ,'x')
      end
      
      testCase.verifyEqual(amin,aQ0,'RelTol',10*eps)
      testCase.verifyEqual(minQ,sq*1,'RelTol',10*eps)
      
      %% with local minimum at leftmost point
      qQ = 1+aQ;
      
      [amin,minQ] = feval(method,aQ,sq*qQ,sq,1);

      if testCase.verbosity
        subplot(312)
        plot(aQ,sq*qQ,'.-'); hold on;
        plot(amin,minQ,'ko')
      end
      
      testCase.verifyEqual(amin,aQ(1),'RelTol',10*eps)
      testCase.verifyEqual(minQ,sq*qQ(1),'RelTol',10*eps)
      
      %% with local minimum at right point
      qQ = 4-aQ;
      
      [amin,minQ] = feval(method,aQ,sq*qQ,sq,1);

      if testCase.verbosity
        subplot(312)
        plot(aQ,sq*qQ,'.-'); hold on;
        plot(amin,minQ,'ok')
      end
      
      testCase.verifyEqual(amin,aQ(end),'RelTol',10*eps)
      testCase.verifyEqual(minQ,sq*qQ(end),'RelTol',10*eps)
      
      %% 2 extrema
      aQ1 = 1.2; aQ2 = 1.8;
      qQ = (aQ-aQ1).^2.*(aQ-aQ2).^2;
      [amin,minQ] = feval(method,aQ,sq*qQ,sq,2);
      
      testCase.verifyEqual(amin,[aQ2;aQ1],'AbsTol',1e-3)
      testCase.verifyEqual(minQ,[0;0],'AbsTol',1e-3)

      if testCase.verbosity
        subplot(313)
        plot(aQ,sq*qQ); hold on
        plot(amin,minQ,'ok');
      end 
      
      %% 3 extrema
      aQ1 = 1.2; aQ2 = 1.8;
      qQ = -(aQ-aQ1).^2.*(aQ-aQ2).^2;
      
      if testCase.verbosity
        plot(aQ,sq*qQ)
        plot(amin,minQ,'xk');
      end
      
      [amin,minQ] = feval(method,aQ,sq*qQ,sq,3);
      
      testCase.verifyEqual(amin,[aQ(end);1.5;aQ(1)],'AbsTol',1e-4)
      testCase.verifyEqual(minQ([1,3]),sq*[qQ(end);qQ(1)],'RelTol',10*eps)
    end
  end
end