function Y_predict = knn( X_train, X_test, Y_train, K )

    classnum = max( Y_train );
%     sqrdist = ml_sqrDist( X_train, X_test );
    
%     sqrdist = zeros( size( X_train, 2 ), size( X_test, 2 ) );
%     for i = 1 : size( X_train, 2 )
%         sqrdist(i,:) = sum( X_test .* log2( X_test ./ repmat( X_train(:,i), [ 1 size(X_test,2) ] ) ) );
%     end

    sqrdist = zeros( size( X_train, 2 ), size( X_test, 2 ) );
    for i = 1 : size( X_train, 2 )
        sqrdist(i,:) = -sum( min( X_test, repmat( X_train(:,i), [ 1 size(X_test,2) ] ) ) );
    end

    % KNN
    idx = zeros( K, size( sqrdist, 2 ) );
    for i = 1 : size( sqrdist, 2 )
        [ sorteddist sortedidx ] = sort( sqrdist( :, i ) );
        idx( :, i ) = sortedidx( 1:K );
    end
    %Y_predict = mode( Y_train( sortedidx( 2 : K + 1, : ) ) );

    Y_predict = zeros( size( X_test, 2 ), 1 );
    for i = 1 : size( X_test, 2 )
        count = hist( Y_train( idx( 1:K, i ) ), 1 : classnum );
        [ maxvalue Y_predict( i ) ] = max( count );
    end
