'Solves a DCP compliant optimization problem.
Saves the values of primal and dual variables in the variable
and constraint objects, respectively.
Parameters
solver : str, optional
The solver to use. Defaults to ECOS.
ignore_dcp : bool, optional
Overrides the default of raising an exception if the problem is not
DCP.
warm_start : bool, optional
Should the previous solver result be used to warm start?
verbose : bool, optional
Overrides the default of hiding solver output.
parallel : bool, optional
If problem is separable, solve in parallel.
kwargs : dict, optional
A dict of options that will be passed to the specific solver.
In general, these options will override any default settings
imposed by cvxpy.
Returns
float
The optimal value for the problem, or a string indicating
why the problem could not be solved.'

def _solve(self, solver=None, ignore_dcp=False, warm_start=False, verbose=False, parallel=False, **kwargs):

    if (not self.is_dcp()):
        if ignore_dcp:
            print 'Problem    does    not    follow    DCP    rules.    Solving    a    convex    relaxation.'
        else:
            raise DCPError('Problem    does    not    follow    DCP    rules.')
    if (solver == s.LS):
        solver = SOLVERS[s.LS]
        solver.validate_solver(self)
        objective = self.objective
        constraints = self.constraints
        sym_data = solver.get_sym_data(objective, constraints)
        results_dict = solver.solve(objective, constraints, self._cached_data, warm_start, verbose, kwargs)
        self._update_problem_state(results_dict, sym_data, solver)
        return self.value
    (objective, constraints) = self.canonicalize()
    if parallel:
        if ((objective != self._cached_data[s.PARALLEL].objective) or (constraints != self._cached_data[s.PARALLEL].constraints)):
            self._separable_problems = cvxpy.transforms.get_separable_problems(self)
            self._cached_data[s.PARALLEL] = CachedProblem(objective, constraints)
        if (len(self._separable_problems) > 1):
            return self._parallel_solve(solver, ignore_dcp, warm_start, verbose, **kwargs)
    if (solver is None):
        solver_name = Solver.choose_solver(constraints)
        solver = SOLVERS[solver_name]
    elif (solver in SOLVERS):
        solver = SOLVERS[solver]
        solver.validate_solver(constraints)
    else:
        raise SolverError('Unknown    solver.')
    sym_data = solver.get_sym_data(objective, constraints, self._cached_data)
    if (sym_data.presolve_status is None):
        results_dict = solver.solve(objective, constraints, self._cached_data, warm_start, verbose, kwargs)
    else:
        results_dict = {s.STATUS: sym_data.presolve_status}
    self._update_problem_state(results_dict, sym_data, solver)
    return self.value
