Skip to content

Validate dimension of Constraint #420

@alphaville

Description

@alphaville

Background

In Python Constraint does not have a method like dimension; this is defined in derived classes like Rectangle. This was deliberate so we can do

constraint = Ball2(radius=1.0)

without having to specify a size. As a result, sometimes the dimension is not determinable.

The issue

The following works and does not raise an exception:

import sys
import os
import casadi.casadi as cs
import opengen as og

optimizers_dir = "my_optimizers"
optimizer_name = "rosenbrock"


def get_open_local_absolute_path():
    return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "rust"))


nu, np = 5, 2
u = cs.SX.sym("u", nu)  # decision variable (nu = 5)
p = cs.SX.sym("p", 2)  # parameter (np = 2)
phi = og.functions.rosenbrock(u, p) + 1500*cs.sum1(u)

# c_f1 = cs.vertcat(p[0] * u[0] - u[1], p[1]*u[2] - u[3] + 0.1)
c_f2 = cs.vertcat(0.2 + 1.5 * u[0] - u[1], u[2] - u[3] - 0.1)

bounds = og.constraints.Rectangle(xmin=[1, 2], xmax=[3, 4])
problem = og.builder.Problem(u, p, phi) \
    .with_penalty_constraints(c_f2)\
    .with_constraints(bounds)
meta = og.config.OptimizerMeta()\
    .with_optimizer_name(optimizer_name)

build_config = og.config.BuildConfiguration() \
    .with_build_directory(optimizers_dir) \
    .with_build_mode(og.config.BuildConfiguration.DEBUG_MODE) \
    .with_build_python_bindings() \
    .with_open_version(local_path=get_open_local_absolute_path())
solver_cfg = og.config.SolverConfiguration() \
    .with_tolerance(1e-6) \
    .with_max_inner_iterations(1000) \
    .with_max_outer_iterations(30) \
    .with_penalty_weight_update_factor(1.5) \
    .with_preconditioning(True)

builder = og.builder.OpEnOptimizerBuilder(problem,
                                          meta,
                                          build_config,
                                          solver_cfg)
builder.build()

Note that we have a decision variable of dimension 5:

u = cs.SX.sym("u", nu)

and a set of constraints of dimension 2:

bounds = og.constraints.Rectangle(xmin=[1, 2], xmax=[3, 4])

Then, the Rust code panics:

thread '<unnamed>' (6694911) panicked at /Users/pantelis/Documents/Development/optimization-engine/rust/src/constraints/rectangle.rs:76:13:
assertion `left == right` failed: x and xmin have incompatible dimensions
  left: 5
 right: 2
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File "/Users/pantelis/Documents/Development/optimization-engine/python/main.py", line 52, in <module>
    response = solver.run(p=[0.5, 8.5], initial_guess=[1, 2, 3, 4, 0]) # SolverResponse
pyo3_runtime.PanicException: assertion `left == right` failed: x and xmin have incompatible dimensions
  left: 5
 right: 2

Solution

Mainly we need to implement dimension() -> int for all constraints. This method will sometimes have to return None (e.g., in case of Ball*). Then we need to verify the user input.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpythonissue related to python

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions