# Path: deeppy/feed.py
# class Feed(object):
#     def __init__(self, x, batch_size=None, epoch_size=None):
#         self.x = x
#         self.n_samples = x.shape[0]
#         if batch_size is None:
#             batch_size = 128 if self.n_samples > 512 else self.n_samples
#         if epoch_size is None:
#             epoch_size = int(np.ceil(float(self.n_samples) / batch_size))
#         self.epoch_size = epoch_size
#         self.batch_size = batch_size
#         self.epoch_idx = 0
# 
#     @classmethod
#     def from_any(cls, arg):
#         if isinstance(arg, Feed):
#             arg.reset()
#             return arg
#         elif isinstance(arg, np.ndarray):
#             return cls(arg)
#         elif isinstance(arg, ca.ndarray):
#             return cls(np.array(arg))
#         elif isinstance(arg, tuple):
#             return SupervisedFeed(arg[0], arg[1])
#         raise ValueError('Invalid arguments.')
# 
#     def reset(self):
#         self.epoch_idx = 0
# 
#     def _batch_slices(self):
#         for b in range(self.epoch_size):
#             start = (self.epoch_idx * self.epoch_size + b) * self.batch_size
#             start = start % self.n_samples
#             stop = (start + self.batch_size) % self.n_samples
#             yield start, stop
#         self.epoch_idx += 1
# 
#     def batches(self):
#         x = ca.empty(self.x_shape, dtype=self.x.dtype)
#         for start, stop in self._batch_slices():
#             if stop > start:
#                 x_np = self.x[start:stop]
#             else:
#                 x_np = np.concatenate((self.x[start:], self.x[:stop]))
#             ca.copyto(x, x_np)
#             yield x,
# 
#     @property
#     def x_shape(self):
#         return (self.batch_size,) + self.x.shape[1:]
# 
#     @property
#     def shapes(self):
#         return self.x_shape,


import numpy as np
import cudarray as ca
from ..feed import Feed


class SiameseFeed(Feed):
    def __init__(self, x1, x2, batch_size=None, epoch_size=None):
        super(SiameseFeed, self).__init__(x1, batch_size, epoch_size)
        if x1.shape[0] != x2.shape[0]:
            raise ValueError('shape mismatch between x1 and x2')
        self.x2 = x2

    def batches(self):
        x1 = ca.empty(self.x_shape, dtype=self.x.dtype)
        x2 = ca.empty_like(x1)
        for start, stop in self._batch_slices():
            if stop > start:
                x1_np = self.x[start:stop]
                x2_np = self.x2[start:stop]
            else:

# Path: deeppy/feed.py
# class Feed(object):
#     def __init__(self, x, batch_size=None, epoch_size=None):
#         self.x = x
#         self.n_samples = x.shape[0]
#         if batch_size is None:
#             batch_size = 128 if self.n_samples > 512 else self.n_samples
#         if epoch_size is None:
#             epoch_size = int(np.ceil(float(self.n_samples) / batch_size))
#         self.epoch_size = epoch_size
#         self.batch_size = batch_size
#         self.epoch_idx = 0
# 
#     @classmethod
#     def from_any(cls, arg):
#         if isinstance(arg, Feed):
#             arg.reset()
#             return arg
#         elif isinstance(arg, np.ndarray):
#             return cls(arg)
#         elif isinstance(arg, ca.ndarray):
#             return cls(np.array(arg))
#         elif isinstance(arg, tuple):
#             return SupervisedFeed(arg[0], arg[1])
#         raise ValueError('Invalid arguments.')
# 
#     def reset(self):
#         self.epoch_idx = 0
# 
#     def _batch_slices(self):
#         for b in range(self.epoch_size):
#             start = (self.epoch_idx * self.epoch_size + b) * self.batch_size
#             start = start % self.n_samples
#             stop = (start + self.batch_size) % self.n_samples
#             yield start, stop
#         self.epoch_idx += 1
# 
#     def batches(self):
#         x = ca.empty(self.x_shape, dtype=self.x.dtype)
#         for start, stop in self._batch_slices():
#             if stop > start:
#                 x_np = self.x[start:stop]
#             else:
#                 x_np = np.concatenate((self.x[start:], self.x[:stop]))
#             ca.copyto(x, x_np)
#             yield x,
# 
#     @property
#     def x_shape(self):
#         return (self.batch_size,) + self.x.shape[1:]
# 
#     @property
#     def shapes(self):
#         return self.x_shape,


# Path: deeppy/siamese/feed.py
import numpy as np
import cudarray as ca
from ..feed import Feed



class SiameseFeed(Feed):
    def __init__(self, x1, x2, batch_size=None, epoch_size=None):
        super(SiameseFeed, self).__init__(x1, batch_size, epoch_size)
        if x1.shape[0] != x2.shape[0]:
            raise ValueError('shape mismatch between x1 and x2')
        self.x2 = x2

    def batches(self):
        x1 = ca.empty(self.x_shape, dtype=self.x.dtype)
        x2 = ca.empty_like(x1)
        for start, stop in self._batch_slices():
            if stop > start:
                x1_np = self.x[start:stop]
                x2_np = self.x2[start:stop]
            else:

                x1_np = np.concatenate((self.x[start:], self.x[:stop]))