Skip to main content

A Python DSL for simply and easily formulating and solving non-convex optimization problems.

Project description

NVXPY

Build Status codecov

Overview

NVXPY is a Python-based Domain Specific Language (DSL) designed for formulating and solving non-convex programs using a natural, math-inspired API. It is designed to have as similar an interface to CVXPY as possible.

NVXPY is not a solver, it uses solvers from other packages (such as SLSQP, IPOPT, etc.), and includes a built-in Branch-and-Bound solver for mixed-integer nonlinear programs (MINLP).

Features

  • Simple, concise, and math-inspired interface
  • Codegen compiler for efficient evaluation (85%-99% as fast as native Python)
  • Built-in Branch-and-Bound MINLP solver with discrete value constraints
  • Graph constructs for clean MIP formulations (wraps networkx)
  • Handles gradients seamlessly, even for custom functions

Installation

NVXPY can be installed from PyPi using:

pip install nvxpy

and has the following dependencies:

  • Python >= 3.11
  • NumPy >= 2.3
  • SciPy >= 1.15
  • Autograd >= 1.8
  • NetworkX >= 3.0
  • cyipopt (optional, for IPOPT solver)

Usage

Basic NLP Example

import numpy as np
import nvxpy as nvx

x = nvx.Variable((3,))
x.value = np.array([-5.0, 0.0, 0.0])  # NLPs require a seed

x_d = np.array([5.0, 0.0, 0.0])

obj = nvx.norm(x - x_d)
constraints = [nvx.norm(x) >= 1.0]  # Non-convex!

prob = nvx.Problem(nvx.Minimize(obj), constraints)
prob.solve(solver=nvx.SLSQP)

print(f'optimized value of x: {x.value}')

Mixed-Integer Programming

NVXPY supports integer and binary variables with a built-in Branch-and-Bound solver:

import nvxpy as nvx

# Binary knapsack problem
x = nvx.Variable(integer=True, name="x")
y = nvx.Variable(integer=True, name="y")

prob = nvx.Problem(
    nvx.Maximize(10*x + 6*y),
    [
        5*x + 3*y <= 15,
        x ^ [0, 1],  # x in {0, 1}
        y ^ [0, 1],  # y in {0, 1}
    ]
)
prob.solve(solver=nvx.BNB)

Discrete Value Constraints

Variables can be constrained to discrete sets of values:

x = nvx.Variable(integer=True)

# x must be one of these values
prob = nvx.Problem(
    nvx.Minimize((x - 7)**2),
    [x ^ [1, 5, 10, 15]]  # x in {1, 5, 10, 15}
)
prob.solve(solver=nvx.BNB)  # Optimal: x = 5

Graph-Based MIP Formulations

NVXPY provides Graph and DiGraph constructs for clean graph optimization problems:

import networkx as nx
import nvxpy as nvx

# Maximum Independent Set
nxg = nx.petersen_graph()
G = nvx.Graph(nxg)
y = G.node_vars(binary=True)

prob = nvx.Problem(
    nvx.Maximize(nvx.sum([y[i] for i in G.nodes])),
    G.independent(y)  # y[i] + y[j] <= 1 for all edges
)
prob.solve(solver=nvx.BNB)

Available graph helpers:

  • G.edge_vars(binary=True) / G.node_vars(binary=True) - Create decision variables
  • G.degree(x) == k - Degree constraints (undirected)
  • G.in_degree(x) / G.out_degree(x) - For directed graphs
  • G.independent(y) - Independent set constraints
  • G.covers(x, y) - Vertex cover constraints
  • G.total_weight(x) - Sum of edge weights for objectives

Custom Functions

Wrap arbitrary Python functions using the @nvx.function decorator:

import autograd.numpy as np
import nvxpy as nvx

@nvx.function(jac="autograd")
def rosenbrock(x):
    return (1 - x[0])**2 + 100 * (x[1] - x[0]**2)**2

