torczon


Nametorczon JSON
Version 0.0.1 PyPI version JSON
download
home_pageNone
SummaryA NLP derivative-free solver using a modified version of the torczon algorithm
upload_time2024-10-30 12:43:22
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords nonlinear programming optimization derivative free constrained optimization
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # A simple python implementation of Torczon algorithm

Torczon algorithm is a derivative free algorithm initially designed for unconstrained nonlinear optimization problems. 
Torczon algorithm is a version of the simplex algorithm (not that used in Linear Programming problems) which avoids the 
Collapse of the polygone of solutions that is iteratively updated through the iterations.

This is a modified version of the Torczon algorithm that incorporates:

- Explicitly handling of hard box constraints on the decision variables
- Penalty-based handling of other (non box-like) constraints
- mutiple initial guess option for global optimization.

The main appealing feature of this family of algorithm lies in the fact that the cost function and the constraints need 
not to be differentiable. The counterpart is that this algorithm is not fitted to very high dimensional problems. 

I personally use it intensively in solving real-life problems arising in **Parameterized Nonlinear Model Predictive Control** 
problems. 

## Installation via pip

```terminal
pip install torczon
```

**Code citation**

[![DOI](https://zenodo.org/badge/260138021.svg)](https://zenodo.org/badge/latestdoi/260138021)

## Required packages

- numpy 

## Usage
 
- Define the cost function to be optimized, the cost might embed soft constraint definition via constraint penalty (the penalty can be a part of the variable p that can be any python object or variable. 

```python
def f(x,p):
    
    return ..
```

- Call the solver using 

```python
solve(f_user=f, 
      par=p, x0=x0, 
      xmin=xmin,
      xmax=xmax, 
      Nguess=Nguess, 
      Niter=Niter, 
      initial_box_width=0.1)
```
where 

- ```x0```
the initial guess (for the first guess)

- ```xmin, xmax``` 
the box of admissible values

- ```Niter``` 
the number of iterations by single guess 

- ```Nguess```: 
the number of initial guesses (randomly sampled using uniform distribution inside the hypercube defined by xmin and xmax)

- ```initial_box_width``` 
the amplitude of the initial steps around each initial guess to bild the polygone of the torczon algorithm.


## Example 

The script below calls the solver for three different optimization problems.

```python
from torczon import solve
import numpy as np

# This is the test file for the torczon module. 
# it contains three constrained optimization examples.

# Example 1
#=============
# Assume a cost function that need some class instance to be defined 
class Data():
        def __init__(self):
            self.a = 10
            self.b = -1
            self.c = 1.0  # assign to 0 to put solution at (a,b)
p = Data()

# The cost function  
def f1dex(x, p):
    return (x[0]-p.a)**2 +p.c*(x[1]*x[0])**4+(x[1]-p.b)**2

Nguess = 5
Niter = 30
R = solve(f1dex, p, [0.0,0.0], [-10,-10], [10, 10], Nguess, Niter)
print("Example 1")
print("----------")
print(f"Best found Solution = {R.x}")
print(f"Best Value found = {R.f}")
print("------------------------------")
#----------------

# Example 2
#============
# from http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page3389.htm

def f2dex(x, constraint_penalty):
    c1 = (np.sin(2*np.pi*x[0]))**3
    c2 = np.sin(2*np.pi*x[1])
    c3 = (x[1]**3)*(x[0]+x[1])
    try:
        cost = c1*c2/c3
    except:
        cost = 1e19
    g1 = x[0]**2-x[1]+1
    g2 = 1-x[0]+(x[1]-4)**2
    constraint = np.max(np.array([0,np.array([g1,g2]).max()]))

    return cost + constraint_penalty*constraint

Nguess = 10
Niter = 50
rho = 1e6
x0 = [0.1,0.1]
dx = 1.0

R = solve(f2dex, rho, x0, [0.001,0.001], [10, 10], Nguess, Niter, initial_box_width=dx)

print("Example 2")
print("----------")
print(f"Best found Solution = {R.x}")
print(f"Best Value found = {R.f}")
print("------------------------------")

# Example 3
#============
# from http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page2031.htm


def f3dex(x, constraint_penalty):

    c1 = (x[0]-10)**2+5*(x[1]-12)**2
    c2 = x[2]**4+3*(x[3]-11)**2+10*x[4]**6
    c3 = 7*x[5]**2+x[6]**4-4*x[5]*x[6]-10*x[5]-8*x[6]
    cost = c1+c2+c3

    v1 = 2*x[0]**2
    v2 = x[1]**2
    g = np.zeros(4)
    g[0] = v1+3*v2**2+x[2]+4*x[3]**2+5*x[4]-127
    g[1] = 7*x[0]+3*x[1]+10*x[2]**2+x[3]-x[4]-282
    g[2] = 23*x[0]+v2+6*x[5]**2-8*x[6]-196
    g[3] = 2*v1+v2-3*x[0]*x[1]+2*x[2]**2+5*x[5]-11*x[6]

    constraint = np.max(np.array([0, g.max()]))

    return cost + constraint_penalty*constraint


Nguess = 5
Niter = 60
rho = 1e6
x0 = np.zeros(7)

xmin = np.asarray([-10]*7)
xmax = np.asarray([+10]*7)

R = solve(f3dex, rho, x0, xmin, xmax, Nguess, Niter)

print("Example 3")
print("----------")
print(f"Best found Solution = {R.x}")
print(f"Best Value found = {R.f}")
print("------------------------------")

```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "torczon",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "Nonlinear Programming, optimization, derivative free, constrained optimization",
    "author": null,
    "author_email": "Mazen Alamir <mazen.alamir@grenoble-inp.fr>",
    "download_url": "https://files.pythonhosted.org/packages/81/b8/953d8a8d9bb5376e9dec9148ec7b95879eee097b279e02aba4b6e6047c17/torczon-0.0.1.tar.gz",
    "platform": null,
    "description": "# A simple python implementation of Torczon algorithm\n\nTorczon algorithm is a derivative free algorithm initially designed for unconstrained nonlinear optimization problems. \nTorczon algorithm is a version of the simplex algorithm (not that used in Linear Programming problems) which avoids the \nCollapse of the polygone of solutions that is iteratively updated through the iterations.\n\nThis is a modified version of the Torczon algorithm that incorporates:\n\n- Explicitly handling of hard box constraints on the decision variables\n- Penalty-based handling of other (non box-like) constraints\n- mutiple initial guess option for global optimization.\n\nThe main appealing feature of this family of algorithm lies in the fact that the cost function and the constraints need \nnot to be differentiable. The counterpart is that this algorithm is not fitted to very high dimensional problems. \n\nI personally use it intensively in solving real-life problems arising in **Parameterized Nonlinear Model Predictive Control** \nproblems. \n\n## Installation via pip\n\n```terminal\npip install torczon\n```\n\n**Code citation**\n\n[![DOI](https://zenodo.org/badge/260138021.svg)](https://zenodo.org/badge/latestdoi/260138021)\n\n## Required packages\n\n- numpy \n\n## Usage\n \n- Define the cost function to be optimized, the cost might embed soft constraint definition via constraint penalty (the penalty can be a part of the variable p that can be any python object or variable. \n\n```python\ndef f(x,p):\n    \n    return ..\n```\n\n- Call the solver using \n\n```python\nsolve(f_user=f, \n      par=p, x0=x0, \n      xmin=xmin,\n      xmax=xmax, \n      Nguess=Nguess, \n      Niter=Niter, \n      initial_box_width=0.1)\n```\nwhere \n\n- ```x0```\nthe initial guess (for the first guess)\n\n- ```xmin, xmax``` \nthe box of admissible values\n\n- ```Niter``` \nthe number of iterations by single guess \n\n- ```Nguess```: \nthe number of initial guesses (randomly sampled using uniform distribution inside the hypercube defined by xmin and xmax)\n\n- ```initial_box_width``` \nthe amplitude of the initial steps around each initial guess to bild the polygone of the torczon algorithm.\n\n\n## Example \n\nThe script below calls the solver for three different optimization problems.\n\n```python\nfrom torczon import solve\nimport numpy as np\n\n# This is the test file for the torczon module. \n# it contains three constrained optimization examples.\n\n# Example 1\n#=============\n# Assume a cost function that need some class instance to be defined \nclass Data():\n        def __init__(self):\n            self.a = 10\n            self.b = -1\n            self.c = 1.0  # assign to 0 to put solution at (a,b)\np = Data()\n\n# The cost function  \ndef f1dex(x, p):\n    return (x[0]-p.a)**2 +p.c*(x[1]*x[0])**4+(x[1]-p.b)**2\n\nNguess = 5\nNiter = 30\nR = solve(f1dex, p, [0.0,0.0], [-10,-10], [10, 10], Nguess, Niter)\nprint(\"Example 1\")\nprint(\"----------\")\nprint(f\"Best found Solution = {R.x}\")\nprint(f\"Best Value found = {R.f}\")\nprint(\"------------------------------\")\n#----------------\n\n# Example 2\n#============\n# from http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page3389.htm\n\ndef f2dex(x, constraint_penalty):\n    c1 = (np.sin(2*np.pi*x[0]))**3\n    c2 = np.sin(2*np.pi*x[1])\n    c3 = (x[1]**3)*(x[0]+x[1])\n    try:\n        cost = c1*c2/c3\n    except:\n        cost = 1e19\n    g1 = x[0]**2-x[1]+1\n    g2 = 1-x[0]+(x[1]-4)**2\n    constraint = np.max(np.array([0,np.array([g1,g2]).max()]))\n\n    return cost + constraint_penalty*constraint\n\nNguess = 10\nNiter = 50\nrho = 1e6\nx0 = [0.1,0.1]\ndx = 1.0\n\nR = solve(f2dex, rho, x0, [0.001,0.001], [10, 10], Nguess, Niter, initial_box_width=dx)\n\nprint(\"Example 2\")\nprint(\"----------\")\nprint(f\"Best found Solution = {R.x}\")\nprint(f\"Best Value found = {R.f}\")\nprint(\"------------------------------\")\n\n# Example 3\n#============\n# from http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO_files/Page2031.htm\n\n\ndef f3dex(x, constraint_penalty):\n\n    c1 = (x[0]-10)**2+5*(x[1]-12)**2\n    c2 = x[2]**4+3*(x[3]-11)**2+10*x[4]**6\n    c3 = 7*x[5]**2+x[6]**4-4*x[5]*x[6]-10*x[5]-8*x[6]\n    cost = c1+c2+c3\n\n    v1 = 2*x[0]**2\n    v2 = x[1]**2\n    g = np.zeros(4)\n    g[0] = v1+3*v2**2+x[2]+4*x[3]**2+5*x[4]-127\n    g[1] = 7*x[0]+3*x[1]+10*x[2]**2+x[3]-x[4]-282\n    g[2] = 23*x[0]+v2+6*x[5]**2-8*x[6]-196\n    g[3] = 2*v1+v2-3*x[0]*x[1]+2*x[2]**2+5*x[5]-11*x[6]\n\n    constraint = np.max(np.array([0, g.max()]))\n\n    return cost + constraint_penalty*constraint\n\n\nNguess = 5\nNiter = 60\nrho = 1e6\nx0 = np.zeros(7)\n\nxmin = np.asarray([-10]*7)\nxmax = np.asarray([+10]*7)\n\nR = solve(f3dex, rho, x0, xmin, xmax, Nguess, Niter)\n\nprint(\"Example 3\")\nprint(\"----------\")\nprint(f\"Best found Solution = {R.x}\")\nprint(f\"Best Value found = {R.f}\")\nprint(\"------------------------------\")\n\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A NLP derivative-free solver using a modified version of the torczon algorithm",
    "version": "0.0.1",
    "project_urls": {
        "Homepage": "https://github.com/mazenalamir/torczon",
        "Issues": "https://github.com/mazenalamir/torczon/issues"
    },
    "split_keywords": [
        "nonlinear programming",
        " optimization",
        " derivative free",
        " constrained optimization"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c57a2398ecc5d3a4a4614537631bc516ca6779d1d590c40ab850cc9cebf7e743",
                "md5": "d9f08dfa323a4cb66b67bb94d556d358",
                "sha256": "950459c163f949e23dab8a789abd76ad59b69b6649759c2d09feebf6287040c4"
            },
            "downloads": -1,
            "filename": "torczon-0.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d9f08dfa323a4cb66b67bb94d556d358",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 4958,
            "upload_time": "2024-10-30T12:43:21",
            "upload_time_iso_8601": "2024-10-30T12:43:21.240306Z",
            "url": "https://files.pythonhosted.org/packages/c5/7a/2398ecc5d3a4a4614537631bc516ca6779d1d590c40ab850cc9cebf7e743/torczon-0.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "81b8953d8a8d9bb5376e9dec9148ec7b95879eee097b279e02aba4b6e6047c17",
                "md5": "ef8f0b5516c33c0166d173af0ea3bf6d",
                "sha256": "77df96d845f6558397aff315d3bc9735d1d771f6bf46e4995405b9b852589f3b"
            },
            "downloads": -1,
            "filename": "torczon-0.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "ef8f0b5516c33c0166d173af0ea3bf6d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 4657,
            "upload_time": "2024-10-30T12:43:22",
            "upload_time_iso_8601": "2024-10-30T12:43:22.622912Z",
            "url": "https://files.pythonhosted.org/packages/81/b8/953d8a8d9bb5376e9dec9148ec7b95879eee097b279e02aba4b6e6047c17/torczon-0.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-30 12:43:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mazenalamir",
    "github_project": "torczon",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "torczon"
}
        
Elapsed time: 1.91808s