www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/@cgmathsobject/private/invert_1D.m

    function [out,err] = invert_1D(invBP,BP,val,flag)
%INVERT_1D
% Function to carry out the inversion of 1D tables. InvBP are the breakpoints of the Inverse table
% BP and val are the breakpoints and values of the table to be inverted. Flag helps us work out what to 
% do when things aren't invertible

%  Copyright 2000-2007 The MathWorks, Inc. and Ford Global Technologies, Inc.

% First let's dispense with the easy cases, when things are monotonic.
err = [];

if length(BP) ~= length(val)
   out = [];
   err = 'Breakpoints not the same length as values.';
   return
end

if length(unique(val)) == 1
   err = 'Cannot invert constant functions.';
   out = [];
   return
end

diffval = diff(sign(diff(val)));

if ~any(diffval) % Monotonic
   out = linear1(val,BP,invBP);
   err = [];
   return
end

% If it's not monotonic, let's break it up into monotonic chunks

count = 1;

BPstore{count} = BP([1;2]);
Valstore{count} = val([1;2]);

currentsign = sign(val(2)-val(1)); 
signstore(count) = currentsign;

if length(BP) > 2
   for i = 3:length(BP)
      tempsign = sign(val(i)-val(i-1));
      if tempsign == currentsign
         BPstore{count} = [BPstore{count};BP(i)];
         Valstore{count} = [Valstore{count};val(i)];
      else
         count = count+1;
         currentsign = tempsign;
         signstore(count) = currentsign;
         BPstore{count} = BP([i-1;i]);
         Valstore{count} = val([i-1;i]);
      end
   end
end

% BPstore now contains flat bits, increasing bits and decreasing bits. If there are only two 
% entries, then we will try to use the right monotonic bit as dictated by the selectionflag.

if count == 2
   % We have two bits - if one of them is flat then use the other, if we have inc + dec, then use the
   % one dictated by selectionflag.
   if flag == 3 | flag == 4, flag = 2; end % if only two bits we only want to deal in mins and maxs
   if sum(abs(signstore)) == 1
      I = find(signstore);
      out = linear1(Valstore{I},BPstore{I},invBP);
   else
      out = linear1(Valstore{flag},BPstore{flag},invBP);
   end
   err = [];
   return 
end

% And now for the linear regression method.

y = linspace(BP(1),BP(end),2001);
x = linear1(BP,val,y');
out = values_regression1(x(:),y(:),invBP);

return


% 
% 
% % In a bad case it would seem logical to use the segment that has the greatest value range intersecting with the 
% % requested breakpoints.
% 
% for k = 1:length(BPstore)
%     % Find out the intersection between this segment and the requested BP range.
%     Interval = [];
%     temp = max(min(Valstore{k}(end),invBP(end)) - max(Valstore{k}(1),invBP(1)),0);
%     Interval = [Interval;temp];
% end
% 
% % Interval gives us the overlap between each of the segments and our desired range. If there are many that match up,
% % then we use selectionflag, if none, then we use the longest.
% 
% Index = zeros(length(BPstore),1);
% Index(Interval(:) == invBP(end)-invBP(1)) = 1;
% if sum(Index) > 1 % more than one perfect match, so we pick one according to the flag.
%     I = find(Index);
%     if flag == 1
%         J = I(1);
%     elseif flag == 2;
%         J = I(end);
%     else
%         J = I(round(length(I)+1)/2);
%     end
% elseif sum(Index) == 1
%     J = find(Index);
% else
%     if ~any(Interval)
%         out = [];
%     else
%         [A,J] = max(Interval);
%     end
% end
% out = linear1(Valstore{J},BPstore{J},invBP);    
% 
% return