x = nvx.Variable(shape=(2,))
x.value = np.array([0.0, 0.0])

prob = nvx.Problem(nvx.Minimize(rosenbrock(x)))
prob.solve(solver=nvx.LBFGSB)

Options:

  • jac="numerical" - Finite difference gradients (default)
  • jac="autograd" - Automatic differentiation via autograd
  • jac=callable - User-provided Jacobian function

Available Solvers

Gradient-Free

Solver Description
nvx.NELDER_MEAD Derivative-free simplex method
nvx.POWELL Derivative-free conjugate direction method
nvx.COBYLA Constrained Optimization BY Linear Approximation
nvx.COBYQA Constrained Optimization BY Quadratic Approximation

Gradient-Based

Solver Description
nvx.CG Conjugate gradient method
nvx.BFGS Quasi-Newton method
nvx.LBFGSB Limited-memory BFGS with bounds
nvx.TNC Truncated Newton method
nvx.SLSQP Sequential Least Squares Programming (supports constraints)

Hessian-Based

Solver Description
nvx.NEWTON_CG Newton-CG trust region method
nvx.DOGLEG Dogleg trust region method
nvx.TRUST_NCG Trust-region Newton-CG
nvx.TRUST_KRYLOV Trust-region with Krylov subspace
nvx.TRUST_EXACT Trust-region with exact Hessian
nvx.TRUST_CONSTR Trust-region constrained algorithm

Global Optimizers

Solver Description
nvx.DIFF_EVOLUTION Differential evolution
nvx.DUAL_ANNEALING Dual annealing
nvx.SHGO Simplicial homology global optimization
nvx.BASINHOPPING Basin-hopping with local minimization

Other

Solver Description
nvx.IPOPT Interior Point Optimizer (requires cyipopt)
nvx.BNB Built-in Branch-and-Bound MINLP solver

Limitations

NVXPY is in active development. Current limitations:

  • Branch-and-Bound solver is basic and may struggle with large problems
  • Limited set of atomic operations
  • Some edge cases may be untested

Development

To contribute to NVXPY, clone the repository and install the development dependencies:

git clone https://github.com/landonclark97/nvxpy.git
cd nvxpy
poetry install --with dev

Running Tests

Tests are written using pytest. To run the tests, execute:

poetry run pytest

License

Apache 2.0

Contact

For any inquiries or issues, please contact Landon Clark at landonclark97@gmail.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nvxpy-0.3.0.tar.gz (64.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nvxpy-0.3.0-py3-none-any.whl (85.3 kB view details)

Uploaded Python 3

File details

Details for the file nvxpy-0.3.0.tar.gz.

File metadata

  • Download URL: nvxpy-0.3.0.tar.gz
  • Upload date:
  • Size: 64.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nvxpy-0.3.0.tar.gz
Algorithm Hash digest
SHA256 333dc87723ad51f3be050c38b433ee44977b472676d803eecf3e4969a9bae23a
MD5 1f19a055a5a00236a1a5f905c70864ba
BLAKE2b-256 1c5dcb7b208ff33ff55ec69105be20716f404959415ae30548a62f1f6bdc8c53

See more details on using hashes here.

Provenance

The following attestation bundles were made for nvxpy-0.3.0.tar.gz:

Publisher: publish.yaml on landonclark97/nvxpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nvxpy-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nvxpy-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 85.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nvxpy-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56a6edd696655c5ff351435cdd4133b0c01bc81f161cfa9e39e4031a172bba07
MD5 0c8a5556af7f84654884629ba1684ffe
BLAKE2b-256 903220946030a9ecbcf6c5f2c070c9740941beb875b37702b80fce1801e13f30

See more details on using hashes here.

Provenance

The following attestation bundles were made for nvxpy-0.3.0-py3-none-any.whl:

Publisher: publish.yaml on landonclark97/nvxpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page