<commit_before># -*- coding: utf-8 -*-


import itertools

import scipy.optimize
import numpy as np
import scipy as sp

from base import dummylogfunc


class LineSearch(object):

    def __init__(self, wrt, logfunc=dummylogfunc):
        self.wrt = wrt
        self.logfunc = logfunc


class BackTrack(LineSearch):
    """Class implementing a back tracking line search.

    The idea is to try out jumps along the search direction until
    one satisfies a condition. Jumps are done by multiplying the search
    direction with a scalar. The field `schedule` holds an iterator which
    successively yields those scalars.

    To not possibly iterate forever, the field `tolerance` holds a very small
    value (1E-20 per default). As soon as the absolute value of every component
    of the step (direction multiplied with the scalar from `schedule`) is less
    than `tolerance`.
    """

    def __init__(self, wrt, f, schedule=None, decay=None, max_iter=float('inf'),
                 tolerance=1E-20, logfunc=dummylogfunc):
        super(BackTrack, self).__init__(wrt, logfunc)
        self.f = f
        self.max_iter = max_iter

        if schedule is not None:
            self.schedule = schedule
        else:
            self.decay = decay
            self.schedule = (decay**i for i in itertools.count())

        self.tolerance = tolerance

    def search(self, direction, initialization=1, args=None, kwargs=None, 
               loss0=None):
        # Recalculate the current loss if it has not been given.
        if loss0 is None:
            loss0 = self.f(self.wrt, *args, **kwargs)

        args = [] if args is None else args
        kwargs = {} if kwargs is None else kwargs

        # Try out every point in the schedule until a reduction has been found.
        for i, s in enumerate(self.schedule):
            if i + 1 >= self.max_iter:
                break
            step = initialization * s * direction
            if abs(step).max() < self.tolerance:
                # If the step is too short, just return 0.
                break
            candidate = self.wrt + step
            loss = self.f(candidate, *args, **kwargs)
            improvement = loss0 - loss
            if -(loss0 - loss) < 0:
                # We check here for negative improvement to also 
                self.logfunc({'message': 'beating loss by %f' % (loss0 - loss)})<commit_msg>added comment.<commit_after># -*- coding: utf-8 -*-


import itertools

import scipy.optimize
import numpy as np
import scipy as sp

from base import dummylogfunc


class LineSearch(object):

    def __init__(self, wrt, logfunc=dummylogfunc):
        self.wrt = wrt
        self.logfunc = logfunc


class BackTrack(LineSearch):
    """Class implementing a back tracking line search.

    The idea is to try out jumps along the search direction until
    one satisfies a condition. Jumps are done by multiplying the search
    direction with a scalar. The field `schedule` holds an iterator which
    successively yields those scalars.

    To not possibly iterate forever, the field `tolerance` holds a very small
    value (1E-20 per default). As soon as the absolute value of every component
    of the step (direction multiplied with the scalar from `schedule`) is less
    than `tolerance`.
    """

    def __init__(self, wrt, f, schedule=None, decay=None, max_iter=float('inf'),
                 tolerance=1E-20, logfunc=dummylogfunc):
        super(BackTrack, self).__init__(wrt, logfunc)
        self.f = f
        self.max_iter = max_iter

        if schedule is not None:
            self.schedule = schedule
        else:
            self.decay = decay
            self.schedule = (decay**i for i in itertools.count())

        self.tolerance = tolerance

    def search(self, direction, initialization=1, args=None, kwargs=None, 
               loss0=None):
        # Recalculate the current loss if it has not been given.
        if loss0 is None:
            loss0 = self.f(self.wrt, *args, **kwargs)

        args = [] if args is None else args
        kwargs = {} if kwargs is None else kwargs

        # Try out every point in the schedule until a reduction has been found.
        for i, s in enumerate(self.schedule):
            if i + 1 >= self.max_iter:
                break
            step = initialization * s * direction
            if abs(step).max() < self.tolerance:
                # If the step is too short, just return 0.
                break
            candidate = self.wrt + step
            loss = self.f(candidate, *args, **kwargs)
            improvement = loss0 - loss
            if -(loss0 - loss) < 0:
                # We check here for negative improvement to also not continue in
                # the case of NaNs.
                self.logfunc({'message': 'beating loss by %f' % (loss0 - loss)})
{'fraction_non_alphanumeric': 0.08167907361455748, 'fraction_numerical': 0.007030603804797354, 'mean_word_length': 2.134802333117304, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7278923', 'n_tokens_mistral': 1348, 'n_tokens_neox': 1299, 'n_words': 521}