%function[ErrorEvent,Distance] = FindMinimumDistanceForTernarySystem_FasterVersion(UChannelTarget1, UChannelTarget2, LChannelTarget1, LChannelTarget2, ErrorEventLength)
function[ErrorEvent,Distance] = FindMinimumDistanceForTernarySystem_FasterVersion(UChannelTarget1, LChannelTarget1, ErrorEventLength)
% Calculates the minimum distance for a ternary magnetic recording system
% with given target(s).
% ARGS:
% UChannelTarget: Target for the upper channel (channel with relatively
% lower density)
% LChannelTarget: Target for the lower channel (channel with relatively
% higher density)
% ErrorEventLength: Maximum Length of the error event

if(length(UChannelTarget1)~=length(LChannelTarget1))
    fprintf(1,'ERROR: Targets should be of same length.\n');
    return;
end
    
% Possible error events are 0,+/-1 for each channel
UErrorEvent = combn([0 +1 -1],ErrorEventLength);    % Error events for upper channel;
LErrorEvent = UErrorEvent;                          % Error events for lower channel;
%Distance=zeros(size(UErrorEvent,1),size(LErrorEvent,1)); % Distance[i][j] implies the distance for the event UErrorEvent(i)+LErrorEvent(j).
USize = size(UErrorEvent,1);
LSize = size(LErrorEvent,1);
Distance=zeros(1,USize*LSize);
ErrorEvent = zeros(USize*LSize,ErrorEventLength*2);
for i=1:USize
    if(mod(i,50)==0 | mod(i,USize)==0)
        fprintf(1,'%d/%d\n',i,USize);
    end
    for j=1:LSize   
        %Distance(j+(i-1)*USize) = sum((conv(UErrorEvent(i,:),UChannelTarget1)+conv(LErrorEvent(j,:),LChannelTarget1)).^2) + sum((conv(UErrorEvent(i,:),UChannelTarget2)+conv(LErrorEvent(j,:),LChannelTarget2)).^2);
        Distance(j+(i-1)*USize) = sum((conv(UErrorEvent(i,:),UChannelTarget1)+conv(LErrorEvent(j,:),LChannelTarget1)).^2);
        ErrorEvent(j+(i-1)*USize,:)=[UErrorEvent(i,:) LErrorEvent(j,:)];
    end
end
%Distance(1,1)=1000; % Some large number. event is (0,0) which is not an error event.
Distance=Distance(2:end);
ErrorEvent = ErrorEvent(2:end,:);
return;
