Skip to main content

Hardware-accelerated nonlinear optimization in Taichi

Project description

Taichi BFGS (TIBFGS)

This package implements the Broyden-Fletcher-Goldfarb-Shanno (BFGS) non-linear optimization algorithm in Taichi, enabling massively-parallel solutions to non-convex optimization problems.

Installation

pip install tibfgs

Use

To use tibfgs, define an objective function as a ti.func, for example the Ackley function:

@ti.func
def ackley(x: ti.math.vec2) -> ti.f32:
    return (
        -20 * ti.exp(-0.2 * ti.sqrt(0.5 * x.norm_sqr()))
        - ti.exp(
            0.5 * ti.cos(2 * ti.math.pi * x.x) + 0.5 * ti.cos(2 * ti.math.pi * x.y)
        )
        + ti.math.e
        + 20
    )

Initialize \(n\) initial conditions as an \(n \times m\) Numpy array (where \(m\) is the dimension of the problem, in this case \(m=2\)):

n_particles = int(1e6)
x0 = 4 * np.random.rand(n_particles, 2) - 2

Run the BFGS optimizer in parallel on the GPU with:

df = tibfgs.minimize(
    ackley, x0, gtol=1e-3, eps=1e-5, discard_failures=False
)

Which returns a polars DataFrame of solutions with df.head() like:

shape: (5, 10)
┌───────┬──────────┬───────────────┬───────────────┬───┬───────┬───────┬────────────────────────┬────────────────────────┐
│ index ┆ fun      ┆ xk            ┆ x0            ┆ … ┆ feval ┆ geval ┆ gradient               ┆ hessian_inverse        │
│ ---   ┆ ---      ┆ ---           ┆ ---           ┆   ┆ ---   ┆ ---   ┆ ---                    ┆ ---                    │
│ u32   ┆ f32      ┆ array[f32, 2] ┆ array[f32, 2] ┆   ┆ i32   ┆ i32   ┆ array[f32, 2]          ┆ array[f32, (2, 2)]     │
╞═══════╪══════════╪═══════════════╪═══════════════╪═══╪═══════╪═══════╪════════════════════════╪════════════════════════╡
│ 0     ┆ 5.381865 ┆ [-0.982348,   ┆ [-0.968771,   ┆ … ┆ 39    ┆ 13    ┆ [0.190735, 0.190735]   ┆ [[0.617119,            │
│       ┆          ┆ 1.964832]     ┆ 1.981125]     ┆   ┆       ┆       ┆                        ┆ -0.479458], [-0.47…    │
│ 1     ┆ 0.000011 ┆ [-5.7371e-7,  ┆ [1.487202,    ┆ … ┆ 147   ┆ 49    ┆ [1.716614, 0.38147]    ┆ [[0.000008, 0.000002], │
│       ┆          ┆ -0.000005]    ┆ -1.334406]    ┆   ┆       ┆       ┆                        ┆ [0.0000…               │
│ 2     ┆ 3.574453 ┆ [-0.968429,   ┆ [-0.806571,   ┆ … ┆ 36    ┆ 12    ┆ [0.0, 0.0]             ┆ [[0.016302, -0.00451], │
│       ┆          ┆ -0.968395]    ┆ -0.820057]    ┆   ┆       ┆       ┆                        ┆ [-0.004…               │
│ 3     ┆ 4.884083 ┆ [0.000768,    ┆ [-0.342866,   ┆ … ┆ 33    ┆ 11    ┆ [0.0, 0.0]             ┆ [[0.020406, 0.000647], │
│       ┆          ┆ -1.959207]    ┆ -1.756427]    ┆   ┆       ┆       ┆                        ┆ [0.0006…               │
│ 4     ┆ 0.000011 ┆ [0.000003,    ┆ [1.534462,    ┆ … ┆ 111   ┆ 37    ┆ [2.861023, 2.861023]   ┆ [[0.000299,            │
│       ┆          ┆ 0.000003]     ┆ 0.979372]     ┆   ┆       ┆       ┆                        ┆ -0.000029], [-0.00…    │
└───────┴──────────┴───────────────┴───────────────┴───┴───────┴───────┴────────────────────────┴────────────────────────┘

The full schema of this dataframe is:

┌─────────────────┬──────────────────────────────┐
│ Column          ┆ Type                         │
│ ---             ┆ ---                          │
│ str             ┆ object                       │
╞═════════════════╪══════════════════════════════╡
│ index           ┆ UInt32                       │
│ fun             ┆ Float32                      │
│ xk              ┆ Array(Float32, shape=(2,))   │
│ x0              ┆ Array(Float32, shape=(2,))   │
│ message         ┆ String                       │
│ iterations      ┆ UInt16                       │
│ feval           ┆ Int32                        │
│ geval           ┆ Int32                        │
│ gradient        ┆ Array(Float32, shape=(2,))   │
│ hessian_inverse ┆ Array(Float32, shape=(2, 2)) │
└─────────────────┴──────────────────────────────┘

Where:

  • index is the particle initial condition index in x0

  • fun is the objective function value at the converged solution

  • xk is the converged solution

  • x0 is the provided initial guess

  • message describes the convergence state

  • iterations is the number of state update iterations used to reach convergence

  • feval is the number of objective function evaluations (including evaluations during gradient evaluation) over all iterations

  • geval is the number of gradient evaluations across all iterations

  • gradient is the gradient at the converged xk

  • hessian_inverse is the inverse of the Hessian matrix maintained by BFGS internally, at the converged xk

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

tibfgs-0.0.4.tar.gz (12.5 kB view hashes)

Uploaded Source

Supported by

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