<commit_before>import numpy as np
import container, smooth, algorithms
from composite import composite
import pylab

class Block(object):

    r"""
    A Block solves a signal approximator problem for a given atom, the form
    of which depends on whether the atom is in constraint mode
    or Lagrange mode. An atom has an affine transform, i.e. a map

    .. math::

       \beta \mapsto D\beta + \alpha

    and a support function. The canonical example, the :math:`\ell_1` norm,
    is the support function of the :math:`\ell_{\infty}` ball.

    If it's in Lagrange mode, the Block solves the following
    dual problem.

    and a support function. The canonical example, the :math:`\ell_1` norm,
    is the support function of the :math:`\ell_{\infty}` ball.

    If it's in Lagrange mode, the Block solves the following
    dual problem.

    .. math::

       \text{minimize} \frac{1}{2} \|Y - D^Tu\|^2_2 - \alpha^T u \ \text{s.t.} \ h^*(u)
       \leq \lambda

    where :math:`h^*(u) \leq \lambda` is the dual constraint of the atom.
    If the atom was the *l1norm*, then the constraint is an
    :math:`\ell_{\infty}` or box constraint.

    If the atom is in constraint mode, the Block solves the following
    dual problem

    .. math::

       \text{minimize} \frac{1}{2} \|Y - D^Tu\|^2_2 - \alpha^T u +
       \lambda h^*(u)

    If the atom was the *l1norm*, then the norm above is
    :math:`\ell_{\infty}` norm.

    """

    def __init__(self, dual, initial=None, response=None):

        self.linear_transform, self.dual_atom = dual
        if response is None:
            response = np.zeros(self.linear_transform.dual_shape)
        if initial is None:
            initial = np.zeros(self.linear_transform.dual_shape)
        else:
            initial = initial.copy()
        if self.linear_transform.linear_operator is not None:
            self.loss = smooth.quadratic.affine(self.linear_transform.linear_operator.T, -response, coef=0.5, diag=self.linear_transform.diagD)
        else:
            self.loss = smooth.quadratic.shift(-response, coef=0.5)

        prox = self.dual_atom.proximal
        nonsmooth = self.dual_atom.nonsmooth_objective
        if nonsmooth(initial) == np.inf:
            raise ValueError('initial point is not feasible')
        
        self.composite = composite(self.loss.smooth_objective, nonsmooth, prox, initial)

    def fit(self, *solver_args, **solver_kw):
        if not hasattr(self, '_solver'):
            self._solver = algorithms.FISTA(self.composite)
        self._solver.fit(*solver_args, **solver_kw)
        return self.composite.coefs

    def set_coefs(self, coefs):
        self.composite.coefs[:] = coefs

    def get_coefs(self):
        return self.composite.coefs
    coefs = property(get_coefs, set_coefs)
    
    # response is the negative offset in the loss which is (quadratic / 2.)
    def set_response(self, response):
        self.loss.affine_transform.affine_offset[:] = -response<commit_msg>adding quadratic parts to compostie in blocks.py<commit_after>import numpy as np
import container, smooth, algorithms
from composite import composite
import pylab

class Block(object):

    r"""
    A Block solves a signal approximator problem for a given atom, the form
    of which depends on whether the atom is in constraint mode
    or Lagrange mode. An atom has an affine transform, i.e. a map

    .. math::

       \beta \mapsto D\beta + \alpha

    and a support function. The canonical example, the :math:`\ell_1` norm,
    is the support function of the :math:`\ell_{\infty}` ball.

    If it's in Lagrange mode, the Block solves the following
    dual problem.

    and a support function. The canonical example, the :math:`\ell_1` norm,
    is the support function of the :math:`\ell_{\infty}` ball.

    If it's in Lagrange mode, the Block solves the following
    dual problem.

    .. math::

       \text{minimize} \frac{1}{2} \|Y - D^Tu\|^2_2 - \alpha^T u \ \text{s.t.} \ h^*(u)
       \leq \lambda

    where :math:`h^*(u) \leq \lambda` is the dual constraint of the atom.
    If the atom was the *l1norm*, then the constraint is an
    :math:`\ell_{\infty}` or box constraint.

    If the atom is in constraint mode, the Block solves the following
    dual problem

    .. math::

       \text{minimize} \frac{1}{2} \|Y - D^Tu\|^2_2 - \alpha^T u +
       \lambda h^*(u)

    If the atom was the *l1norm*, then the norm above is
    :math:`\ell_{\infty}` norm.

    """

    def __init__(self, dual, initial=None, response=None):

        self.linear_transform, self.dual_atom = dual
        if response is None:
            response = np.zeros(self.linear_transform.dual_shape)
        if initial is None:
            initial = np.zeros(self.linear_transform.dual_shape)
        else:
            initial = initial.copy()
        if self.linear_transform.linear_operator is not None:
            self.loss = smooth.quadratic.affine(self.linear_transform.linear_operator.T, -response, coef=0.5, diag=self.linear_transform.diagD)
        else:
            self.loss = smooth.quadratic.shift(-response, coef=0.5)

        prox = self.dual_atom.proximal
        nonsmooth = self.dual_atom.nonsmooth_objective
        if nonsmooth(initial) == np.inf:
            raise ValueError('initial point is not feasible')
        
        self.composite = composite(self.loss.smooth_objective, nonsmooth, prox, initial)
        if self.loss.quadratic is not None:
            q = self.loss.quadratic
            self.composite.quadratic = (q.coef, q.offset, q.linear)

    def fit(self, *solver_args, **solver_kw):
        if not hasattr(self, '_solver'):
            self._solver = algorithms.FISTA(self.composite)
        self._solver.fit(*solver_args, **solver_kw)
        return self.composite.coefs

    def set_coefs(self, coefs):
        self.composite.coefs[:] = coefs

    def get_coefs(self):
        return self.composite.coefs
    coefs = property(get_coefs, set_coefs)
    
    # response is the negative offset in the loss which is (quadratic / 2.)
    def set_response(self, response):
        self.loss.affine_transform.affine_offset[:] = -response
{'fraction_non_alphanumeric': 0.10703264576904337, 'fraction_numerical': 0.0055221698879324346, 'mean_word_length': 2.592765460910152, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5177444', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1873, 'n_words': 594}