Skip to content

Instantly share code, notes, and snippets.

@alecjacobson
Created December 30, 2020 19:49
Show Gist options
  • Save alecjacobson/6e44aab33661955bf55ca2193f0a0db5 to your computer and use it in GitHub Desktop.
Save alecjacobson/6e44aab33661955bf55ca2193f0a0db5 to your computer and use it in GitHub Desktop.
Templated C-Style wrapper for Luca Di Gaspero's QuadProg++ https://github.com/liuq/QuadProgpp
// MIT License
//
// Copyright (c) 2020 Alec Jacobson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifdef IM_SCARED_I_WANT_TO_COPY
# include "src/Array.hh"
#else
# define oldprivate private
# define private public
# include "src/Array.hh"
# define private oldprivate
#endif
#include "src/QuadProg++.hh"
// C-style api
template <typename T>
T solve_quadprog(
const int n,
const int m,
const int p,
const T * _G,
const T * _g0,
const T * _CE,
const T * _ce0,
const T * _CI,
const T * _ci0,
T * _x)
{
#ifdef IM_SCARED_I_WANT_TO_COPY
quadprogpp::Matrix<T> G(_G,n,n);
quadprogpp::Matrix<T> CE(_CE,n,m);
quadprogpp::Matrix<T> CI(_CI,n,p);
quadprogpp::Vector<T> g0(_g0,n);
quadprogpp::Vector<T> ce0(_ce0,m);
quadprogpp::Vector<T> ci0(_ci0,p);
quadprogpp::Vector<T> x(n);
#else
// Map without copy ("I solemnly swear this is maintaining constness")
quadprogpp::Vector<T> g0; g0.n = n; g0.v = const_cast<double*>( _g0);
quadprogpp::Vector<T> ce0; ce0.n = m; ce0.v = const_cast<double*>(_ce0);
quadprogpp::Vector<T> ci0; ci0.n = p; ci0.v = const_cast<double*>(_ci0);
quadprogpp::Vector<T> x; x.n = n; x.v = const_cast<double*>( _x);
quadprogpp::Matrix<T> G; G.n = n; G.m = n; G.v = new T*[G.n]; G.v[0] = const_cast<double*>( _G); for (unsigned int i = 1; i < G.n; i++){ G.v[i] = G.v[i - 1] + G.m;}
quadprogpp::Matrix<T> CE; CE.n = n; CE.m = m; CE.v = new T*[G.n]; CE.v[0] = const_cast<double*>(_CE); for (unsigned int i = 1; i < CE.n; i++){ CE.v[i] = CE.v[i - 1] + CE.m;}
quadprogpp::Matrix<T> CI; CI.n = n; CI.m = p; CI.v = new T*[G.n]; CI.v[0] = const_cast<double*>(_CI); for (unsigned int i = 1; i < CI.n; i++){ CI.v[i] = CI.v[i - 1] + CI.m;}
#endif
T ret = solve_quadprog(G, g0, CE, ce0, CI, ci0, x);
#ifdef IM_SCARED_I_WANT_TO_COPY
for(int i = 0;i<n;i++){ _x[i] = x[i]; }
#else
// Prevent destructor from deleting things
g0.v = 0;
ce0.v = 0;
ci0.v = 0;
x.v = 0;
delete[]( G.v); G.v = 0;
delete[](CE.v);CE.v = 0;
delete[](CI.v);CI.v = 0;
#endif
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment