Tulip

April 19, 2026 · View on GitHub

DOI

Tulip is an open-source interior-point solver for linear optimization, written in pure Julia. It implements the homogeneous primal-dual interior-point algorithm with multiple centrality corrections, and therefore handles unbounded and infeasible problems. Tulip’s main feature is that its algorithmic framework is disentangled from linear algebra implementations. This allows to seamlessly integrate specialized routines for structured problems.

License

Tulip is licensed under the MPL 2.0 license.

Installation

Install Tulip using the Julia package manager:

import Pkg
Pkg.add("Tulip")

Usage

The recommended way of using Tulip is through JuMP or MathOptInterface (MOI).

The low-level interface is still under development and is likely change in the future. The JuMP/MOI interface is more stable and regularly tested.

Using with JuMP

Tulip can be used with JuMP in indirect and direct modes. Linear objectives, linear constraints and lower/upper bounds on variables are supported.

using JuMP
import Tulip

# With a JuMP-level cache
model = Model(Tulip.Optimizer)
# Direct mode (faster incremental modifications)
model = direct_model(Tulip.Optimizer())
# You can also add the optimizer later
model = Model()
...
set_optimizer(model, Tulip.Optimizer)

To use a non-default numeric type (e.g., BigFloat), use JuMP.GenericModel{T} (requires JuMP v1.13):

using JuMP
import Tulip
model = JuMP.GenericModel{BigFloat}(Tulip.Optimizer{BigFloat})

Note that The correct syntax is JuMP.GenericModel{T}(Tulip.Optimizer{T}), i.e., the type parameter must match between Tulip and JuMP.

# Both examples below will error when calling optimize!
# because the JuMP- and Tulip-level numerical types are different
model = JuMP.GenericModel{BigFloat}(Tulip.Optimizer)
model = JuMP.GenericModel{Float64}(Tulip.Optimizer{BigFloat})

Using with MOI

The MOI-level interface is not recommended for most users, and is considered an advanced feature.

The type Tulip.Optimizer is parametrized by the model's arithmetic, for example, Float64 or BigFloat. This allows to solve problem in higher numerical precision. See the documentation for more details.

import MathOptInterface as MOI
import Tulip
model = Tulip.Optimizer{Float64}()   # Create a model in Float64 precision
model = Tulip.Optimizer()            # Defaults to the above call
model = Tulip.Optimizer{BigFloat}()  # Create a model in BigFloat precision

Solver parameters

See the documentation for a full list of parameters.

To set parameters in JuMP, use:

using JuMP, Tulip
model = Model(Tulip.Optimizer)
set_attribute(model, "IPM_IterationsLimit", 200)

To set parameters in MathOptInterface, use:

using Tulip
import MathOptInterface as MOI
model = Tulip.Optimizer{Float64}()
MOI.set(model, MOI.RawOptimizerAttribute("IPM_IterationsLimit"), 200)

To set parameters in the Tulip API, use:

using Tulip
model = Tulip.Model{Float64}()
Tulip.set_parameter(model, "IPM_IterationsLimit", 200)

Command-line executable

See app building instructions.

Citing Tulip.jl

If you use Tulip in your work, we kindly ask that you cite the following reference (preprint available here).

@Article{Tulip.jl,
  author   = {Tanneau, Mathieu and Anjos, Miguel F. and Lodi, Andrea},
  journal  = {Mathematical Programming Computation},
  title    = {Design and implementation of a modular interior-point solver for linear optimization},
  year     = {2021},
  issn     = {1867-2957},
  month    = feb,
  doi      = {10.1007/s12532-020-00200-8},
  language = {en},
  url      = {https://doi.org/10.1007/s12532-020-00200-8},
  urldate  = {2021-03-07},
}