{"id":25833114,"url":"https://github.com/woolfrey/software_simple_qp","last_synced_at":"2026-03-08T22:32:13.294Z","repository":{"id":186493895,"uuid":"675265370","full_name":"Woolfrey/software_simple_qp","owner":"Woolfrey","description":"A small, efficient class for solving convex optimisation problems.","archived":false,"fork":false,"pushed_at":"2025-11-18T14:23:05.000Z","size":6432,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-08T08:52:37.643Z","etag":null,"topics":["optimisation","qp","quadratic-programming"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Woolfrey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-08-06T10:52:23.000Z","updated_at":"2025-11-18T14:16:23.000Z","dependencies_parsed_at":"2024-06-01T14:10:55.261Z","dependency_job_id":"211df89b-5a6f-4496-ac87-2ad8356d1ad9","html_url":"https://github.com/Woolfrey/software_simple_qp","commit_stats":{"total_commits":60,"total_committers":2,"mean_commits":30.0,"dds":"0.18333333333333335","last_synced_commit":"22b463c6a7c909fe824ca8718761bd4c0ae9a726"},"previous_names":["woolfrey/simpleqpsolver","woolfrey/software_simple_qp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Woolfrey/software_simple_qp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fsoftware_simple_qp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fsoftware_simple_qp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fsoftware_simple_qp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fsoftware_simple_qp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Woolfrey","download_url":"https://codeload.github.com/Woolfrey/software_simple_qp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fsoftware_simple_qp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30275538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:45:49.896Z","status":"ssl_error","status_checked_at":"2026-03-08T20:45:49.525Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["optimisation","qp","quadratic-programming"],"created_at":"2025-02-28T22:47:07.568Z","updated_at":"2026-03-08T22:32:13.261Z","avatar_url":"https://github.com/Woolfrey.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple QP Solver\nA small, efficient class for solving convex optimisation problems. A generic quadratic programming (QP) problem is of the form:\n```math\n\\begin{align}\n\t\\min_{\\mathbf{x}} ~ \\frac{1}{2}\\mathbf{x^\\mathrm{T}Hx + x^\\mathrm{T}f} \\\\\n\t\\text{subject to: } \\mathbf{Bx \\le z}\n\\end{align}\n```\nwhere:\n- $\\mathbf{x}\\in\\mathbb{R}^\\mathrm{n}$ is the decision variable,\n- $\\mathbf{H = H^\\mathrm{T}}\\in\\mathbb{R}^\\mathrm{n\\times n}$ is a weighting matrix,\n- $\\mathbf{f}\\in\\mathbb{R}^\\mathrm{n}$ is the linear component of the quadratic equation,\n- $\\mathbf{B}\\in\\mathbb{R}^\\mathrm{c\\times n}$ is a constraint matrix, and\n- $\\mathbf{z}\\in\\mathbb{R}^\\mathrm{c}$ is a constraint vector.\n\nThere are also several functions for handling linear least squares problems with equality and inequality constraints. It is fast, and effective. It has been used to control the upper body of a humanoid robot subject to grasp constraints and joint limits.\n\n\u003cp align=\"center\"\u003e\n\t\u003cimg src=\"https://github.com/Woolfrey/software_simple_qp/blob/master/assets/bimanual_manipulation.gif\" width=200 height=\"auto\"/\u003e\n\u003c/p\u003e\n\n\u003e[!NOTE]\n\u003e Simple QP Solver is **free to use** under the GNU General Public License v3.0. If you find this software useful, [citing it](#citing-this-repository) would be appreciated.\n\n\n**Jump To:**\n- [Installation Instructions](#installation-instructions)\n\t- [Installing Eigen](#installing-eigen)\n \t- [Installing SimpleQPSolver](#installing-simpleqpsolver)\n\t- [Automatic Download in Another Package](#automatic-download-in-another-package)\n- [Using the QP Solver](#using-the-qp-solver)\n  \t- [A Generic QP Problem](#a-generic-qp-problem)\n   \t- [Linear Least Squares](#linear-least-squares-linear-regression)\n   \t- [Least Squares with Equality Constraints](#least-squares-with-equality-constraints-over-determined-systems)\n   \t - [Optimisation with Inequality Constraints](#optimisation-with-inequality-constraints)\n   \t- [Options for the Interior Point Algorithm](#options-for-the-interior-point-algorithm)\n   \t- [Running the Test File](#running-the-test-file)\n- [Citing this Repository](#citing-this-repository)\n\n## Installation Instructions\n\n### Installing Eigen:\n\nThe `SimpleQPSolver` requires the `Eigen` libraries. If you're using Linux you can install it from the command line:\n\n```\nsudo apt install libeigen3-dev\n```\nOtherwise, you can head over to the [main page](https://eigen.tuxfamily.org/index.php?title=Main_Page) to see how you can install it.\n\n### Installing SimpleQPSolver:\n\nSimpleQPSolver is a template class contained in a single header file. There is no need to clone this repository and build any packages (unless you want to, of course). All you need to do is download the header file `QPSolver.h` and include it in your package:\n\n```\nsoftware_simple_qp/include/QPSolver.h\n```\nThat is all!\n\n\u003e[!NOTE]\n\u003e If you want to build the package for some reason, there is a simple `test.cpp` file [you can run](#running-the-test-file) that demonstrates the use of the `QPSolver` class.\n\n### Automatic Download in Another Package:\n\nIt is possible to automatically download the `QPSolver.h` header file as part of another package. In your `CMakeLists.txt` file you can add something like:\n```\nif(NOT EXISTS \"${CMAKE_SOURCE_DIR}/your_package/include/QPSolver.h\")\n\tfile(DOWNLOAD\n\t     https://raw.githubusercontent.com/Woolfrey/software_simple_qp/master/include/QPSolver.h\n\t     ${CMAKE_SOURCE_DIR}/your_package/include/QPSolver.h)\nendif()\n```\n[:arrow_backward: Go Back.](#simple-qp-solver)\n\n## Using the QP Solver\n\nYou can use `float` or `double` with this class. Input arguments for the `Eigen` classes must match:\n- `Eigen::MatrixXf` and `Eigen::VectorXf` when using `QPSolver\u003cfloat\u003e`, or\n- `Eigen::MatrixXd` and `Eigen::VectorXd` when using `QPSolver\u003cdouble\u003e`.\n\nFor problems _without_ inequality constraints, you can call `static` methods without creating a `QPSolver` object:\n- `QPSolver\u003cfloat\u003e::solve(H,f)`\n- `QPSolver\u003cdouble\u003e::least_squares(y,A,W)`\n- `QPSolver\u003cfloat\u003e::redundant_least_squares(xd,W,A,y)`\n\nMethods with inequality constraints, e.g. $\\mathbf{Bx \\le z}$, or $\\mathbf{x_\\mathrm{min} \\le x \\le x_\\mathrm{max}}$ use an interior point algorithm, and thus require you to create an instance of the class.\n\nSome examples are below.\n\n### A Generic QP Problem:\n\n```math\n\\min_{\\mathbf{x}} \\frac{1}{2}\\mathbf{x^\\mathrm{T} Hx + x^\\mathrm{T}f}\n```\nAssuming $\\mathbf{H}$ and $\\mathbf{f}$ are given, then you can call:\n```\nEigen::VectorXd x = QPSolver\u003cdouble\u003e::solve(H,f);\n```\n\u003e[!TIP]\n\u003e You can actually solve this yourself by calling something like `x = H.ldlt().solve(-f)`, but I put this function in for completeness.\n\n### Linear Least Squares (Linear Regression):\n\n```math\n\\min_{\\mathbf{x}} \\frac{1}{2}\\|\\mathbf{y - Ax}\\|^2_\\mathbf{W} = \\frac{1}{2}\\mathbf{\\left(y - Ax\\right)^\\mathrm{T} W\\left(y - Ax\\right)}\n```\nwhere:\n- $\\mathbf{y}\\in\\mathbb{R}^\\mathrm{m}$,\n- $\\mathbf{A}\\in\\mathbb{R}^\\mathrm{m\\times n}$,\n- $\\mathbf{x}\\in\\mathbb{R}^\\mathrm{n}$,\n- $\\mathbf{W}\\in\\mathbb{R}^\\mathrm{m\\times m}$ weights the error, and\n- m $\\ge$ n (more outputs than inputs)\n\nCall:\n```\nEigen::VectorXf x = QPSolver\u003cfloat\u003e::least_squares(y,A,W);\n```\n### Least Squares with Equality Constraints (Over-determined Systems):\n```math\n\\begin{align}\n\\min_{\\mathbf{x}} \\frac{1}{2}\\|\\mathbf{x_\\mathrm{d} - x}\\|^2_\\mathrm{W} = \\frac{1}{2}\\mathbf{\\left(x_\\mathrm{d} - x\\right)^\\mathrm{T} W\\left(x_\\mathrm{d} - x\\right)} \\\\\n\\text{subject to: } \\mathbf{Ax} = \\mathbf{y}\n\\end{align}\n```\nwhere:\n- $\\mathbf{y}\\in\\mathbb{R}^\\mathrm{m}$,\n- $\\mathbf{A}\\in\\mathbb{R}^\\mathrm{m\\times n}$,\n- $\\mathbf{x}\\in\\mathbb{R}^\\mathrm{n}$,\n- $\\mathbf{x}_\\mathrm{d}\\in\\mathbb{R}^\\mathrm{n}$ is a _desired_ value for $\\mathbf{x}$,\n- $\\mathbf{W}\\in\\mathbb{R}^\\mathrm{n\\times n}$ weights the solution,\n- m \u003c n (more inputs than outputs)\n\nIn this situation the $\\mathbf{x}$ vector has more dimensions than the $\\mathbf{y}$ vector. Therefore, infinite solutions exist. You can give a desired value $\\mathbf{x}_\\mathrm{d}$ that the solver will try to achieve whilst satisfying the relationship $\\mathbf{Ax = y}$. Call:\n```\nEigen::VectorXd x = QPSolver\u003cdouble\u003e::redundant_least_squares(xd,W,A,y);\n```\n\n### Optimisation with Inequality Constraints:\n```math\n\\begin{align}\n\t\\min_{\\mathbf{x}} \\frac{1}{2}\\mathbf{x^\\mathrm{T}Hx + x^\\mathrm{T}f} \\\\\n\t\\text{subject to: } \\mathbf{Bx} \\le \\mathbf{z}\n\\end{align}\n```\n\u003e[!NOTE]\n\u003e For problems like this with inequality constraints, the solver uses an interior point algorithm. This uses Newton's method to iteratively minimize the objective function whilst satisfying the inequality. It therefore requires a _start point_ or _initial guess_.\n\nFirst create an object, then call the function:\n```\nQPSolver\u003cdouble\u003e solver;\nEigen::VectorXd x = solver.solve(H,f,B,z,x0);\n```\nwhere `x0` is the start point argument. It can have a huge influence on the result, so it is good to give the solver an approximate solution if you can.\n\nIf you're repeatedly solving a QP problem you can get the last solution and use that as the input:\n```\nEigen::VectorXd x0 = solver.last_solution();\n```\nThere are several functions conveniently written for least squares type problems:\n\n**Linear least squares with upper and lower bounds:**\n\n```math\n\\begin{align}\n\t\\min_{\\mathbf{x}} \\frac{1}{2}\\mathbf{\\left(y - Ax\\right)^\\mathrm{T} W\\left(y - Ax\\right)} \\\\\n\t\\text{subject to: } \\mathbf{x_\\mathrm{min} \\le x \\le x_\\mathrm{max}}\n\\end{align}\n```\nuse:\n```\nEigen::VectorXf x = solver.constrained_least_squares(y,A,W,xMin,xMax,x0);\n```\n**Redundant least squares with upper and lower bounds:**\n\n```math\n\\begin{align}\n\t\\min_{\\mathbf{x}} \\frac{1}{2}\\mathbf{\\left(x_\\mathrm{d} - x\\right)^\\mathrm{T} W\\left(x_\\mathrm{d} - x\\right)} \\\\\n\t\\text{subject to: } \\mathbf{Ax} = \\mathbf{y} \\\\\n            \\mathbf{x_\\mathrm{min} \\le x \\le x_\\mathrm{max}}\n\\end{align}\n```\nuse:\n```\nEigen::VectorXd x = solver.constrained_least_squares(xd,W,A,y,xMin,xMax,x0);\n```\n**Redundant least squares with inequality constraints:**\n\n```math\n\\begin{align}\n\t\\min_{\\mathbf{x}} \\frac{1}{2}\\mathbf{\\left(x_\\mathrm{d} - x\\right)^\\mathrm{T} W\\left(x_\\mathrm{d} - x\\right)} \\\\\n\t\\text{subject to: } \\mathbf{Ax} \u0026= \\mathbf{y} \\\\\n                          \\mathbf{Bx} \u0026\\le \\mathbf{z}\n\\end{align}\n```\nuse:\n```\nEigen::VectorXd x = solver.constrained_least_squares(xd,W,A,y,B,z,x0);\n```\n\u003e[!WARNING]\n\u003e When using this particular function the desired value $\\mathbf{x}_{\\mathrm{d}}$ must satisfy constraints when projected on to the null space of $\\mathbf{A}$.\n\n[:arrow_backward: Go Back.](#simple-qp-solver)\n\n### Options for the Interior Point Algorithm\n\nThere are several parameters that can be set when solving for inequality constaints:\n- `set_step_size(const DataType \u0026size)`: The parameter $\\alpha$ scales the step size $\\alpha\\cdot\\Delta\\mathbf{x}$. Default value is 1; a smaller size will mean slower convergence.\n- `set_tolerance(const DataType \u0026tolerance)`: The algorithm terminates when $\\|\\alpha\\cdot\\Delta\\mathbf{x}\\|$ is less than this value. A smaller value means a more accurate solution, but slower solution time.\n- `set_num_steps(const unsigned int \u0026numer)`: The algorithm terminates if this number of steps is reached. A higher value means a more accurate solution, but it might take longer to solve.\n- `set_barrier_scalar(const DataType \u0026scalar)`: The inequality constraints are converted to a log-barrier function. This parameter determines how steep the slope of the barrier is. A smaller value means a faster solution, but you may prematurely run in to the constraint and terminate the algorithm.\n- `set_barrier_reduction_rate(const DataType \u0026rate)`: Every loop the barrier slope is decreased. This determines how fast it decreases. A smaller value means the barrier effect will shrink quickly. This will make the algorithm faster, but then it may not find a solution if it hits the constraints prematurely.\n\n [:arrow_backward: Go Back.](#simple-qp-solver)\n\n### Running the Test File:\n\nFirst navigate to your working directory:\n```\ncd ~/MyWorkspace\n```\nThen clone the repository:\n```\ngit clone https://github.com/Woolfrey/software_simple_qp.git\n```\nCreate a build folder and navigate to it:\n```\ncd software_simple_qp/ \u0026\u0026 mkdir build \u0026\u0026 cd build\n```\nGenerate the build tools using:\n```\ncmake ../\n```\nThen build the package with:\n```\nmake\n```\nYou can then run\n```\n./test\n```\nwhich prints information about the use of different class methods, as well as the accuracy and speed of solutions.\n\n\u003cimg src=\"https://github.com/Woolfrey/software_simple_qp/assets/62581255/8ecb93a6-e45b-4ff9-aebf-1f2f27c62f25\" width=\"600\" height=\"auto\"\u003e\n\n[:arrow_backward: Go back.](#simple-qp-solver)\n\n## Citing this Repository\n\nIf you use `SimpleQPSolver` and find it useful, I'd appreciate it if you could cite me. Here is a `BibTeX` format:\n```\n@software{Woolfrey_SimpleQPSolver_2023,\n     author  = {Woolfrey, Jon},\n     month   = aug,\n     title   = {{S}imple {QP} {S}olver},\n     url     = {https://github.com/Woolfrey/software_simple_qp},\n     version = {1.0.0},\n     year    = {2023}\n}\n```\nHere's the automatically generated APA format:\n```\nWoolfrey, J. (2023). SimpleQPSolver (Version 1.0.0) [Computer software]. https://github.com/Woolfrey/software_simple_qp\n```\nAlternatively, click on `Cite this repository` on the top-right corner of this page.\n\n[:arrow_backward: Go Back.](#simple-qp-solver)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoolfrey%2Fsoftware_simple_qp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoolfrey%2Fsoftware_simple_qp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoolfrey%2Fsoftware_simple_qp/lists"}