<commit_before>import numpy as np
from scipy import sparse
from algorithms import FISTA
from composite import (composite, nonsmooth as nonsmooth_composite,
                       smooth as smooth_composite)
from affine import (vstack as afvstack, identity as afidentity, power_L,
                    selector as afselector)
from separable import separable
#from conjugate import conjugate
from atoms import affine_atom as nonsmooth_affine_atom
from cones import zero_constraint, zero as zero_nonsmooth, affine_cone

class container(composite):
    """
    A container class for storing/combining seminorm_atom classes
    """
    def __init__(self, *atoms, **keywords):
        self.compute_difference = keywords.pop('compute_difference', True)
        self.nonsmooth_atoms = []
        self.smooth_atoms = []
        for atom in atoms:
            if (isinstance(atom, nonsmooth_composite) or 
                isinstance(atom, nonsmooth_affine_atom) or
                isinstance(atom, affine_cone)):
                self.nonsmooth_atoms.append(atom)
            elif isinstance(atom, smooth_composite):
                self.smooth_atoms.append(atom)
            else:
                raise ValueError('each atom should either be a smooth or nonsmooth composite')

        if len(self.nonsmooth_atoms) == 0 and len(self.smooth_atoms) == 0:
            raise ValueError('must specify some atoms')

        if len(self.nonsmooth_atoms) == 0:
            self.nonsmooth_atoms = [zero_nonsmooth(self.smooth_atoms[0].primal_shape)]
        transform, _ = self.dual
        self.coefs = np.zeros(transform.primal_shape)


    @property
    def dual(self):
        if not hasattr(self, "_dual"):
            transforms = []
            dual_atoms = []
            if len(self.nonsmooth_atoms) > 1:
                for atom in self.nonsmooth_atoms:
                    t, a = atom.dual
                    transforms.append(t)
                    dual_atoms.append(a)
                transform = afvstack(transforms)
                nonsm = separable(transform.dual_shape, dual_atoms,
                                  transform.dual_slices)
                self._dual = transform, nonsm
            else:
                self._dual = self.nonsmooth_atoms[0].dual
        return self._dual

    def smooth_objective(self, x, mode='both', check_feasibility=False):
        value, grad = 0, np.zeros(x.shape)
        if mode == 'func':
            for atom in self.smooth_atoms:
                value += atom.smooth_objective(x, mode=mode, 
                                               check_feasibility=check_feasibility)
            return value
        elif mode == 'both':
            for atom in self.smooth_atoms:
                v, g = atom.smooth_objective(x, mode=mode, 
                                               check_feasibility=check_feasibility)
                value += v
                grad += g
            return value, grad

        elif mode == 'grad':
            for atom in self.smooth_atoms:
                grad += atom.smooth_objective(x, mode=mode, 
                                              check_feasibility=check_feasibility)
            return grad
        else:
            raise ValueError("Mode specified incorrectly")

    def nonsmooth_objective(self, x, check_feasibility=False):
        out = 0.
        for atom in self.nonsmooth_atoms:
            out += atom.nonsmooth_objective(x,<commit_msg>fixing total_smooth_objective for container. so, for smooth composites, it would seem the quadratic is included in the smooth part, for nonsmooth, it is included in the nonsmooth part -- this is a conflict. for smooth ones, should we think of the quadratic in its nonsmooth part of its smooth part? if it is in the nonsmooth part, then the proximal method of smooth things should reflect this.<commit_after>import numpy as np
from scipy import sparse
from algorithms import FISTA
from composite import (composite, nonsmooth as nonsmooth_composite,
                       smooth as smooth_composite)
from affine import (vstack as afvstack, identity as afidentity, power_L,
                    selector as afselector)
from separable import separable
#from conjugate import conjugate
from atoms import affine_atom as nonsmooth_affine_atom
from cones import zero_constraint, zero as zero_nonsmooth, affine_cone

class container(composite):
    """
    A container class for storing/combining seminorm_atom classes
    """
    def __init__(self, *atoms, **keywords):
        self.compute_difference = keywords.pop('compute_difference', True)
        self.nonsmooth_atoms = []
        self.smooth_atoms = []
        for atom in atoms:
            if (isinstance(atom, nonsmooth_composite) or 
                isinstance(atom, nonsmooth_affine_atom) or
                isinstance(atom, affine_cone)):
                self.nonsmooth_atoms.append(atom)
            elif isinstance(atom, smooth_composite):
                self.smooth_atoms.append(atom)
            else:
                raise ValueError('each atom should either be a smooth or nonsmooth composite')

        if len(self.nonsmooth_atoms) == 0 and len(self.smooth_atoms) == 0:
            raise ValueError('must specify some atoms')

        if len(self.nonsmooth_atoms) == 0:
            self.nonsmooth_atoms = [zero_nonsmooth(self.smooth_atoms[0].primal_shape)]
        transform, _ = self.dual
        self.coefs = np.zeros(transform.primal_shape)


    @property
    def dual(self):
        if not hasattr(self, "_dual"):
            transforms = []
            dual_atoms = []
            if len(self.nonsmooth_atoms) > 1:
                for atom in self.nonsmooth_atoms:
                    t, a = atom.dual
                    transforms.append(t)
                    dual_atoms.append(a)
                transform = afvstack(transforms)
                nonsm = separable(transform.dual_shape, dual_atoms,
                                  transform.dual_slices)
                self._dual = transform, nonsm
            else:
                self._dual = self.nonsmooth_atoms[0].dual
        return self._dual

    def smooth_objective(self, x, mode='both', check_feasibility=False):
        """
        The smooth_objective __INCLUDES__ the identity
        quadratic of all the smooth atoms.
        """
        value, grad = 0, np.zeros(x.shape)
        if mode == 'func':
            for atom in self.smooth_atoms:
                value += atom.total_smooth_objective(x, mode=mode, 
                                                     check_feasibility=check_feasibility)
            return value
        elif mode == 'both':
            for atom in self.smooth_atoms:
                v, g = atom.total_smooth_objective(x, mode=mode, 
                                               check_feasibility=check_feasibility)
                value += v
                grad += g
            return value, grad

        elif mode == 'grad':
            for atom in self.smooth_atoms:
                grad += atom.total_smooth_objective(x, mode=mode, 
                                                    check_feasibility=check_feasibility)
            return grad
        else:
            raise ValueError("Mode specified incorrectly")

    def nonsmooth_objective(self, x, check_feasibility=False):
        out = 0.
        for atom in self.nonsmooth_atoms:
            out += atom.nonsmooth_objective(x,
{'fraction_non_alphanumeric': 0.0733387358184765, 'fraction_numerical': 0.0021609940572663426, 'mean_word_length': 1.908483896307934, 'pattern_counts': {'":': 0, '<': 3, '<?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': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3185397', 'n_tokens_mistral': 2119, 'n_tokens_neox': 1952, 'n_words': 537}