import torch


def get_cyclic_scheduler(optimizer, batches_per_epoch, base_lr=10e-6, max_lr=0.1, step_size_factor=5):
    """
    Get cyclic scheduler.

    Note that the resulting optimizer's step function is called after each batch!

    :param optimizer: optimizer
    :type optimizer: torch.optim.Optimizer
    :param batches_per_epoch: number of batches per epoch
    :type batches_per_epoch: int
    :param base_lr: base learning rate
    :type base_lr: float
    :param max_lr: max learning rate
    :type max_lr: float
    :param step_size_factor: step size in multiples of batches
    :type step_size_factor: int
    :return: scheduler
    :rtype: torch.optim.lr_scheduler.LRScheduler
    """

    return torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=base_lr, max_lr=max_lr, step_size_up=batches_per_epoch*step_size_factor)