Skip to content

Commit

Permalink
Add derivative checks to unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chrhansk committed Sep 15, 2023
1 parent 394665d commit 0626939
Showing 1 changed file with 182 additions and 0 deletions.
182 changes: 182 additions & 0 deletions cyipopt/tests/unit/test_deriv_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import numpy as np

import cyipopt

import pytest


def full_indices(shape):
def indices():
r, c = np.indices(shape)
return r.flatten(), c.flatten()

return indices


def tril_indices(size):
def indices():
return np.tril_indices(size)

return indices


def flatten(func):
def _func(*args):
return func(*args).flatten()

return _func


@pytest.fixture
def hs071_sparse_definition_fixture(hs071_variable_lower_bounds_fixture,
hs071_constraint_lower_bounds_fixture,
hs071_definition_instance_fixture):
problem = hs071_definition_instance_fixture
n = len(hs071_variable_lower_bounds_fixture)
m = len(hs071_constraint_lower_bounds_fixture)

problem.jacobianstructure = full_indices((m, n))
problem.hessianstructure = tril_indices(n)

problem.jacobian = flatten(problem.jacobian)
problem.hessian = flatten(problem.hessian)

return problem


@pytest.fixture
def hs071_sparse_instance(hs071_initial_guess_fixture,
hs071_variable_lower_bounds_fixture,
hs071_variable_upper_bounds_fixture,
hs071_constraint_lower_bounds_fixture,
hs071_constraint_upper_bounds_fixture,
hs071_sparse_definition_fixture):

class Instance:
pass

instance = Instance()
instance.problem_definition = hs071_sparse_definition_fixture
instance.x0 = hs071_initial_guess_fixture
instance.lb = hs071_variable_lower_bounds_fixture
instance.ub = hs071_variable_upper_bounds_fixture
instance.cl = hs071_constraint_lower_bounds_fixture
instance.cu = hs071_constraint_upper_bounds_fixture
instance.n = len(instance.x0)
instance.m = len(instance.cl)

return instance


def problem_for_instance(instance):
return cyipopt.Problem(n=instance.n,
m=instance.m,
problem_obj=instance.problem_definition,
lb=instance.lb,
ub=instance.ub,
cl=instance.cl,
cu=instance.cu)


def test_solve_sparse(hs071_sparse_instance):
instance = hs071_sparse_instance
problem = problem_for_instance(instance)

x, info = problem.solve(instance.x0)

assert info['status'] == 0


def ensure_invalid_option(instance):
problem = problem_for_instance(instance)

problem.add_option('max_iter', 50)
x, info = problem.solve(instance.x0)

# -12: Invalid option
assert info['status'] == -12


@pytest.mark.skip
def test_solve_neg_jac(hs071_sparse_instance):
n = hs071_sparse_instance.n
m = hs071_sparse_instance.m
problem_definition = hs071_sparse_instance.problem_definition

def jacobianstructure():
r = np.full((m*n,), fill_value=-1, dtype=int)
c = np.full((m*n,), fill_value=-1, dtype=int)
return r, c

problem_definition.jacobianstructure = jacobianstructure

ensure_invalid_option(hs071_sparse_instance)


@pytest.mark.skip
def test_solve_large_jac(hs071_sparse_instance):
n = hs071_sparse_instance.n
m = hs071_sparse_instance.m
problem_definition = hs071_sparse_instance.problem_definition

import logging
logging.basicConfig(level=logging.DEBUG)

def jacobianstructure():
r = np.full((m*n,), fill_value=(m + n + 100), dtype=int)
c = np.full((m*n,), fill_value=(m + n + 100), dtype=int)
return r, c

problem_definition.jacobianstructure = jacobianstructure

ensure_invalid_option(hs071_sparse_instance)


def test_solve_triu_hess(hs071_sparse_instance):
n = hs071_sparse_instance.n
problem_definition = hs071_sparse_instance.problem_definition
problem_definition.hessianstructure = lambda: np.triu_indices(n)

ensure_invalid_option(hs071_sparse_instance)


def test_solve_neg_hess_entries(hs071_sparse_instance):
n = hs071_sparse_instance.n
problem_definition = hs071_sparse_instance.problem_definition

def hessianstructure():
r, c = np.tril_indices(n)
rneg = np.full_like(r, -1, dtype=int)
cneg = np.full_like(c, -1, dtype=int)
return rneg, cneg

problem_definition.hessianstructure = hessianstructure

ensure_invalid_option(hs071_sparse_instance)


def test_solve_large_hess_entries(hs071_sparse_instance):
n = hs071_sparse_instance.n
problem_definition = hs071_sparse_instance.problem_definition

def hessianstructure():
r, c = np.tril_indices(n)
rlarge = np.full_like(r, n + 100, dtype=int)
clarge = np.full_like(c, n + 100, dtype=int)
return rlarge, clarge

problem_definition.hessianstructure = hessianstructure

ensure_invalid_option(hs071_sparse_instance)


def test_solve_wrong_size(hs071_sparse_instance):
n = hs071_sparse_instance.n
problem_definition = hs071_sparse_instance.problem_definition

def hessianstructure():
return np.tril_indices(n + 10)

problem_definition.hessianstructure = hessianstructure

ensure_invalid_option(hs071_sparse_instance)

0 comments on commit 0626939

Please sign in to comment.