{"id":19855105,"url":"https://github.com/leggedrobotics/rayen","last_synced_at":"2025-09-08T15:48:51.126Z","repository":{"id":181775649,"uuid":"650227694","full_name":"leggedrobotics/rayen","owner":"leggedrobotics","description":"Imposition of Hard Convex Constraints on Neural Networks","archived":false,"fork":false,"pushed_at":"2024-01-18T09:36:48.000Z","size":823,"stargazers_count":81,"open_issues_count":0,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-09T17:36:03.951Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leggedrobotics.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-06T16:04:22.000Z","updated_at":"2025-07-05T12:29:38.000Z","dependencies_parsed_at":"2024-11-12T14:11:46.858Z","dependency_job_id":"89fb4c4c-70ec-458a-aeb9-92e8a12da7a3","html_url":"https://github.com/leggedrobotics/rayen","commit_stats":null,"previous_names":["leggedrobotics/rayen"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/leggedrobotics/rayen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Frayen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Frayen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Frayen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Frayen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leggedrobotics","download_url":"https://codeload.github.com/leggedrobotics/rayen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Frayen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274209687,"owners_count":25241788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T14:11:43.278Z","updated_at":"2025-09-08T15:48:51.081Z","avatar_url":"https://github.com/leggedrobotics.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RAYEN: Imposition of Hard Convex Constraints on Neural Networks #\n\nPaper: [http://arxiv.org/abs/2307.08336](http://arxiv.org/abs/2307.08336)\n\nThis framework allows you to impose convex constraints on the output or latent variable of a Neural Network.\n![](./imgs/rayen.png)\n\n![](./imgs/rayen_equations.png)\n\n\n\n# Installation\n\nFirst make sure that you have pip up-to-date:\n```bash\npip install --upgrade pip\n```\n\nThen, you simply need to do:\n\n```bash\npip install rayen\n```\n\nIf you want to do an editable install, you can also do:\n\n```bash\ngit clone https://github.com/leggedrobotics/rayen.git\ncd rayen \u0026\u0026 pip install -e .\n```\n\n# Usage\n\nA minimal example is as follows:\n\n```python\nimport torch\nimport numpy as np\nfrom rayen import constraints, constraint_module\n\n#Linear constraints\nA1 = np.array([[1.0, 0, 0], [0, 1.0, 0], [0, 0, 1.0], [-1.0, 0, 0], [0, -1.0, 0], [0, 0, -1.0]]);\nb1 = np.array([[1.0], [1.0], [1.0], [0], [0], [0]])\nA2 = np.array([[1.0, 1.0, 1.0]]);\nb2 = np.array([[1.0]]);\nlc=constraints.LinearConstraint(A1, b1, A2, b2) #Set lc to None if there are no linear constraints\n                                                #Set A1 and b1 to None if there are no linear inequality constraints\n                                                #Set A2 and b2 to None if there are no linear equality constraints\n\n#Quadratic constraints\nP = np.array([[3.125,0.0,0.0], [0.0,3.125,0.0], [0.0,0.0,3.125]])\nq = np.array([[0.0],[0.0],[0.0]])\nr = np.array([[-1.0]])\nqcs = [constraints.ConvexQuadraticConstraint(P, q, r)] #Set qcs to [] if there are no quadratic constraints\n                                                       #More quadratic constraints can be appended to this list\n\n#SOC constraints\nM=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0],[0.0, 0.0, 0.0]])\ns=np.array([[0.0],[0.0],[0.0]])\nc=np.array([[0.0],[0.0],[1.0]])\nd=np.array([[0.0]])\nsocs = [constraints.SOCConstraint(M, s, c, d)] #Set socs to [] if there are no SOC constraints\n                                               #More SOC constraints can be appended to this list\n\n#LMI constraint (semidefinite constraint)\nF0=np.array([[1.0, 0.0],[0.0, 0.0]])\nF1=np.array([[0.0, 1.0],[1.0, 0.0]])\nF2=np.array([[0.0, 0.0],[0.0, 1.0]])\nF3=np.array([[0.0, 0.0],[0.0, 0.0]])\nlmic=constraints.LMIConstraint([F0, F1, F2, F3]) #Set lmic to None if there are no LMI constraints\n\n#----\n\ncs = constraints.ConvexConstraints(lc=lc, qcs=qcs, socs=socs, lmic=lmic)\n\nmodel = torch.nn.Sequential(torch.nn.Flatten(), torch.nn.Linear(3, 64),\n                            torch.nn.ReLU(),    torch.nn.Linear(64, 64),\n                            constraint_module.ConstraintModule(cs, input_dim=64, create_map=True)) \n\nx_batched = torch.Tensor(500, 3, 1).uniform_(-1.0, 1.0)\ny_batched = model(x_batched)\n\n#Each element of y_batched is guaranteed to satisfy the constraints\n\n# loss = ...      # y_batched can be used here\n# loss.backward() # Backpropagate\n```\n\nThese are the methods implemented in this repo (please see the paper for details):\n\n\n\n\nMethod | Linear | Quadratic | SOC | LMI\n:------------ | :-------------: | :-------------: | :-------------: | :-------------: \n**UU** |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |     \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e   \n**UP** |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |     \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e   \n**PP** |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |     \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e   \n**DC3** |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |     \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |  \u003cimg src='./imgs/diamond.svg' width='25'\u003e |  \u003cimg src='./imgs/diamond.svg' width='25'\u003e\n**Bar** |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |  \u003cimg src='./imgs/red_cross.svg' width='20'\u003e | \u003cimg src='./imgs/red_cross.svg' width='20'\u003e | \u003cimg src='./imgs/red_cross.svg' width='20'\u003e\n**RAYEN** |  \u003cimg src='./imgs/green-tick.png' width='25'\u003e |     \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e    |    \u003cimg src='./imgs/green-tick.png' width='25'\u003e   \n\nwhere    \u003cimg src='./imgs/green-tick.png' width='20'\u003e    denotes supported by the algorithm and implemented in the code, \u003cimg src='./imgs/red_cross.svg' width='15'\u003e denotes not supported by the algorithm, and  \u003cimg src='./imgs/diamond.svg' width='20'\u003e denotes supported by the algorithm but not implemented yet. \n\nYou can choose the method to use setting the argument `method` when creating the layer. \n\n# More examples\n\nThere are more complex examples in the `examples` folder. If you want to run these examples: \n\n```bash\nsudo apt-get install git-lfs\ngit clone https://github.com/leggedrobotics/rayen.git\ncd rayen\ngit lfs install \ngit submodule init \u0026\u0026 git submodule update --init --recursive\npip install -r examples/requirements_examples.txt\n```\n\nThese are the most important files in the `examples` folder:\n* **`test_layer.py`**: This file imposes many different constraints using all the methods shown above. It will create plots similar to the one shown at the beginning of this repo \n* **`time_analysis.py`**: This file obtains the computation time of RAYEN when applied to many different constraints. \n* **`run.sh`**: This file will train the networks for all the algorithms used in the paper, and then evaluate them using the testing sets. Depending on the computer to use, this can take ~1 day to run. The datasets that this file uses are stored in the files `corridor_dim2.mat` (Optimization 1 of the paper, which is for a 2D scenario) and `corridor_dim3.mat` (Optimization 2 of the paper, which is for a 3D scenario). These files were generated running the file `traj_planning_in_corridor.m`. These Matlab files requires Casadi (and its interface with Gurobi) to be installed. You can do this using the instructions below\n\nSome of these examples use (or can use) [Gurobi Optimizer](https://www.gurobi.com/products/gurobi-optimizer/). Once installed (following the instructions in the previous link) you can test the installation typing `gurobi.sh` in the terminal. You will also need this package:\n```\npip install gurobipy\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e \u003cb\u003eCasadi installation instructions (optional dependency)\u003c/b\u003e\u003c/summary\u003e\n\n```bash\n#IPOPT stuff\nsudo apt-get install gcc g++ gfortran git cmake liblapack-dev pkg-config --install-recommends\nsudo apt-get install coinor-libipopt1v5 coinor-libipopt-dev\n\n#SWIG stuff\nsudo apt-get remove swig swig3.0 swig4.0 #If you don't do this, the compilation of casadi may fail with the error \"swig error : Unrecognized option -matlab\"\nmkdir ~/installations \u0026\u0026 cd ~/installations\ngit clone https://github.com/jaeandersson/swig\ncd swig\ngit checkout -b matlab-customdoc origin/matlab-customdoc        \nsh autogen.sh\nsudo apt-get install gcc-7 g++-7 bison byacc\nsudo apt-get install libpcre3 libpcre3-dev\n./configure CXX=g++-7 CC=gcc-7            \nmake\nsudo make install\n\n#CASADI stuff\ncd ~/installations \u0026\u0026 mkdir casadi \u0026\u0026 cd casadi\ngit clone https://github.com/casadi/casadi\ncd casadi/cmake \u0026\u0026 wget https://github.com/leggedrobotics/rayen/raw/master/examples/other/FindGurobi.cmake #This ones works for higher versions of Gurobi\ncd ..\n#cd build \u0026\u0026 make clean \u0026\u0026 cd .. \u0026\u0026 rm -rf build #Only if you want to clean any previous installation/compilation \nmkdir build \u0026\u0026 cd build\ncmake . -DCMAKE_BUILD_TYPE=Release -DWITH_IPOPT=ON -DWITH_MATLAB=ON -DWITH_PYTHON=ON -DWITH_DEEPBIND=ON -DWITH_GUROBI=ON ..\n#You may need to run the command above twice until the output says that `Ipopt` has been detected (although `IPOPT` is also being detected when you run it for the first time)\nmake -j20\nsudo make install\n\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e \u003cb\u003ePublishing to PyPI\u003c/b\u003e\u003c/summary\u003e\n\nMore info [here](https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/). See also the file `python-publish.yml`\n\nFirst change the `version` line in `pyproject.toml`  to X.X.X. Then do the following:\n```bash\ngit add pyproject.toml \u0026\u0026 git commit -m \"updated version\" \u0026\u0026 git tag vX.X.X\ngit push origin master vX.X.X\n\n```\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Frayen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleggedrobotics%2Frayen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Frayen/lists"}