Skip to content
Open
164 changes: 163 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,169 @@ if (${BUILD_MATLAB_INTERFACE})
COPY ${MATLAB_INTERFACE_DIR}/${MATLAB_INTERFACE_NAME}.m
DESTINATION ${MATLAB_INTERFACE_DESTINATION}
)


file(
COPY ${MATLAB_INTERFACE_DIR}/${MATLAB_INTERFACE_NAME}_options.m
DESTINATION ${MATLAB_INTERFACE_DESTINATION}
)

# HERE STARTS A HACK
# Copy over new interface .m file
file(
COPY ${MATLAB_INTERFACE_DIR}/@LCQProblem/LCQProblem.m
DESTINATION ${MATLAB_INTERFACE_DESTINATION}/@LCQProblem
)
# Include new matlab interface stuff
# constructProblem
matlab_add_mex(
NAME constructProblem
SRC ${MATLAB_INTERFACE_DIR}/@LCQProblem/constructProblem.cpp
OUTPUT_NAME ${MATLAB_INTERFACE_DESTINATION}/@LCQProblem/constructProblem
LINK_TO "-llcqpow -lqpOASES -losqp -lmwblas -lmwlapack -lmwma57"
)

target_link_directories(
constructProblem
PUBLIC ${CMAKE_BINARY_DIR}/lib
)

target_compile_options(
constructProblem
PUBLIC -D${DEF_SOLVER}
PUBLIC -D__USE_LONG_FINTS__
PUBLIC -D__MATLAB__
PUBLIC -D__NO_COPYRIGHT__
PUBLIC -D__cpluplus
PUBLIC -O
PUBLIC -largeArrayDims
PUBLIC -lmwblas
PUBLIC -lmwlapack
PUBLIC -lmwma57
PUBLIC -llcqpow
PUBLIC -lqpOASES
PUBLIC -losqp
)

target_include_directories(
constructProblem
PRIVATE include
SYSTEM ${osqp_include}
SYSTEM ${qpoases_include}
)

# destructProblem
matlab_add_mex(
NAME destructProblem
SRC ${MATLAB_INTERFACE_DIR}/@LCQProblem/destructProblem.cpp
OUTPUT_NAME ${MATLAB_INTERFACE_DESTINATION}/@LCQProblem/destructProblem
LINK_TO "-llcqpow -lqpOASES -losqp -lmwblas -lmwlapack -lmwma57"
)

target_link_directories(
destructProblem
PUBLIC ${CMAKE_BINARY_DIR}/lib
)

target_compile_options(
destructProblem
PUBLIC -D${DEF_SOLVER}
PUBLIC -D__USE_LONG_FINTS__
PUBLIC -D__MATLAB__
PUBLIC -D__NO_COPYRIGHT__
PUBLIC -D__cpluplus
PUBLIC -O
PUBLIC -largeArrayDims
PUBLIC -lmwblas
PUBLIC -lmwlapack
PUBLIC -lmwma57
PUBLIC -llcqpow
PUBLIC -lqpOASES
PUBLIC -losqp
)

target_include_directories(
destructProblem
PRIVATE include
SYSTEM ${osqp_include}
SYSTEM ${qpoases_include}
)

# loadLCQP
matlab_add_mex(
NAME loadLCQP
SRC ${MATLAB_INTERFACE_DIR}/@LCQProblem/loadLCQP.cpp
OUTPUT_NAME ${MATLAB_INTERFACE_DESTINATION}/@LCQProblem/loadLCQP
LINK_TO "-llcqpow -lqpOASES -losqp -lmwblas -lmwlapack -lmwma57"
)

target_link_directories(
loadLCQP
PUBLIC ${CMAKE_BINARY_DIR}/lib
)

target_compile_options(
loadLCQP
PUBLIC -D${DEF_SOLVER}
PUBLIC -D__USE_LONG_FINTS__
PUBLIC -D__MATLAB__
PUBLIC -D__NO_COPYRIGHT__
PUBLIC -D__cpluplus
PUBLIC -O
PUBLIC -largeArrayDims
PUBLIC -lmwblas
PUBLIC -lmwlapack
PUBLIC -lmwma57
PUBLIC -llcqpow
PUBLIC -lqpOASES
PUBLIC -losqp
PUBLIC -g
)

target_include_directories(
loadLCQP
PRIVATE include
SYSTEM ${osqp_include}
SYSTEM ${qpoases_include}
)

# runProblem
matlab_add_mex(
NAME runProblem
SRC ${MATLAB_INTERFACE_DIR}/@LCQProblem/runProblem.cpp
OUTPUT_NAME ${MATLAB_INTERFACE_DESTINATION}/@LCQProblem/runProblem
LINK_TO "-llcqpow -lqpOASES -losqp -lmwblas -lmwlapack -lmwma57"
)

target_link_directories(
runProblem
PUBLIC ${CMAKE_BINARY_DIR}/lib
)

