# Path: simpleknn/bigfile.py
# class BigFile:
# 
#     def __init__(self, datadir):
#         self.nr_of_images, self.ndims = map(int, open(os.path.join(datadir,'shape.txt')).readline().split())
#         id_file = os.path.join(datadir, "id.txt")
#         self.names = open(id_file).read().strip().split()
#         assert(len(self.names) == self.nr_of_images)
#         self.name2index = dict(zip(self.names, range(self.nr_of_images)))
#         self.binary_file = os.path.join(datadir, "feature.bin")
#         print ("[%s] %dx%d instances loaded from %s" % (self.__class__.__name__, self.nr_of_images, self.ndims, datadir))
# 
# 
#     def read(self, requested, isname=True):
#         requested = set(requested)
#         if isname:
#             index_name_array = [(self.name2index[x], x) for x in requested if x in self.name2index]
#         else:
#             assert(min(requested)>=0)
#             assert(max(requested)<len(self.names))
#             index_name_array = [(x, self.names[x]) for x in requested]
#         if len(index_name_array) == 0:
#             return [], []
#        
#         index_name_array.sort(key=lambda v:v[0])
#         sorted_index = [x[0] for x in index_name_array]
# 
#         nr_of_images = len(index_name_array)
#         vecs = [None] * nr_of_images
#         offset = np.float32(1).nbytes * self.ndims
#         
#         res = array.array('f')
#         fr = open(self.binary_file, 'rb')
#         fr.seek(index_name_array[0][0] * offset)
#         res.fromfile(fr, self.ndims)
#         previous = index_name_array[0][0]
#  
#         for next in sorted_index[1:]:
#             move = (next-1-previous) * offset
#             #print next, move
#             fr.seek(move, 1)
#             res.fromfile(fr, self.ndims)
#             previous = next
# 
#         fr.close()
# 
#         return [x[1] for x in index_name_array], [ res[i*self.ndims:(i+1)*self.ndims].tolist() for i in range(nr_of_images) ]
# 
# 
#     def read_one(self, name):
#         renamed, vectors = self.read([name])
#         return vectors[0]    
# 
#     def shape(self):
#         return [self.nr_of_images, self.ndims]


import numpy as np
from scipy.spatial import distance
from simpleknn.bigfile import BigFile


def calImageSimiByL2(image_1, image_2):
    A = np.mat(image_1)
    B = np.mat(image_2)
    dist = 1.0/(1 + np.linalg.norm(A-B, axis=1))
    return dist.tolist()

def calImageSimiByCos(image_1, image_2):
    A = np.mat(image_1)
    B = np.mat(image_2)
    num = A * B.T
    denom = np.linalg.norm(A) * np.linalg.norm(B, axis=1)
    cos = num / denom

    return cos.tolist()[0]


class ImageSimer:
    def __init__(self, dev_feat_path, train_feat_path):
        self.dev_feats = BigFile(dev_feat_path)

# Path: simpleknn/bigfile.py
# class BigFile:
# 
#     def __init__(self, datadir):
#         self.nr_of_images, self.ndims = map(int, open(os.path.join(datadir,'shape.txt')).readline().split())
#         id_file = os.path.join(datadir, "id.txt")
#         self.names = open(id_file).read().strip().split()
#         assert(len(self.names) == self.nr_of_images)
#         self.name2index = dict(zip(self.names, range(self.nr_of_images)))
#         self.binary_file = os.path.join(datadir, "feature.bin")
#         print ("[%s] %dx%d instances loaded from %s" % (self.__class__.__name__, self.nr_of_images, self.ndims, datadir))
# 
# 
#     def read(self, requested, isname=True):
#         requested = set(requested)
#         if isname:
#             index_name_array = [(self.name2index[x], x) for x in requested if x in self.name2index]
#         else:
#             assert(min(requested)>=0)
#             assert(max(requested)<len(self.names))
#             index_name_array = [(x, self.names[x]) for x in requested]
#         if len(index_name_array) == 0:
#             return [], []
#        
#         index_name_array.sort(key=lambda v:v[0])
#         sorted_index = [x[0] for x in index_name_array]
# 
#         nr_of_images = len(index_name_array)
#         vecs = [None] * nr_of_images
#         offset = np.float32(1).nbytes * self.ndims
#         
#         res = array.array('f')
#         fr = open(self.binary_file, 'rb')
#         fr.seek(index_name_array[0][0] * offset)
#         res.fromfile(fr, self.ndims)
#         previous = index_name_array[0][0]
#  
#         for next in sorted_index[1:]:
#             move = (next-1-previous) * offset
#             #print next, move
#             fr.seek(move, 1)
#             res.fromfile(fr, self.ndims)
#             previous = next
# 
#         fr.close()
# 
#         return [x[1] for x in index_name_array], [ res[i*self.ndims:(i+1)*self.ndims].tolist() for i in range(nr_of_images) ]
# 
# 
#     def read_one(self, name):
#         renamed, vectors = self.read([name])
#         return vectors[0]    
# 
#     def shape(self):
#         return [self.nr_of_images, self.ndims]


# Path: util/irc_image.py
import numpy as np
from scipy.spatial import distance
from simpleknn.bigfile import BigFile



def calImageSimiByL2(image_1, image_2):
    A = np.mat(image_1)
    B = np.mat(image_2)
    dist = 1.0/(1 + np.linalg.norm(A-B, axis=1))
    return dist.tolist()

def calImageSimiByCos(image_1, image_2):
    A = np.mat(image_1)
    B = np.mat(image_2)
    num = A * B.T
    denom = np.linalg.norm(A) * np.linalg.norm(B, axis=1)
    cos = num / denom

    return cos.tolist()[0]


class ImageSimer:
    def __init__(self, dev_feat_path, train_feat_path):
        self.dev_feats = BigFile(dev_feat_path)

        self.train_feats =  BigFile(train_feat_path)