function [dist_val, dist_idx] = kNN_dist_mat(X_train, X_test, Num, max_mat_elements)
%KNN_DIST_MAT calculates the distance between instances
%
%   Syntax
%
%       [dist_val,dist_idx] = NN_dist_mat(X_train, X_test, Num, max_mat_elements)
%   
%   Description  
% 
% 
% 
% 
% 
% 
% 
% 此处显示详细说明
    if nargin < 4
        max_mat_elements = 1000*1000;
    end
    if nargin < 3
        Num = 10;
    end
    if nargin < 2
        error('Input parameters not enough!')
    end
    num_training = size(X_train,1);
    num_testing = size(X_test,1);
    if num_training == num_testing
        if sum(sum(abs(X_train-X_test))) < 1e-3
            the_same_flag = 1;
        else
            the_same_flag = 0;
        end
    else
        the_same_flag = 0;
    end
    block_size = floor(max_mat_elements/num_training);
    num_blocks = ceil(num_testing/block_size);
    dist_val = zeros(num_testing,Num);
    dist_idx = zeros(num_testing,Num);
    for i = 1:num_blocks
        low = block_size*(i-1)+1;
        if i == num_blocks
            high = num_testing;
        else
            high = block_size*i;
        end
        temp_data = X_test(low:high,:);
        temp_size = size(temp_data,1);
        mat_1 = repmat(sum(X_train.^2,2),1,temp_size);
        mat_2 = repmat(sum(temp_data.^2,2),1,num_training)';
        temp_dist_mat = mat_1+mat_2-2*X_train*temp_data';
        temp_dist_mat = sqrt(temp_dist_mat);
        temp_dist_mat = temp_dist_mat';
        if the_same_flag
            for j = low:high
                temp_dist_mat(j-low+1,j) = realmax;
            end
        end
        for j = low:high
            [temp,index] = sort(temp_dist_mat(j-low+1,:));
            dist_val(j,:) = temp(1:Num);
            dist_idx(j,:) = index(1:Num);
        end
    end
end