target_compile_options(
runProblem
PUBLIC -D${DEF_SOLVER}
PUBLIC -D__USE_LONG_FINTS__
PUBLIC -D__MATLAB__
PUBLIC -D__NO_COPYRIGHT__
PUBLIC -D__cpluplus
PUBLIC -O
PUBLIC -largeArrayDims
PUBLIC -lmwblas
PUBLIC -lmwlapack
PUBLIC -lmwma57
PUBLIC -llcqpow
PUBLIC -lqpOASES
PUBLIC -losqp
PUBLIC -g
)

target_include_directories(
runProblem
PRIVATE include
SYSTEM ${osqp_include}
SYSTEM ${qpoases_include}
)

endif()

endif()
Expand Down
24 changes: 24 additions & 0 deletions include/LCQProblem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,30 @@ namespace LCQPow {
*/
inline void setOptions( const Options& _options );

/** Get nV
*
* @return Returns nV.
*/
int getNV() const;

/** Get nV
*
* @return Returns nC.
*/
int getNC() const;

/** Get nV
*
* @return Returns nComp.
*/
int getNComp() const;

/** Get (a copy of) Options object
*
* @return Returns deep copy of current Options object.
*/
Options getOptions() const;


/**
* PROTECTED METHODS
Expand Down
3 changes: 2 additions & 1 deletion include/Utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ namespace LCQPow {

/** Clear sparse matrix **/
static void ClearSparseMat(csc* M);
static void ClearSparseMatCPP(csc* M);


/** Clear sparse matrix **/
Expand Down Expand Up @@ -368,4 +369,4 @@ namespace LCQPow {
};
}

#endif // LCQPOW_UTILITIES_HPP
#endif // LCQPOW_UTILITIES_HPP
29 changes: 29 additions & 0 deletions interfaces/matlab/@LCQProblem/LCQProblem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
classdef LCQProblem < handle
properties%(Access=private)
self % ptr to C++ LCQProblem object. On a 64 bit x86
end

methods
% Constuctor
function obj = LCQProblem(nV, nC, nComp)
obj.constructProblem(nV, nC, nComp);
end


%
loadLCQP(obj, Q, g, L, R, lbL, ubL, lbR, ubR, A, lbA, ubA, lb, ub, opts);

%
[varargout] = runSolver(obj);

function delete(obj)
% obj is always scalar, if it isn't we panic :)
obj.destructProblem();
end
end

methods(Access=private)
constructProblem(obj, nV, nC, nComp);
destructProblem(obj);
end
end
85 changes: 85 additions & 0 deletions interfaces/matlab/@LCQProblem/constructProblem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* This file is part of LCQPow.
*
* LCQPow -- A Solver for Quadratic Programs with Commplementarity Constraints.
* Copyright (C) 2020 - 2022 by Jonas Hall et al.
*
* LCQPow is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* LCQPow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with LCQPow; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "mex.hpp"
#include "mexAdapter.hpp"
#include "LCQProblem.hpp"
#include <cstdint>

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
public:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlab = getEngine();
matlab::data::ArrayFactory factory;

// Check inputs are valid
checkArguments(outputs, inputs);

// Assume the inputs are integral, this is generally not true but, shrug, it is fine.
int nV = (int) inputs[1][0];
int nC = (int) inputs[2][0];
int nComp = (int) inputs[3][0];

// Use raw pointer because we will have to handle this as an implicit unique pointer stored in matlab.
LCQPow::LCQProblem* problem = new LCQPow::LCQProblem(nV,nC,nComp);

// Reinterpret the pointer to an unsigned integer
std::uintptr_t self = reinterpret_cast<std::uintptr_t>(problem);

// Set the self property the current object
matlab->setProperty(inputs[0], u"self", factory.createScalar(self));
}

void checkArguments(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlab = getEngine();
matlab::data::ArrayFactory factory;
if(outputs.size() > 0)
{
matlab->feval(u"error", 0,
std::vector<matlab::data::Array>({ factory.createScalar("no outputs returned") }));

}
if(inputs.size() != 4)
{
matlab->feval(u"error", 0,
std::vector<matlab::data::Array>({ factory.createScalar("Incorrect number of inputs") }));

}
if (inputs[1].getType() != matlab::data::ArrayType::DOUBLE || inputs[1].getNumberOfElements() != 1)
{
matlab->feval(u"error", 0,
std::vector<matlab::data::Array>({ factory.createScalar("nV must be a scalar double") }));
}
if (inputs[2].getType() != matlab::data::ArrayType::DOUBLE || inputs[2].getNumberOfElements() != 1)
{
matlab->feval(u"error", 0,
std::vector<matlab::data::Array>({ factory.createScalar("nC must be a scalar double") }));
}
if (inputs[3].getType() != matlab::data::ArrayType::DOUBLE || inputs[3].getNumberOfElements() != 1)
{
matlab->feval(u"error", 0,
std::vector<matlab::data::Array>({ factory.createScalar("nComp must be a scalar double") }));
}
}
};
Loading