function [idxout,valout,barrier] = chooseval(valin, minmaxval, idxin )
% idxout = chooseval(num, cval, [idxin] )
% Selects highest values of a vector
%
% Input:
%   valin         vector, values to choose from
%   minmaxval     1x2 array, [minimal number of things to choose, maximal number of things to choose]
%   idxin         optional, logical array of size num. Defines from which num we want to choose. All entries where idx==0 are not considered in the choice-process.
%
% Output:
%   idxout        Indices of values chosen
%   valout        the selected values
%   barrier       the lower bound of the chosen values
%
% Note: undefined behaviour if minimal > maximal
%       undefined behaviour for complex input
%
% E.g.: [idxout, valout, barrier]=chooseval(randn(1,100),[10 50])
%
% Written by tommsch, 2018

WEIGHT=1.05; %The higher this value, the more high numbers are weighted more then small numbers.

    if(nargin==2 || isempty(idxin)); 
        idxin=true(size(valin)); 
    end;
    
    %cases when we have to choose everything
    if(~any(idxin) || nnz(idxin)<=minmaxval(1)); 
        idxout=logical(idxin); 
        valout=valin(idxout);
        barrier=-inf;
        return; 
    end; 
    
    %cases when we have to choose nothing
    if(minmaxval(2)==0); valout=[]; idxout=[]; barrier=-inf; return; end;
    
    %if(minmaxval(2)<minmaxval(1)); error('cval(2) < cval(1)'); end;
    
    valin_select=valin(logical(idxin));
    idxin=find(idxin);
    [values,idxout]=sort(valin_select,'MissingPlacement','first');
    %idxin_select=idxin(idxout);
    
    [~,idxdiffvalues]=sort(diff(WEIGHT.^values),'descend','MissingPlacement','last');
    
    val=length(valin_select)-idxdiffvalues; %number of values higher then the number on the resp. position +1

    idx=find(val>=minmaxval(1) & val<=minmaxval(2),1); %first index of the elements we choose
   
    idx=idxdiffvalues(idx(1));
    
    idx=idxout(idx+1:end);
    idx=idxin(idx);
    
    %convert to logical indexing
    idxout=false(size(valin));
    idxout(idx)=true;
    
    if(nargout>=2); valout=valin(idxout); end;
    if(nargout>=3); barrier=min(valout); end;
    
end


function dummy; end %#ok<DEFNU> %Generates an error, if the 'end' of a function is missing. 